mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 13:03:33 +00:00
Compare commits
660 Commits
fairwaves/
...
sysmocom/i
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6950d14c5b | ||
|
|
cd5e52605c | ||
|
|
7c55ede8b1 | ||
|
|
5f2524fe3d | ||
|
|
cf2ca648e9 | ||
|
|
62ee416d95 | ||
|
|
e42a2ab158 | ||
|
|
9336cede84 | ||
|
|
8c6732909b | ||
|
|
960d28087e | ||
|
|
a27b295100 | ||
|
|
9015d4db52 | ||
|
|
3cda077541 | ||
|
|
c3da27fa98 | ||
|
|
bfc190e0fc | ||
|
|
f959ad8991 | ||
|
|
f3bcdd272b | ||
|
|
1d125c902f | ||
|
|
35ebbbea7a | ||
|
|
a95927c1de | ||
|
|
03ded61060 | ||
|
|
26d0326157 | ||
|
|
885a11b33e | ||
|
|
99f2477653 | ||
|
|
a9791df3b9 | ||
|
|
d9202b342c | ||
|
|
c902bd4032 | ||
|
|
ad21c3b8e3 | ||
|
|
28fdbdcd53 | ||
|
|
903ad2e135 | ||
|
|
04bfcdd6c2 | ||
|
|
3a9c52a5dc | ||
|
|
c6580c5b2c | ||
|
|
fb845bb1df | ||
|
|
6f4e83beb0 | ||
|
|
214302b306 | ||
|
|
defe78f1e1 | ||
|
|
061787878c | ||
|
|
00007897d4 | ||
|
|
5c4386c692 | ||
|
|
fc68c83ddb | ||
|
|
74101106a1 | ||
|
|
db916bfd8d | ||
|
|
a54358879f | ||
|
|
a54b47b048 | ||
|
|
3b922064a4 | ||
|
|
5b3fd465d1 | ||
|
|
5d547a4358 | ||
|
|
d8aa412c46 | ||
|
|
564c06525b | ||
|
|
31760a1f60 | ||
|
|
23d77d56ea | ||
|
|
50f1c0af56 | ||
|
|
eff215a8bb | ||
|
|
7ca035deca | ||
|
|
85234a32db | ||
|
|
842674b8b3 | ||
|
|
28903a99ea | ||
|
|
d3fa84dbba | ||
|
|
53373bca8f | ||
|
|
121e9a4164 | ||
|
|
3ffce19cb4 | ||
|
|
35697b9a10 | ||
|
|
299a999465 | ||
|
|
0991c684d3 | ||
|
|
dc4b14b269 | ||
|
|
687270de3a | ||
|
|
96f88fda06 | ||
|
|
2ae1f5b7e0 | ||
|
|
e01f5050ef | ||
|
|
8db12e4263 | ||
|
|
aafff96c40 | ||
|
|
26679e0475 | ||
|
|
27c3e76aa7 | ||
|
|
0c1bc26b64 | ||
|
|
36212f2850 | ||
|
|
63b99ced83 | ||
|
|
0b8e6dd2df | ||
|
|
9f2eaf8f56 | ||
|
|
afce55a4bc | ||
|
|
f3a1ca5d04 | ||
|
|
c7fcdeb18e | ||
|
|
3aa8b30bb3 | ||
|
|
208250558f | ||
|
|
bdb3f26668 | ||
|
|
69d3c26e43 | ||
|
|
3f18cfce85 | ||
|
|
658d1c3e14 | ||
|
|
6d1df9ad96 | ||
|
|
9bc1ddc849 | ||
|
|
90e2c751e9 | ||
|
|
15f6c9f1e8 | ||
|
|
5d5a25bc5a | ||
|
|
95c9f29634 | ||
|
|
30753e4a28 | ||
|
|
8fe0feb21b | ||
|
|
444a516f18 | ||
|
|
3a434f8e8c | ||
|
|
e43f8e0400 | ||
|
|
59a1bf3dae | ||
|
|
5fa7e36bbc | ||
|
|
f3f3505f49 | ||
|
|
c9ac20ea43 | ||
|
|
a6e81a0986 | ||
|
|
312bf6ce8b | ||
|
|
8bb6204d50 | ||
|
|
2abf2b072d | ||
|
|
e98c9c7136 | ||
|
|
84ae27e731 | ||
|
|
44ed4979c9 | ||
|
|
f1a61bb99f | ||
|
|
4936448761 | ||
|
|
82f5ecde6a | ||
|
|
70cf7290da | ||
|
|
a47b401990 | ||
|
|
714b170f89 | ||
|
|
7a301d3576 | ||
|
|
f220b52df3 | ||
|
|
e5686f21d6 | ||
|
|
0f3bce4aef | ||
|
|
edafdc14f3 | ||
|
|
54fc3a1318 | ||
|
|
baefda5d64 | ||
|
|
8dfe9690c5 | ||
|
|
687f048ab0 | ||
|
|
fafb074268 | ||
|
|
a3dfdcb308 | ||
|
|
bae2594424 | ||
|
|
5e007d9445 | ||
|
|
42024336fe | ||
|
|
9bcb1a56cb | ||
|
|
adb86759da | ||
|
|
2826df56b2 | ||
|
|
de392254ff | ||
|
|
7dd2eed6d3 | ||
|
|
bb81326719 | ||
|
|
c6a65511f3 | ||
|
|
740e65fb7b | ||
|
|
3a38ee6c3d | ||
|
|
276192d27c | ||
|
|
c4b9b4edbb | ||
|
|
b70dfa610d | ||
|
|
cf1302e4cb | ||
|
|
0d929be826 | ||
|
|
4e875aec0f | ||
|
|
f9b212fabd | ||
|
|
d617c5d3ac | ||
|
|
4554a62c4d | ||
|
|
37984bdb1b | ||
|
|
56ea30ff3f | ||
|
|
4b940126a3 | ||
|
|
debb0e3868 | ||
|
|
d025a3cfbb | ||
|
|
4b3b13e10c | ||
|
|
fa48a98e71 | ||
|
|
9fd87ecd11 | ||
|
|
8e5c63f032 | ||
|
|
2cd36e87ae | ||
|
|
0bc6c11cbf | ||
|
|
182adecb98 | ||
|
|
3d0a500f2d | ||
|
|
a5c9cea22c | ||
|
|
f45dc35321 | ||
|
|
2f6c4b6479 | ||
|
|
2385074cba | ||
|
|
d8b0b61ca8 | ||
|
|
19f0735752 | ||
|
|
ffd9968d3a | ||
|
|
3ad0346f00 | ||
|
|
044fbe6568 | ||
|
|
d2fa7a509a | ||
|
|
deb227b98e | ||
|
|
5e611021b0 | ||
|
|
f4afcf0b23 | ||
|
|
d04db9d907 | ||
|
|
10cd11345c | ||
|
|
8c515272c3 | ||
|
|
961bd0b121 | ||
|
|
531734a547 | ||
|
|
3c94c2c597 | ||
|
|
372a3bd346 | ||
|
|
51bf76ef47 | ||
|
|
aa60582036 | ||
|
|
6b2623d944 | ||
|
|
8b1272a6d3 | ||
|
|
080921a551 | ||
|
|
8e7f4c6f21 | ||
|
|
4a9b871de5 | ||
|
|
93f6fa5a81 | ||
|
|
f1777ee843 | ||
|
|
9e8e0e6a29 | ||
|
|
cf3d2a1fad | ||
|
|
e4baf402cb | ||
|
|
53d782fc38 | ||
|
|
33a343858d | ||
|
|
15b1fce69c | ||
|
|
2f8117d214 | ||
|
|
8927bb46d5 | ||
|
|
d52b1c4342 | ||
|
|
5d9004bc9b | ||
|
|
a4198d1922 | ||
|
|
544a203f67 | ||
|
|
b40df4c09e | ||
|
|
5c1c0bad89 | ||
|
|
1e361301d1 | ||
|
|
9e8322ca0c | ||
|
|
9bd121b75b | ||
|
|
fa029f08c2 | ||
|
|
db9c064dd4 | ||
|
|
a0da2dbe9e | ||
|
|
7df5705251 | ||
|
|
da7424cc54 | ||
|
|
8146cfa782 | ||
|
|
330898afb7 | ||
|
|
77544a65b5 | ||
|
|
4e5ddfa91a | ||
|
|
cba441f3de | ||
|
|
3acbc817f6 | ||
|
|
bcb98b1754 | ||
|
|
2a7426d7cb | ||
|
|
b9bb2a4f54 | ||
|
|
098c14800f | ||
|
|
a46c651a4a | ||
|
|
4cc1f72cb7 | ||
|
|
4f143e52b6 | ||
|
|
e3407f8884 | ||
|
|
7d1b6b1c79 | ||
|
|
656d7cd0b4 | ||
|
|
553d2a8ceb | ||
|
|
23f22b1183 | ||
|
|
090aabe052 | ||
|
|
be37fbd85d | ||
|
|
3cc0836b1a | ||
|
|
8cd32937da | ||
|
|
377a9f5dea | ||
|
|
b8df4d5318 | ||
|
|
daa0652d3f | ||
|
|
f7436b22b3 | ||
|
|
711333c113 | ||
|
|
91f04dfe3a | ||
|
|
4371ff8cce | ||
|
|
92223cc32e | ||
|
|
2f5cc8abe0 | ||
|
|
ba47b525ff | ||
|
|
cf1707af7f | ||
|
|
d6d0d8b86f | ||
|
|
38137e84f7 | ||
|
|
82724653e7 | ||
|
|
da8d9bc355 | ||
|
|
c59e52a6aa | ||
|
|
24c4af1d82 | ||
|
|
f918920d65 | ||
|
|
292f1ce533 | ||
|
|
23e7f28c5c | ||
|
|
243c7cb044 | ||
|
|
cf2591f6fc | ||
|
|
6a2d8985bf | ||
|
|
c6794eed1d | ||
|
|
7a70a4f52a | ||
|
|
c6172a320b | ||
|
|
5280ed558c | ||
|
|
b36b910366 | ||
|
|
b47e52c958 | ||
|
|
267f6c7e0d | ||
|
|
5e47b1a1d3 | ||
|
|
b9e5403ef4 | ||
|
|
b6769b99de | ||
|
|
39daffd7a5 | ||
|
|
71d1e17e5e | ||
|
|
2c9e65051c | ||
|
|
a2ce4aa615 | ||
|
|
ee1541d504 | ||
|
|
9dcae17866 | ||
|
|
c2c5176328 | ||
|
|
a2c182df6d | ||
|
|
070f673b12 | ||
|
|
e2a10dbe35 | ||
|
|
bf30ec26e5 | ||
|
|
dcbc852125 | ||
|
|
48e091ea2b | ||
|
|
712074cb17 | ||
|
|
a34aedf7f9 | ||
|
|
2e5c13129d | ||
|
|
da5b3fcd32 | ||
|
|
5291ee5c16 | ||
|
|
5773987881 | ||
|
|
836b904e77 | ||
|
|
444d50b77f | ||
|
|
b3b8ccfa54 | ||
|
|
231aa60ce4 | ||
|
|
8b713f817d | ||
|
|
ce3b41fdb6 | ||
|
|
0f93bb80e4 | ||
|
|
477a054c2c | ||
|
|
52ddce4378 | ||
|
|
2945fd4611 | ||
|
|
2449c0ce58 | ||
|
|
5d145b5477 | ||
|
|
45b13244f0 | ||
|
|
cb91aa7e6c | ||
|
|
7ef6d9893f | ||
|
|
6aeee0a0d9 | ||
|
|
17d061bd8e | ||
|
|
ef3548c0a1 | ||
|
|
add0953692 | ||
|
|
ca3977c8fe | ||
|
|
a234287d09 | ||
|
|
8440c9f04b | ||
|
|
2cb732aeb9 | ||
|
|
a7551e033e | ||
|
|
08ed1d73f2 | ||
|
|
af9bfac58d | ||
|
|
ac9951e54a | ||
|
|
75cdeaf1e3 | ||
|
|
41f8f047bc | ||
|
|
195d2dc724 | ||
|
|
315abfd46b | ||
|
|
648b9db47f | ||
|
|
8291623054 | ||
|
|
5331cf8dbd | ||
|
|
cf8e56cd1e | ||
|
|
e157174447 | ||
|
|
493534bf56 | ||
|
|
342f59d92e | ||
|
|
aefb0c45e9 | ||
|
|
692f31446e | ||
|
|
2cde90e904 | ||
|
|
f6672ab8b0 | ||
|
|
51273157fa | ||
|
|
6a1d172c95 | ||
|
|
45ee133d1d | ||
|
|
5b38312b92 | ||
|
|
49b83d8f67 | ||
|
|
a7313dd886 | ||
|
|
fea1df8587 | ||
|
|
1b0e5540db | ||
|
|
73828152d9 | ||
|
|
fc7add20e1 | ||
|
|
f4a3123145 | ||
|
|
0ade63233b | ||
|
|
fa0f71526c | ||
|
|
58d5430dd5 | ||
|
|
127fc93a13 | ||
|
|
547f048c89 | ||
|
|
fd1187e2e9 | ||
|
|
1901b92f0c | ||
|
|
69da1d453c | ||
|
|
03933a49de | ||
|
|
389a62d752 | ||
|
|
5ac4aadd1a | ||
|
|
1330478aa5 | ||
|
|
d35957a7d9 | ||
|
|
d58c033305 | ||
|
|
e7bcdc3bda | ||
|
|
9158089fa8 | ||
|
|
3fbf0a3735 | ||
|
|
2259c7528e | ||
|
|
28e9f60404 | ||
|
|
bafc1e4cfe | ||
|
|
e9f420d487 | ||
|
|
8239e063b9 | ||
|
|
1da0a7e229 | ||
|
|
6d575cbe57 | ||
|
|
34cf923704 | ||
|
|
9c4f1d6fd0 | ||
|
|
1bf8617610 | ||
|
|
de76661cf3 | ||
|
|
f9f44901a2 | ||
|
|
fec29ab4e9 | ||
|
|
7ba088bdf0 | ||
|
|
91e0e1b038 | ||
|
|
22a7142129 | ||
|
|
6cacc56d8e | ||
|
|
5cb480a4c0 | ||
|
|
cdc548cb0a | ||
|
|
69a720f3be | ||
|
|
da5359f1b6 | ||
|
|
720372e4e8 | ||
|
|
4adca4e8af | ||
|
|
0a8cf32a48 | ||
|
|
53d51f501c | ||
|
|
da8a19fec0 | ||
|
|
36948bf7c7 | ||
|
|
4d2b3ff6a2 | ||
|
|
d010c49407 | ||
|
|
bee75969cc | ||
|
|
ee07e4f75d | ||
|
|
f6e4d08219 | ||
|
|
328d2f78c1 | ||
|
|
23d09cc904 | ||
|
|
ee1e5d758e | ||
|
|
e38fb66f4b | ||
|
|
956d856b61 | ||
|
|
ba0525e3d8 | ||
|
|
28a70f20cd | ||
|
|
9d8f506f7f | ||
|
|
5d5c31a367 | ||
|
|
5c7dcf9665 | ||
|
|
3f015f04b1 | ||
|
|
c14574b567 | ||
|
|
d8352d75b6 | ||
|
|
c696cc28d8 | ||
|
|
e1ba781f7b | ||
|
|
f8c701008b | ||
|
|
1ae3ebd68b | ||
|
|
ca2361c237 | ||
|
|
d53c6046bc | ||
|
|
e5a0798c9c | ||
|
|
8c5b073072 | ||
|
|
8defadbdd2 | ||
|
|
59c1b645e2 | ||
|
|
87c83d0b89 | ||
|
|
d8660ef090 | ||
|
|
c6d51f5fb4 | ||
|
|
996ec1d731 | ||
|
|
18d3049612 | ||
|
|
237fee649e | ||
|
|
936b890f71 | ||
|
|
be4bebaad0 | ||
|
|
4573ca8834 | ||
|
|
52c0bd3025 | ||
|
|
bc44330671 | ||
|
|
3fdba2ed5a | ||
|
|
7559910e8c | ||
|
|
99a50b3529 | ||
|
|
10fc024472 | ||
|
|
2f67125c32 | ||
|
|
800126b1f3 | ||
|
|
cd865d62f0 | ||
|
|
085500807c | ||
|
|
ff4b630de9 | ||
|
|
817bc32696 | ||
|
|
a9905a51f9 | ||
|
|
7174b169e0 | ||
|
|
d121ea6124 | ||
|
|
f977320736 | ||
|
|
ba9e9f63bc | ||
|
|
8d1ffbd3ba | ||
|
|
005f175c3b | ||
|
|
fc1be3a0c1 | ||
|
|
e54cd1555a | ||
|
|
2c8b58139f | ||
|
|
1aa0e47104 | ||
|
|
508514c7c5 | ||
|
|
29d926be12 | ||
|
|
231653a8d0 | ||
|
|
4b2cbdab3e | ||
|
|
1ba50c6598 | ||
|
|
dba6d1af69 | ||
|
|
20bd6bfef5 | ||
|
|
1ed9a8673d | ||
|
|
b6c2db569f | ||
|
|
d9b1d49485 | ||
|
|
4960fab767 | ||
|
|
e2ed8e6cc3 | ||
|
|
334af5dd9d | ||
|
|
5e95a41194 | ||
|
|
e5e78c21bb | ||
|
|
ff252bb801 | ||
|
|
8fbfaa51bb | ||
|
|
4ae165da61 | ||
|
|
a4370dd969 | ||
|
|
273f875c42 | ||
|
|
6a8cbe9718 | ||
|
|
97b6bfa996 | ||
|
|
1b9c815024 | ||
|
|
557c84e9f7 | ||
|
|
a2bbc5ec0e | ||
|
|
ae2c18c57b | ||
|
|
0d21ac8f5a | ||
|
|
24e3c3e136 | ||
|
|
6187e010a8 | ||
|
|
3c820ee532 | ||
|
|
3d3aa8fb88 | ||
|
|
4034897038 | ||
|
|
ad945b6aa7 | ||
|
|
9cfe037559 | ||
|
|
063a802d46 | ||
|
|
390e910125 | ||
|
|
a208c734a2 | ||
|
|
16c3f57ed6 | ||
|
|
3317c84c16 | ||
|
|
c83cd898ef | ||
|
|
e921e32c82 | ||
|
|
c227594394 | ||
|
|
5b664f4b9b | ||
|
|
bb3d6785e1 | ||
|
|
30f7bcbd79 | ||
|
|
c8a614d2e9 | ||
|
|
65482c919f | ||
|
|
98fa3dc1c6 | ||
|
|
9270dc8ca3 | ||
|
|
4316cb2f25 | ||
|
|
292769e19e | ||
|
|
46caed8fc4 | ||
|
|
64630cccc7 | ||
|
|
11cb27ece6 | ||
|
|
568a727550 | ||
|
|
9c534fdbe8 | ||
|
|
89ef324eab | ||
|
|
f06046b6af | ||
|
|
d739f092be | ||
|
|
d48f057328 | ||
|
|
fe60cfb1d6 | ||
|
|
69ca8f01ec | ||
|
|
537d480f39 | ||
|
|
d1554ecb78 | ||
|
|
044ce5fb84 | ||
|
|
133e8624ef | ||
|
|
cf15187458 | ||
|
|
a777c9ee3d | ||
|
|
9861c122dd | ||
|
|
fa07b489dc | ||
|
|
f3316e30d6 | ||
|
|
d74cce266b | ||
|
|
6962127982 | ||
|
|
1afe7c7fe5 | ||
|
|
20626dde8f | ||
|
|
6598ded5cd | ||
|
|
15a40db606 | ||
|
|
b45e4d80b6 | ||
|
|
641d387409 | ||
|
|
2aedfbdfe1 | ||
|
|
62a63f54a6 | ||
|
|
6cf0249dac | ||
|
|
cdeb815c78 | ||
|
|
b3cbd9aa3b | ||
|
|
0e62e595a6 | ||
|
|
06cfe00c71 | ||
|
|
8b4e584621 | ||
|
|
7a77d0155f | ||
|
|
a174a47811 | ||
|
|
615ed46a6a | ||
|
|
11cb7a9fd9 | ||
|
|
130be40c3e | ||
|
|
d3496aed69 | ||
|
|
3e4e8cfb74 | ||
|
|
925504bfe0 | ||
|
|
e57e0fa701 | ||
|
|
732665269e | ||
|
|
354d1f3084 | ||
|
|
c6a8d09b78 | ||
|
|
51cf69cdb4 | ||
|
|
4b4a187b4f | ||
|
|
53122b09d0 | ||
|
|
c21dcb20e5 | ||
|
|
c8a6c13e4e | ||
|
|
ffbf45e09e | ||
|
|
08c508f84a | ||
|
|
d721579a6a | ||
|
|
92360b15e3 | ||
|
|
614aba391d | ||
|
|
79135acbb8 | ||
|
|
e5ba92e7be | ||
|
|
e18f78e81d | ||
|
|
8fc568466c | ||
|
|
0190d790b6 | ||
|
|
c390ae8eaf | ||
|
|
e6ed009a36 | ||
|
|
ceef936ea8 | ||
|
|
57e95a22f0 | ||
|
|
ecff2424e5 | ||
|
|
b9845f937e | ||
|
|
6b39feedc7 | ||
|
|
601cf12f81 | ||
|
|
eb98c74fb1 | ||
|
|
22df4ac848 | ||
|
|
78fa99103d | ||
|
|
6a19dd0d31 | ||
|
|
9450882901 | ||
|
|
39ba248608 | ||
|
|
4d4944a07d | ||
|
|
93e795c1fd | ||
|
|
4c97435b35 | ||
|
|
d17bc7b3a8 | ||
|
|
a334e90ddf | ||
|
|
aeadf261e5 | ||
|
|
ca7d05bdb9 | ||
|
|
a611da8407 | ||
|
|
0eaad4f216 | ||
|
|
e9f7c9925c | ||
|
|
29d58b734d | ||
|
|
c9dbe3c7b1 | ||
|
|
2f25764e51 | ||
|
|
5425e5ea27 | ||
|
|
8159455506 | ||
|
|
e019b564ec | ||
|
|
eb48cafac9 | ||
|
|
778c7d1544 | ||
|
|
ba43365e96 | ||
|
|
469f992b2b | ||
|
|
b618c7ec9b | ||
|
|
daaea0c84f | ||
|
|
5c06e4045a | ||
|
|
145e2532f4 | ||
|
|
666e36aea9 | ||
|
|
5f8a0c5c70 | ||
|
|
d15409876c | ||
|
|
4672059d94 | ||
|
|
a2c41c42b1 | ||
|
|
1e365477ee | ||
|
|
14a434b9d6 | ||
|
|
7c19c6b406 | ||
|
|
42cf2e03c9 | ||
|
|
dcbc83355e | ||
|
|
e3c391e8d0 | ||
|
|
af1b968b22 | ||
|
|
b69518f383 | ||
|
|
58ec15c4ed | ||
|
|
9f95ae8885 | ||
|
|
8ee53ed9ec | ||
|
|
694d98042f | ||
|
|
e2ac6b77fe | ||
|
|
9705671025 | ||
|
|
fce6971fe3 | ||
|
|
8a8df80772 | ||
|
|
0363d1bb97 | ||
|
|
aa0cecd9b7 | ||
|
|
2dd18bdd87 | ||
|
|
57ee780789 | ||
|
|
797eb7b592 | ||
|
|
4bb3fccb75 | ||
|
|
b25c8342cc | ||
|
|
c58a1e573b | ||
|
|
ce97a06fa3 | ||
|
|
0958938d4e | ||
|
|
f2e114ac85 | ||
|
|
65b0efe56e | ||
|
|
c36a13b073 | ||
|
|
9cb249bf84 | ||
|
|
5fd0c64e0a | ||
|
|
b7ae0b34f9 | ||
|
|
a5a6da46a0 | ||
|
|
39c430ee29 | ||
|
|
66e7106d39 | ||
|
|
ccd2312d10 | ||
|
|
7605bdc02c | ||
|
|
08bb84b04e | ||
|
|
9270d99f3d | ||
|
|
5e4b88cbb2 | ||
|
|
8ee13e2937 | ||
|
|
10c0f56a0e | ||
|
|
0bb5674cde | ||
|
|
e54a24d4e6 | ||
|
|
0f7a279a06 | ||
|
|
c1c6a28c8d | ||
|
|
4c6e667968 | ||
|
|
072bee5c85 | ||
|
|
267fd0c7f7 | ||
|
|
d6900dfba4 | ||
|
|
6ddb6ac028 | ||
|
|
22093ef964 | ||
|
|
77ff1c40e2 | ||
|
|
446f8403d1 | ||
|
|
7882d2751f | ||
|
|
c15c61c401 | ||
|
|
4f5b8237ec | ||
|
|
b100895557 | ||
|
|
20de3ae17c | ||
|
|
b448dd849a |
57
contrib/jenkins.sh
Executable file
57
contrib/jenkins.sh
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex
|
||||
|
||||
rm -rf deps/install
|
||||
mkdir deps || true
|
||||
export LD_LIBRARY_PATH=$PWD/deps/install/lib
|
||||
cd deps
|
||||
osmo-deps.sh libosmocore
|
||||
|
||||
cd libosmocore
|
||||
autoreconf --install --force
|
||||
./configure --prefix=$PWD/../install
|
||||
$MAKE $PARALLEL_MAKE install
|
||||
|
||||
|
||||
cd ../
|
||||
osmo-deps.sh libosmo-abis
|
||||
cd libosmo-abis
|
||||
autoreconf --install --force
|
||||
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
|
||||
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
|
||||
|
||||
cd ../
|
||||
osmo-deps.sh libosmo-netif
|
||||
cd libosmo-netif
|
||||
autoreconf --install --force
|
||||
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
|
||||
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
|
||||
|
||||
cd ../
|
||||
osmo-deps.sh libosmo-sccp
|
||||
cd libosmo-sccp
|
||||
autoreconf --install --force
|
||||
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
|
||||
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
|
||||
|
||||
cd ../
|
||||
osmo-deps.sh libsmpp34
|
||||
cd libsmpp34
|
||||
autoreconf --install --force
|
||||
./configure --prefix=$PWD/../install
|
||||
$MAKE install
|
||||
|
||||
cd ../
|
||||
osmo-deps.sh openggsn
|
||||
cd openggsn
|
||||
autoreconf --install --force
|
||||
PKG_CONFIG_PATH=$PWD/../install/lib/pkgconfig ./configure --prefix=$PWD/../install
|
||||
PKG_CONFIG_PATH=$PWD/..//install/lib/pkgconfig $MAKE $PARALLEL_MAKE install
|
||||
|
||||
cd ../../openbsc
|
||||
autoreconf --install --force
|
||||
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig ./configure --enable-osmo-bsc --enable-nat $SMPP $MGCP --enable-vty-tests --enable-external-tests
|
||||
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig $MAKE $PARALLEL_MAKE
|
||||
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/../deps/install/lib $MAKE check
|
||||
PKG_CONFIG_PATH=$PWD/../deps/install/lib/pkgconfig LD_LIBRARY_PATH=$PWD/../deps/install/lib $MAKE distcheck
|
||||
18
debian/control
vendored
18
debian/control
vendored
@@ -2,7 +2,7 @@ Source: openbsc
|
||||
Section: net
|
||||
Priority: optional
|
||||
Maintainer: Harald Welte <laforge@gnumonks.org>
|
||||
Build-Depends: debhelper (>= 7.0.0~), autotools-dev, pkg-config, libgtp0-dev, libosmocore-dev, libosmo-sccp-dev, libdbi0-dev, dh-autoreconf, libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, libpcap-dev
|
||||
Build-Depends: debhelper (>= 7.0.0~), autotools-dev, pkg-config, libgtp0-dev, libosmocore-dev, libosmo-sccp-dev, libdbi0-dev, dh-autoreconf, libosmo-abis-dev, libosmo-netif-dev, libdbd-sqlite3, libpcap-dev, libssl-dev, libc-ares-dev, libsmpp34-dev
|
||||
Standards-Version: 3.8.4
|
||||
Homepage: http://openbsc.osmocom.org/
|
||||
Vcs-Git: git://bs11-abis.gnumonks.org/openbsc.git
|
||||
@@ -16,7 +16,7 @@ Description: GSM Base Station Controller; BSC-only version of OpenBSC. Needs a
|
||||
|
||||
Package: osmocom-nitb
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends} libdbd-sqlite3
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libdbd-sqlite3
|
||||
Description: GSM Network-in-a-Box, implements BSC, MSC, SMSC, HLR, VLR
|
||||
All the GSM network components bundled together.
|
||||
|
||||
@@ -50,6 +50,12 @@ Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Osmocom Base Station Controller Network Address Translation
|
||||
Network address translation for BSC.
|
||||
|
||||
Package: osmo-gtphub
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: Osmocom GTP Hub
|
||||
Proxy for comms between multiple SGSNs and GGSNs.
|
||||
|
||||
Package: osmocom-bsc-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
@@ -105,3 +111,11 @@ Priority: extra
|
||||
Depends: osmocom-bsc-nat (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for the OpenBSC Network Address Translation
|
||||
Make debugging possible
|
||||
|
||||
Package: osmo-gtphub-dbg
|
||||
Architecture: any
|
||||
Section: debug
|
||||
Priority: extra
|
||||
Depends: osmo-gtphub (= ${binary:Version}), ${misc:Depends}
|
||||
Description: Debug symbols for Osmocom GTP Hub
|
||||
Make debugging possible
|
||||
|
||||
2
debian/docs
vendored
2
debian/docs
vendored
@@ -1 +1 @@
|
||||
README
|
||||
openbsc/README
|
||||
|
||||
2
debian/osmo-gtphub.default
vendored
Normal file
2
debian/osmo-gtphub.default
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
CONFIG_FILE="/etc/osmocom/osmo-gtphub.cfg"
|
||||
|
||||
1
debian/osmo-gtphub.examples
vendored
Normal file
1
debian/osmo-gtphub.examples
vendored
Normal file
@@ -0,0 +1 @@
|
||||
openbsc/doc/examples/osmo-gtphub
|
||||
150
debian/osmo-gtphub.init
vendored
Executable file
150
debian/osmo-gtphub.init
vendored
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: osmo-gtphub
|
||||
# Required-Start: $network $local_fs
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Osmocom GTP hub
|
||||
# Description: Osmocom GTP hub
|
||||
### END INIT INFO
|
||||
|
||||
# Author: Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
NAME=osmo-gtphub # Introduce the short server's name here
|
||||
DESC="Osmocom GTP hub" # Introduce a short description here
|
||||
DAEMON=/usr/bin/osmo-gtphub # Introduce the server's location here
|
||||
SCRIPTNAME=/etc/init.d/osmo-gtphub
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x $DAEMON ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/default/osmo-gtphub ] && . /etc/default/osmo-gtphub
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
DAEMON_ARGS="$DAEMON_ARGS -D -c $CONFIG_FILE"
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --exec $DAEMON -- \
|
||||
$DAEMON_ARGS \
|
||||
|| return 2
|
||||
# Add code here, if necessary, that waits for the process to be ready
|
||||
# to handle requests from services started subsequently which depend
|
||||
# on this one. As a last resort, sleep for some time.
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
|
||||
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
#reload|force-reload)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
1
debian/osmo-gtphub.install
vendored
Normal file
1
debian/osmo-gtphub.install
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/usr/bin/osmo-gtphub
|
||||
2
debian/osmocom-ipaccess-utils.install
vendored
2
debian/osmocom-ipaccess-utils.install
vendored
@@ -1,3 +1,3 @@
|
||||
/usr/bin/ipaccess-config
|
||||
/usr/bin/ipaccess-find
|
||||
/usr/bin/abisip-find
|
||||
/usr/bin/ipaccess-proxy
|
||||
|
||||
3
debian/rules
vendored
3
debian/rules
vendored
@@ -34,8 +34,9 @@ override_dh_strip:
|
||||
dh_strip -posmocom-sgsn --dbg-package=osmocom-sgsn-dbg
|
||||
dh_strip -posmocom-gbproxy --dbg-package=osmocom-gbproxy-dbg
|
||||
dh_strip -posmocom-bsc-nat --dbg-package=osmocom-bsc-nat-dbg
|
||||
dh_strip -posmo-gtphub --dbg-package=osmo-gtphub-dbg
|
||||
|
||||
override_dh_auto_configure:
|
||||
echo $(VERSION) > openbsc/.tarball-version
|
||||
dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc
|
||||
dh_auto_configure --sourcedirectory=openbsc -- --enable-nat --enable-osmo-bsc --enable-smpp
|
||||
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c linux-2.6.27.4/drivers/isdn/mISDN/layer2.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/layer2.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/layer2.c 2008-12-23 16:16:29.000000000 +0100
|
||||
@@ -94,8 +94,10 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
va_list va;
|
||||
|
||||
+#if 0
|
||||
if (!(*debug & DEBUG_L2_FSM))
|
||||
return;
|
||||
+#endif
|
||||
va_start(va, fmt);
|
||||
printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
|
||||
vprintk(fmt, va);
|
||||
@@ -882,6 +884,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
clear_exception(l2);
|
||||
send_uframe(l2, NULL, UA | get_PollFlag(l2, skb), RSP);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
@@ -898,6 +902,7 @@
|
||||
struct layer2 *l2 = fi->userdata;
|
||||
struct sk_buff *skb = arg;
|
||||
|
||||
+ printk(KERN_DEBUG "l2_send_UA()\n");
|
||||
send_uframe(l2, skb, UA | get_PollFlag(l2, skb), RSP);
|
||||
}
|
||||
|
||||
@@ -931,6 +936,8 @@
|
||||
l2->va = 0;
|
||||
l2->vr = 0;
|
||||
l2->sow = 0;
|
||||
+ l2->sapi = skb->data[0] >> 2;
|
||||
+ set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
mISDN_FsmChangeState(fi, ST_L2_7);
|
||||
stop_t200(l2, 3);
|
||||
mISDN_FsmRestartTimer(&l2->t203, l2->T203, EV_L2_T203, NULL, 3);
|
||||
@@ -982,6 +989,8 @@
|
||||
} else if (l2->vs != l2->va) {
|
||||
skb_queue_purge(&l2->i_queue);
|
||||
pr = DL_ESTABLISH_IND;
|
||||
+ //l2->sapi = skb->data[0] >> 2;
|
||||
+ //set_channel_address(&l2->ch, l2->sapi, l2->tei);
|
||||
}
|
||||
stop_t200(l2, 5);
|
||||
l2->vr = 0;
|
||||
@@ -1841,11 +1850,14 @@
|
||||
u_int l;
|
||||
int c = 0;
|
||||
|
||||
+ printk(KERN_DEBUG "ph_data_indication 0x%x 0x%x 0x%x\n", datap[0], datap[1], datap[2]);
|
||||
+
|
||||
l = l2addrsize(l2);
|
||||
if (skb->len <= l) {
|
||||
mISDN_FsmEvent(&l2->l2m, EV_L2_FRAME_ERROR, (void *) 'N');
|
||||
return ret;
|
||||
}
|
||||
+#if 0
|
||||
if (test_bit(FLG_LAPD, &l2->flag)) { /* Maybe not needed */
|
||||
psapi = *datap++;
|
||||
ptei = *datap++;
|
||||
@@ -1875,6 +1887,7 @@
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
+#endif
|
||||
datap += l;
|
||||
if (!(*datap & 1)) { /* I-Frame */
|
||||
c = iframe_error(l2, skb);
|
||||
@@ -1890,6 +1903,7 @@
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_UI, skb);
|
||||
} else if (IsSABME(datap, l2)) {
|
||||
c = unnum_error(l2, skb, CMD);
|
||||
+ printk(KERN_DEBUG "IsSABME() returned true, unnum_error=%d\n", c);
|
||||
if (!c)
|
||||
ret = mISDN_FsmEvent(&l2->l2m, EV_L2_SABME, skb);
|
||||
} else if (IsUA(datap)) {
|
||||
@@ -2087,7 +2101,7 @@
|
||||
test_and_set_bit(FLG_LAPD, &l2->flag);
|
||||
test_and_set_bit(FLG_LAPD_NET, &l2->flag);
|
||||
test_and_set_bit(FLG_MOD128, &l2->flag);
|
||||
- l2->sapi = 0;
|
||||
+ l2->sapi = 62;
|
||||
l2->maxlen = MAX_DFRAME_LEN;
|
||||
if (test_bit(OPTION_L2_PMX, &options))
|
||||
l2->window = 7;
|
||||
diff -Nru --exclude-from /sunbeam/home/laforge/scripts/dontdiff linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c linux-2.6.27.4/drivers/isdn/mISDN/tei.c
|
||||
--- linux-2.6.27.4-clean/drivers/isdn/mISDN/tei.c 2008-10-26 00:05:07.000000000 +0200
|
||||
+++ linux-2.6.27.4/drivers/isdn/mISDN/tei.c 2008-12-23 16:32:59.000000000 +0100
|
||||
@@ -830,18 +830,29 @@
|
||||
int tei, ri;
|
||||
struct layer2 *l2;
|
||||
|
||||
+ printk(KERN_DEBUG "new tei request: tei=%d\n", dp[3] >> 1);
|
||||
+
|
||||
ri = dp[0] << 8;
|
||||
ri += dp[1];
|
||||
- if (!mgr->up)
|
||||
- goto denied;
|
||||
- tei = get_free_tei(mgr);
|
||||
- if (tei < 0) {
|
||||
- printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ if (!mgr->up) {
|
||||
+ printk(KERN_DEBUG "mgr->up == NULL\n");
|
||||
goto denied;
|
||||
}
|
||||
+ if (dp[3] != 0xff) {
|
||||
+ /* This is a TEI request according to 3GPP TS 08.56 6.1.11.2 */
|
||||
+ tei = dp[3] >> 1;
|
||||
+ } else {
|
||||
+ tei = get_free_tei(mgr);
|
||||
+ if (tei < 0) {
|
||||
+ printk(KERN_WARNING "%s:No free tei\n", __func__);
|
||||
+ goto denied;
|
||||
+ }
|
||||
+ }
|
||||
l2 = create_new_tei(mgr, tei);
|
||||
- if (!l2)
|
||||
+ if (!l2) {
|
||||
+ printk(KERN_DEBUG "create_new_tei == NULL\n");
|
||||
goto denied;
|
||||
+ }
|
||||
else
|
||||
mISDN_FsmEvent(&l2->tm->tei_m, EV_ASSIGN_REQ, dp);
|
||||
return;
|
||||
@@ -1159,12 +1170,14 @@
|
||||
return -ENOTCONN;
|
||||
if (skb->len != 3)
|
||||
return -ENOTCONN;
|
||||
+#if 0
|
||||
if (skb->data[0] != 0)
|
||||
/* only SAPI 0 command */
|
||||
return -ENOTCONN;
|
||||
+#endif
|
||||
if (!(skb->data[1] & 1)) /* invalid EA1 */
|
||||
return -EINVAL;
|
||||
- tei = skb->data[1] >> 0;
|
||||
+ tei = skb->data[1] >> 1;
|
||||
if (tei > 63) /* not a fixed tei */
|
||||
return -ENOTCONN;
|
||||
if ((skb->data[2] & ~0x10) != SABME)
|
||||
@@ -1,486 +0,0 @@
|
||||
This experimental patch splits one E1 card into three virtual cards,
|
||||
|
||||
TS 1,2,3,4,5 is card 0
|
||||
TS 6,7,8,9,10 is card 1
|
||||
TS 11,12,13,14 is card 2
|
||||
|
||||
This allows you to run one L2 TEI handler on each of the virtual cards,
|
||||
which is required if you want to run multiple BTS on a single E1 link.
|
||||
|
||||
Thanks to Andreas Eversberg for this patch.
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi.h b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
index 0c77386..02dd4a1 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfc_multi.h
|
||||
@@ -209,14 +209,17 @@ struct hfc_multi {
|
||||
u_long ledstate; /* save last state of leds */
|
||||
int opticalsupport; /* has the e1 board */
|
||||
/* an optical Interface */
|
||||
- int dslot; /* channel # of d-channel (E1) default 16 */
|
||||
+
|
||||
+ u_int bmask[32]; /* bitmask of bchannels for port */
|
||||
+ u_char dnum[32]; /* array of used dchannel numbers for port */
|
||||
+ u_char created[32]; /* what port is created */
|
||||
+ u_int activity[32]; /* if there is any action on this */
|
||||
+ /* port (will be cleared after */
|
||||
+ /* showing led-states) */
|
||||
|
||||
u_long wdcount; /* every 500 ms we need to */
|
||||
/* send the watchdog a signal */
|
||||
u_char wdbyte; /* watchdog toggle byte */
|
||||
- u_int activity[8]; /* if there is any action on this */
|
||||
- /* port (will be cleared after */
|
||||
- /* showing led-states) */
|
||||
int e1_state; /* keep track of last state */
|
||||
int e1_getclock; /* if sync is retrieved from interface */
|
||||
int syncronized; /* keep track of existing sync interface */
|
||||
@@ -233,7 +236,6 @@ struct hfc_multi {
|
||||
* the bch->channel is equvalent to the hfc-channel
|
||||
*/
|
||||
struct hfc_chan chan[32];
|
||||
- u_char created[8]; /* what port is created */
|
||||
signed char slot_owner[256]; /* owner channel of slot */
|
||||
};
|
||||
|
||||
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
index e1dab30..4fe2d27 100644
|
||||
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
|
||||
@@ -1619,8 +1619,8 @@ hfcmulti_leds(struct hfc_multi *hc)
|
||||
* left red: frame sync, but no L1
|
||||
* right green: L2 active
|
||||
*/
|
||||
- if (hc->chan[hc->dslot].sync != 2) { /* no frame sync */
|
||||
- if (hc->chan[hc->dslot].dch->dev.D.protocol
|
||||
+ if (hc->chan[hc->dnum[0]].sync != 2) { /* no frame sync */
|
||||
+ if (hc->chan[hc->dnum[0]].dch->dev.D.protocol
|
||||
!= ISDN_P_NT_E1) {
|
||||
led[0] = 1;
|
||||
led[1] = 1;
|
||||
@@ -2428,55 +2428,56 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
}
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo: put interface parameters to hc
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* LOS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_SIG_LOS;
|
||||
- if (!temp && hc->chan[hc->dslot].los)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_ON,
|
||||
"LOS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].los)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].los)
|
||||
signal_state_up(dch, L1_SIGNAL_LOS_OFF,
|
||||
"LOS gone");
|
||||
- hc->chan[hc->dslot].los = temp;
|
||||
+ hc->chan[hc->dnum[0]].los = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_AIS, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* AIS */
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA) & V_AIS;
|
||||
- if (!temp && hc->chan[hc->dslot].ais)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_ON,
|
||||
"AIS detected");
|
||||
- if (temp && !hc->chan[hc->dslot].ais)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].ais)
|
||||
signal_state_up(dch, L1_SIGNAL_AIS_OFF,
|
||||
"AIS gone");
|
||||
- hc->chan[hc->dslot].ais = temp;
|
||||
+ hc->chan[hc->dnum[0]].ais = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_SLIP, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* SLIP */
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_RX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_rx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_rx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_RX,
|
||||
" bit SLIP detected RX");
|
||||
- hc->chan[hc->dslot].slip_rx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_rx = temp;
|
||||
temp = HFC_inb_nodebug(hc, R_SLIP) & V_FOSLIP_TX;
|
||||
- if (!temp && hc->chan[hc->dslot].slip_tx)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].slip_tx)
|
||||
signal_state_up(dch, L1_SIGNAL_SLIP_TX,
|
||||
" bit SLIP detected TX");
|
||||
- hc->chan[hc->dslot].slip_tx = temp;
|
||||
+ hc->chan[hc->dnum[0]].slip_tx = temp;
|
||||
}
|
||||
- if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_REPORT_RDI, &hc->chan[hc->dnum[0]].cfg)) {
|
||||
/* RDI */
|
||||
temp = HFC_inb_nodebug(hc, R_RX_SL0_0) & V_A;
|
||||
- if (!temp && hc->chan[hc->dslot].rdi)
|
||||
+ if (!temp && hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_ON,
|
||||
"RDI detected");
|
||||
- if (temp && !hc->chan[hc->dslot].rdi)
|
||||
+ if (temp && !hc->chan[hc->dnum[0]].rdi)
|
||||
signal_state_up(dch, L1_SIGNAL_RDI_OFF,
|
||||
"RDI gone");
|
||||
- hc->chan[hc->dslot].rdi = temp;
|
||||
+ hc->chan[hc->dnum[0]].rdi = temp;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_JATT_DIR);
|
||||
- switch (hc->chan[hc->dslot].sync) {
|
||||
+ switch (hc->chan[hc->dnum[0]].sync) {
|
||||
case 0:
|
||||
if ((temp & 0x60) == 0x60) {
|
||||
if (debug & DEBUG_HFCMULTI_SYNC)
|
||||
@@ -2485,10 +2486,10 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"in clock sync\n",
|
||||
__func__, hc->id);
|
||||
HFC_outb(hc, R_RX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
HFC_outb(hc, R_TX_OFF,
|
||||
- hc->chan[hc->dslot].jitter | V_RX_INIT);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].jitter | V_RX_INIT);
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
goto check_framesync;
|
||||
}
|
||||
break;
|
||||
@@ -2499,7 +2500,7 @@ handle_timer_irq(struct hfc_multi *hc)
|
||||
"%s: (id=%d) E1 "
|
||||
"lost clock sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
check_framesync:
|
||||
@@ -2510,7 +2511,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"now in frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 2;
|
||||
+ hc->chan[hc->dnum[0]].sync = 2;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -2520,7 +2521,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 lost "
|
||||
"clock & frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 0;
|
||||
+ hc->chan[hc->dnum[0]].sync = 0;
|
||||
break;
|
||||
}
|
||||
temp = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
@@ -2530,7 +2531,7 @@ check_framesync:
|
||||
"%s: (id=%d) E1 "
|
||||
"lost frame sync\n",
|
||||
__func__, hc->id);
|
||||
- hc->chan[hc->dslot].sync = 1;
|
||||
+ hc->chan[hc->dnum[0]].sync = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2746,7 +2747,8 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
if (r_irq_misc & V_STA_IRQ) {
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
/* state machine */
|
||||
- dch = hc->chan[hc->dslot].dch;
|
||||
+#warning todo
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
|
||||
if (test_bit(HFC_CHIP_PLXSD, &hc->chip)
|
||||
&& hc->e1_getclock) {
|
||||
@@ -2768,7 +2770,15 @@ hfcmulti_interrupt(int intno, void *dev_id)
|
||||
}
|
||||
dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
& 0x7;
|
||||
+#warning todo hack!!! broadcast state change!!!
|
||||
+ dch = hc->chan[hc->dnum[0]].dch;
|
||||
schedule_event(dch, FLG_PHCHANGE);
|
||||
+ dch = hc->chan[hc->dnum[1]].dch;
|
||||
+ dch->state = HFC_inb_nodebug(hc, R_E1_RD_STA)
|
||||
+ & 0x7;
|
||||
+ schedule_event(dch, FLG_PHCHANGE);
|
||||
+
|
||||
+
|
||||
if (debug & DEBUG_HFCMULTI_STATE)
|
||||
printk(KERN_DEBUG
|
||||
"%s: E1 (id=%d) newstate %x\n",
|
||||
@@ -3851,31 +3861,35 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: entered\n", __func__);
|
||||
|
||||
+ i = dch->slot;
|
||||
+ pt = hc->chan[i].port;
|
||||
if (hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->chan[hc->dslot].slot_tx = -1;
|
||||
- hc->chan[hc->dslot].slot_rx = -1;
|
||||
- hc->chan[hc->dslot].conf = -1;
|
||||
- if (hc->dslot) {
|
||||
- mode_hfcmulti(hc, hc->dslot, dch->dev.D.protocol,
|
||||
+ /* E1 */
|
||||
+#warning todo: don''t do it if dnum == 0
|
||||
+ hc->chan[hc->dnum[pt]].slot_tx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].slot_rx = -1;
|
||||
+ hc->chan[hc->dnum[pt]].conf = -1;
|
||||
+ if (hc->dnum[pt]) {
|
||||
+ mode_hfcmulti(hc, dch->slot, dch->dev.D.protocol,
|
||||
-1, 0, -1, 0);
|
||||
dch->timer.function = (void *) hfcmulti_dbusy_timer;
|
||||
dch->timer.data = (long) dch;
|
||||
init_timer(&dch->timer);
|
||||
}
|
||||
for (i = 1; i <= 31; i++) {
|
||||
- if (i == hc->dslot)
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
mode_hfcmulti(hc, i, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
}
|
||||
- /* E1 */
|
||||
- if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
|
||||
+#warning todo (global)
|
||||
+ if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_LOS0, 255); /* 2 ms */
|
||||
HFC_outb(hc, R_LOS1, 255); /* 512 ms */
|
||||
}
|
||||
- if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dslot].cfg)) {
|
||||
+ if (test_bit(HFC_CFG_OPTICAL, &hc->chan[hc->dnum[pt]].cfg)) {
|
||||
HFC_outb(hc, R_RX0, 0);
|
||||
hc->hw.r_tx0 = 0 | V_OUT_EN;
|
||||
} else {
|
||||
@@ -3888,12 +3902,12 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
HFC_outb(hc, R_TX_FR0, 0x00);
|
||||
HFC_outb(hc, R_TX_FR1, 0xf8);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_TX_FR2, V_TX_MF | V_TX_E | V_NEG_E);
|
||||
|
||||
HFC_outb(hc, R_RX_FR0, V_AUTO_RESYNC | V_AUTO_RECO | 0);
|
||||
|
||||
- if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dslot].cfg))
|
||||
+ if (test_bit(HFC_CFG_CRC4, &hc->chan[hc->dnum[pt]].cfg))
|
||||
HFC_outb(hc, R_RX_FR1, V_RX_MF | V_RX_MF_SYNC);
|
||||
|
||||
if (dch->dev.D.protocol == ISDN_P_NT_E1) {
|
||||
@@ -3957,7 +3971,7 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
plxsd_checksync(hc, 0);
|
||||
}
|
||||
} else {
|
||||
- i = dch->slot;
|
||||
+ /* ST */
|
||||
hc->chan[i].slot_tx = -1;
|
||||
hc->chan[i].slot_rx = -1;
|
||||
hc->chan[i].conf = -1;
|
||||
@@ -3973,8 +3987,6 @@ hfcmulti_initmode(struct dchannel *dch)
|
||||
hc->chan[i - 1].slot_rx = -1;
|
||||
hc->chan[i - 1].conf = -1;
|
||||
mode_hfcmulti(hc, i - 1, ISDN_P_NONE, -1, 0, -1, 0);
|
||||
- /* ST */
|
||||
- pt = hc->chan[i].port;
|
||||
/* select interface */
|
||||
HFC_outb(hc, R_ST_SEL, pt);
|
||||
/* undocumented: delay after R_ST_SEL */
|
||||
@@ -4557,6 +4569,8 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
|
||||
}
|
||||
/* free channels */
|
||||
for (i = 0; i <= 31; i++) {
|
||||
+ if (!((1 << i) & hc->bmask[pt])) /* skip unused channel */
|
||||
+ continue;
|
||||
if (hc->chan[i].bch) {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
@@ -4680,12 +4694,13 @@ release_card(struct hfc_multi *hc)
|
||||
}
|
||||
|
||||
static int
|
||||
-init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
+init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt)
|
||||
{
|
||||
struct dchannel *dch;
|
||||
struct bchannel *bch;
|
||||
int ch, ret = 0;
|
||||
char name[MISDN_MAX_IDLEN];
|
||||
+ int bcount = 0;
|
||||
|
||||
dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL);
|
||||
if (!dch)
|
||||
@@ -4698,13 +4713,12 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
|
||||
dch->dev.D.send = handle_dmsg;
|
||||
dch->dev.D.ctrl = hfcm_dctrl;
|
||||
- dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
|
||||
- dch->slot = hc->dslot;
|
||||
- hc->chan[hc->dslot].dch = dch;
|
||||
- hc->chan[hc->dslot].port = 0;
|
||||
- hc->chan[hc->dslot].nt_timer = -1;
|
||||
+ dch->slot = hc->dnum[pt];
|
||||
+ hc->chan[hc->dnum[pt]].dch = dch;
|
||||
+ hc->chan[hc->dnum[pt]].port = pt;
|
||||
+ hc->chan[hc->dnum[pt]].nt_timer = -1;
|
||||
for (ch = 1; ch <= 31; ch++) {
|
||||
- if (ch == hc->dslot) /* skip dchannel */
|
||||
+ if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */
|
||||
continue;
|
||||
bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL);
|
||||
if (!bch) {
|
||||
@@ -4733,7 +4747,10 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
hc->chan[ch].bch = bch;
|
||||
hc->chan[ch].port = 0;
|
||||
set_channelmap(bch->nr, dch->dev.channelmap);
|
||||
+ bcount++;
|
||||
}
|
||||
+ dch->dev.nrbchan = bcount;
|
||||
+#warning todo: must be set globally, and must be a seperate function
|
||||
/* set optical line type */
|
||||
if (port[Port_cnt] & 0x001) {
|
||||
if (!m->opticalsupport) {
|
||||
@@ -4749,7 +4766,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
__func__,
|
||||
HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_OPTICAL,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
}
|
||||
/* set LOS report */
|
||||
@@ -4759,7 +4776,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"LOS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_LOS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set AIS report */
|
||||
if (port[Port_cnt] & 0x008) {
|
||||
@@ -4768,7 +4785,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"AIS report: card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_AIS,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set SLIP report */
|
||||
if (port[Port_cnt] & 0x010) {
|
||||
@@ -4778,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_SLIP,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set RDI report */
|
||||
if (port[Port_cnt] & 0x020) {
|
||||
@@ -4788,7 +4805,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
"card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_REPORT_RDI,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
}
|
||||
/* set CRC-4 Mode */
|
||||
if (!(port[Port_cnt] & 0x100)) {
|
||||
@@ -4797,7 +4814,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
" card(%d) port(%d)\n",
|
||||
__func__, HFC_cnt + 1, 1);
|
||||
test_and_set_bit(HFC_CFG_CRC4,
|
||||
- &hc->chan[hc->dslot].cfg);
|
||||
+ &hc->chan[hc->dnum[pt]].cfg);
|
||||
} else {
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG "%s: PORT turn off CRC4"
|
||||
@@ -4829,20 +4846,23 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
|
||||
}
|
||||
/* set elastic jitter buffer */
|
||||
if (port[Port_cnt] & 0x3000) {
|
||||
- hc->chan[hc->dslot].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
+ hc->chan[hc->dnum[pt]].jitter = (port[Port_cnt]>>12) & 0x3;
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
printk(KERN_DEBUG
|
||||
"%s: PORT set elastic "
|
||||
"buffer to %d: card(%d) port(%d)\n",
|
||||
- __func__, hc->chan[hc->dslot].jitter,
|
||||
+ __func__, hc->chan[hc->dnum[pt]].jitter,
|
||||
HFC_cnt + 1, 1);
|
||||
} else
|
||||
- hc->chan[hc->dslot].jitter = 2; /* default */
|
||||
- snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
+ hc->chan[hc->dnum[pt]].jitter = 2; /* default */
|
||||
+ if (hc->ports > 1)
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d-%d", HFC_cnt + 1, pt+1);
|
||||
+ else
|
||||
+ snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-e1.%d", HFC_cnt + 1);
|
||||
ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
|
||||
if (ret)
|
||||
goto free_chan;
|
||||
- hc->created[0] = 1;
|
||||
+ hc->created[pt] = 1;
|
||||
return ret;
|
||||
free_chan:
|
||||
release_port(hc, dch);
|
||||
@@ -5009,18 +5029,30 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
hc->id = HFC_cnt;
|
||||
hc->pcm = pcm[HFC_cnt];
|
||||
hc->io_mode = iomode[HFC_cnt];
|
||||
+#warning todo: rework module parameters for customizing e1 fragments.... yea, let''s call it: fragments
|
||||
if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = 0;
|
||||
+ hc->dnum[0] = 0;
|
||||
printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
|
||||
"31 B-channels\n");
|
||||
}
|
||||
if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
|
||||
&& hc->ctype == HFC_TYPE_E1) {
|
||||
- hc->dslot = dslot[HFC_cnt];
|
||||
+ hc->dnum[0] = dslot[HFC_cnt];
|
||||
printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
|
||||
"time slot %d\n", dslot[HFC_cnt]);
|
||||
} else
|
||||
- hc->dslot = 16;
|
||||
+ hc->dnum[0] = 16;
|
||||
+
|
||||
+#warning todo HACK!!! just a small map of two "fragments"
|
||||
+ if (hc->ctype == HFC_TYPE_E1) {
|
||||
+ hc->dnum[0] = 1;
|
||||
+ hc->bmask[0] = 0x0000003c;
|
||||
+ hc->dnum[1] = 6;
|
||||
+ hc->bmask[1] = 0x00000780;
|
||||
+ hc->dnum[2] = 11;
|
||||
+ hc->bmask[2] = 0x00007800;
|
||||
+ hc->ports = 3;
|
||||
+ }
|
||||
|
||||
/* set chip specific features */
|
||||
hc->masterclk = -1;
|
||||
@@ -5103,7 +5135,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
goto free_card;
|
||||
}
|
||||
if (hc->ctype == HFC_TYPE_E1)
|
||||
- ret_err = init_e1_port(hc, m);
|
||||
+ ret_err = init_e1_port(hc, m, pt);
|
||||
else
|
||||
ret_err = init_multi_port(hc, pt);
|
||||
if (debug & DEBUG_HFCMULTI_INIT)
|
||||
@@ -5115,10 +5147,14 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
|
||||
if (ret_err) {
|
||||
while (pt) { /* release already registered ports */
|
||||
pt--;
|
||||
- release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
+ if (hc->ctype == HFC_TYPE_E1)
|
||||
+ release_port(hc, hc->chan[hc->dnum[pt]].dch);
|
||||
+ else
|
||||
+ release_port(hc, hc->chan[(pt << 2) + 2].dch);
|
||||
}
|
||||
goto free_card;
|
||||
}
|
||||
+#warning todo: count it right, add additional "fragment" counter...
|
||||
Port_cnt++;
|
||||
}
|
||||
|
||||
10
openbsc/.gitignore
vendored
10
openbsc/.gitignore
vendored
@@ -46,14 +46,16 @@ ltmain.sh
|
||||
hlr.sqlite3
|
||||
src/utils/bs11_config
|
||||
src/ipaccess/ipaccess-config
|
||||
src/ipaccess/ipaccess-find
|
||||
src/ipaccess/abisip-find
|
||||
src/ipaccess/ipaccess-firmware
|
||||
src/ipaccess/ipaccess-proxy
|
||||
src/utils/isdnsync
|
||||
src/nat/bsc_nat
|
||||
src/gprs/osmo-sgsn
|
||||
src/gprs/osmo-gbproxy
|
||||
src/gprs/osmo-gtphub
|
||||
src/osmo-bsc_nat/osmo-bsc_nat
|
||||
src/osmo-cscn/osmo-cscn
|
||||
|
||||
#tests
|
||||
tests/testsuite.dir
|
||||
@@ -77,6 +79,9 @@ tests/trau/trau_test
|
||||
tests/mgcp/mgcp_transcoding_test
|
||||
tests/sgsn/sgsn_test
|
||||
tests/subscr/subscr_test
|
||||
tests/oap/oap_test
|
||||
tests/gtphub/gtphub_test
|
||||
tests/mm_auth/mm_auth_test
|
||||
|
||||
tests/atconfig
|
||||
tests/atlocal
|
||||
@@ -84,5 +89,6 @@ tests/package.m4
|
||||
tests/testsuite
|
||||
tests/testsuite.log
|
||||
|
||||
|
||||
src/openbsc.cfg*
|
||||
writtenconfig/
|
||||
gtphub_restart_count
|
||||
|
||||
@@ -5,3 +5,5 @@ Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
Sylvain Munaut <246tnt@gmail.com>
|
||||
Jacob Erlbeck <jerlbeck@sysmocom.de>
|
||||
Neels Hofmeyr <nhofmeyr@sysmocom.de>
|
||||
|
||||
@@ -7,7 +7,7 @@ pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = git-version-gen osmoappdesc.py
|
||||
EXTRA_DIST = git-version-gen osmoappdesc.py .version
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
About OpenBSC
|
||||
=============
|
||||
|
||||
OpenBSC is a minimalistic implementation of the GSM Network, with
|
||||
particular emphasis on the functionality typically provided by the BSC,
|
||||
MSC, HLR, VLR and SMSC.
|
||||
OpenBSC started as a minimalistic all-in-one implementation of the GSM Network,
|
||||
with particular emphasis on the functionality typically provided by the BSC,
|
||||
MSC, HLR, VLR and SMSC. Today it is a growing suite of libraries and programs,
|
||||
implementing protocol stacks and functional elements, including
|
||||
|
||||
Its currently supported interfaces towards the BTS are:
|
||||
* OsmoBSC - a pure GSM BSC, speaking Abis/IP to the BTS and A/IP to the MSC
|
||||
* OsmoBSC-MGCP - MGCP helper to the OsmoBSC software
|
||||
* OsmoNITB - a BSC+MSC+VLR+HLR+SMSC "Network in the box".
|
||||
* OsmoCSCN - a voice CN with A/IP and IuCS/IP towards the BSC and/or HNB-GW
|
||||
* OsmoSGSN - a GPRS SGSN with Gb/IP and IuPS/IP towards the PCU and/or HNB-GW
|
||||
* Osmo-GbProxy - a Proxy to aggregate many Gb links as one Gb link to the SGSN
|
||||
* OsmoBSCNAT - a gateway aggregating many A links as one A link to the MSC
|
||||
* OsmoGTPHUB - a hub aggregating many GTP links (between SGSN and GGSN)
|
||||
* ipaccess-utils - some tools to discover + configure ip.access nanoBTS
|
||||
* bs11_config - a tool to configure the Siemens BS-11 microBTS
|
||||
|
||||
Various interfaces towards the BTS are supported, among which are:
|
||||
|
||||
* Classic A-bis over E1 using a mISDN based E1 interface. In other
|
||||
words, you can connect existing GSM Base Transceiver Station (BTS)
|
||||
through E1 to OpenBSC. So far, we have only tested the Siemens BS-11
|
||||
Test reports with other BTS are much appreciated!
|
||||
through E1 to OpenBSC. So far, we have made it work with the Siemens BS-11,
|
||||
various Ericsson RBS2xxx BTS models and the Nokia MetroSite.
|
||||
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family as well as
|
||||
the Open Source OsmoBTS software (by the same authors as OpenBSC). OsmoBTS
|
||||
in turn supports various transceiver hardware, including the sysmoBTS
|
||||
product family, as well as SDR transceivers supported by OsmoTRX, such as
|
||||
the UmTRX or USRP boardss.
|
||||
|
||||
You can find the project documentation at http://openbsc.gnumonks.org/
|
||||
* IuCS and IuPS over IP towards an HNB-GW (see osmo-iuh) for UMTS (3G)
|
||||
voice and data links.
|
||||
|
||||
This project is still in its early days, and there are lots of areas where it
|
||||
doesn't behave as per GSM spec.
|
||||
Find OpenBSC online at
|
||||
http://openbsc.osmocom.org/
|
||||
|
||||
Harald Welte <laforge@gnumonks.org>
|
||||
|
||||
|
||||
libosmocore
|
||||
===========
|
||||
|
||||
Please note that as of March 2010, OpenBSC has a dependency to a library
|
||||
called "libosmocore". You can obtain that library from
|
||||
|
||||
git://git.osmocom.org/libosmocore.git
|
||||
|
||||
|
||||
11
openbsc/README.vty-tests
Normal file
11
openbsc/README.vty-tests
Normal file
@@ -0,0 +1,11 @@
|
||||
To run the configuration parsing and output (VTY) test suite, first install
|
||||
|
||||
git://git.osmocom.org/python/osmo-python-tests
|
||||
|
||||
and pass the following configure options here:
|
||||
|
||||
./configure --enable-vty-tests --enable-external-tests
|
||||
|
||||
The VTY tests are then included in the standard check target:
|
||||
|
||||
make check
|
||||
@@ -16,8 +16,6 @@ AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl checks for libraries
|
||||
AC_SEARCH_LIBS(crypt, crypt,
|
||||
[LIBCRYPT="-lcrypt"; AC_DEFINE([VTY_CRYPT_PW], [], [Use crypt functionality of vty.])])
|
||||
AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DL="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_DL)
|
||||
|
||||
@@ -29,6 +27,10 @@ PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.2.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGB, libosmogb >= 0.6.4)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 0.0.1)
|
||||
PKG_CHECK_MODULES(LIBCRYPTO, libcrypto >= 0.9.5)
|
||||
PKG_CHECK_MODULES(LIBASN1C, libasn1c)
|
||||
PKG_CHECK_MODULES(LIBOSMORANAP, libosmo-ranap)
|
||||
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran)
|
||||
|
||||
# Enabke/disable the NAT?
|
||||
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
|
||||
@@ -48,7 +50,7 @@ fi
|
||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
|
||||
AC_SUBST(osmo_ac_build_bsc)
|
||||
|
||||
# Enable/disable smpp support in the nitb?
|
||||
# Enable/disable smpp support in the cscn?
|
||||
AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
|
||||
[osmo_ac_build_smpp="$enableval"],[osmo_ac_build_smpp="no"])
|
||||
if test "$osmo_ac_build_smpp" = "yes" ; then
|
||||
@@ -64,7 +66,8 @@ AC_ARG_ENABLE([mgcp-transcoding], [AS_HELP_STRING([--enable-mgcp-transcoding], [
|
||||
AC_ARG_WITH([g729], [AS_HELP_STRING([--with-g729], [Enable G.729 encoding/decoding.])], [osmo_ac_with_g729="$withval"],[osmo_ac_with_g729="no"])
|
||||
|
||||
if test "$osmo_ac_mgcp_transcoding" = "yes" ; then
|
||||
AC_SEARCH_LIBS(gsm_create, gsm)
|
||||
AC_SEARCH_LIBS([gsm_create], [gsm], [LIBRARY_GSM="$LIBS";LIBS=""])
|
||||
AC_SUBST(LIBRARY_GSM)
|
||||
if test "$osmo_ac_with_g729" = "yes" ; then
|
||||
PKG_CHECK_MODULES(LIBBCG729, libbcg729 >= 0.1, [AC_DEFINE([HAVE_BCG729], [1], [Use bgc729 decoder/encoder])])
|
||||
fi
|
||||
@@ -75,14 +78,25 @@ AC_SUBST(osmo_ac_mgcp_transcoding)
|
||||
|
||||
|
||||
found_libgtp=yes
|
||||
PKG_CHECK_MODULES(LIBGTP, libgtp, , found_libgtp=no)
|
||||
PKG_CHECK_MODULES(LIBGTP, libgtp >= 0.92, , found_libgtp=no)
|
||||
AM_CONDITIONAL(HAVE_LIBGTP, test "$found_libgtp" = yes)
|
||||
AC_SUBST(found_libgtp)
|
||||
|
||||
found_libcares=yes
|
||||
PKG_CHECK_MODULES([LIBCARES], [libcares], [], [found_libcares=no])
|
||||
AM_CONDITIONAL(HAVE_LIBCARES, test "$found_libcares" = yes)
|
||||
AC_SUBST(found_libcares)
|
||||
|
||||
found_libgtp_and_libcares=no
|
||||
if test "$found_libgtp" = "yes" -a "$found_libcares" = "yes"; then
|
||||
found_libgtp_and_libcares=yes
|
||||
fi
|
||||
AC_SUBST(found_libgtp_and_libcares)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built))
|
||||
AC_CHECK_HEADERS(dbi/dbd.h,,AC_MSG_ERROR(DBI library is not installed))
|
||||
AC_CHECK_HEADERS(pcap/pcap.h,,AC_MSG_ERROR(PCAP library is not installed))
|
||||
|
||||
found_cdk=yes
|
||||
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
|
||||
@@ -180,7 +194,9 @@ AC_OUTPUT(
|
||||
src/libmgcp/Makefile
|
||||
src/libcommon/Makefile
|
||||
src/libfilter/Makefile
|
||||
src/osmo-nitb/Makefile
|
||||
src/libiu/Makefile
|
||||
src/libxsc/Makefile
|
||||
src/osmo-cscn/Makefile
|
||||
src/osmo-bsc/Makefile
|
||||
src/osmo-bsc_nat/Makefile
|
||||
src/osmo-bsc_mgcp/Makefile
|
||||
@@ -189,6 +205,7 @@ AC_OUTPUT(
|
||||
src/gprs/Makefile
|
||||
tests/Makefile
|
||||
tests/atlocal
|
||||
tests/libiudummy/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
tests/db/Makefile
|
||||
tests/channel/Makefile
|
||||
@@ -203,6 +220,9 @@ AC_OUTPUT(
|
||||
tests/trau/Makefile
|
||||
tests/sgsn/Makefile
|
||||
tests/subscr/Makefile
|
||||
tests/oap/Makefile
|
||||
tests/gtphub/Makefile
|
||||
tests/mm_auth/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
Makefile)
|
||||
|
||||
65
openbsc/contrib/nat/ussd_example.py
Normal file
65
openbsc/contrib/nat/ussd_example.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python2.7
|
||||
|
||||
"""
|
||||
AGPLv3+ 2016 Copyright Holger Hans Peter Freyther
|
||||
|
||||
Example of how to connect to the USSD side-channel and how to respond
|
||||
with a fixed message.
|
||||
"""
|
||||
|
||||
import socket
|
||||
import struct
|
||||
|
||||
ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
ussdSocket.connect(('127.0.0.1', 5001))
|
||||
|
||||
def send_dt1(dstref, data):
|
||||
dlen = struct.pack('B', len(data)).encode('hex')
|
||||
hex = '06' + dstref.encode('hex') + '00' + '01' + dlen + data.encode('hex')
|
||||
pdata = hex.decode('hex')
|
||||
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
|
||||
ussdSocket.send(out)
|
||||
|
||||
def send_rel(srcref, dstref):
|
||||
hex = '04' + dstref.encode('hex') + srcref.encode('hex') + '000100'
|
||||
pdata = hex.decode('hex')
|
||||
out = struct.pack('>HB', len(pdata), 0xfd) + pdata
|
||||
ussdSocket.send(out)
|
||||
|
||||
def recv_one():
|
||||
plen = ussdSocket.recv(3)
|
||||
(plen,ptype) = struct.unpack(">HB", plen)
|
||||
data = ussdSocket.recv(plen)
|
||||
|
||||
return ptype, data
|
||||
|
||||
# Assume this is the ID request
|
||||
data = ussdSocket.recv(4)
|
||||
ussdSocket.send("\x00\x08\xfe\x05\x00" + "\x05\x01" + "ussd")
|
||||
# ^len ^len of tag ... and ignore
|
||||
|
||||
# Expect a fake message. see struct ipac_msgt_sccp_state
|
||||
ptype, data = recv_one()
|
||||
print("%d %s" % (ptype, data.encode('hex')))
|
||||
(srcref, dstref, transid, invokeid) = struct.unpack("<3s3sBB", data[1:9])
|
||||
print("New transID %d invoke %d" % (transid, invokeid))
|
||||
|
||||
# Expect a the invocation.. todo.. extract invoke id
|
||||
ptype, data = recv_one()
|
||||
print("%d %s" % (ptype, data.encode('hex')))
|
||||
|
||||
# Reply with BSSAP + GSM 04.08 + MAP portion
|
||||
# 00 == invoke id 0f == DCS
|
||||
res = "01002a9b2a0802e1901c22a220020100301b02013b301604010f041155e7d2f9bc3a41412894991c06a9c9a713"
|
||||
send_dt1(dstref, res.decode('hex'))
|
||||
|
||||
clear = "000420040109"
|
||||
send_dt1(dstref, clear.decode('hex'))
|
||||
|
||||
# should be the clear complete
|
||||
send_rel(srcref, dstref)
|
||||
|
||||
# Give it some time to handle connection shutdown properly
|
||||
print("Gracefully sleeping")
|
||||
import time
|
||||
time.sleep(3)
|
||||
608
openbsc/doc/call-graphs-MSC-BSC-HNBGW.txt
Normal file
608
openbsc/doc/call-graphs-MSC-BSC-HNBGW.txt
Normal file
@@ -0,0 +1,608 @@
|
||||
gprs_iu_tx
|
||||
|
||||
-- WORK IN PROGRESS --
|
||||
|
||||
This is an incomplete collection of call graphs between MSC and Osmo-BSC,
|
||||
partly including Osmo-BTS. These traces helped understanding the separation of
|
||||
the BSC part from Osmo-NITB. The aim: obtain a clearly separated "A" interface
|
||||
towards the BSC, and have an Iu-CS interface to operate with HNB-GW and hNodeB.
|
||||
The working title for the result is Osmo-CSCN (Circuit Switched Core Network),
|
||||
combining an MSC with various other core network components, but without the
|
||||
BSC parts.
|
||||
|
||||
|
||||
Some Specs and Overview
|
||||
|
||||
0408: Radio interface
|
||||
0411: PP-SMS on Radio interface
|
||||
0802: A Interface MSC<->BSS (BSS = BSC + BTS)
|
||||
0804: A Interface L1 MSC<->BSS
|
||||
0806: A Interface L2 MSC<->BSS
|
||||
0808: A Interface L3 MSC<->BSS
|
||||
0808: Figure 1: A MSC<->BSS
|
||||
0820: RA (Rate Adaption) MSC<->BSS
|
||||
|
||||
0851,0852: A-bis general BSC<->BTS
|
||||
1221: A-bis NM BSC<->BTS
|
||||
1201: Figure 9: A-bis BSC<->BTS
|
||||
|
||||
MS <-> BTS <-> BSC <-> MSC <-> cn
|
||||
| | | | |
|
||||
|<-------0408=DTAP----->| |
|
||||
|<-------0411---------->| |
|
||||
| | |<--0808>| |
|
||||
| | |<BSSMAP>| |
|
||||
| | | | |
|
||||
| Abis | A |
|
||||
|
||||
MS <-> hNodeB <-> HNB-GW <-> MSC <-> cn
|
||||
| | | | |
|
||||
|<-0408->|<--Iu--->|<-Iu-cs->| |
|
||||
|<-0411->| | | |
|
||||
| | | | |
|
||||
|
||||
Entry/Exit points
|
||||
|
||||
Osmo-BSC <--A--> MSC or Osmo-CSCN
|
||||
format: BSSAP/SCCP (where BSSAP = DTAP + BSSMAP)
|
||||
Osmo-BSC
|
||||
read from MSC: sccp_system_incoming_ctx()
|
||||
write to MSC: sccp_connection_write() <-- osmo-bsc/osmo_bsc_sccp.c:bsc_queue_for_msc()
|
||||
MSC:
|
||||
third party
|
||||
Osmo-CSCN:
|
||||
read: does not exist yet
|
||||
write: does not exist yet
|
||||
|
||||
HNB-GW <--Iu-CS--> Osmo-CSCN
|
||||
format: CC+MM/RANAP/SUA
|
||||
HNB-GW:
|
||||
read: does not exist yet
|
||||
write: does not exist yet
|
||||
Osmo-CSCN:
|
||||
read: does not exist yet
|
||||
write: does not exist yet
|
||||
|
||||
Osmo-BTS <-Abis-> Osmo-BSC
|
||||
Osmo-BSC:
|
||||
read: libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg)
|
||||
write: libosmo-abis/src/e1_input.c:abis_sendmsg() (e1inp_sign_link*)msg->dst;
|
||||
|
||||
Osmo-BTS <-Abis-> Osmo-NITB
|
||||
Osmo-NITB:
|
||||
read:
|
||||
osmo_signal_dispatch():
|
||||
from on_dso_load_token() libmsc/token_auth.c
|
||||
SS_SUBSCR: token_subscr_cb() libmsc/token_auth.c
|
||||
SS_SMS: token_sms_cb() libmsc/token_auth.c
|
||||
from subscr_sig_cb() libmsc/rrlp.c
|
||||
SS_SUBSCR: subscr_sig_cb() libmsc/rrlp.c
|
||||
SS_PAGING: paging_sig_cb() libmsc/rrlp.c
|
||||
from on_dso_load_ho_dec() libbsc/handover_decision.c
|
||||
SS_LCHAN: ho_dec_sig_cb() libbsc/handover_decision.c
|
||||
from e1inp_init() libosmo-abis/src/e1_input.c
|
||||
SS_L_GLOBAL: e1i_sig_cb() libosmo-abis/src/e1_input.c
|
||||
|
||||
bts_model_bs11_init();
|
||||
bts_model_rbs2k_init();
|
||||
bts_model_nanobts_init();
|
||||
bts_model_nokia_site_init();
|
||||
bts_model_sysmobts_init();
|
||||
|
||||
bsc_bootstrap_network():
|
||||
osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);
|
||||
osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
|
||||
|
||||
|
||||
Call Trees
|
||||
|
||||
- A Interface
|
||||
|
||||
Osmo-BSC sends to MSC:
|
||||
|
||||
sccp_connection_write(conn->sccp, msg);
|
||||
^ bsc_queue_for_msc()
|
||||
^
|
||||
| osmo-bsc/osmo_bsc_api.c:
|
||||
| bsc_clear_request()
|
||||
| queue_msg_or_return() osmo-bsc/osmo_bsc_api.c
|
||||
| ^ bsc_sapi_n_reject()
|
||||
| | ^send_sapi_reject()
|
||||
| | ^ gsm0808_submit_dtap() libbsc/bsc_api.c
|
||||
| | | ^ gsm48_conn_sendmsg() libmsc/gsm_04_08.c
|
||||
| | | | ^ gsm48_cc_tx_notify_ss() libmsc/gsm_04_08.c
|
||||
| | | | | mm_tx_identity_req() libmsc/gsm_04_08.c
|
||||
| | | | | gsm48_tx_mm_info() libmsc/gsm_04_08.c
|
||||
| | | | | gsm48_tx_mm_auth_req()
|
||||
| | | | | gsm48_send_rr_app_info()
|
||||
| | | | | gsm48_cc_tx_status()
|
||||
| | | | | gsm48_tx_simple()
|
||||
| | | | | ^ gsm48_tx_mm_auth_rej()
|
||||
| | | | | gsm48_cc_tx_setup()
|
||||
| | | | | gsm48_cc_tx_call_proc()
|
||||
| | | | | gsm48_cc_tx_alerting()
|
||||
| | | | | gsm48_cc_tx_progress()
|
||||
| | | | | gsm48_cc_tx_connect()
|
||||
| | | | | gsm48_cc_tx_connect_ack()
|
||||
| | | | | gsm48_cc_tx_disconnect()
|
||||
| | | | | gsm48_cc_tx_release()
|
||||
| | | | | gsm48_cc_tx_release_compl()
|
||||
| | | | | gsm48_cc_tx_facility()
|
||||
| | | | | gsm48_cc_tx_hold_ack()
|
||||
| | | | | gsm48_cc_tx_hold_rej()
|
||||
| | | | | gsm48_cc_tx_retrieve_ack()
|
||||
| | | | | gsm48_cc_tx_retrieve_rej()
|
||||
| | | | | gsm48_cc_tx_start_dtmf_ack()
|
||||
| | | | | gsm48_cc_tx_start_dtmf_rej()
|
||||
| | | | | gsm48_cc_tx_stop_dtmf_ack()
|
||||
| | | | | gsm48_cc_tx_modify()
|
||||
| | | | | gsm48_cc_tx_modify_complete()
|
||||
| | | | | gsm48_cc_tx_modify_reject()
|
||||
| | | | | gsm48_cc_tx_notify()
|
||||
| | | | | gsm48_cc_tx_userinfo()
|
||||
| | | |
|
||||
| | | | gsm0480_send_ussd_response() libmsc/gsm_04_80.c
|
||||
| | | | gsm0480_send_ussd_reject() libmsc/gsm_04_80.c
|
||||
| | | | gsm0480_send_ussdNotify() libmsc/gsm_04_80.c
|
||||
| | | | ^ bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
|
||||
| | | | gsm0480_send_releaseComplete() libmsc/gsm_04_80.c
|
||||
| | | | ^ bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
|
||||
| | | |
|
||||
| | | | gsm411_sendmsg() libmsc/gsm_04_11.c
|
||||
| | | |
|
||||
| | | | bsc_maybe_lu_reject() osmo-bsc/osmo_bsc_api.c
|
||||
| | | | ^ complete_layer3()
|
||||
| | | | | bsc_dtap()
|
||||
| | | |
|
||||
| | | | dtap_rcvmsg() osmo-bsc/osmo_bsc_bssap.c
|
||||
| | | |
|
||||
| | | | gsm48_tx_mm_serv_ack() libbsc/gsm_04_08_utils.c
|
||||
| | | | ^ _gsm48_rx_mm_serv_req_sec_cb()
|
||||
| | | | | bsc_send_ussd_no_srv() osmo-bsc/osmo_bsc_api.c
|
||||
| | | |
|
||||
| | | | gsm48_tx_mm_serv_rej() libbsc/gsm_04_08_utils.c
|
||||
| | |
|
||||
| | | bsc_rll_req.cb = rll_ind_cb() from rll_establish() from gsm0808_submit_dtap()
|
||||
| | | ^ complete_rllr() libbsc/bsc_rll.c
|
||||
| | | | ^ timer_cb() libbsc/bsc_rll.c
|
||||
| | | | | rll_indication() libbsc/bsc_rll.c
|
||||
| | | | | rll_lchan_signal() libbsc/bsc_rll.c
|
||||
| |
|
||||
| | bsc_cipher_mode_compl()
|
||||
| | ^ bsc_api.cipher_mode_compl()
|
||||
| | | dispatch_dtap() (2)
|
||||
| | | with GSM48_MT_RR_CIPH_M_COMPL
|
||||
| |
|
||||
| | bsc_dtap()
|
||||
| | ^ cb from osmo-bsc/osmo_bsc_api.c
|
||||
| | bsc_api.dtap()
|
||||
| | ^ libbsc/bsc_api.c:
|
||||
| | | dispatch_dtap() (2)
|
||||
| | | case GSM48_MT_RR_APP_INFO
|
||||
| | | case unknown 04.08 RR
|
||||
| |
|
||||
| | bsc_assign_compl()
|
||||
| | ^ osmo-bsc/osmo_bsc_api.c
|
||||
| | bsc_api.assign_compl()
|
||||
| | ^ libbsc/bsc_api.c:
|
||||
| | | dispatch_dtap() (2)
|
||||
| | | case GSM48_MT_RR_CHAN_MODE_MODIF_ACK
|
||||
| | | handle_ass_compl()
|
||||
| | | ^ dispatch_dtap() (2)
|
||||
| | | | case GSM48_MT_RR_ASS_COMPL
|
||||
| |
|
||||
| | bsc_assign_fail()
|
||||
| |
|
||||
| | bsc_cm_update()
|
||||
|
|
||||
| osmo-bsc/osmo_bsc_bssap.c:
|
||||
| bssmap_handle_clear_command()
|
||||
| bssmap_handle_cipher_mode()
|
||||
| bssmap_handle_assignm_req()
|
||||
|
|
||||
|
||||
|
||||
Osmo-BSC receives from MSC:
|
||||
sccp_system_incoming_ctx() (libosmo-sccp)
|
||||
| L2 type:
|
||||
v SCCP_MSG_TYPE_CR: _sccp_handle_connection_request(msgb, ctx);
|
||||
SCCP_MSG_TYPE_RLSD: _sccp_handle_connection_released(msgb);
|
||||
SCCP_MSG_TYPE_CREF: _sccp_handle_connection_refused(msgb);
|
||||
SCCP_MSG_TYPE_CC: _sccp_handle_connection_confirm(msgb);
|
||||
SCCP_MSG_TYPE_RLC: _sccp_handle_connection_release_complete(msgb);
|
||||
|
||||
SCCP_MSG_TYPE_DT1: _sccp_handle_connection_dt1(msgb);
|
||||
Note: a dt1 target entry was created during one of:
|
||||
- bsc_open_connection() (SCCP connections are established by the BSC, exclusively)
|
||||
sccp_connection_connect()
|
||||
_sccp_send_connection_request()
|
||||
llist_add_tail(&connection->list, &sccp_connections);
|
||||
- sccp_system_incoming_ctx()
|
||||
SCCP_MSG_TYPE_CR:
|
||||
_sccp_handle_connection_request(struct msgb *msgb, void *ctx)
|
||||
cb->accept_cb() = msc_sccp_accept()
|
||||
|
||||
SCCP_MSG_TYPE_UDT: _sccp_handle_read(msgb) --read_cb--> osmo-bsc/osmo_bsc_sccp.c:msc_sccp_read()
|
||||
msc_sccp_read()
|
||||
| bsc_handle_udt() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:494
|
||||
v bssmap_rcvmsg_udt() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:387
|
||||
gsm0808_bssmap_name() ./libosmocore/src/gsm/gsm0808.c:535
|
||||
bssmap_handle_reset_ack() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:91
|
||||
LOGP()
|
||||
bssmap_handle_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_bssap.c:99
|
||||
GSM0808_IE_IMSI
|
||||
GSM0808_IE_CELL_IDENTIFIER_LIST
|
||||
GSM0808_IE_TMSI
|
||||
CELL_IDENT_LAC
|
||||
CELL_IDENT_BSS
|
||||
GSM0808_IE_CHANNEL_NEEDED
|
||||
GSM0808_IE_EMLPP_PRIORITY
|
||||
subscr_get_or_create() ./openbsc/openbsc/src/libcommon/gsm_subscriber_base.c:101
|
||||
subscr_group
|
||||
LOGL_INFO
|
||||
bsc_grace_paging_request() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:87
|
||||
normal_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:37
|
||||
if (msc->core_lac != -1)
|
||||
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
|
||||
trx_is_usable() ./openbsc/openbsc/src/libbsc/chan_alloc.c:49
|
||||
if is_ipaccess_bts() and nm_is_running(): 0
|
||||
else: 1
|
||||
paging_init_if_needed() ./openbsc/openbsc/src/libbsc/paging.c:224
|
||||
LAUNCH TIMER:
|
||||
bts->paging.work_timer.cb = paging_worker;
|
||||
paging_worker() ./openbsc/openbsc/src/libbsc/paging.c:217
|
||||
paging_handle_pending_requests() ./openbsc/openbsc/src/libbsc/paging.c:169 (R):
|
||||
paging_give_credit() ./openbsc/openbsc/src/libbsc/paging.c:107 (R):
|
||||
recurse paging_handle_pending_requests()
|
||||
can_send_pag_req() ./openbsc/openbsc/src/libbsc/paging.c:116
|
||||
page_ms() ./openbsc/openbsc/src/libbsc/paging.c:69
|
||||
gsm0808_page() ./openbsc/openbsc/src/libbsc/bsc_api.c:415
|
||||
rsl_paging_cmd() ./openbsc/openbsc/src/libbsc/abis_rsl.c:751
|
||||
abis_rsl_dchan_hdr
|
||||
RSL_MT_PAGING_CMD
|
||||
RSL_CHAN_PCH_AGCH
|
||||
init_dchan_hdr() ./openbsc/openbsc/src/libbsc/abis_rsl.c:99
|
||||
mdisc_by_msgtype() ./openbsc/openbsc/src/libbsc/abis_rsl.c:80
|
||||
ABIS_RSL_MDISC_RLL
|
||||
ABIS_RSL_MDISC_TRX
|
||||
ABIS_RSL_MDISC_COM_CHAN
|
||||
ABIS_RSL_MDISC_DED_CHAN
|
||||
ABIS_RSL_MDISC_LOC
|
||||
RSL_IE_CHAN_NR
|
||||
RSL_IE_PAGING_GROUP
|
||||
RSL_IE_MS_IDENTITY
|
||||
RSL_IE_CHAN_NEEDED
|
||||
abis_rsl_sendmsg() ./libosmo-abis/src/e1_input.c:258
|
||||
_paging_request() ./openbsc/openbsc/src/libbsc/paging.c:279
|
||||
llist_add_tail(&req->entry, &bts_entry->pending_requests);
|
||||
paging_schedule_if_needed() ./openbsc/openbsc/src/libbsc/paging.c:96
|
||||
if (msc->core_lac == -1)
|
||||
paging_request()
|
||||
gsm_bts_by_lac() ./openbsc/openbsc/src/libcommon/gsm_data.c:135
|
||||
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
|
||||
(see above)
|
||||
if err
|
||||
paging_request_stop()
|
||||
(see below)
|
||||
locked_paging() ./openbsc/openbsc/src/osmo-bsc/osmo_bsc_grace.c:54
|
||||
paging_request_bts() ./openbsc/openbsc/src/libbsc/paging.c:307
|
||||
(see above)
|
||||
|
||||
|
||||
- A-bis Interface
|
||||
|
||||
Osmo-BSC to BTS:
|
||||
abis_sendmsg()
|
||||
^
|
||||
| libosmo-abis/src/e1_input.c:abis_rsl_sendmsg()
|
||||
| ^
|
||||
| | libbsc/abis_rsl.c: 23 callers
|
||||
| | rsl_bcch_info()
|
||||
| | rsl_sacch_filling()
|
||||
| | rsl_sacch_info_modify()
|
||||
| | rsl_chan_bs_power_ctrl()
|
||||
| | rsl_chan_ms_power_ctrl()
|
||||
| | rsl_chan_activate_lchan()
|
||||
| | rsl_chan_mode_modify_req()
|
||||
| | rsl_encryption_cmd()
|
||||
| | rsl_deact_sacch()
|
||||
| | rsl_rf_chan_release()
|
||||
| | rsl_paging_cmd()
|
||||
| | rsl_imm_assign_cmd()
|
||||
| | rsl_siemens_mrpci()
|
||||
| | rsl_data_request()
|
||||
| | rsl_establish_request()
|
||||
| | rsl_release_request()
|
||||
| | rsl_ipacc_crcx()
|
||||
| | rsl_ipacc_mdcx()
|
||||
| | rsl_ipacc_pdch_activate()
|
||||
| | rsl_sms_cb_command()
|
||||
| | rsl_nokia_si_begin()
|
||||
| | rsl_nokia_si_end()
|
||||
| | rsl_bs_power_control()
|
||||
|
|
||||
| libbsc/bts_nokia_site.c:nokia_abis_nm_queue_send_next()
|
||||
|
|
||||
| libbsc/abis_nm.c:_abis_nm_sendmsg()
|
||||
| ^ abis_nm_sendmsg()
|
||||
| | abis_nm_sendmsg_direct()
|
||||
|
|
||||
| osmo-bts/src/common/abis.c:abis_oml_sendmsg()
|
||||
| osmo-bts/src/common/abis.c:abis_bts_rsl_sendmsg()
|
||||
|
||||
|
||||
|
||||
libbsc/e1_config.c:bts_isdn_e1inp_line_ops.sign_link =
|
||||
libbsc/e1_config.c:bts_isdn_sign_link(struct msgb *msg)
|
||||
case E1INP_SIGN_RSL:
|
||||
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg) (1)
|
||||
case E1INP_SIGN_OML:
|
||||
ret = bts->model->oml_rcvmsg(msg);
|
||||
|
||||
libbsc/bts_ipaccess_nanobts.c:ipaccess_e1inp_line_ops.sign_link =
|
||||
ipaccess_sign_link(struct msgb *msg)
|
||||
case E1INP_SIGN_RSL:
|
||||
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg) (1)
|
||||
case E1INP_SIGN_OML:
|
||||
libbsc/abis_nm.c:abis_nm_rcvmsg(msg);
|
||||
|
||||
|
||||
(1)
|
||||
libbsc/abis_rsl.c:abis_rsl_rcvmsg(msg)
|
||||
case ABIS_RSL_MDISC_RLL:
|
||||
libbsc/abis_rsl.c:abis_rsl_rx_rll(msg)
|
||||
case DATA_IND, EST_IND:
|
||||
libbsc/bsc_api.c:gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
|
||||
msg->lchan->ts->trx->bts->network->bsc_api;
|
||||
if (lchan->conn)
|
||||
libbsc/bsc_api.c:dispatch_dtap() (2)
|
||||
else
|
||||
lchan->conn = subscr_con_allocate(msg->lchan);
|
||||
rc = api->compl_l3(lchan->conn, msg, 0); (3)
|
||||
|
||||
case ABIS_RSL_MDISC_DED_CHAN:
|
||||
rc = abis_rsl_rx_dchan(msg);
|
||||
|
||||
case ABIS_RSL_MDISC_COM_CHAN:
|
||||
rc = abis_rsl_rx_cchan(msg);
|
||||
|
||||
case ABIS_RSL_MDISC_TRX:
|
||||
rc = abis_rsl_rx_trx(msg);
|
||||
|
||||
case ABIS_RSL_MDISC_IPACCESS:
|
||||
rc = abis_rsl_rx_ipacc(msg);
|
||||
break;
|
||||
|
||||
case ABIS_RSL_MDISC_LOC:
|
||||
LOGP(DRSL, LOGL_NOTICE, "unimplemented RSL msg disc 0x%02x\n",
|
||||
|
||||
|
||||
(2)
|
||||
libbsc/bsc_api.c:dispatch_dtap()
|
||||
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
|
||||
|
||||
default:
|
||||
if (api->dtap)
|
||||
api->dtap(conn, link_id, msg); (5)
|
||||
|
||||
case GSM48_PDISC_RR:
|
||||
case GSM48_MT_RR_HANDO_COMPL:
|
||||
handle_rr_ho_compl(msg);
|
||||
|
||||
case GSM48_MT_RR_HANDO_FAIL:
|
||||
handle_rr_ho_fail(msg);
|
||||
|
||||
case GSM48_MT_RR_CIPH_M_COMPL:
|
||||
if (api->cipher_mode_compl)
|
||||
api->cipher_mode_compl(conn, msg, (4)
|
||||
conn->lchan->encr.alg_id);
|
||||
|
||||
case GSM48_MT_RR_ASS_COMPL:
|
||||
handle_ass_compl(conn, msg);
|
||||
|
||||
case GSM48_MT_RR_ASS_FAIL:
|
||||
handle_ass_fail(conn, msg);
|
||||
|
||||
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
||||
rc = gsm48_rx_rr_modif_ack(msg);
|
||||
if (rc < 0) {
|
||||
api->assign_fail(conn, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE)
|
||||
else
|
||||
api->assign_compl()
|
||||
|
||||
case GSM48_MT_RR_CLSM_CHG:
|
||||
handle_classmark_chg(conn, msg);
|
||||
|
||||
case GSM48_MT_RR_APP_INFO:
|
||||
if (api->dtap)
|
||||
api->dtap(conn, link_id, msg); (5)
|
||||
|
||||
default:
|
||||
if (api->dtap)
|
||||
api->dtap(conn, link_id, msg); (5)
|
||||
|
||||
case GSM48_MT_RR_GPRS_SUSP_REQ:
|
||||
DEBUGP(DRR, "GRPS SUSPEND REQUEST\n");
|
||||
|
||||
case GSM48_MT_RR_STATUS:
|
||||
LOGP(DRR, LOGL_NOTICE, "RR STATUS (cause: %s)\n",
|
||||
|
||||
case GSM48_MT_RR_MEAS_REP:
|
||||
LOGP(DMEAS, LOGL_ERROR, "DIRECT GSM48 MEASUREMENT REPORT ?!? ");
|
||||
|
||||
|
||||
(3)[0]
|
||||
msc_bsc_api().compl_l3 =
|
||||
libmsc/osmo_msc.c: msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
libmsc/gsm0408.c: gsm0408_dispatch() (6)
|
||||
|
||||
(3)[1]
|
||||
osmo_bsc_api().compl_l3 =
|
||||
osmo-bsc/osmo_bsc_api.c:bsc_compl_l3()
|
||||
msc = bsc_find_msc(conn, msg);
|
||||
complete_layer3(conn, msg, msc)
|
||||
bsc_filter_initial(msc->network->bsc_data, msc, conn, msg,
|
||||
&imsi, &con_type, &lu_cause);
|
||||
bsc_create_new_connection(conn, msc, send_ping);
|
||||
sccp->state_cb = msc_outgoing_sccp_state()
|
||||
sccp->data_cb = msc_outgoing_sccp_data()
|
||||
bsc_con->send_ping = send_ping()
|
||||
bsc_con->sccp_it_timeout.cb = sccp_it_timeout()
|
||||
bsc_con->sccp_cc_timeout.cb = sccp_cc_timeout()
|
||||
bsc_scan_bts_msg(conn, msg); (7)
|
||||
resp = gsm0808_create_layer3(msg, network_code, country_code, lac, ci);
|
||||
|
||||
(5)[0]
|
||||
msc_bsc_api().dtap =
|
||||
libmsc/osmo_msc.c: msc_dtap(conn, link_id, msg)
|
||||
gsm0408_dispatch(conn, msg) (6)
|
||||
|
||||
(5)[1]
|
||||
osmo_bsc_api().dtap =
|
||||
osmo-bsc/osmo_bsc_api.c: bsc_dtap(conn, link_id, msg)
|
||||
if (handle_cc_setup(conn, msg) >= 1) return;
|
||||
if (bsc_filter_data(conn, msg, &lu_cause) < 0)
|
||||
bsc_maybe_lu_reject()
|
||||
return;
|
||||
bsc_scan_bts_msg(conn, msg); (7)
|
||||
resp = gsm0808_create_dtap(msg, link_id);
|
||||
queue_msg_or_return(resp);
|
||||
|
||||
(7)
|
||||
bsc_scan_bts_msg() <osmo-bsc/osmo_bsc_filter.c:212>:
|
||||
if GSM48_PDISC_MM, GSM48_MT_MM_LOC_UPD_REQUEST
|
||||
handle_lu_request() <osmo-bsc/osmo_bsc_filter.c:29>:
|
||||
gsm48_generate_lai()
|
||||
if GSM48_PDISC_RR, GSM48_MT_RR_PAG_RESP
|
||||
handle_page_resp() <osmo-bsc/osmo_bsc_filter.c:97>:
|
||||
extract_sub() <osmo-bsc/osmo_bsc_filter.c:57>
|
||||
paging_request_stop() <libbsc/paging.c:390>:
|
||||
log_set_context()
|
||||
_paging_request_stop() <libbsc/paging.c:359>:
|
||||
paging_init_if_needed() <libbsc/paging.c:224>:
|
||||
paging_worker() <libbsc/paging.c:217>:
|
||||
paging_handle_pending_requests() <libbsc/paging.c:169> (R):
|
||||
cb()
|
||||
paging_give_credit() <libbsc/paging.c:107> (R):
|
||||
paging_handle_pending_requests() <libbsc/paging.c:169> (recursive: see 37)
|
||||
can_send_pag_req() <libbsc/paging.c:116>:
|
||||
page_ms() <libbsc/paging.c:69>:
|
||||
gsm0808_page() <libbsc/bsc_api.c:415>:
|
||||
rsl_paging_cmd() <libbsc/abis_rsl.c:751>:
|
||||
abis_rsl_dchan_hdr = RSL_IE_CHAN_NR
|
||||
mdisc_by_msgtype() <libbsc/abis_rsl.c:80>:
|
||||
ABIS_RSL_MDISC_RLL
|
||||
ABIS_RSL_MDISC_TRX
|
||||
ABIS_RSL_MDISC_COM_CHAN
|
||||
ABIS_RSL_MDISC_DED_CHAN
|
||||
ABIS_RSL_MDISC_LOC
|
||||
msgb_tv_put(msg, RSL_IE_PAGING_GROUP, paging_group);
|
||||
msgb_tlv_put(msg, RSL_IE_MS_IDENTITY, len-2, ms_ident+2);
|
||||
msgb_tv_put(msg, RSL_IE_CHAN_NEEDED, chan_needed);
|
||||
rsl_link
|
||||
abis_rsl_sendmsg()
|
||||
cbfn() (8)
|
||||
paging_remove_request() <libbsc/paging.c:60>:
|
||||
subscr_put() <libcommon/gsm_subscriber_base.c:89>
|
||||
subscr_put() <libcommon/gsm_subscriber_base.c:89>
|
||||
|
||||
(8)[0]
|
||||
libmsc/gsm_04_08.c:mncc_tx_to_cc()
|
||||
req->cbfn =
|
||||
libmsc/gsm_04_08.c:setup_trig_pag_evt
|
||||
|
||||
(8)[1]
|
||||
libmsc/gsm_04_11.c:gsm411_send_sms_subscr()
|
||||
req->cbfn =
|
||||
libmsc/gsm_04_11.c:paging_cb_send_sms
|
||||
|
||||
(9)
|
||||
bsc_scan_msc_msg() ./osmo-bsc/osmo_bsc_filter.c:330
|
||||
gsm48_hdr
|
||||
send_welcome_ussd() ./osmo-bsc/osmo_bsc_filter.c:229
|
||||
LOGP()
|
||||
DMSC
|
||||
LOGL_DEBUG
|
||||
ussd_welcome_txt
|
||||
BSS_SEND_USSD
|
||||
GSM48_MT_MM_INFO
|
||||
bsc_patch_mm_info() ./osmo-bsc/osmo_bsc_filter.c:255
|
||||
uint8_t
|
||||
tzbsd
|
||||
dst
|
||||
tlv_parse()
|
||||
gsm48_mm_att_tlvdef
|
||||
override
|
||||
hr
|
||||
mn
|
||||
TLVP_PRESENT()
|
||||
GSM48_IE_UTC
|
||||
LOGP()
|
||||
DMSC
|
||||
LOGL_DEBUG
|
||||
TLVP_VAL()
|
||||
GSM48_IE_NET_TIME_TZ
|
||||
GSM48_IE_NET_DST
|
||||
|
||||
|
||||
(6)
|
||||
libmsc/gsm0408.c: gsm0408_dispatch() (MSC rx from BSC)
|
||||
if (silent_call_reroute(conn, msg))
|
||||
return silent_call_rx(conn, msg);
|
||||
|
||||
case gsm48_pdisc_cc:
|
||||
rc = gsm0408_rcv_cc(conn, msg);
|
||||
|
||||
case gsm48_pdisc_mm:
|
||||
rc = gsm0408_rcv_mm(conn, msg);
|
||||
|
||||
case gsm48_pdisc_rr:
|
||||
rc = gsm0408_rcv_rr(conn, msg);
|
||||
|
||||
case gsm48_pdisc_sms:
|
||||
rc = gsm0411_rcv_sms(conn, msg);
|
||||
|
||||
case gsm48_pdisc_nc_ss:
|
||||
rc = handle_rcv_ussd(conn, msg);
|
||||
|
||||
case gsm48_pdisc_mm_gprs:
|
||||
case gsm48_pdisc_sm_gprs:
|
||||
logp(drll, logl_notice, "unimplemented "
|
||||
|
||||
msc_bsc_api().assign_compl =
|
||||
msc_assign_compl()
|
||||
nothing
|
||||
|
||||
(4)[0]
|
||||
libmsc/osmo_msc.c:msc_bsc_api().cipher_mode_compl =
|
||||
msc_ciph_m_compl(conn, msg, alg_id)
|
||||
conn->sec_operation->cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_SUCCEEDED,
|
||||
NULL, conn, conn->sec_operation->cb_data)
|
||||
release_security_operation(conn);
|
||||
msc_release_connection(conn)
|
||||
bsc_api.c:gsm0808_clear(conn)
|
||||
libbsc/handover_logic.c:bsc_clear_handover(conn, 1)
|
||||
libbsc/chan_alloc.c:lchan_release(ho->new_lchan, 0, RSL_REL_LOCAL_END);
|
||||
libbsc/chan_alloc.c:lchan_release(conn->secondary_lchan, 0, RSL_REL_LOCAL_END),
|
||||
(conn->lchan, 1, RSL_REL_NORMAL)
|
||||
bsc_api.c:subscr_con_free(conn)
|
||||
libcommon/gsm_subscriber_base.c:subscr_put(conn->subscr);
|
||||
|
||||
(4)[1]
|
||||
osmo-bsc/osmo_bsc_api.c:osmo_bsc_api().cipher_mode_compl =
|
||||
bsc_cipher_mode_compl()
|
||||
queue_msg_or_return() osmo-bsc/osmo_bsc_api.c
|
||||
bsc_queue_for_msc()
|
||||
|
||||
|
||||
libbsc/abis_nm.c:abis_nm_rcvmsg(msg);
|
||||
case ABIS_OM_MDISC_FOM:
|
||||
rc = abis_nm_rcvmsg_fom(msg);
|
||||
|
||||
case ABIS_OM_MDISC_MANUF:
|
||||
rc = abis_nm_rcvmsg_manuf(msg);
|
||||
|
||||
case ABIS_OM_MDISC_MMI:
|
||||
case ABIS_OM_MDISC_TRAU:
|
||||
LOGP(DNM, LOGL_ERROR, "unimplemented ABIS OML message discriminator 0x%x\n",
|
||||
|
||||
@@ -69,30 +69,30 @@ network
|
||||
nominal power 23
|
||||
max_power_red 20
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
msc
|
||||
ip.access rtp-base 4000
|
||||
timeout-ping 20
|
||||
|
||||
13
openbsc/doc/examples/osmo-bsc_nat/bscs.config
Normal file
13
openbsc/doc/examples/osmo-bsc_nat/bscs.config
Normal file
@@ -0,0 +1,13 @@
|
||||
nat
|
||||
bsc 0
|
||||
token lol
|
||||
location_area_code 1234
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
||||
bsc 1
|
||||
token wat
|
||||
location_area_code 5678
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
||||
@@ -62,11 +62,5 @@ nat
|
||||
timeout ping 20
|
||||
timeout pong 5
|
||||
ip-dscp 0
|
||||
bscs-config-file bscs.config
|
||||
access-list bla imsi-allow ^11$
|
||||
|
||||
bsc 0
|
||||
token bla
|
||||
location_area_code 1234
|
||||
description bsc
|
||||
max-endpoints 32
|
||||
paging forbidden 0
|
||||
|
||||
36
openbsc/doc/examples/osmo-cscn/osmo-cscn.cfg
Normal file
36
openbsc/doc/examples/osmo-cscn/osmo-cscn.cfg
Normal file
@@ -0,0 +1,36 @@
|
||||
!
|
||||
! OsmoCSCN configuration saved from vty
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
short name OsmoCSCN
|
||||
long name OsmoCSCN
|
||||
auth policy closed
|
||||
location updating reject cause 13
|
||||
encryption a5 0
|
||||
rrlp mode none
|
||||
mm info 1
|
||||
handover 0
|
||||
handover window rxlev averaging 10
|
||||
handover window rxqual averaging 1
|
||||
handover window rxlev neighbor averaging 10
|
||||
handover power budget interval 6
|
||||
handover power budget hysteresis 3
|
||||
handover maximum distance 9999
|
||||
timer t3101 10
|
||||
timer t3103 0
|
||||
timer t3105 0
|
||||
timer t3107 0
|
||||
timer t3109 4
|
||||
timer t3111 0
|
||||
timer t3113 60
|
||||
timer t3115 0
|
||||
timer t3117 0
|
||||
timer t3119 0
|
||||
timer t3141 0
|
||||
cscn
|
||||
subscriber-create-on-demand
|
||||
44
openbsc/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
Normal file
44
openbsc/doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg
Normal file
@@ -0,0 +1,44 @@
|
||||
!
|
||||
! OsmoGbProxy (UNKNOWN) configuration saved from vty
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging timestamp 0
|
||||
logging level all everything
|
||||
logging level gprs debug
|
||||
logging level ns info
|
||||
logging level bssgp debug
|
||||
logging level lglobal notice
|
||||
logging level llapd notice
|
||||
logging level linp notice
|
||||
logging level lmux notice
|
||||
logging level lmi notice
|
||||
logging level lmib notice
|
||||
logging level lsms notice
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
ns
|
||||
nse 666 nsvci 666
|
||||
nse 666 remote-role sgsn
|
||||
! nse 666 encapsulation framerelay-gre
|
||||
! nse 666 remote-ip 172.16.1.70
|
||||
! nse 666 fr-dlci 666
|
||||
timer tns-block 3
|
||||
timer tns-block-retries 3
|
||||
timer tns-reset 3
|
||||
timer tns-reset-retries 3
|
||||
timer tns-test 30
|
||||
timer tns-alive 3
|
||||
timer tns-alive-retries 10
|
||||
encapsulation udp local-port 23000
|
||||
! encapsulation framerelay-gre enabled 1
|
||||
gbproxy
|
||||
sgsn nsei 666
|
||||
core-mobile-country-code 666
|
||||
core-mobile-network-code 6
|
||||
core-access-point-name none match-imsi ^666066|^66607
|
||||
tlli-list max-length 200
|
||||
90
openbsc/doc/examples/osmo-gtphub/gtphub-example.txt
Normal file
90
openbsc/doc/examples/osmo-gtphub/gtphub-example.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
Here is a simple setup to test GTPHub operations. The IP addresses picked will
|
||||
work well only on a system that creates local addresses (127.0.0.123) on the
|
||||
fly (like linux) -- you may pick of course different IP addresses.
|
||||
|
||||
Overview of the example setup:
|
||||
|
||||
sgsnemu gtphub ggsn
|
||||
127.0.0.1 <--> 127.0.0.3 127.0.0.4 <--> 127.0.0.2
|
||||
|
||||
Prerequisites: openggsn.
|
||||
|
||||
Have a local directory where you store config files and from which you launch
|
||||
the GSNs and the hub (they will store restart counter files in that dir).
|
||||
In it, have these config files:
|
||||
|
||||
ggsn.conf:
|
||||
|
||||
# GGSN local address
|
||||
listen 127.0.0.2
|
||||
|
||||
# End User Addresses are picked from this range
|
||||
net 10.23.42.0/24
|
||||
|
||||
pcodns1 8.8.8.8
|
||||
|
||||
logfile /tmp/foo
|
||||
|
||||
gtphub.conf:
|
||||
|
||||
gtphub
|
||||
bind-to-sgsns 127.0.0.3
|
||||
bind-to-ggsns 127.0.0.4
|
||||
ggsn-proxy 127.0.0.2
|
||||
end
|
||||
|
||||
|
||||
(
|
||||
You may omit the ggsn-proxy if GRX ares is working, or if you add the GRX
|
||||
address and GGSN IP address to /etc/hosts something like:
|
||||
|
||||
127.0.0.2 internet.mnc070.mcc901.gprs
|
||||
|
||||
)
|
||||
|
||||
|
||||
Once the config files are in place, start the programs, in separate terminals.
|
||||
GGSN and SGSN need to be started with root priviliges to be able to create tun
|
||||
interfaces. GTPHub may run as unprivileged user.
|
||||
|
||||
The LD_LIBRARY_PATH below may be needed if OpenGGSN installed to /usr/local.
|
||||
|
||||
|
||||
1. GGSN:
|
||||
|
||||
sudo -s
|
||||
cd <your-test-dir>
|
||||
LD_LIBRARY_PATH=/usr/local/lib /usr/local/bin/ggsn -f -c ./ggsn.conf
|
||||
|
||||
2. GTPHub:
|
||||
|
||||
cd <your-test-dir>
|
||||
path/to/openbsc/openbsc/src/gprs/osmo-gtphub -c gtphub.conf #-e 1 #for DEBUG level
|
||||
|
||||
3. SGSN tests:
|
||||
|
||||
sudo -s
|
||||
cd <your-test-dir>
|
||||
/usr/local/bin/sgsnemu --createif -l 127.0.0.1 -r 127.0.0.3 --imsi 420001214365100 --contexts=3
|
||||
|
||||
Add more SGSNs using different IMSIs and local ports (if the same IMSI is used,
|
||||
the GGSN will reuse TEIs and tunnels will be discarded automatically):
|
||||
|
||||
/usr/local/bin/sgsnemu --createif -l 127.0.0.11 -r 127.0.0.3 --imsi 420001214365300 --contexts=3
|
||||
|
||||
This shows the basic setup of GTPHub. Testing internet traffic via sgsnemu
|
||||
still needs some effort to announce a mobile subscriber or the like (I have
|
||||
used a real BTS, osmo-sgsn and a testing SIM in a web phone, instead).
|
||||
|
||||
The core capability of GTPHub is to manage more than two GSNs, e.g. an SGSN
|
||||
contacting various GGSNs over the single GTPHub link. You would configure the
|
||||
SGSN to use one fixed GGSN (sending to gtphub) and gtphub will resolve the
|
||||
GGSNs once it has received the messages. So the SGSN may be behind NAT (add
|
||||
"sgsn-use-sender" to gtphub.conf) and communicate to various GGSNs over a
|
||||
single link to gtphub.
|
||||
|
||||
I hope this helps to get you going.
|
||||
Any suggestions/patches are welcome!
|
||||
|
||||
~Neels
|
||||
|
||||
25
openbsc/doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
Normal file
25
openbsc/doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg
Normal file
@@ -0,0 +1,25 @@
|
||||
!
|
||||
! Osmocom gtphub configuration
|
||||
!
|
||||
! This file is used for VTY tests, referenced by openbsc/osmoappdesc.py
|
||||
! For the test, try to use most config commands.
|
||||
!
|
||||
|
||||
line vty
|
||||
no login
|
||||
|
||||
gtphub
|
||||
! Local addresses to listen on and send from, both on one interface.
|
||||
! The side towards SGSN uses nonstandard ports.
|
||||
bind-to-sgsns ctrl 127.0.0.1 12123 user 127.0.0.1 12153
|
||||
! The GGSN side with standard ports.
|
||||
bind-to-ggsns 127.0.0.1
|
||||
|
||||
! Proxy: unconditionally direct all traffic to...
|
||||
sgsn-proxy 127.0.0.4
|
||||
|
||||
! Proxy with nonstandard ports or separate IPs:
|
||||
ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
|
||||
|
||||
! Add a name server for GGSN resolution
|
||||
grx-dns-add 192.168.0.1
|
||||
25
openbsc/doc/examples/osmo-gtphub/osmo-gtphub.cfg
Normal file
25
openbsc/doc/examples/osmo-gtphub/osmo-gtphub.cfg
Normal file
@@ -0,0 +1,25 @@
|
||||
!
|
||||
! Osmocom gtphub configuration
|
||||
!
|
||||
|
||||
line vty
|
||||
no login
|
||||
|
||||
gtphub
|
||||
! Local addresses to listen on and send from, each on standard ports
|
||||
! 2123 and 2152. Setting these addresses is mandatory.
|
||||
bind-to-sgsns 127.0.0.1
|
||||
bind-to-ggsns 127.0.0.2
|
||||
|
||||
! Local nonstandard ports or separate IPs:
|
||||
!bind-to-sgsns ctrl 127.0.0.1 2342 user 127.0.0.1 4223
|
||||
|
||||
! Proxy: unconditionally direct all traffic to...
|
||||
!ggsn-proxy 127.0.0.3
|
||||
!sgsn-proxy 127.0.0.4
|
||||
|
||||
! Proxy with nonstandard ports or separate IPs:
|
||||
!ggsn-proxy ctrl 127.0.0.3 2123 user 127.0.0.5 2152
|
||||
|
||||
! Add a name server for GGSN resolution
|
||||
!grx-dns-add 192.168.0.1
|
||||
@@ -60,38 +60,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 119
|
||||
@@ -99,66 +99,66 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 1
|
||||
hopping sequence-number 0
|
||||
hopping maio 0
|
||||
hopping arfcn add 117
|
||||
hopping arfcn add 119
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
|
||||
@@ -29,56 +29,56 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
arfcn 123
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
|
||||
@@ -27,59 +27,59 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
arfcn 123
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 4 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
bts 1
|
||||
type bs11
|
||||
band GSM900
|
||||
@@ -93,56 +93,56 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 1 timeslot 6 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 1 timeslot 7 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 1 timeslot 7 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 1 timeslot 7 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 1 timeslot 7 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 7 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 8 sub-slot 3
|
||||
trx 1
|
||||
arfcn 124
|
||||
max_power_red 0
|
||||
rsl e1 line 1 timeslot 6 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 9 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 1 timeslot 10 sub-slot 3
|
||||
|
||||
@@ -29,28 +29,28 @@ network
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
|
||||
|
||||
@@ -59,41 +59,41 @@ network
|
||||
nominal power 23
|
||||
max_power_red 0
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 873
|
||||
nominal power 23
|
||||
max_power_red 0
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
|
||||
@@ -59,19 +59,19 @@ network
|
||||
nominal power 23
|
||||
max_power_red 20
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
|
||||
@@ -31,87 +31,87 @@ network
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 2 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 7 sub-slot 3
|
||||
|
||||
trx 1
|
||||
arfcn 870
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 3 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
|
||||
trx 2
|
||||
arfcn 874
|
||||
max_power_red 24
|
||||
rsl e1 line 0 timeslot 4 sub-slot full
|
||||
rsl e1 tei 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 10 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
|
||||
@@ -67,38 +67,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 2 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 3
|
||||
trx 1
|
||||
rf_locked 0
|
||||
arfcn 57
|
||||
@@ -106,38 +106,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 4 sub-slot full
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 3
|
||||
trx 2
|
||||
rf_locked 0
|
||||
arfcn 59
|
||||
@@ -145,38 +145,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 7 sub-slot full
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 3
|
||||
trx 3
|
||||
rf_locked 0
|
||||
arfcn 61
|
||||
@@ -184,38 +184,38 @@ network
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 10 sub-slot full
|
||||
rsl e1 tei 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 1
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 2
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 11 sub-slot 3
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 1
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 2
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 12 sub-slot 3
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
|
||||
38
openbsc/doc/libbsc-data-structures.dot
Normal file
38
openbsc/doc/libbsc-data-structures.dot
Normal file
@@ -0,0 +1,38 @@
|
||||
digraph G {
|
||||
net [label="gsm_network"]
|
||||
subconns [label="subscr_conns"]
|
||||
btslist [label="bts_list"]
|
||||
bts [label="gsm_bts"]
|
||||
trx [label="gsm_bts_trx"]
|
||||
ts [label="gsm_bts_trx_ts"]
|
||||
lchan [label="gsm_lchan"]
|
||||
sub [label="gsm_subscriber"]
|
||||
subcon [label="gsm_subscriber_conn"]
|
||||
sccpcon [label="osmo_bsc_sccp_con"]
|
||||
subgrp [label="gsm_subscriber_group"]
|
||||
|
||||
net -> btslist
|
||||
btslist -> bts [label="llist"]
|
||||
bts -> trx
|
||||
trx -> ts
|
||||
ts -> lchan
|
||||
|
||||
lchan -> ts
|
||||
ts -> trx
|
||||
trx -> bts
|
||||
bts -> net
|
||||
|
||||
lchan -> subcon
|
||||
|
||||
net -> subconns
|
||||
subconns -> subcon [label="llist"]
|
||||
subcon -> sub
|
||||
subcon -> sccpcon
|
||||
subcon -> lchan
|
||||
subcon -> lchan [label="ho_lchan"]
|
||||
subcon -> bts
|
||||
subcon -> lchan [label="secondary_lchan"]
|
||||
|
||||
sub -> subgrp
|
||||
subgrp -> net
|
||||
}
|
||||
15
openbsc/doc/libmsc-data-structures.dot
Normal file
15
openbsc/doc/libmsc-data-structures.dot
Normal file
@@ -0,0 +1,15 @@
|
||||
digraph G {
|
||||
net [label="gsm_network"]
|
||||
subconns [label="subscr_conns"]
|
||||
sub [label="gsm_subscriber"]
|
||||
subcon [label="gsm_subscriber_conn"]
|
||||
subgrp [label="gsm_subscriber_group"]
|
||||
|
||||
net -> subconns
|
||||
subconns -> subcon [label="llist"]
|
||||
subcon -> sub
|
||||
subcon -> net
|
||||
|
||||
sub -> subgrp
|
||||
subgrp -> net
|
||||
}
|
||||
250
openbsc/doc/osmocom-authn-protocol.txt
Normal file
250
openbsc/doc/osmocom-authn-protocol.txt
Normal file
@@ -0,0 +1,250 @@
|
||||
|
||||
Osmocom Authentication Protocol (OAP)
|
||||
|
||||
1. General
|
||||
|
||||
The Osmocom Authentication Protocol employs mutual authentication to register a
|
||||
client with a server over an IPA connection. Milenage is used as the
|
||||
authentication algorithm, where client and server have a shared secret.
|
||||
|
||||
For example, an SGSN, as OAP client, may use its SGSN ID to register with a MAP
|
||||
proxy, an OAP server.
|
||||
|
||||
1.1. Connection
|
||||
|
||||
The protocol expects that a reliable, ordered, packet boundaries preserving
|
||||
connection is used (e.g. IPA over TCP).
|
||||
|
||||
1.2. Using IPA
|
||||
|
||||
By default, the following identifiers should be used:
|
||||
- IPA protocol: 0xee (OSMO)
|
||||
- IPA OSMO protocol extension: 0x06 (OAP)
|
||||
|
||||
2. Procedures
|
||||
|
||||
Ideal communication sequence:
|
||||
|
||||
Client Server
|
||||
| |
|
||||
| Register (ID) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Challenge (RAND+AUTN) |
|
||||
|<-----------------------------------|
|
||||
| |
|
||||
| Challenge Result (XRES) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Register Result |
|
||||
|<-----------------------------------|
|
||||
|
||||
Variation "test setup":
|
||||
|
||||
Client Server
|
||||
| |
|
||||
| Register (ID) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Register Result |
|
||||
|<-----------------------------------|
|
||||
|
||||
Variation "invalid sequence nr":
|
||||
|
||||
Client Server
|
||||
| |
|
||||
| Register (ID) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Challenge (RAND+AUTN) |
|
||||
|<-----------------------------------|
|
||||
| |
|
||||
| Sync Request (AUTS) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Challenge (RAND'+AUTN') |
|
||||
|<-----------------------------------|
|
||||
| |
|
||||
| Challenge Result (XRES) |
|
||||
|----------------------------------->|
|
||||
| |
|
||||
| Register Result |
|
||||
|<-----------------------------------|
|
||||
|
||||
2.1. Register
|
||||
|
||||
The client sends a REGISTER_REQ message containing an identifier number.
|
||||
|
||||
2.2. Challenge
|
||||
|
||||
The OAP server (optionally) sends back a CHALLENGE_REQ, containing random bytes
|
||||
and a milenage authentication token generated from these random bytes, using a
|
||||
shared secret, to authenticate itself to the OAP client. The server may omit
|
||||
this challenge entirely, based on its configuration, and immediately reply with
|
||||
a Register Result response. If the client cannot be registered (e.g. id is
|
||||
invalid), the server sends a REGISTER_ERR response.
|
||||
|
||||
2.3. Challenge Result
|
||||
|
||||
When the client has received a Challenge, it may verify the server's
|
||||
authenticity and validity of the sequence number (included in AUTN), and, if
|
||||
valid, reply with a CHALLENGE_RES message. This shall contain an XRES
|
||||
authentication token generated by milenage from the same random bytes received
|
||||
from the server and the same shared secet. If the client decides to cancel the
|
||||
registration (e.g. invalid AUTN), it shall not reply to the CHALLENGE_REQ; a
|
||||
CHALLENGE_ERR message may be sent, but is not mandatory. For example, the
|
||||
client may directly start with a new REGISTER_REQ message.
|
||||
|
||||
2.4. Sync Request
|
||||
|
||||
When the client has received a Challenge but sees an invalid sequence number
|
||||
(embedded in AUTN, according to the milenage algorithm), the client may send a
|
||||
SYNC_REQ message containing an AUTS synchronisation token.
|
||||
|
||||
2.5. Sync Result
|
||||
|
||||
If the server has received a valid Sync Request, it shall answer by directly
|
||||
sending another Challenge (see 2.2.). If an invalid Sync Request is received,
|
||||
the server shall reply with a REGISTER_ERR message.
|
||||
|
||||
2.6. Register Result
|
||||
|
||||
The server sends a REGISTER_RES message to indicate that registration has been
|
||||
successful. If the server cannot register the client (e.g. invalid challenge
|
||||
response), it shall send a REGISTER_ERR message.
|
||||
|
||||
3. Message Format
|
||||
|
||||
3.1. General
|
||||
|
||||
Every message is based on the following message format
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
|
||||
The receiver shall be able to receive IEs in any order. Unknown IEs shall be
|
||||
ignored.
|
||||
|
||||
3.2.1. Register Request
|
||||
|
||||
Client -> Server
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
30 Client ID big endian int (2 oct) M TLV 4
|
||||
|
||||
3.2.2. Register Error
|
||||
|
||||
Server -> Client
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.6. Register Result
|
||||
|
||||
Server -> Client
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
|
||||
3.2.3. Challenge
|
||||
|
||||
Server -> Client
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
20 RAND octet string (16) M TLV 18
|
||||
23 AUTN octet string (16) M TLV 18
|
||||
|
||||
3.2.4. Challenge Error
|
||||
|
||||
Client -> Server
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
3.2.5. Challenge Result
|
||||
|
||||
Client -> Server
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
21 XRES octet string (8) M TLV 10
|
||||
|
||||
3.2.3. Sync Request
|
||||
|
||||
Client -> Server
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
20 AUTS octet string (16) M TLV 18
|
||||
|
||||
3.2.4. Sync Error
|
||||
|
||||
Server -> Client
|
||||
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
02 Cause GMM cause, M TLV 3
|
||||
04.08: 10.5.5.14
|
||||
|
||||
4. Information Elements
|
||||
|
||||
4.1. General
|
||||
|
||||
[...]
|
||||
|
||||
4.2.1. Message Type
|
||||
|
||||
+---------------------------------------------------+
|
||||
| 8 7 6 5 4 3 2 1 |
|
||||
| |
|
||||
| 0 0 0 0 0 1 0 0 - Register Request |
|
||||
| 0 0 0 0 0 1 0 1 - Register Error |
|
||||
| 0 0 0 0 0 1 1 0 - Register Result |
|
||||
| |
|
||||
| 0 0 0 0 1 0 0 0 - Challenge Request |
|
||||
| 0 0 0 0 1 0 0 1 - Challenge Error |
|
||||
| 0 0 0 0 1 0 1 0 - Challenge Result |
|
||||
| |
|
||||
| 0 0 0 0 1 1 0 0 - Sync Request |
|
||||
| 0 0 0 0 1 1 0 1 - Sync Error (not used) |
|
||||
| 0 0 0 0 1 1 1 0 - Sync Result (not used) |
|
||||
| |
|
||||
+---------------------------------------------------+
|
||||
|
||||
4.2.2. IE Identifier (informational)
|
||||
|
||||
These are the standard values for the IEI.
|
||||
|
||||
+---------------------------------------------------------+
|
||||
| IEI Info Element Type |
|
||||
| |
|
||||
| 0x02 Cause GMM cause, 04.08: 10.5.5.14 |
|
||||
| 0x20 RAND octet string |
|
||||
| 0x23 AUTN octet string |
|
||||
| 0x24 XRES octet string |
|
||||
| 0x25 AUTS octet string |
|
||||
| 0x30 Client ID big endian int (2 octets) |
|
||||
+---------------------------------------------------------+
|
||||
|
||||
4.2.3. Client ID
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | Client ID IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of Client ID IE contents (2) | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Client ID number, most significant byte | octet 3
|
||||
+-----------------------------------------------------+
|
||||
| Client ID number, least significant byte | octet 4
|
||||
+-----------------------------------------------------+
|
||||
|
||||
The Client ID number shall be interpreted as an unsigned 16bit integer, where 0
|
||||
indicates an invalid / unset ID.
|
||||
|
||||
@@ -120,6 +120,7 @@ Network peer -> SGSN
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
08 MSISDN 4.2.10 O TLV 0-9
|
||||
09 HLR Number 4.2.12 O TLV 0-9
|
||||
04 PDP info complete 4.2.8 O TLV 2
|
||||
05 PDP info 4.2.3 1-10 TLV
|
||||
|
||||
@@ -149,6 +150,7 @@ SGSN -> Network peer
|
||||
IEI Info Element Type Pres. Format Length
|
||||
Message type 4.2.1 M V 1
|
||||
01 IMSI 4.2.9 M TLV 2-10
|
||||
09 HLR Number 4.2.12 M TLV 0-9
|
||||
|
||||
3.2.10. Purge MS Error
|
||||
|
||||
@@ -357,6 +359,7 @@ IEI that shall be used for the encoding.
|
||||
| 0x06 Cancel type 4.2.6 |
|
||||
| 0x07 Freeze P-TMSI 4.2.8 |
|
||||
| 0x08 MSISDN ISDN-AddressString/octet, 4.2.10 |
|
||||
| 0x09 HLR Number 4.2.12 |
|
||||
| 0x10 PDP context id big endian int |
|
||||
| 0x11 PDP type 4.2.4 |
|
||||
| 0x12 APN 04.08, 10.5.6.1 |
|
||||
@@ -442,3 +445,24 @@ Priority and the reset are encoded as octets 3-N of 24.008.
|
||||
+-----------------------------------------------------+
|
||||
: : :
|
||||
+-----------------------------------------------------+
|
||||
|
||||
4.2.12. HLR Number encoded as GSM 09.02 ISDN-AddressString
|
||||
|
||||
The HLR Number is encoded as an ISDN-AddressString in GSM 09.02. It
|
||||
will be stored by the SGSN can be used by the CDR module to keep a
|
||||
record.
|
||||
|
||||
8 7 6 5 4 3 2 1
|
||||
+-----------------------------------------------------+
|
||||
| | IEI | octet 1
|
||||
+-----------------------------------------------------+
|
||||
| Length of IE contents | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| ext | Type of num | Numbering plan | octet 2
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 2 | Number digit 1 | octet 3
|
||||
+-----------------------------------------------------+
|
||||
| Number digit 4 | Number digit 3 | octet 4
|
||||
+-----------------------------------------------------+
|
||||
: : :
|
||||
+-----------------------------------------------------+
|
||||
|
||||
@@ -15,8 +15,12 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
bss.h gsm_data_shared.h ipaccess.h mncc_int.h \
|
||||
arfcn_range_encode.h nat_rewrite_trie.h bsc_nat_callstats.h \
|
||||
osmux.h mgcp_transcode.h gprs_utils.h \
|
||||
gprs_gb_parse.h smpp.h meas_feed.h gprs_gsup_messages.h \
|
||||
gprs_gsup_client.h bsc_msg_filter.h
|
||||
gprs_gb_parse.h smpp.h meas_feed.h \
|
||||
gprs_gsup_client.h bsc_msg_filter.h \
|
||||
oap.h oap_messages.h \
|
||||
gtphub.h \
|
||||
msc_api.h msc_ifaces.h iu.h iu_cs.h \
|
||||
xsc.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
|
||||
@@ -31,6 +31,7 @@ struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_bts_trx_ts;
|
||||
|
||||
#define GSM48_LEN2PLEN(a) (((a) << 2) | 1)
|
||||
|
||||
int rsl_bcch_info(struct gsm_bts_trx *trx, uint8_t type,
|
||||
const uint8_t *data, int len);
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
#ifndef _AUTH_H
|
||||
#define _AUTH_H
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
struct gsm_auth_tuple;
|
||||
struct gsm_subscriber;
|
||||
|
||||
enum auth_action {
|
||||
AUTH_ERROR = -1, /* Internal error */
|
||||
AUTH_NOT_AVAIL = 0, /* No auth tuple available */
|
||||
AUTH_DO_AUTH_THAN_CIPH = 1, /* Firsth authenticate, then cipher */
|
||||
AUTH_DO_AUTH_THEN_CIPH = 1, /* Firsth authenticate, then cipher */
|
||||
AUTH_DO_CIPH = 2, /* Only ciphering */
|
||||
AUTH_DO_AUTH = 3, /* Only authentication, no ciphering */
|
||||
};
|
||||
|
||||
extern const struct value_string auth_action_names[];
|
||||
static inline const char *auth_action_str(enum auth_action a)
|
||||
{
|
||||
return get_value_string(auth_action_names, a);
|
||||
}
|
||||
|
||||
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr, int key_seq);
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ struct bsc_api {
|
||||
* not implemented AMR5.9 will be used.
|
||||
*/
|
||||
void (*mr_config)(struct gsm_subscriber_connection *conn,
|
||||
struct gsm48_multi_rate_conf *conf);
|
||||
struct gsm_lchan *lchan, int full_rate);
|
||||
};
|
||||
|
||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
|
||||
@@ -52,6 +52,4 @@ int gsm0808_page(struct gsm_bts *bts, unsigned int page_group,
|
||||
unsigned int mi_len, uint8_t *mi, int chan_type);
|
||||
int gsm0808_clear(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct llist_head *bsc_api_sub_connections(struct gsm_network *net);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -60,6 +60,6 @@ void bsc_msc_schedule_connect(struct bsc_msc_connection *);
|
||||
|
||||
void bsc_msc_lost(struct bsc_msc_connection *);
|
||||
|
||||
struct msgb *bsc_msc_id_get_resp(const char *token);
|
||||
struct msgb *bsc_msc_id_get_resp(int fixed, const char *token, const uint8_t *res, int len);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
#include <regex.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define DIR_BSC 1
|
||||
#define DIR_MSC 2
|
||||
@@ -84,6 +85,7 @@ struct bsc_connection {
|
||||
|
||||
/* do we know anything about this BSC? */
|
||||
int authenticated;
|
||||
uint8_t last_rand[16];
|
||||
|
||||
/* the fd we use to communicate */
|
||||
struct osmo_wqueue write_queue;
|
||||
@@ -147,6 +149,8 @@ enum bsc_cfg_ctr {
|
||||
struct bsc_config {
|
||||
struct llist_head entry;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t key_present;
|
||||
char *token;
|
||||
int nr;
|
||||
|
||||
@@ -161,6 +165,10 @@ struct bsc_config {
|
||||
/* audio handling */
|
||||
int max_endpoints;
|
||||
|
||||
/* used internally for reload handling */
|
||||
bool remove;
|
||||
bool token_updated;
|
||||
|
||||
/* backpointer */
|
||||
struct bsc_nat *nat;
|
||||
|
||||
@@ -261,6 +269,11 @@ struct bsc_nat {
|
||||
|
||||
struct bsc_endpoint *bsc_endpoints;
|
||||
|
||||
/* path to file with BSC config */
|
||||
char *include_file;
|
||||
char *include_base;
|
||||
char *resolved_path;
|
||||
|
||||
/* filter */
|
||||
char *acc_lst_name;
|
||||
|
||||
@@ -317,8 +330,10 @@ struct bsc_nat_ussd_con {
|
||||
};
|
||||
|
||||
/* create and init the structures */
|
||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token);
|
||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token,
|
||||
unsigned int number);
|
||||
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
|
||||
struct bsc_config *bsc_config_by_token(struct bsc_nat *nat, const char *token, int len);
|
||||
void bsc_config_free(struct bsc_config *);
|
||||
void bsc_config_add_lac(struct bsc_config *cfg, int lac);
|
||||
void bsc_config_del_lac(struct bsc_config *cfg, int lac);
|
||||
@@ -368,7 +383,7 @@ int bsc_mgcp_nat_init(struct bsc_nat *nat);
|
||||
|
||||
struct nat_sccp_connection *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
|
||||
struct msgb *bsc_mgcp_rewrite(char *input, int length, int endp, const char *ip,
|
||||
int port, int osmux, int *payload_type, int mode_set);
|
||||
int port, int osmux, int *first_payload_type, int mode_set);
|
||||
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
|
||||
|
||||
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
|
||||
@@ -419,7 +434,8 @@ void bsc_nat_num_rewr_entry_adapt(void *ctx, struct llist_head *head, const stru
|
||||
void bsc_nat_send_mgcp_to_msc(struct bsc_nat *bsc_nat, struct msgb *msg);
|
||||
void bsc_nat_handle_mgcp(struct bsc_nat *bsc, struct msgb *msg);
|
||||
|
||||
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat, int port);
|
||||
struct ctrl_handle *bsc_nat_controlif_setup(struct bsc_nat *nat,
|
||||
const char *bind_addr, int port);
|
||||
void bsc_nat_ctrl_del_pending(struct bsc_cmd_list *pending);
|
||||
int bsc_nat_handle_ctrlif_msg(struct bsc_connection *bsc, struct msgb *msg);
|
||||
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
#ifndef _BSS_H_
|
||||
#define _BSS_H_
|
||||
|
||||
#include <openbsc/xsc.h>
|
||||
|
||||
struct gsm_network;
|
||||
struct msgb;
|
||||
|
||||
/* start and stop network */
|
||||
extern int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, struct msgb *), const char *cfg_file);
|
||||
extern int bsc_network_init(mncc_recv_cb_t mncc_recv);
|
||||
extern int bsc_network_configure(const char *cfg_file);
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
|
||||
/* register all supported BTS */
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port);
|
||||
struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net,
|
||||
const char *bind_addr, uint16_t port);
|
||||
|
||||
@@ -33,6 +33,10 @@ enum {
|
||||
DCTRL,
|
||||
DSMPP,
|
||||
DFILTER,
|
||||
DGTPHUB,
|
||||
DSUA,
|
||||
DRANAP,
|
||||
DIUCS,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
|
||||
@@ -48,8 +48,24 @@ enum gbproxy_peer_ctr {
|
||||
GBPROX_PEER_CTR_PATCH_ERR,
|
||||
GBPROX_PEER_CTR_ATTACH_REQS,
|
||||
GBPROX_PEER_CTR_ATTACH_REJS,
|
||||
GBPROX_PEER_CTR_ATTACH_ACKS,
|
||||
GBPROX_PEER_CTR_ATTACH_COMPLS,
|
||||
GBPROX_PEER_CTR_RA_UPD_REQS,
|
||||
GBPROX_PEER_CTR_RA_UPD_REJS,
|
||||
GBPROX_PEER_CTR_RA_UPD_ACKS,
|
||||
GBPROX_PEER_CTR_RA_UPD_COMPLS,
|
||||
GBPROX_PEER_CTR_GMM_STATUS_BSS,
|
||||
GBPROX_PEER_CTR_GMM_STATUS_SGSN,
|
||||
GBPROX_PEER_CTR_DETACH_REQS,
|
||||
GBPROX_PEER_CTR_DETACH_ACKS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_REQS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_REJS,
|
||||
GBPROX_PEER_CTR_PDP_ACT_ACKS,
|
||||
GBPROX_PEER_CTR_PDP_DEACT_REQS,
|
||||
GBPROX_PEER_CTR_PDP_DEACT_ACKS,
|
||||
GBPROX_PEER_CTR_TLLI_UNKNOWN,
|
||||
GBPROX_PEER_CTR_TLLI_CACHE_SIZE,
|
||||
GBPROX_PEER_CTR_LAST,
|
||||
};
|
||||
|
||||
enum gbproxy_keep_mode {
|
||||
@@ -101,10 +117,6 @@ struct gbproxy_config {
|
||||
|
||||
/* IMSI checking/matching */
|
||||
struct gbproxy_match matches[GBPROX_MATCH_LAST];
|
||||
|
||||
/* Used to generate identifiers */
|
||||
unsigned bss_ptmsi_state;
|
||||
unsigned sgsn_tlli_state;
|
||||
};
|
||||
|
||||
struct gbproxy_patch_state {
|
||||
|
||||
@@ -10,7 +10,9 @@ int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
|
||||
int gsm48_tx_gsm_act_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||
int gsm48_tx_gsm_deact_pdp_acc(struct sgsn_pdp_ctx *pdp);
|
||||
|
||||
int gsm0408_gprs_rcvmsg(struct msgb *msg, struct gprs_llc_llme *llme);
|
||||
int gsm0408_gprs_rcvmsg_gb(struct msgb *msg, struct gprs_llc_llme *llme);
|
||||
int gsm0408_gprs_rcvmsg_iu(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||
uint16_t *sai);
|
||||
int gsm0408_gprs_force_reattach(struct sgsn_mm_ctx *mmctx);
|
||||
int gsm0408_gprs_force_reattach_oldmsg(struct msgb *msg);
|
||||
void gsm0408_gprs_access_granted(struct sgsn_mm_ctx *mmctx);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
|
||||
#include <openbsc/oap.h>
|
||||
|
||||
#define GPRS_GSUP_RECONNECT_INTERVAL 10
|
||||
#define GPRS_GSUP_PING_INTERVAL 20
|
||||
|
||||
@@ -38,6 +40,8 @@ struct gprs_gsup_client {
|
||||
gprs_gsup_read_cb_t read_cb;
|
||||
void *data;
|
||||
|
||||
struct oap_state oap_state;
|
||||
|
||||
struct osmo_timer_list ping_timer;
|
||||
struct osmo_timer_list connect_timer;
|
||||
int is_connected;
|
||||
@@ -46,7 +50,8 @@ struct gprs_gsup_client {
|
||||
|
||||
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
gprs_gsup_read_cb_t read_cb);
|
||||
gprs_gsup_read_cb_t read_cb,
|
||||
struct oap_config *oap_config);
|
||||
|
||||
void gprs_gsup_client_destroy(struct gprs_gsup_client *gsupc);
|
||||
int gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg);
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
/* GPRS Subscriber Update Protocol message encoder/decoder */
|
||||
|
||||
/* (C) 2014 by Sysmocom s.f.m.c. GmbH
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Jacob Erlbeck
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
/* Needed for GSM_IMSI_LENGTH: */
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
#define GPRS_GSUP_MAX_NUM_PDP_INFO 10 /* GSM 09.02 limits this to 50 */
|
||||
#define GPRS_GSUP_MAX_NUM_AUTH_INFO 5
|
||||
#define GPRS_GSUP_MAX_MSISDN_LEN 9
|
||||
|
||||
#define GPRS_GSUP_PDP_TYPE_SIZE 2
|
||||
|
||||
enum gprs_gsup_iei {
|
||||
GPRS_GSUP_IMSI_IE = 0x01,
|
||||
GPRS_GSUP_CAUSE_IE = 0x02,
|
||||
GPRS_GSUP_AUTH_TUPLE_IE = 0x03,
|
||||
GPRS_GSUP_PDP_INFO_COMPL_IE = 0x04,
|
||||
GPRS_GSUP_PDP_INFO_IE = 0x05,
|
||||
GPRS_GSUP_CANCEL_TYPE_IE = 0x06,
|
||||
GPRS_GSUP_FREEZE_PTMSI_IE = 0x07,
|
||||
GPRS_GSUP_MSISDN_IE = 0x08,
|
||||
GPRS_GSUP_PDP_CONTEXT_ID_IE = 0x10,
|
||||
GPRS_GSUP_PDP_TYPE_IE = 0x11,
|
||||
GPRS_GSUP_ACCESS_POINT_NAME_IE = 0x12,
|
||||
GPRS_GSUP_PDP_QOS_IE = 0x13,
|
||||
GPRS_GSUP_RAND_IE = 0x20,
|
||||
GPRS_GSUP_SRES_IE = 0x21,
|
||||
GPRS_GSUP_KC_IE = 0x22
|
||||
};
|
||||
|
||||
enum gprs_gsup_message_type {
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_REQUEST = 0b00000100,
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_ERROR = 0b00000101,
|
||||
GPRS_GSUP_MSGT_UPDATE_LOCATION_RESULT = 0b00000110,
|
||||
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_REQUEST = 0b00001000,
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_ERROR = 0b00001001,
|
||||
GPRS_GSUP_MSGT_SEND_AUTH_INFO_RESULT = 0b00001010,
|
||||
|
||||
GPRS_GSUP_MSGT_PURGE_MS_REQUEST = 0b00001100,
|
||||
GPRS_GSUP_MSGT_PURGE_MS_ERROR = 0b00001101,
|
||||
GPRS_GSUP_MSGT_PURGE_MS_RESULT = 0b00001110,
|
||||
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_REQUEST = 0b00010000,
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_ERROR = 0b00010001,
|
||||
GPRS_GSUP_MSGT_INSERT_DATA_RESULT = 0b00010010,
|
||||
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_REQUEST = 0b00010100,
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_ERROR = 0b00010101,
|
||||
GPRS_GSUP_MSGT_DELETE_DATA_RESULT = 0b00010110,
|
||||
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_REQUEST = 0b00011100,
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_ERROR = 0b00011101,
|
||||
GPRS_GSUP_MSGT_LOCATION_CANCEL_RESULT = 0b00011110,
|
||||
};
|
||||
|
||||
#define GPRS_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)
|
||||
#define GPRS_GSUP_IS_MSGT_ERROR(msgt) (((msgt) & 0b00000011) == 0b01)
|
||||
#define GPRS_GSUP_TO_MSGT_ERROR(msgt) (((msgt) & 0b11111100) | 0b01)
|
||||
|
||||
enum gprs_gsup_cancel_type {
|
||||
GPRS_GSUP_CANCEL_TYPE_UPDATE = 1, /* on wire: 0 */
|
||||
GPRS_GSUP_CANCEL_TYPE_WITHDRAW = 2, /* on wire: 1 */
|
||||
};
|
||||
|
||||
struct gprs_gsup_pdp_info {
|
||||
unsigned int context_id;
|
||||
int have_info;
|
||||
uint16_t pdp_type;
|
||||
const uint8_t *apn_enc;
|
||||
size_t apn_enc_len;
|
||||
const uint8_t *qos_enc;
|
||||
size_t qos_enc_len;
|
||||
};
|
||||
|
||||
struct gprs_gsup_message {
|
||||
enum gprs_gsup_message_type message_type;
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
enum gsm48_gmm_cause cause;
|
||||
enum gprs_gsup_cancel_type cancel_type;
|
||||
int pdp_info_compl;
|
||||
int freeze_ptmsi;
|
||||
struct gsm_auth_tuple auth_tuples[GPRS_GSUP_MAX_NUM_AUTH_INFO];
|
||||
size_t num_auth_tuples;
|
||||
struct gprs_gsup_pdp_info pdp_infos[GPRS_GSUP_MAX_NUM_PDP_INFO];
|
||||
size_t num_pdp_infos;
|
||||
const uint8_t *msisdn_enc;
|
||||
size_t msisdn_enc_len;
|
||||
};
|
||||
|
||||
int gprs_gsup_decode(const uint8_t *data, size_t data_len,
|
||||
struct gprs_gsup_message *gsup_msg);
|
||||
void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg);
|
||||
@@ -9,11 +9,10 @@
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
||||
#include <osmocom/crypt/gprs_cipher.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_EXTENSION_LENGTH 15
|
||||
#define GSM_APN_LENGTH 102
|
||||
|
||||
@@ -24,7 +23,7 @@ struct gsm_subscriber;
|
||||
enum gsm48_gsm_cause;
|
||||
|
||||
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
|
||||
enum gprs_mm_state {
|
||||
enum gprs_gmm_state {
|
||||
GMM_DEREGISTERED, /* 4.1.3.3.1.1 */
|
||||
GMM_COMMON_PROC_INIT, /* 4.1.3.3.1.2 */
|
||||
GMM_REGISTERED_NORMAL, /* 4.1.3.3.2.1 */
|
||||
@@ -32,6 +31,16 @@ enum gprs_mm_state {
|
||||
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
|
||||
};
|
||||
|
||||
/* TS 23.060 6.1.1 and 6.1.2 Mobility management states A/Gb and Iu mode */
|
||||
enum gprs_pmm_state {
|
||||
PMM_DETACHED,
|
||||
PMM_CONNECTED,
|
||||
PMM_IDLE,
|
||||
MM_IDLE = PMM_DETACHED,
|
||||
MM_READY = PMM_CONNECTED,
|
||||
MM_STANDBY = PMM_IDLE,
|
||||
};
|
||||
|
||||
enum gprs_mm_ctr {
|
||||
GMM_CTR_PKTS_SIG_IN,
|
||||
GMM_CTR_PKTS_SIG_OUT,
|
||||
@@ -70,24 +79,88 @@ enum sgsn_auth_state {
|
||||
|
||||
#define MS_RADIO_ACCESS_CAPA
|
||||
|
||||
enum sgsn_ggsn_lookup_state {
|
||||
SGSN_GGSN_2DIGIT,
|
||||
SGSN_GGSN_3DIGIT,
|
||||
};
|
||||
|
||||
struct sgsn_ggsn_lookup {
|
||||
int state;
|
||||
|
||||
struct sgsn_mm_ctx *mmctx;
|
||||
|
||||
/* APN string */
|
||||
char apn_str[GSM_APN_LENGTH];
|
||||
|
||||
/* the original data */
|
||||
struct msgb *orig_msg;
|
||||
struct tlv_parsed tp;
|
||||
|
||||
/* for dealing with re-transmissions */
|
||||
uint8_t nsapi;
|
||||
uint8_t sapi;
|
||||
uint8_t ti;
|
||||
};
|
||||
|
||||
enum sgsn_ran_type {
|
||||
/* GPRS/EDGE via Gb */
|
||||
MM_CTX_T_GERAN_Gb,
|
||||
/* UMTS via Iu */
|
||||
MM_CTX_T_UTRAN_Iu,
|
||||
/* GPRS/EDGE via Iu */
|
||||
MM_CTX_T_GERAN_Iu,
|
||||
};
|
||||
|
||||
struct service_info {
|
||||
uint8_t type;
|
||||
uint16_t pdp_status;
|
||||
};
|
||||
|
||||
struct ue_conn_ctx;
|
||||
|
||||
/* According to TS 03.60, Table 5: SGSN MM and PDP Contexts */
|
||||
/* Extended by 3GPP TS 23.060, Table 6: SGSN MM and PDP Contexts */
|
||||
struct sgsn_mm_ctx {
|
||||
struct llist_head list;
|
||||
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
enum gprs_mm_state mm_state;
|
||||
enum sgsn_ran_type ran_type;
|
||||
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
enum gprs_gmm_state mm_state;
|
||||
enum gprs_pmm_state pmm_state;
|
||||
uint32_t p_tmsi;
|
||||
uint32_t p_tmsi_old; /* old P-TMSI before new is confirmed */
|
||||
uint32_t p_tmsi_sig;
|
||||
char imei[GSM_IMEI_LENGTH];
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
/* Opt: Software Version Numbber / TS 23.195 */
|
||||
char msisdn[GSM_EXTENSION_LENGTH];
|
||||
struct gprs_ra_id ra;
|
||||
uint16_t cell_id;
|
||||
uint32_t cell_id_age;
|
||||
uint16_t sac; /* Iu: Service Area Code */
|
||||
uint32_t sac_age;/* Iu: Service Area Code age */
|
||||
struct {
|
||||
uint16_t cell_id; /* Gb only */
|
||||
uint32_t cell_id_age; /* Gb only */
|
||||
uint8_t radio_prio_sms;
|
||||
|
||||
/* Additional bits not present in the GSM TS */
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
struct gprs_llc_llme *llme;
|
||||
uint32_t tlli;
|
||||
uint32_t tlli_new;
|
||||
} gb;
|
||||
struct {
|
||||
int new_key;
|
||||
uint16_t sac; /* Iu: Service Area Code */
|
||||
uint32_t sac_age; /* Iu: Service Area Code age */
|
||||
/* CSG ID */
|
||||
/* CSG Membership */
|
||||
/* Access Mode */
|
||||
/* Seelected CN Operator ID (TS 23.251) */
|
||||
/* CSG Subscription Data */
|
||||
/* LIPA Allowed */
|
||||
/* Voice Support Match Indicator */
|
||||
struct ue_conn_ctx *ue_ctx;
|
||||
struct service_info service;
|
||||
} iu;
|
||||
/* VLR number */
|
||||
uint32_t new_sgsn_addr;
|
||||
/* Authentication Triplet */
|
||||
@@ -96,30 +169,38 @@ struct sgsn_mm_ctx {
|
||||
/* Iu: CK, IK, KSI */
|
||||
/* CKSN */
|
||||
enum gprs_ciph_algo ciph_algo;
|
||||
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t buf[50]; /* GSM 04.08 10.5.5.12a, extended in TS 24.008 */
|
||||
} ms_radio_access_capa;
|
||||
/* Supported Codecs (SRVCC) */
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t buf[8]; /* GSM 04.08 10.5.5.12, extended in TS 24.008 */
|
||||
} ms_network_capa;
|
||||
/* UE Netowrk Capability (E-UTRAN) */
|
||||
uint16_t drx_parms;
|
||||
/* Active Time value for PSM */
|
||||
int mnrg; /* MS reported to HLR? */
|
||||
int ngaf; /* MS reported to MSC/VLR? */
|
||||
int ppf; /* paging for GPRS + non-GPRS? */
|
||||
/* Subscribed Charging Characteristics */
|
||||
/* Trace Reference */
|
||||
/* Trace Type */
|
||||
/* Trigger ID */
|
||||
/* OMC Identity */
|
||||
/* SMS Parameters */
|
||||
int recovery;
|
||||
uint8_t radio_prio_sms;
|
||||
/* Access Restriction */
|
||||
/* GPRS CSI (CAMEL) */
|
||||
/* MG-CSI (CAMEL) */
|
||||
/* Subscribed UE-AMBR */
|
||||
/* UE-AMBR */
|
||||
/* APN Subscribed */
|
||||
|
||||
struct llist_head pdp_list;
|
||||
|
||||
/* Additional bits not present in the GSM TS */
|
||||
struct gprs_llc_llme *llme;
|
||||
uint32_t tlli;
|
||||
uint32_t tlli_new;
|
||||
uint16_t nsei;
|
||||
uint16_t bvci;
|
||||
struct rate_ctr_group *ctrg;
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
@@ -136,6 +217,12 @@ struct sgsn_mm_ctx {
|
||||
enum sgsn_auth_state auth_state;
|
||||
int is_authenticated;
|
||||
|
||||
/* the string representation of the current hlr */
|
||||
char hlr[GSM_EXTENSION_LENGTH];
|
||||
|
||||
/* the current GGSN look-up operation */
|
||||
struct sgsn_ggsn_lookup *ggsn_lookup;
|
||||
|
||||
struct gsm_subscriber *subscr;
|
||||
};
|
||||
|
||||
@@ -148,16 +235,23 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ptmsi(uint32_t tmsi);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_imsi(const char *imsi);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx);
|
||||
|
||||
/* look-up by matching TLLI and P-TMSI (think twice before using this) */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
|
||||
/* Allocate a new SGSN MM context */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm);
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx);
|
||||
|
||||
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *ctx);
|
||||
|
||||
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
struct tlv_parsed *tp,
|
||||
enum gsm48_gsm_cause *gsm_cause);
|
||||
enum gsm48_gsm_cause *gsm_cause,
|
||||
char *apn_str);
|
||||
|
||||
enum pdp_ctx_state {
|
||||
PDP_STATE_NONE,
|
||||
@@ -180,6 +274,7 @@ struct sgsn_pdp_ctx {
|
||||
struct llist_head list; /* list_head for mmctx->pdp_list */
|
||||
struct llist_head g_list; /* list_head for global list */
|
||||
struct sgsn_mm_ctx *mm; /* back pointer to MM CTX */
|
||||
int destroy_ggsn; /* destroy it on destruction */
|
||||
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
@@ -208,6 +303,12 @@ struct sgsn_pdp_ctx {
|
||||
struct osmo_timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
unsigned int num_T_exp; /* number of consecutive T expirations */
|
||||
|
||||
struct osmo_timer_list cdr_timer; /* CDR record wird timer */
|
||||
struct timespec cdr_start; /* The start of the CDR */
|
||||
uint64_t cdr_bytes_in;
|
||||
uint64_t cdr_bytes_out;
|
||||
uint32_t cdr_charging_id;
|
||||
};
|
||||
|
||||
#define LOGPDPCTXP(level, pdp, fmt, args...) \
|
||||
@@ -275,7 +376,8 @@ int sgsn_force_reattach_oldmsg(struct msgb *oldmsg);
|
||||
* ctrl interface related work
|
||||
*/
|
||||
struct gsm_network;
|
||||
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *, uint16_t port);
|
||||
struct ctrl_handle *sgsn_controlif_setup(struct gsm_network *,
|
||||
const char *bind_addr, uint16_t port);
|
||||
int sgsn_ctrl_cmds_install(void);
|
||||
|
||||
/*
|
||||
@@ -307,6 +409,9 @@ struct sgsn_subscriber_data {
|
||||
|
||||
uint8_t msisdn[9];
|
||||
size_t msisdn_len;
|
||||
|
||||
uint8_t hlr[9];
|
||||
size_t hlr_len;
|
||||
};
|
||||
|
||||
#define SGSN_ERROR_CAUSE_NONE (-1)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
struct msgb;
|
||||
struct gprs_ra_id;
|
||||
|
||||
struct msgb *gprs_msgb_copy(const struct msgb *msg, const char *name);
|
||||
int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
|
||||
@@ -41,14 +42,4 @@ int gprs_is_mi_imsi(const uint8_t *value, size_t value_len);
|
||||
int gprs_parse_mi_tmsi(const uint8_t *value, size_t value_len, uint32_t *tmsi);
|
||||
void gprs_parse_tmsi(const uint8_t *value, uint32_t *tmsi);
|
||||
|
||||
int gprs_shift_v_fixed(uint8_t **data, size_t *data_len,
|
||||
size_t len, uint8_t **value);
|
||||
int gprs_match_tv_fixed(uint8_t **data, size_t *data_len,
|
||||
uint8_t tag, size_t len, uint8_t **value);
|
||||
int gprs_shift_tlv(uint8_t **data, size_t *data_len,
|
||||
uint8_t *tag, uint8_t **value, size_t *value_len);
|
||||
int gprs_match_tlv(uint8_t **data, size_t *data_len,
|
||||
uint8_t tag, uint8_t **value, size_t *value_len);
|
||||
int gprs_shift_lv(uint8_t **data, size_t *data_len,
|
||||
uint8_t **value, size_t *value_len);
|
||||
|
||||
int gprs_ra_id_equals(const struct gprs_ra_id *id1, const struct gprs_ra_id *id2);
|
||||
|
||||
@@ -13,14 +13,30 @@ struct gsm_subscriber;
|
||||
struct gsm_network;
|
||||
struct gsm_trans;
|
||||
struct gsm_subscriber_connection;
|
||||
struct amr_multirate_conf;
|
||||
struct amr_mode;
|
||||
|
||||
#define GSM48_ALLOC_SIZE 2048
|
||||
#define GSM48_ALLOC_HEADROOM 256
|
||||
|
||||
static inline struct msgb *gsm48_msgb_alloc(void)
|
||||
static inline struct msgb *gsm48_msgb_alloc_name(const char *name)
|
||||
{
|
||||
return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
|
||||
"GSM 04.08");
|
||||
name);
|
||||
}
|
||||
|
||||
static inline int get_radio_link_timeout(struct gsm48_cell_options *cell_options)
|
||||
{
|
||||
return (cell_options->radio_link_timeout + 1) << 2;
|
||||
}
|
||||
|
||||
static inline void set_radio_link_timeout(struct gsm48_cell_options *cell_options, int value)
|
||||
{
|
||||
if (value < 4)
|
||||
value = 4;
|
||||
if (value > 64)
|
||||
value = 64;
|
||||
cell_options->radio_link_timeout = (value >> 2) - 1;
|
||||
}
|
||||
|
||||
/* config options controlling the behaviour of the lower leves */
|
||||
@@ -61,6 +77,8 @@ int decode_bcd_number(char *output, int output_len, const uint8_t *bcd_lv,
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan, uint8_t *classmark2_lv);
|
||||
int gsm48_extract_mi(uint8_t *classmark2, int length, char *mi_string, uint8_t *mi_type);
|
||||
int gsm48_paging_extract_mi(struct gsm48_pag_resp *pag, int length, char *mi_string, uint8_t *mi_type);
|
||||
|
||||
/* TODO MSCSPLIT remove gsm48_handle_paging_resp() */
|
||||
int gsm48_handle_paging_resp(struct gsm_subscriber_connection *conn, struct msgb *msg, struct gsm_subscriber *subscr);
|
||||
|
||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t lchan_mode);
|
||||
@@ -75,4 +93,6 @@ void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
|
||||
void release_security_operation(struct gsm_subscriber_connection *conn);
|
||||
void allocate_security_operation(struct gsm_subscriber_connection *conn);
|
||||
|
||||
int gsm48_multirate_config(uint8_t *lv, struct amr_multirate_conf *mr, struct amr_mode *modes);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,397 +1,21 @@
|
||||
#ifndef _GSM48_GPRS_H
|
||||
#define _GSM48_GPRS_H
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
||||
/* Table 10.4 / 10.4a, GPRS Mobility Management (GMM) */
|
||||
#define GSM48_MT_GMM_ATTACH_REQ 0x01
|
||||
#define GSM48_MT_GMM_ATTACH_ACK 0x02
|
||||
#define GSM48_MT_GMM_ATTACH_COMPL 0x03
|
||||
#define GSM48_MT_GMM_ATTACH_REJ 0x04
|
||||
#define GSM48_MT_GMM_DETACH_REQ 0x05
|
||||
#define GSM48_MT_GMM_DETACH_ACK 0x06
|
||||
/* TODO: Move this to osmocom/gsm/protocol/gsm_04_08_gprs.h ? */
|
||||
|
||||
#define GSM48_MT_GMM_RA_UPD_REQ 0x08
|
||||
#define GSM48_MT_GMM_RA_UPD_ACK 0x09
|
||||
#define GSM48_MT_GMM_RA_UPD_COMPL 0x0a
|
||||
#define GSM48_MT_GMM_RA_UPD_REJ 0x0b
|
||||
/* Table 10.4 in 3GPP TS 24.008 (successor to 04.08) */
|
||||
#define GSM48_MT_GMM_SERVICE_REQ 0x0c
|
||||
#define GSM48_MT_GMM_SERVICE_ACK 0x0d
|
||||
#define GSM48_MT_GMM_SERVICE_REJ 0x0e
|
||||
|
||||
#define GSM48_MT_GMM_PTMSI_REALL_CMD 0x10
|
||||
#define GSM48_MT_GMM_PTMSI_REALL_COMPL 0x11
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_REQ 0x12
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_RESP 0x13
|
||||
#define GSM48_MT_GMM_AUTH_CIPH_REJ 0x14
|
||||
#define GSM48_MT_GMM_ID_REQ 0x15
|
||||
#define GSM48_MT_GMM_ID_RESP 0x16
|
||||
#define GSM48_MT_GMM_STATUS 0x20
|
||||
#define GSM48_MT_GMM_INFO 0x21
|
||||
|
||||
/* Table 10.4a, GPRS Session Management (GSM) */
|
||||
#define GSM48_MT_GSM_ACT_PDP_REQ 0x41
|
||||
#define GSM48_MT_GSM_ACT_PDP_ACK 0x42
|
||||
#define GSM48_MT_GSM_ACT_PDP_REJ 0x43
|
||||
#define GSM48_MT_GSM_REQ_PDP_ACT 0x44
|
||||
#define GSM48_MT_GSM_REQ_PDP_ACT_REJ 0x45
|
||||
#define GSM48_MT_GSM_DEACT_PDP_REQ 0x46
|
||||
#define GSM48_MT_GSM_DEACT_PDP_ACK 0x47
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_REQ 0x50
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_ACK 0x51
|
||||
#define GSM48_MT_GSM_ACT_AA_PDP_REJ 0x52
|
||||
#define GSM48_MT_GSM_DEACT_AA_PDP_REQ 0x53
|
||||
#define GSM48_MT_GSM_DEACT_AA_PDP_ACK 0x54
|
||||
#define GSM48_MT_GSM_STATUS 0x55
|
||||
|
||||
/* Chapter 10.5.5.2 / Table 10.5.135 */
|
||||
#define GPRS_ATT_T_ATTACH 1
|
||||
#define GPRS_ATT_T_ATT_WHILE_IMSI 2
|
||||
#define GPRS_ATT_T_COMBINED 3
|
||||
|
||||
extern const struct value_string *gprs_att_t_strs;
|
||||
|
||||
/* Chapter 10.5.5.5 / Table 10.5.138 */
|
||||
#define GPRS_DET_T_MO_GPRS 1
|
||||
#define GPRS_DET_T_MO_IMSI 2
|
||||
#define GPRS_DET_T_MO_COMBINED 3
|
||||
/* Network to MS direction */
|
||||
#define GPRS_DET_T_MT_REATT_REQ 1
|
||||
#define GPRS_DET_T_MT_REATT_NOTREQ 2
|
||||
#define GPRS_DET_T_MT_IMSI 3
|
||||
|
||||
extern const struct value_string *gprs_det_t_mo_strs;
|
||||
extern const struct value_string *gprs_det_t_mt_strs;
|
||||
|
||||
/* Chapter 10.5.5.18 / Table 105.150 */
|
||||
#define GPRS_UPD_T_RA 0
|
||||
#define GPRS_UPD_T_RA_LA 1
|
||||
#define GPRS_UPD_T_RA_LA_IMSI_ATT 2
|
||||
#define GPRS_UPD_T_PERIODIC 3
|
||||
|
||||
extern const struct value_string *gprs_upd_t_strs;
|
||||
|
||||
enum gsm48_gprs_ie_mm {
|
||||
GSM48_IE_GMM_CIPH_CKSN = 0x08, /* 10.5.1.2 */
|
||||
GSM48_IE_GMM_TIMER_READY = 0x17, /* 10.5.7.3 */
|
||||
GSM48_IE_GMM_ALLOC_PTMSI = 0x18, /* 10.5.1.4 */
|
||||
GSM48_IE_GMM_PTMSI_SIG = 0x19, /* 10.5.5.8 */
|
||||
GSM48_IE_GMM_AUTH_RAND = 0x21, /* 10.5.3.1 */
|
||||
GSM48_IE_GMM_AUTH_SRES = 0x22, /* 10.5.3.2 */
|
||||
GSM48_IE_GMM_IMEISV = 0x23, /* 10.5.1.4 */
|
||||
GSM48_IE_GMM_CAUSE = 0x25, /* 10.5.5.14 */
|
||||
GSM48_IE_GMM_DRX_PARAM = 0x27, /* 10.5.5.6 */
|
||||
GSM48_IE_GMM_MS_NET_CAPA = 0x31, /* 10.5.5.12 */
|
||||
GSM48_IE_GMM_PDP_CTX_STATUS = 0x32, /* 10.5.7.1 */
|
||||
GSM48_IE_GMM_PS_LCS_CAPA = 0x33, /* 10.5.5.22 */
|
||||
GSM48_IE_GMM_GMM_MBMS_CTX_ST = 0x35, /* 10.5.7.6 */
|
||||
/* 3GPP 24.008 / Chapter 10.5.5.20 / Table 10.5.153a */
|
||||
enum gsm48_gmm_service_type {
|
||||
GPRS_SERVICE_T_SIGNALLING = 0x00,
|
||||
GPRS_SERVICE_T_DATA = 0x01,
|
||||
GPRS_SERVICE_T_PAGING_RESP = 0x02,
|
||||
GPRS_SERVICE_T_MBMS_MC_SERV = 0x03,
|
||||
GPRS_SERVICE_T_MBMS_BC_SERV = 0x04,
|
||||
};
|
||||
|
||||
enum gsm48_gprs_ie_sm {
|
||||
GSM48_IE_GSM_APN = 0x28, /* 10.5.6.1 */
|
||||
GSM48_IE_GSM_PROTO_CONF_OPT = 0x27, /* 10.5.6.3 */
|
||||
GSM48_IE_GSM_PDP_ADDR = 0x2b, /* 10.5.6.4 */
|
||||
GSM48_IE_GSM_AA_TMR = 0x29, /* 10.5.7.3 */
|
||||
GSM48_IE_GSM_NAME_FULL = 0x43, /* 10.5.3.5a */
|
||||
GSM48_IE_GSM_NAME_SHORT = 0x45, /* 10.5.3.5a */
|
||||
GSM48_IE_GSM_TIMEZONE = 0x46, /* 10.5.3.8 */
|
||||
GSM48_IE_GSM_UTC_AND_TZ = 0x47, /* 10.5.3.9 */
|
||||
GSM48_IE_GSM_LSA_ID = 0x48, /* 10.5.3.11 */
|
||||
|
||||
/* Fake IEs that are not present on the Layer3 air interface,
|
||||
* but which we use to simplify internal APIs */
|
||||
OSMO_IE_GSM_REQ_QOS = 0xfd,
|
||||
OSMO_IE_GSM_REQ_PDP_ADDR = 0xfe,
|
||||
OSMO_IE_GSM_SUB_QOS = 0xff,
|
||||
};
|
||||
|
||||
/* Chapter 9.4.15 / Table 9.4.15 */
|
||||
struct gsm48_ra_upd_ack {
|
||||
uint8_t force_stby:4, /* 10.5.5.7 */
|
||||
upd_result:4; /* 10.5.5.17 */
|
||||
uint8_t ra_upd_timer; /* 10.5.7.3 */
|
||||
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.7.3 */
|
||||
enum gsm48_gprs_tmr_unit {
|
||||
GPRS_TMR_2SECONDS = 0 << 5,
|
||||
GPRS_TMR_MINUTE = 1 << 5,
|
||||
GPRS_TMR_6MINUTE = 2 << 5,
|
||||
GPRS_TMR_DEACTIVATED = 7 << 5,
|
||||
};
|
||||
|
||||
#define GPRS_TMR_UNIT_MASK (7 << 5)
|
||||
#define GPRS_TMR_FACT_MASK ((1 << 5)-1)
|
||||
|
||||
/* Chapter 9.4.2 / Table 9.4.2 */
|
||||
struct gsm48_attach_ack {
|
||||
uint8_t att_result:4, /* 10.5.5.7 */
|
||||
force_stby:4; /* 10.5.5.1 */
|
||||
uint8_t ra_upd_timer; /* 10.5.7.3 */
|
||||
uint8_t radio_prio; /* 10.5.7.2 */
|
||||
struct gsm48_ra_id ra_id; /* 10.5.5.15 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.4.9 / Table 9.4.9 */
|
||||
struct gsm48_auth_ciph_req {
|
||||
uint8_t ciph_alg:4, /* 10.5.5.3 */
|
||||
imeisv_req:4; /* 10.5.5.10 */
|
||||
uint8_t force_stby:4, /* 10.5.5.7 */
|
||||
ac_ref_nr:4; /* 10.5.5.19 */
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
/* optional: TV RAND, TV CKSN */
|
||||
|
||||
struct gsm48_auth_ciph_resp {
|
||||
uint8_t ac_ref_nr:4,
|
||||
spare:4;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.5.1 / Table 9.5.1 */
|
||||
struct gsm48_act_pdp_ctx_req {
|
||||
uint8_t req_nsapi;
|
||||
uint8_t req_llc_sapi;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.5.14 / Table 10.5.147 */
|
||||
enum gsm48_gmm_cause {
|
||||
GMM_CAUSE_IMSI_UNKNOWN = 0x02,
|
||||
GMM_CAUSE_ILLEGAL_MS = 0x03,
|
||||
GMM_CAUSE_ILLEGAL_ME = 0x06,
|
||||
GMM_CAUSE_GPRS_NOTALLOWED = 0x07,
|
||||
GMM_CAUSE_GPRS_OTHER_NOTALLOWED = 0x08,
|
||||
GMM_CAUSE_MS_ID_NOT_DERIVED = 0x09,
|
||||
GMM_CAUSE_IMPL_DETACHED = 0x0a,
|
||||
GMM_CAUSE_PLMN_NOTALLOWED = 0x0b,
|
||||
GMM_CAUSE_LA_NOTALLOWED = 0x0c,
|
||||
GMM_CAUSE_ROAMING_NOTALLOWED = 0x0d,
|
||||
GMM_CAUSE_NO_GPRS_PLMN = 0x0e,
|
||||
GMM_CAUSE_MSC_TEMP_NOTREACH = 0x10,
|
||||
GMM_CAUSE_NET_FAIL = 0x11,
|
||||
GMM_CAUSE_CONGESTION = 0x16,
|
||||
GMM_CAUSE_SEM_INCORR_MSG = 0x5f,
|
||||
GMM_CAUSE_INV_MAND_INFO = 0x60,
|
||||
GMM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
|
||||
GMM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
|
||||
GMM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
|
||||
GMM_CAUSE_COND_IE_ERR = 0x64,
|
||||
GMM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
|
||||
GMM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
|
||||
};
|
||||
|
||||
extern const struct value_string *gsm48_gmm_cause_names;
|
||||
|
||||
/* Chapter 10.4.6.6 / Table 10.5.157 */
|
||||
enum gsm48_gsm_cause {
|
||||
GSM_CAUSE_INSUFF_RSRC = 0x1a,
|
||||
GSM_CAUSE_MISSING_APN = 0x1b,
|
||||
GSM_CAUSE_UNKNOWN_PDP = 0x1c,
|
||||
GSM_CAUSE_AUTH_FAILED = 0x1d,
|
||||
GSM_CAUSE_ACT_REJ_GGSN = 0x1e,
|
||||
GSM_CAUSE_ACT_REJ_UNSPEC = 0x1f,
|
||||
GSM_CAUSE_SERV_OPT_NOTSUPP = 0x20,
|
||||
GSM_CAUSE_REQ_SERV_OPT_NOTSUB = 0x21,
|
||||
GSM_CAUSE_SERV_OPT_TEMP_OOO = 0x22,
|
||||
GSM_CAUSE_NSAPI_IN_USE = 0x23,
|
||||
GSM_CAUSE_DEACT_REGULAR = 0x24,
|
||||
GSM_CAUSE_QOS_NOT_ACCEPTED = 0x25,
|
||||
GSM_CAUSE_NET_FAIL = 0x26,
|
||||
GSM_CAUSE_REACT_RQD = 0x27,
|
||||
GSM_CAUSE_FEATURE_NOTSUPP = 0x28,
|
||||
GSM_CAUSE_INVALID_TRANS_ID = 0x51,
|
||||
GSM_CAUSE_SEM_INCORR_MSG = 0x5f,
|
||||
GSM_CAUSE_INV_MAND_INFO = 0x60,
|
||||
GSM_CAUSE_MSGT_NOTEXIST_NOTIMPL = 0x61,
|
||||
GSM_CAUSE_MSGT_INCOMP_P_STATE = 0x62,
|
||||
GSM_CAUSE_IE_NOTEXIST_NOTIMPL = 0x63,
|
||||
GSM_CAUSE_COND_IE_ERR = 0x64,
|
||||
GSM_CAUSE_MSG_INCOMP_P_STATE = 0x65,
|
||||
GSM_CAUSE_PROTO_ERR_UNSPEC = 0x6f,
|
||||
};
|
||||
|
||||
extern const struct value_string *gsm48_gsm_cause_names;
|
||||
|
||||
/* Section 6.1.2.2: Session management states on the network side */
|
||||
enum gsm48_pdp_state {
|
||||
PDP_S_INACTIVE,
|
||||
PDP_S_ACTIVE_PENDING,
|
||||
PDP_S_ACTIVE,
|
||||
PDP_S_INACTIVE_PENDING,
|
||||
PDP_S_MODIFY_PENDING,
|
||||
};
|
||||
|
||||
/* Table 10.5.155/3GPP TS 24.008 */
|
||||
enum gsm48_pdp_type_org {
|
||||
PDP_TYPE_ORG_ETSI = 0x00,
|
||||
PDP_TYPE_ORG_IETF = 0x01,
|
||||
};
|
||||
enum gsm48_pdp_type_nr {
|
||||
PDP_TYPE_N_ETSI_RESERVED = 0x00,
|
||||
PDP_TYPE_N_ETSI_PPP = 0x01,
|
||||
PDP_TYPE_N_IETF_IPv4 = 0x21,
|
||||
PDP_TYPE_N_IETF_IPv6 = 0x57,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_reliab_class {
|
||||
GSM48_QOS_RC_LLC_ACK_RLC_ACK_DATA_PROT = 2,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_ACK_DATA_PROT = 3,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_UN_PROT_DATA = 4,
|
||||
GSM48_QOS_RC_LLC_UN_RLC_UN_DATA_UN = 5,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_preced_class {
|
||||
GSM48_QOS_PC_HIGH = 1,
|
||||
GSM48_QOS_PC_NORMAL = 2,
|
||||
GSM48_QOS_PC_LOW = 3,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_peak_tput {
|
||||
GSM48_QOS_PEAK_TPUT_1000bps = 1,
|
||||
GSM48_QOS_PEAK_TPUT_2000bps = 2,
|
||||
GSM48_QOS_PEAK_TPUT_4000bps = 3,
|
||||
GSM48_QOS_PEAK_TPUT_8000bps = 4,
|
||||
GSM48_QOS_PEAK_TPUT_16000bps = 5,
|
||||
GSM48_QOS_PEAK_TPUT_32000bps = 6,
|
||||
GSM48_QOS_PEAK_TPUT_64000bps = 7,
|
||||
GSM48_QOS_PEAK_TPUT_128000bps = 8,
|
||||
GSM48_QOS_PEAK_TPUT_256000bps = 9,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_mean_tput {
|
||||
GSM48_QOS_MEAN_TPUT_100bph = 1,
|
||||
GSM48_QOS_MEAN_TPUT_200bph = 2,
|
||||
GSM48_QOS_MEAN_TPUT_500bph = 3,
|
||||
GSM48_QOS_MEAN_TPUT_1000bph = 4,
|
||||
GSM48_QOS_MEAN_TPUT_2000bph = 5,
|
||||
GSM48_QOS_MEAN_TPUT_5000bph = 6,
|
||||
GSM48_QOS_MEAN_TPUT_10000bph = 7,
|
||||
GSM48_QOS_MEAN_TPUT_20000bph = 8,
|
||||
GSM48_QOS_MEAN_TPUT_50000bph = 9,
|
||||
GSM48_QOS_MEAN_TPUT_100kbph = 10,
|
||||
GSM48_QOS_MEAN_TPUT_200kbph = 11,
|
||||
GSM48_QOS_MEAN_TPUT_500kbph = 0xc,
|
||||
GSM48_QOS_MEAN_TPUT_1Mbph = 0xd,
|
||||
GSM48_QOS_MEAN_TPUT_2Mbph = 0xe,
|
||||
GSM48_QOS_MEAN_TPUT_5Mbph = 0xf,
|
||||
GSM48_QOS_MEAN_TPUT_10Mbph = 0x10,
|
||||
GSM48_QOS_MEAN_TPUT_20Mbph = 0x11,
|
||||
GSM48_QOS_MEAN_TPUT_50Mbph = 0x12,
|
||||
GSM48_QOS_MEAN_TPUT_BEST_EFFORT = 0x1f,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_err_sdu {
|
||||
GSM48_QOS_ERRSDU_NODETECT = 1,
|
||||
GSM48_QOS_ERRSDU_YES = 2,
|
||||
GSM48_QOS_ERRSDU_NO = 3,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_deliv_order {
|
||||
GSM48_QOS_DO_ORDERED = 1,
|
||||
GSM48_QOS_DO_UNORDERED = 2,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_traf_class {
|
||||
GSM48_QOS_TC_CONVERSATIONAL = 1,
|
||||
GSM48_QOS_TC_STREAMING = 2,
|
||||
GSM48_QOS_TC_INTERACTIVE = 3,
|
||||
GSM48_QOS_TC_BACKGROUND = 4,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_max_sdu_size {
|
||||
/* values below in 10 octet granularity */
|
||||
GSM48_QOS_MAXSDU_1502 = 0x97,
|
||||
GSM48_QOS_MAXSDU_1510 = 0x98,
|
||||
GSM48_QOS_MAXSDU_1520 = 0x99,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_max_bitrate {
|
||||
GSM48_QOS_MBRATE_1k = 0x01,
|
||||
GSM48_QOS_MBRATE_63k = 0x3f,
|
||||
GSM48_QOS_MBRATE_64k = 0x40,
|
||||
GSM48_QOS_MBRATE_568k = 0x7f,
|
||||
GSM48_QOS_MBRATE_576k = 0x80,
|
||||
GSM48_QOS_MBRATE_8640k = 0xfe,
|
||||
GSM48_QOS_MBRATE_0k = 0xff,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_resid_ber {
|
||||
GSM48_QOS_RBER_5e_2 = 0x01,
|
||||
GSM48_QOS_RBER_1e_2 = 0x02,
|
||||
GSM48_QOS_RBER_5e_3 = 0x03,
|
||||
GSM48_QOS_RBER_4e_3 = 0x04,
|
||||
GSM48_QOS_RBER_1e_3 = 0x05,
|
||||
GSM48_QOS_RBER_1e_4 = 0x06,
|
||||
GSM48_QOS_RBER_1e_5 = 0x07,
|
||||
GSM48_QOS_RBER_1e_6 = 0x08,
|
||||
GSM48_QOS_RBER_6e_8 = 0x09,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
enum gsm48_qos_sdu_err {
|
||||
GSM48_QOS_SERR_1e_2 = 0x01,
|
||||
GSM48_QOS_SERR_7e_2 = 0x02,
|
||||
GSM48_QOS_SERR_1e_3 = 0x03,
|
||||
GSM48_QOS_SERR_1e_4 = 0x04,
|
||||
GSM48_QOS_SERR_1e_5 = 0x05,
|
||||
GSM48_QOS_SERR_1e_6 = 0x06,
|
||||
GSM48_QOS_SERR_1e_1 = 0x07,
|
||||
};
|
||||
|
||||
/* Figure 10.5.138/24.008 / Chapter 10.5.6.5 */
|
||||
struct gsm48_qos {
|
||||
/* octet 3 */
|
||||
uint8_t reliab_class:3;
|
||||
uint8_t delay_class:3;
|
||||
uint8_t spare:2;
|
||||
/* octet 4 */
|
||||
uint8_t preced_class:3;
|
||||
uint8_t spare2:1;
|
||||
uint8_t peak_tput:4;
|
||||
/* octet 5 */
|
||||
uint8_t mean_tput:5;
|
||||
uint8_t spare3:3;
|
||||
/* octet 6 */
|
||||
uint8_t deliv_err_sdu:3;
|
||||
uint8_t deliv_order:2;
|
||||
uint8_t traf_class:3;
|
||||
/* octet 7 */
|
||||
uint8_t max_sdu_size;
|
||||
/* octet 8 */
|
||||
uint8_t max_bitrate_up;
|
||||
/* octet 9 */
|
||||
uint8_t max_bitrate_down;
|
||||
/* octet 10 */
|
||||
uint8_t sdu_err_ratio:4;
|
||||
uint8_t resid_ber:4;
|
||||
/* octet 11 */
|
||||
uint8_t handling_prio:2;
|
||||
uint8_t xfer_delay:6;
|
||||
/* octet 12 */
|
||||
uint8_t guar_bitrate_up;
|
||||
/* octet 13 */
|
||||
uint8_t guar_bitrate_down;
|
||||
/* octet 14 */
|
||||
uint8_t src_stats_desc:4;
|
||||
uint8_t sig_ind:1;
|
||||
uint8_t spare5:3;
|
||||
/* octet 15 */
|
||||
uint8_t max_bitrate_down_ext;
|
||||
/* octet 16 */
|
||||
uint8_t guar_bitrate_down_ext;
|
||||
};
|
||||
|
||||
|
||||
#endif /* _GSM48_GPRS_H */
|
||||
extern const struct value_string *gprs_service_t_strs;
|
||||
|
||||
@@ -38,5 +38,5 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn,
|
||||
struct gsm_sms *sms);
|
||||
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
|
||||
|
||||
uint8_t sms_next_rp_msg_ref(struct gsm_subscriber_connection *conn);
|
||||
uint8_t sms_next_rp_msg_ref(uint8_t *next_rp_ref);
|
||||
#endif
|
||||
|
||||
@@ -14,6 +14,9 @@ int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *msg,
|
||||
const struct ussd_request *request);
|
||||
|
||||
struct msgb *gsm0480_gen_ussdNotify(int level, const char *text);
|
||||
struct msgb *gsm0480_gen_releaseComplete(void);
|
||||
|
||||
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
|
||||
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/crypt/auth.h>
|
||||
|
||||
#include <openbsc/rest_octets.h>
|
||||
#include <openbsc/xsc.h>
|
||||
|
||||
/** annotations for msgb ownership */
|
||||
#define __uses
|
||||
@@ -47,9 +49,7 @@ struct gsm_auth_info {
|
||||
struct gsm_auth_tuple {
|
||||
int use_count;
|
||||
int key_seq;
|
||||
uint8_t rand[16];
|
||||
uint8_t sres[4];
|
||||
uint8_t kc[8];
|
||||
struct osmo_auth_vector vec;
|
||||
};
|
||||
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
|
||||
|
||||
@@ -98,7 +98,19 @@ struct neigh_meas_proc {
|
||||
uint8_t last_seen_nr;
|
||||
};
|
||||
|
||||
/* the per subscriber data for lchan */
|
||||
enum interface_type {
|
||||
IFACE_UNKNOWN = -1,
|
||||
IFACE_A = 0, /* A-interface for 2G */
|
||||
IFACE_IU = 1 /* Iu-interface for UMTS aka 3G (IuCS or IuPS) */
|
||||
};
|
||||
|
||||
enum integrity_protection_state {
|
||||
INTEGRITY_PROTECTION_NONE = 0,
|
||||
INTEGRITY_PROTECTION_IK = 1,
|
||||
INTEGRITY_PROTECTION_IK_CK = 2,
|
||||
};
|
||||
|
||||
/* mobile subscriber data */
|
||||
struct gsm_subscriber_connection {
|
||||
struct llist_head entry;
|
||||
|
||||
@@ -120,18 +132,45 @@ struct gsm_subscriber_connection {
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
||||
/* bsc structures */
|
||||
struct osmo_bsc_sccp_con *sccp_con;
|
||||
/* MNCC rtp bridge markers */
|
||||
int mncc_rtp_bridge;
|
||||
int mncc_rtp_create_pending;
|
||||
int mncc_rtp_connect_pending;
|
||||
|
||||
/* back pointers */
|
||||
struct gsm_network *network;
|
||||
|
||||
/* The BSC used to be an integral part of OsmoNITB. In OsmoCSCN, the
|
||||
* BSC and/or RNC is a separate entity, and no back pointers to the bts
|
||||
* and lchan structures are available. To facilitate separation of the
|
||||
* code paths, I'm explicitly excluding the unavailable structures from
|
||||
* the build. Once separated, this split may become unnecessary. */
|
||||
#if COMPILING_LIBMSC
|
||||
int in_release;
|
||||
uint16_t lac;
|
||||
struct gsm_encr encr;
|
||||
|
||||
/* 2G or 3G? See enum interface_type */
|
||||
int via_iface;
|
||||
|
||||
/* which Iu-CS connection, if any. */
|
||||
struct {
|
||||
struct ue_conn_ctx *ue_ctx;
|
||||
int integrity_protection;
|
||||
} iu;
|
||||
|
||||
#else
|
||||
struct gsm_bts *bts;
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_lchan *ho_lchan;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
/* bsc structures */
|
||||
struct osmo_bsc_sccp_con *sccp_con;
|
||||
|
||||
/* for assignment handling */
|
||||
struct osmo_timer_list T10;
|
||||
struct gsm_lchan *secondary_lchan;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
@@ -203,7 +242,20 @@ enum gsm_auth_policy {
|
||||
#define GSM_T3113_DEFAULT 60
|
||||
#define GSM_T3122_DEFAULT 10
|
||||
|
||||
struct gsm_tz {
|
||||
int override; /* if 0, use system's time zone instead. */
|
||||
int hr; /* hour */
|
||||
int mn; /* minute */
|
||||
int dst; /* daylight savings */
|
||||
};
|
||||
|
||||
struct gsm_network {
|
||||
/* TODO MSCSPLIT the gsm_network struct is basically a kitchen sink for
|
||||
* global settings and variables, "madly" mixing BSC and MSC stuff. Split
|
||||
* this in e.g. struct osmo_bsc and struct osmo_msc, with the things
|
||||
* these have in common, like country and network code, put in yet
|
||||
* separate structs and placed as members in osmo_bsc and osmo_msc. */
|
||||
|
||||
/* global parameters */
|
||||
uint16_t country_code;
|
||||
uint16_t network_code;
|
||||
@@ -281,8 +333,24 @@ struct gsm_network {
|
||||
struct gsm_subscriber_group *subscr_group;
|
||||
struct gsm_sms_queue *sms_queue;
|
||||
|
||||
/* nitb related control */
|
||||
int avoid_tmsi;
|
||||
|
||||
/* control interface */
|
||||
struct ctrl_handle *ctrl;
|
||||
|
||||
/* all active subscriber connections. */
|
||||
struct llist_head subscr_conns;
|
||||
|
||||
/* if override is nonzero, this timezone data is used for all MM
|
||||
* contexts. */
|
||||
/* TODO: in OsmoNITB, tz-override used to be BTS-specific. To enable
|
||||
* BTS|RNC specific timezone overrides for multi-tz networks in
|
||||
* OsmoCSCN, this should be tied to the location area code (LAC). */
|
||||
struct gsm_tz tz;
|
||||
|
||||
/* Periodic location update default value */
|
||||
uint8_t t3212;
|
||||
};
|
||||
|
||||
struct osmo_esme;
|
||||
@@ -329,13 +397,12 @@ struct gsm_sms {
|
||||
char text[SMS_TEXT_SIZE];
|
||||
};
|
||||
|
||||
struct gsm_network *gsm_network_init(uint16_t country_code, uint16_t network_code,
|
||||
int (*mncc_recv)(struct gsm_network *, struct msgb *));
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
struct gsm_network *gsm_network_init(void *ctx,
|
||||
uint16_t country_code,
|
||||
uint16_t network_code,
|
||||
mncc_recv_cb_t mncc_recv);
|
||||
|
||||
/* Get reference to a neighbor cell on a given BCCH ARFCN */
|
||||
struct gsm_bts *gsm_bts_neighbor(const struct gsm_bts *bts,
|
||||
uint16_t arfcn, uint8_t bsic);
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
@@ -419,17 +486,19 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
|
||||
|
||||
int gsm48_ra_id_by_bts(uint8_t *buf, struct gsm_bts *bts);
|
||||
void gprs_ra_id_by_bts(struct gprs_ra_id *raid, struct gsm_bts *bts);
|
||||
struct gsm_meas_rep *lchan_next_meas_rep(struct gsm_lchan *lchan);
|
||||
|
||||
int gsm_btsmodel_set_feature(struct gsm_bts_model *model, enum gsm_bts_features feat);
|
||||
int gsm_bts_model_register(struct gsm_bts_model *model);
|
||||
|
||||
struct gsm_subscriber_connection *subscr_con_allocate(struct gsm_lchan *lchan);
|
||||
void subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_lchan *lchan);
|
||||
void bsc_subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct gsm_subscriber_connection *msc_subscr_con_allocate(struct gsm_network *network);
|
||||
void msc_subscr_con_free(struct gsm_subscriber_connection *conn);
|
||||
|
||||
struct gsm_bts *gsm_bts_alloc_register(struct gsm_network *net,
|
||||
enum gsm_bts_type type,
|
||||
uint8_t tsc, uint8_t bsic);
|
||||
uint8_t bsic);
|
||||
|
||||
void set_ts_e1link(struct gsm_bts_trx_ts *ts, uint8_t e1_nr,
|
||||
uint8_t e1_ts, uint8_t e1_ts_ss);
|
||||
@@ -438,6 +507,7 @@ void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
|
||||
int gsm_bts_has_feature(struct gsm_bts *bts, enum gsm_bts_features feat);
|
||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
|
||||
int gsm_bts_trx_set_system_infos(struct gsm_bts_trx *trx);
|
||||
int gsm_bts_set_system_infos(struct gsm_bts *bts);
|
||||
|
||||
/* generic E1 line operations for all ISDN-based BTS. */
|
||||
extern struct e1inp_line_ops bts_isdn_e1inp_line_ops;
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <osmocom/gsm/lapdm.h>
|
||||
#endif
|
||||
|
||||
#include <openbsc/xsc.h>
|
||||
|
||||
struct osmo_bsc_data;
|
||||
|
||||
struct osmo_bsc_sccp_con;
|
||||
@@ -50,7 +52,6 @@ enum gsm_chreq_reason_t {
|
||||
#define TS_MAX_LCHAN 8
|
||||
|
||||
#define HARDCODED_ARFCN 123
|
||||
#define HARDCODED_TSC 7
|
||||
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
|
||||
|
||||
/* for multi-drop config */
|
||||
@@ -101,11 +102,11 @@ struct gsm_abis_mo {
|
||||
struct gsm_bts *bts;
|
||||
};
|
||||
|
||||
#define MAX_A5_KEY_LEN (128/8)
|
||||
#define A38_XOR_MIN_KEY_LEN 12
|
||||
#define A38_XOR_MAX_KEY_LEN 16
|
||||
#define A38_COMP128_KEY_LEN 16
|
||||
#define RSL_ENC_ALG_A5(x) (x+1)
|
||||
#define MAX_EARFCN_LIST 32
|
||||
|
||||
/* is the data link established? who established it? */
|
||||
#define LCHAN_SAPI_UNUSED 0
|
||||
@@ -153,9 +154,11 @@ struct amr_mode {
|
||||
uint8_t threshold;
|
||||
uint8_t hysteresis;
|
||||
};
|
||||
|
||||
struct amr_multirate_conf {
|
||||
uint8_t gsm48_ie[2];
|
||||
struct amr_mode mode[4];
|
||||
struct amr_mode ms_mode[4];
|
||||
struct amr_mode bts_mode[4];
|
||||
uint8_t num_modes;
|
||||
};
|
||||
/* /BTS ONLY */
|
||||
@@ -200,14 +203,11 @@ struct gsm_lchan {
|
||||
uint8_t bs_power;
|
||||
uint8_t ms_power;
|
||||
/* Encryption information */
|
||||
struct {
|
||||
uint8_t alg_id;
|
||||
uint8_t key_len;
|
||||
uint8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
struct gsm_encr encr;
|
||||
|
||||
/* AMR bits */
|
||||
struct gsm48_multi_rate_conf mr_conf;
|
||||
uint8_t mr_ms_lv[7];
|
||||
uint8_t mr_bts_lv[7];
|
||||
|
||||
/* Established data link layer services */
|
||||
uint8_t sapis[8];
|
||||
@@ -231,6 +231,8 @@ struct gsm_lchan {
|
||||
|
||||
uint8_t rqd_ta;
|
||||
|
||||
char *name;
|
||||
|
||||
#ifdef ROLE_BSC
|
||||
struct osmo_timer_list T3101;
|
||||
struct osmo_timer_list T3109;
|
||||
@@ -346,7 +348,7 @@ struct gsm_bts_trx_ts {
|
||||
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||
};
|
||||
|
||||
/* One TRX in a BTS */
|
||||
/* One TRX (transceiver) in a BTS */
|
||||
struct gsm_bts_trx {
|
||||
/* list header in bts->trx_list */
|
||||
struct llist_head list;
|
||||
@@ -566,9 +568,8 @@ struct gsm_bts {
|
||||
uint16_t cell_identity;
|
||||
/* location area code of this BTS */
|
||||
uint16_t location_area_code;
|
||||
/* Training Sequence Code */
|
||||
uint8_t tsc;
|
||||
/* Base Station Identification Code (BSIC) */
|
||||
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
||||
* which is used as TSC for the CCCH */
|
||||
uint8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
@@ -605,14 +606,6 @@ struct gsm_bts {
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||
|
||||
/* TimeZone hours, mins, and bts specific */
|
||||
struct {
|
||||
int hr;
|
||||
int mn;
|
||||
int override;
|
||||
int dst;
|
||||
} tz;
|
||||
|
||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||
union {
|
||||
struct {
|
||||
@@ -712,12 +705,18 @@ struct gsm_bts {
|
||||
struct bitvec neigh_list;
|
||||
struct bitvec cell_alloc;
|
||||
struct bitvec si5_neigh_list;
|
||||
struct osmo_earfcn_si2q si2quater_neigh_list;
|
||||
size_t uarfcn_length; /* index for uarfcn and scramble lists */
|
||||
struct {
|
||||
/* bitmask large enough for all possible ARFCN's */
|
||||
uint8_t neigh_list[1024/8];
|
||||
uint8_t cell_alloc[1024/8];
|
||||
/* If the user wants a different neighbor list in SI5 than in SI2 */
|
||||
uint8_t si5_neigh_list[1024/8];
|
||||
uint8_t meas_bw_list[MAX_EARFCN_LIST];
|
||||
uint16_t earfcn_list[MAX_EARFCN_LIST];
|
||||
uint16_t uarfcn_list[MAX_EARFCN_LIST];
|
||||
uint16_t scramble_list[MAX_EARFCN_LIST];
|
||||
} data;
|
||||
} si_common;
|
||||
|
||||
@@ -732,6 +731,11 @@ struct gsm_bts {
|
||||
|
||||
/* BTS dependencies bit field */
|
||||
uint32_t depends_on[256/(8*4)];
|
||||
|
||||
/* full and half rate multirate config */
|
||||
struct amr_multirate_conf mr_full;
|
||||
struct amr_multirate_conf mr_half;
|
||||
|
||||
#endif /* ROLE_BSC */
|
||||
void *role;
|
||||
};
|
||||
@@ -753,9 +757,13 @@ const char *gsm_lchant_name(enum gsm_chan_t c);
|
||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
||||
char *gsm_trx_name(const struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name(const struct gsm_lchan *lchan);
|
||||
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
|
||||
{
|
||||
return lchan->name;
|
||||
}
|
||||
|
||||
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
||||
|
||||
@@ -790,7 +798,7 @@ static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
|
||||
if (ts->tsc != -1)
|
||||
return ts->tsc;
|
||||
else
|
||||
return ts->trx->bts->tsc;
|
||||
return ts->trx->bts->bsic & 7;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
#ifndef _GSM_SUBSCR_H
|
||||
#define _GSM_SUBSCR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "gsm_data.h"
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_NAME_LENGTH 160
|
||||
|
||||
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
|
||||
@@ -32,7 +33,7 @@ struct gsm_subscriber_group {
|
||||
|
||||
struct gsm_equipment {
|
||||
long long unsigned int id;
|
||||
char imei[GSM_IMEI_LENGTH];
|
||||
char imei[GSM23003_IMEISV_NUM_DIGITS+1];
|
||||
char name[GSM_NAME_LENGTH];
|
||||
|
||||
struct gsm48_classmark1 classmark1;
|
||||
@@ -45,7 +46,7 @@ struct gsm_equipment {
|
||||
struct gsm_subscriber {
|
||||
struct gsm_subscriber_group *group;
|
||||
long long unsigned int id;
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
uint32_t tmsi;
|
||||
uint16_t lac;
|
||||
char name[GSM_NAME_LENGTH];
|
||||
@@ -69,6 +70,7 @@ struct gsm_subscriber {
|
||||
|
||||
/* pending requests */
|
||||
int is_paging;
|
||||
struct osmo_timer_list paging_timeout;
|
||||
struct llist_head requests;
|
||||
|
||||
/* GPRS/SGSN related fields */
|
||||
@@ -88,6 +90,20 @@ enum gsm_subscriber_update_reason {
|
||||
GSM_SUBSCRIBER_UPDATE_EQUIPMENT,
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct for pending channel requests. This is managed in the
|
||||
* llist_head requests of each subscriber. The reference counting
|
||||
* should work in such a way that a subscriber with a pending request
|
||||
* remains in memory.
|
||||
*/
|
||||
struct subscr_request {
|
||||
struct llist_head entry;
|
||||
|
||||
/* the callback data */
|
||||
gsm_cbfn *cbfn;
|
||||
void *param;
|
||||
};
|
||||
|
||||
struct gsm_subscriber *subscr_get(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_put(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber *subscr_create_subscriber(struct gsm_subscriber_group *sgrp,
|
||||
@@ -102,7 +118,8 @@ struct gsm_subscriber *subscr_get_by_id(struct gsm_subscriber_group *sgrp,
|
||||
unsigned long long id);
|
||||
struct gsm_subscriber *subscr_get_or_create(struct gsm_subscriber_group *sgrp,
|
||||
const char *imsi);
|
||||
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
|
||||
int subscr_update(struct gsm_network *network, struct gsm_subscriber *s,
|
||||
uint16_t lac, int reason);
|
||||
struct gsm_subscriber *subscr_active_by_tmsi(struct gsm_subscriber_group *sgrp,
|
||||
uint32_t tmsi);
|
||||
struct gsm_subscriber *subscr_active_by_imsi(struct gsm_subscriber_group *sgrp,
|
||||
@@ -113,14 +130,18 @@ char *subscr_name(struct gsm_subscriber *subscr);
|
||||
int subscr_purge_inactive(struct gsm_subscriber_group *sgrp);
|
||||
void subscr_update_from_db(struct gsm_subscriber *subscr);
|
||||
void subscr_expire(struct gsm_subscriber_group *sgrp);
|
||||
int subscr_update_expire_lu(struct gsm_subscriber *subscr, struct gsm_bts *bts);
|
||||
int subscr_update_expire_lu(struct gsm_network *network, struct gsm_subscriber *subscr);
|
||||
|
||||
bool subscr_authorized(struct gsm_subscriber *subsc);
|
||||
|
||||
/*
|
||||
* Paging handling with authentication
|
||||
*/
|
||||
struct subscr_request *subscr_request_channel(struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *param);
|
||||
struct subscr_request *subscr_request_conn(struct gsm_subscriber *subscr,
|
||||
gsm_cbfn *cbfn, void *param);
|
||||
void subscr_remove_request(struct subscr_request *req);
|
||||
int subscr_rx_paging_response(struct msgb *msg,
|
||||
struct gsm_subscriber_connection *conn);
|
||||
|
||||
/* internal */
|
||||
struct gsm_subscriber *subscr_alloc(void);
|
||||
|
||||
523
openbsc/include/openbsc/gtphub.h
Normal file
523
openbsc/include/openbsc/gtphub.h
Normal file
@@ -0,0 +1,523 @@
|
||||
/* GTP Hub Implementation */
|
||||
|
||||
/* (C) 2015 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Neels Hofmeyr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
|
||||
/* support */
|
||||
|
||||
/* TODO move to osmocom/core/socket.c ? */
|
||||
#include <netdb.h> /* for IPPROTO_* etc */
|
||||
struct osmo_sockaddr {
|
||||
struct sockaddr_storage a;
|
||||
socklen_t l;
|
||||
};
|
||||
|
||||
/* TODO move to osmocom/core/socket.c ? */
|
||||
/*! \brief Initialize a sockaddr
|
||||
* \param[out] addr Valid osmo_sockaddr pointer to write result to
|
||||
* \param[in] family Address Family like AF_INET, AF_INET6, AF_UNSPEC
|
||||
* \param[in] type Socket type like SOCK_DGRAM, SOCK_STREAM
|
||||
* \param[in] proto Protocol like IPPROTO_TCP, IPPROTO_UDP
|
||||
* \param[in] host Remote host name or IP address in string form
|
||||
* \param[in] port Remote port number in host byte order
|
||||
* \returns 0 on success, otherwise an error code (from getaddrinfo()).
|
||||
*
|
||||
* Copy the first result from a getaddrinfo() call with the given parameters to
|
||||
* *addr and *addr_len. On error, do not change *addr and return nonzero.
|
||||
*/
|
||||
int osmo_sockaddr_init(struct osmo_sockaddr *addr,
|
||||
uint16_t family, uint16_t type, uint8_t proto,
|
||||
const char *host, uint16_t port);
|
||||
|
||||
/* Conveniently pass AF_UNSPEC, SOCK_DGRAM and IPPROTO_UDP to
|
||||
* osmo_sockaddr_init(). */
|
||||
static inline int osmo_sockaddr_init_udp(struct osmo_sockaddr *addr,
|
||||
const char *host, uint16_t port)
|
||||
{
|
||||
return osmo_sockaddr_init(addr, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP,
|
||||
host, port);
|
||||
}
|
||||
|
||||
/*! \brief convert sockaddr to human readable string.
|
||||
* \param[out] addr_str Valid pointer to a buffer of length addr_str_len.
|
||||
* \param[in] addr_str_len Size of buffer addr_str points at.
|
||||
* \param[out] port_str Valid pointer to a buffer of length port_str_len.
|
||||
* \param[in] port_str_len Size of buffer port_str points at.
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \param[in] flags flags as passed to getnameinfo().
|
||||
* \returns 0 on success, an error code on error.
|
||||
*
|
||||
* Return the IPv4 or IPv6 address string and the port (a.k.a. service) string
|
||||
* representations of the given struct osmo_sockaddr in two caller provided
|
||||
* char buffers. Flags of (NI_NUMERICHOST | NI_NUMERICSERV) return numeric
|
||||
* address and port. Either one of addr_str or port_str may be NULL, in which
|
||||
* case nothing is returned there.
|
||||
*
|
||||
* See also osmo_sockaddr_to_str() (less flexible, but much more convenient). */
|
||||
int osmo_sockaddr_to_strs(char *addr_str, size_t addr_str_len,
|
||||
char *port_str, size_t port_str_len,
|
||||
const struct osmo_sockaddr *addr,
|
||||
int flags);
|
||||
|
||||
|
||||
/*! \brief concatenate the parts returned by osmo_sockaddr_to_strs().
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \param[in] buf A buffer to use for string operations.
|
||||
* \param[in] buf_len Length of the buffer.
|
||||
* \returns Address string (in buffer).
|
||||
*
|
||||
* Compose a string of the numeric IP-address and port represented by *addr of
|
||||
* the form "<ip-addr> port <port>". The returned string is valid until the
|
||||
* next invocation of this function.
|
||||
*/
|
||||
const char *osmo_sockaddr_to_strb(const struct osmo_sockaddr *addr,
|
||||
char *buf, size_t buf_len);
|
||||
|
||||
/*! \brief conveniently return osmo_sockaddr_to_strb() in a static buffer.
|
||||
* \param[in] addr Binary representation as returned by osmo_sockaddr_init().
|
||||
* \returns Address string in static buffer.
|
||||
*
|
||||
* See osmo_sockaddr_to_strb().
|
||||
*
|
||||
* Note: only one osmo_sockaddr_to_str() call will work per print/log
|
||||
* statement. For two or more, use osmo_sockaddr_to_strb() with a separate
|
||||
* buffer each.
|
||||
*/
|
||||
const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *addr);
|
||||
|
||||
/*! \brief compare two osmo_sockaddr.
|
||||
* \param[in] a The first address to compare.
|
||||
* \param[in] b The other address to compare.
|
||||
* \returns 0 if equal, otherwise -1 or 1.
|
||||
*/
|
||||
int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
|
||||
const struct osmo_sockaddr *b);
|
||||
|
||||
/*! \brief Overwrite *dst with *src.
|
||||
* Like memcpy(), but copy only the valid bytes. */
|
||||
void osmo_sockaddr_copy(struct osmo_sockaddr *dst,
|
||||
const struct osmo_sockaddr *src);
|
||||
|
||||
|
||||
/* general */
|
||||
|
||||
enum gtphub_plane_idx {
|
||||
GTPH_PLANE_CTRL = 0,
|
||||
GTPH_PLANE_USER = 1,
|
||||
GTPH_PLANE_N
|
||||
};
|
||||
|
||||
enum gtphub_side_idx {
|
||||
GTPH_SIDE_SGSN = 0,
|
||||
GTPH_SIDE_GGSN = 1,
|
||||
GTPH_SIDE_N
|
||||
};
|
||||
|
||||
#define for_each_side(I) for (I = 0; I < GTPH_SIDE_N; I++)
|
||||
#define for_each_plane(I) for (I = 0; I < GTPH_PLANE_N; I++)
|
||||
#define for_each_side_and_plane(I,J) for_each_side(I) for_each_plane(J)
|
||||
|
||||
static inline int other_side_idx(int side_idx)
|
||||
{
|
||||
return (side_idx + 1) & 1;
|
||||
}
|
||||
|
||||
extern const char* const gtphub_plane_idx_names[GTPH_PLANE_N];
|
||||
extern const uint16_t gtphub_plane_idx_default_port[GTPH_PLANE_N];
|
||||
|
||||
extern const char* const gtphub_side_idx_names[GTPH_SIDE_N];
|
||||
|
||||
/* A host address in the form that is expected in the 7.7.32 GSN Address IE.
|
||||
* len is either 4 (IPv4) or 16 (IPv6), any other value is invalid. If no
|
||||
* address is set, len shall be 0. */
|
||||
struct gsn_addr {
|
||||
uint16_t len;
|
||||
uint8_t buf[16];
|
||||
};
|
||||
|
||||
void gsn_addr_copy(struct gsn_addr *gsna, const struct gsn_addr *src);
|
||||
int gsn_addr_from_str(struct gsn_addr *gsna, const char *numeric_addr_str);
|
||||
|
||||
/* Return gsna in numeric string form, in a static buffer. */
|
||||
const char *gsn_addr_to_str(const struct gsn_addr *gsna);
|
||||
|
||||
/* note: strbuf_len doesn't need to be larger than INET6_ADDRSTRLEN + 1. */
|
||||
const char *gsn_addr_to_strb(const struct gsn_addr *gsna,
|
||||
char *strbuf, int strbuf_len);
|
||||
|
||||
/* Return 1 on match, zero otherwise. */
|
||||
int gsn_addr_same(const struct gsn_addr *a, const struct gsn_addr *b);
|
||||
|
||||
/* Decode sa to gsna. Return 0 on success. If port is non-NULL, the port number
|
||||
* from sa is also returned. */
|
||||
int gsn_addr_from_sockaddr(struct gsn_addr *gsna, uint16_t *port,
|
||||
const struct osmo_sockaddr *sa);
|
||||
|
||||
/* expiry */
|
||||
|
||||
struct expiring_item;
|
||||
typedef void (*del_cb_t)(struct expiring_item *);
|
||||
|
||||
struct expiring_item {
|
||||
struct llist_head entry;
|
||||
time_t expiry;
|
||||
del_cb_t del_cb;
|
||||
};
|
||||
|
||||
struct expiry {
|
||||
int expiry_in_seconds;
|
||||
struct llist_head items;
|
||||
};
|
||||
|
||||
/* Initialize an expiry queue. */
|
||||
void expiry_init(struct expiry *exq, int expiry_in_seconds);
|
||||
|
||||
/* Add a new mapping, or restart the expiry timeout for an already listed
|
||||
* mapping. */
|
||||
void expiry_add(struct expiry *exq, struct expiring_item *item, time_t now);
|
||||
|
||||
/* Initialize to all-empty; must be called before using the item in any way. */
|
||||
void expiring_item_init(struct expiring_item *item);
|
||||
|
||||
/* Remove the given item from its expiry queue, and call item->del_cb, if set.
|
||||
* This sets item->del_cb to NULL and is harmless when run a second time on the
|
||||
* same item, so the del_cb may choose to call this function, too, to allow
|
||||
* deleting items from several code paths. */
|
||||
void expiring_item_del(struct expiring_item *item);
|
||||
|
||||
/* Carry out due expiry of mappings. Must be invoked regularly.
|
||||
* 'now' is the current clock count in seconds and must correspond to the clock
|
||||
* count passed to nr_map_add(). A monotonous clock counter should be used. */
|
||||
int expiry_tick(struct expiry *exq, time_t now);
|
||||
|
||||
/* Expire all items. */
|
||||
void expiry_clear(struct expiry *exq);
|
||||
|
||||
|
||||
/* number map */
|
||||
|
||||
/* A number map assigns a "random" mapped number to each user provided number.
|
||||
* If the same number is requested multiple times, the same mapped number is
|
||||
* returned.
|
||||
*
|
||||
* Number maps plug into possibly shared pools and expiry queues, for example:
|
||||
*
|
||||
* mapA -----------+-> pool1 <-+-- mapB
|
||||
* {10->1, 11->5} | {1, 2, 3, ...} | {10->2, 11->3}
|
||||
* | |
|
||||
* | |
|
||||
* /-> \-> expiry1 <-/
|
||||
* | (30 seconds)
|
||||
* |
|
||||
* mapC -------+-----> pool2 <-+-- mapD
|
||||
* {10->1, 11->3} {1, 2, 3, ...} | {10->2, 11->5}
|
||||
* |
|
||||
* expiry2 <-/
|
||||
* (60 seconds)
|
||||
*
|
||||
* A map contains mappings ("10->1"). Each map needs a number pool, which can
|
||||
* be shared with other maps. Each new mapping receives a number from the pool,
|
||||
* which is then unavailable to any other map using the same pool.
|
||||
*
|
||||
* A map may point at an expiry queue, in which case all mappings added to it
|
||||
* are also appended to the expiry queue (using a separate llist entry in the
|
||||
* mapping). Any number of maps may submit to the same expiry queue, if they
|
||||
* desire the same expiry timeout. An expiry queue stores the mappings in
|
||||
* chronological order, so that expiry checking is needed only from the start
|
||||
* of the queue; hence only mappings with identical expiry timeout can be added
|
||||
* to the same expiry queue. Upon expiry, a mapping is dropped from the map it
|
||||
* was submitted at. expiry_tick() needs to be called regularly for each expiry
|
||||
* queue.
|
||||
*
|
||||
* A nr_mapping can be embedded in a larger struct: each mapping can have a
|
||||
* distinct destructor (del_cb), and each del_cb can figure out the container
|
||||
* struct's address and free that upon expiry or manual deletion. So in expiry
|
||||
* queues (and even maps), mappings of different container types can be mixed.
|
||||
* This can help to drastically reduce the amount of unnecessary visits during
|
||||
* expiry checking, for the case that no expiry is pending. An expiry queue
|
||||
* always knows which mappings to expire next, because they are right at the
|
||||
* start of its list.
|
||||
*
|
||||
* Mapping allocation and a del_cb are provided by the caller. If del_cb is
|
||||
* NULL, no deallocation will be done (allowing statically allocated entries).
|
||||
*/
|
||||
|
||||
typedef unsigned int nr_t;
|
||||
|
||||
/* Generator for unused numbers. So far this counts upwards from zero, but the
|
||||
* implementation may change in the future. Treat this like an opaque struct.
|
||||
* If this becomes random, the tests need to be fixed. */
|
||||
struct nr_pool {
|
||||
nr_t last_nr;
|
||||
nr_t nr_min;
|
||||
nr_t nr_max;
|
||||
};
|
||||
|
||||
struct nr_mapping {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
void *origin;
|
||||
nr_t orig;
|
||||
nr_t repl;
|
||||
};
|
||||
|
||||
struct nr_map {
|
||||
struct nr_pool *pool; /* multiple nr_maps can share a nr_pool. */
|
||||
struct expiry *add_items_to_expiry;
|
||||
struct llist_head mappings;
|
||||
};
|
||||
|
||||
|
||||
void nr_pool_init(struct nr_pool *pool, nr_t nr_min, nr_t nr_max);
|
||||
|
||||
/* Return the next unused number from the nr_pool. */
|
||||
nr_t nr_pool_next(struct nr_pool *pool);
|
||||
|
||||
/* Initialize the nr_mapping to zero/empty values. */
|
||||
void nr_mapping_init(struct nr_mapping *mapping);
|
||||
|
||||
/* Remove the given mapping from its parent map and expiry queue, and call
|
||||
* mapping->del_cb, if set. */
|
||||
void nr_mapping_del(struct nr_mapping *mapping);
|
||||
|
||||
/* Initialize an (already allocated) nr_map, and set the map's number pool.
|
||||
* Multiple nr_map instances may use the same nr_pool. Set the nr_map's expiry
|
||||
* queue to exq, so that all added mappings are automatically expired after the
|
||||
* time configured in exq. exq may be NULL to disable automatic expiry. */
|
||||
void nr_map_init(struct nr_map *map, struct nr_pool *pool,
|
||||
struct expiry *exq);
|
||||
|
||||
/* Add a new entry to the map. mapping->orig, mapping->origin and
|
||||
* mapping->del_cb must be set before calling this function. The remaining
|
||||
* fields of *mapping will be overwritten. mapping->repl is set to the next
|
||||
* available mapped number from map->pool. 'now' is the current clock count in
|
||||
* seconds; if no map->expiry is used, just pass 0 for 'now'. */
|
||||
void nr_map_add(struct nr_map *map, struct nr_mapping *mapping,
|
||||
time_t now);
|
||||
|
||||
/* Restart the timeout for the given mapping. mapping must be a member of map.
|
||||
*/
|
||||
void nr_map_refresh(struct nr_map *map, struct nr_mapping *mapping,
|
||||
time_t now);
|
||||
|
||||
/* Return a known mapping from nr_orig and the given origin. If nr_orig is
|
||||
* unknown, return NULL. */
|
||||
struct nr_mapping *nr_map_get(const struct nr_map *map,
|
||||
void *origin, nr_t nr_orig);
|
||||
|
||||
/* Return a known mapping to nr_repl. If nr_repl is unknown, return NULL. */
|
||||
struct nr_mapping *nr_map_get_inv(const struct nr_map *map, nr_t nr_repl);
|
||||
|
||||
/* Remove all mappings from map. */
|
||||
void nr_map_clear(struct nr_map *map);
|
||||
|
||||
/* Return 1 if map has no entries, 0 otherwise. */
|
||||
int nr_map_empty(const struct nr_map *map);
|
||||
|
||||
|
||||
/* config */
|
||||
|
||||
static const int GTPH_EXPIRE_QUICKLY_SECS = 30; /* TODO is there a spec for this? */
|
||||
static const int GTPH_EXPIRE_SLOWLY_MINUTES = 6 * 60; /* TODO is there a spec for this? */
|
||||
|
||||
struct gtphub_cfg_addr {
|
||||
const char *addr_str;
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
struct gtphub_cfg_bind {
|
||||
struct gtphub_cfg_addr bind;
|
||||
};
|
||||
|
||||
struct gtphub_cfg {
|
||||
struct gtphub_cfg_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
struct gtphub_cfg_addr proxy[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
int sgsn_use_sender; /* Use sender, not GSN addr IE with std ports */
|
||||
};
|
||||
|
||||
|
||||
/* state */
|
||||
|
||||
struct gtphub_peer {
|
||||
struct llist_head entry;
|
||||
|
||||
struct llist_head addresses; /* Alternatives, not load balancing. */
|
||||
struct nr_pool seq_pool;
|
||||
struct nr_map seq_map;
|
||||
};
|
||||
|
||||
struct gtphub_peer_addr {
|
||||
struct llist_head entry;
|
||||
|
||||
struct gtphub_peer *peer;
|
||||
struct gsn_addr addr;
|
||||
struct llist_head ports;
|
||||
};
|
||||
|
||||
struct gtphub_peer_port {
|
||||
struct llist_head entry;
|
||||
|
||||
struct gtphub_peer_addr *peer_addr;
|
||||
uint16_t port;
|
||||
unsigned int ref_count; /* references from other peers' seq_maps */
|
||||
struct osmo_sockaddr sa; /* a "cache" for (peer_addr->addr, port) */
|
||||
int last_restart_count; /* 0..255 = valid, all else means unknown */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel_endpoint {
|
||||
struct gtphub_peer_port *peer;
|
||||
uint32_t tei_orig; /* from/to peer */
|
||||
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_tunnel {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
uint32_t tei_repl; /* unique TEI to replace peers' TEIs */
|
||||
struct gtphub_tunnel_endpoint endpoint[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
};
|
||||
|
||||
struct gtphub_bind {
|
||||
struct gsn_addr local_addr;
|
||||
uint16_t local_port;
|
||||
struct osmo_fd ofd;
|
||||
|
||||
/* list of struct gtphub_peer */
|
||||
struct llist_head peers;
|
||||
|
||||
const char *label; /* For logging */
|
||||
struct rate_ctr_group *counters_io;
|
||||
};
|
||||
|
||||
struct gtphub_resolved_ggsn {
|
||||
struct llist_head entry;
|
||||
struct expiring_item expiry_entry;
|
||||
|
||||
/* The APN OI, the Operator Identifier, is the combined address,
|
||||
* including parts of the IMSI and APN NI, and ending with ".gprs". */
|
||||
char apn_oi_str[GSM_APN_LENGTH];
|
||||
|
||||
/* Which address and port we resolved that to. */
|
||||
struct gtphub_peer_port *peer;
|
||||
};
|
||||
|
||||
struct gtphub {
|
||||
struct gtphub_bind to_gsns[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
|
||||
/* pointers to an entry of to_gsns[s][p].peers */
|
||||
struct gtphub_peer_port *proxy[GTPH_SIDE_N][GTPH_PLANE_N];
|
||||
|
||||
/* The TEI numbers will simply wrap and be reused, which will work out
|
||||
* in practice. Problems would arise if one given peer maintained the
|
||||
* same TEI for a time long enough for the TEI nr map to wrap an entire
|
||||
* uint32_t; if a new TEI were mapped every second, this would take
|
||||
* more than 100 years (in which a single given TEI must not time out)
|
||||
* to cause a problem. */
|
||||
struct nr_pool tei_pool;
|
||||
|
||||
struct llist_head tunnels; /* struct gtphub_tunnel */
|
||||
struct llist_head pending_deletes; /* opaque (gtphub.c) */
|
||||
|
||||
struct llist_head ggsn_lookups; /* opaque (gtphub_ares.c) */
|
||||
struct llist_head resolved_ggsns; /* struct gtphub_resolved_ggsn */
|
||||
|
||||
struct osmo_timer_list gc_timer;
|
||||
struct expiry expire_quickly;
|
||||
struct expiry expire_slowly;
|
||||
|
||||
uint8_t restart_counter;
|
||||
|
||||
int sgsn_use_sender;
|
||||
};
|
||||
|
||||
struct gtp_packet_desc;
|
||||
|
||||
|
||||
/* api */
|
||||
|
||||
int gtphub_vty_init(struct gtphub *global_hub, struct gtphub_cfg *global_cfg);
|
||||
int gtphub_cfg_read(struct gtphub_cfg *cfg, const char *config_file);
|
||||
|
||||
/* Initialize and start gtphub: bind to ports, run expiry timers. */
|
||||
int gtphub_start(struct gtphub *hub, struct gtphub_cfg *cfg,
|
||||
uint8_t restart_counter);
|
||||
|
||||
/* Close all sockets, expire all maps and peers and free all allocations. The
|
||||
* struct is then unusable, unless gtphub_start() is run on it again. */
|
||||
void gtphub_stop(struct gtphub *hub);
|
||||
|
||||
time_t gtphub_now(void);
|
||||
|
||||
/* Remove expired items, empty peers, ... */
|
||||
void gtphub_gc(struct gtphub *hub, time_t now);
|
||||
|
||||
/* Return the string of the first address for this peer. */
|
||||
const char *gtphub_peer_str(struct gtphub_peer *peer);
|
||||
|
||||
/* Return a human readable description of tun in a static buffer. */
|
||||
const char *gtphub_tunnel_str(struct gtphub_tunnel *tun);
|
||||
|
||||
/* Return 1 if all of tun's endpoints are fully established, 0 otherwise. */
|
||||
int gtphub_tunnel_complete(struct gtphub_tunnel *tun);
|
||||
|
||||
int gtphub_handle_buf(struct gtphub *hub,
|
||||
unsigned int side_idx,
|
||||
unsigned int port_idx,
|
||||
const struct osmo_sockaddr *from_addr,
|
||||
uint8_t *buf,
|
||||
size_t received,
|
||||
time_t now,
|
||||
uint8_t **reply_buf,
|
||||
struct osmo_fd **to_ofd,
|
||||
struct osmo_sockaddr *to_addr);
|
||||
|
||||
struct gtphub_peer_port *gtphub_port_have(struct gtphub *hub,
|
||||
struct gtphub_bind *bind,
|
||||
const struct gsn_addr *addr,
|
||||
uint16_t port);
|
||||
|
||||
struct gtphub_peer_port *gtphub_port_find_sa(const struct gtphub_bind *bind,
|
||||
const struct osmo_sockaddr *addr);
|
||||
|
||||
void gtphub_resolved_ggsn(struct gtphub *hub, const char *apn_oi_str,
|
||||
struct gsn_addr *resolved_addr,
|
||||
time_t now);
|
||||
|
||||
const char *gtphub_port_str(struct gtphub_peer_port *port);
|
||||
|
||||
int gtphub_write(const struct osmo_fd *to,
|
||||
const struct osmo_sockaddr *to_addr,
|
||||
const uint8_t *buf, size_t buf_len);
|
||||
@@ -5,13 +5,14 @@
|
||||
#include "gsm_subscriber.h"
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
struct ipac_msgt_sccp_state {
|
||||
uint8_t src_ref[3];
|
||||
uint8_t dst_ref[3];
|
||||
uint8_t trans_id;
|
||||
uint8_t invoke_id;
|
||||
char imsi[GSM_IMSI_LENGTH];
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
61
openbsc/include/openbsc/iu.h
Normal file
61
openbsc/include/openbsc/iu.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct sgsn_pdp_ctx;
|
||||
struct msgb;
|
||||
struct gprs_ra_id;
|
||||
|
||||
struct RANAP_RAB_SetupOrModifiedItemIEs_s;
|
||||
struct RANAP_GlobalRNC_ID;
|
||||
|
||||
struct ue_conn_ctx {
|
||||
struct llist_head list;
|
||||
struct osmo_sua_link *link;
|
||||
uint32_t conn_id;
|
||||
int integrity_active;
|
||||
struct gprs_ra_id ra_id;
|
||||
};
|
||||
|
||||
enum iu_event_type {
|
||||
IU_EVENT_RAB_ASSIGN,
|
||||
IU_EVENT_SECURITY_MODE_COMPLETE,
|
||||
IU_EVENT_IU_RELEASE, /* An actual Iu Release message was received */
|
||||
IU_EVENT_LINK_INVALIDATED, /* A SUA link was lost or closed down */
|
||||
/* FIXME: maybe IU_EVENT_IU_RELEASE and IU_EVENT_LINK_INVALIDATED
|
||||
* should be combined to one generic event that simply means the
|
||||
* ue_conn_ctx should no longer be used, for whatever reason. */
|
||||
};
|
||||
|
||||
extern const struct value_string iu_event_type_names[];
|
||||
static inline const char *iu_event_type_str(enum iu_event_type e)
|
||||
{
|
||||
return get_value_string(iu_event_type_names, e);
|
||||
}
|
||||
|
||||
/* Implementations of iu_recv_cb_t shall find the ue_conn_ctx in msg->dst. */
|
||||
typedef int (* iu_recv_cb_t )(struct msgb *msg, struct gprs_ra_id *ra_id,
|
||||
/* TODO "gprs_" in generic CS+PS domain ^ */
|
||||
uint16_t *sai);
|
||||
|
||||
typedef int (* iu_event_cb_t )(struct ue_conn_ctx *ue_ctx,
|
||||
enum iu_event_type type, void *data);
|
||||
|
||||
typedef int (* iu_rab_ass_resp_cb_t )(struct ue_conn_ctx *ue_ctx, uint8_t rab_id,
|
||||
struct RANAP_RAB_SetupOrModifiedItemIEs_s *setup_ies);
|
||||
|
||||
int iu_init(void *ctx, const char *listen_addr, uint16_t listen_port,
|
||||
iu_recv_cb_t iu_recv_cb, iu_event_cb_t iu_event_cb);
|
||||
|
||||
void iu_link_del(struct osmo_sua_link *link);
|
||||
|
||||
int iu_tx(struct msgb *msg, uint8_t sapi);
|
||||
|
||||
int iu_page_cs(const char *imsi, const uint32_t *tmsi, uint16_t lac);
|
||||
int iu_page_ps(const char *imsi, const uint32_t *ptmsi, uint16_t lac, uint8_t rac);
|
||||
|
||||
int iu_rab_act_cs(struct ue_conn_ctx *ue_ctx, uint32_t rtp_ip, uint16_t rtp_port);
|
||||
int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp, bool use_x213_nsap);
|
||||
int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id);
|
||||
int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp,
|
||||
int send_ck, int new_key);
|
||||
7
openbsc/include/openbsc/iu_cs.h
Normal file
7
openbsc/include/openbsc/iu_cs.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg,
|
||||
uint16_t *lac);
|
||||
|
||||
struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network,
|
||||
struct ue_conn_ctx *ue);
|
||||
@@ -17,13 +17,25 @@ struct meas_feed_meas {
|
||||
char name[31+1];
|
||||
char scenario[31+1];
|
||||
struct gsm_meas_rep mr;
|
||||
/* The logical channel type, enum gsm_chan_t */
|
||||
uint8_t lchan_type;
|
||||
/* The physical channel type, enum gsm_phys_chan_config */
|
||||
uint8_t pchan_type;
|
||||
/* number of ths BTS in network */
|
||||
uint8_t bts_nr;
|
||||
/* number of this TRX in the BTS */
|
||||
uint8_t trx_nr;
|
||||
/* number of this timeslot at the TRX */
|
||||
uint8_t ts_nr;
|
||||
/* The logical subslot number in the TS */
|
||||
uint8_t ss_nr;
|
||||
};
|
||||
|
||||
enum meas_feed_msgtype {
|
||||
MEAS_FEED_MEAS = 0,
|
||||
};
|
||||
|
||||
#define MEAS_FEED_VERSION 0
|
||||
#define MEAS_FEED_VERSION 1
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include "debug.h"
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define RTP_PORT_DEFAULT 4000
|
||||
#define RTP_PORT_NET_DEFAULT 16000
|
||||
@@ -114,6 +117,9 @@ typedef void (*mgcp_get_format)(struct mgcp_endpoint *endp,
|
||||
struct mgcp_port_range {
|
||||
int mode;
|
||||
|
||||
/* addr or NULL to fall-back to default */
|
||||
char *bind_addr;
|
||||
|
||||
/* pre-allocated from a base? */
|
||||
int base_port;
|
||||
|
||||
@@ -214,6 +220,8 @@ struct mgcp_config {
|
||||
|
||||
/* osmux translator: 0 means disabled, 1 means enabled */
|
||||
int osmux;
|
||||
/* addr to bind the server to */
|
||||
char *osmux_addr;
|
||||
/* The BSC-NAT may ask for enabling osmux on demand. This tells us if
|
||||
* the osmux socket is already initialized.
|
||||
*/
|
||||
@@ -224,6 +232,10 @@ struct mgcp_config {
|
||||
int osmux_batch_size;
|
||||
/* osmux port */
|
||||
uint16_t osmux_port;
|
||||
/* Pad circuit with dummy messages until we see the first voice
|
||||
* message.
|
||||
*/
|
||||
uint16_t osmux_dummy;
|
||||
};
|
||||
|
||||
/* config management */
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <osmocom/core/select.h>
|
||||
|
||||
#define CI_UNUSED 0
|
||||
@@ -190,6 +192,8 @@ struct mgcp_endpoint {
|
||||
/* Osmux state: disabled, activating, active */
|
||||
enum osmux_state state;
|
||||
/* Allocated Osmux circuit ID for this endpoint */
|
||||
int allocated_cid;
|
||||
/* Used Osmux circuit ID for this endpoint */
|
||||
uint8_t cid;
|
||||
/* handle to batch messages */
|
||||
struct osmux_in_handle *in;
|
||||
@@ -203,11 +207,51 @@ struct mgcp_endpoint {
|
||||
} osmux;
|
||||
};
|
||||
|
||||
#define for_each_line(line, save) \
|
||||
for (line = strline_r(NULL, &save); line;\
|
||||
line = strline_r(NULL, &save))
|
||||
|
||||
static inline char *strline_r(char *str, char **saveptr)
|
||||
{
|
||||
char *result;
|
||||
|
||||
if (str)
|
||||
*saveptr = str;
|
||||
|
||||
result = *saveptr;
|
||||
|
||||
if (*saveptr != NULL) {
|
||||
*saveptr = strpbrk(*saveptr, "\r\n");
|
||||
|
||||
if (*saveptr != NULL) {
|
||||
char *eos = *saveptr;
|
||||
|
||||
if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
|
||||
(*saveptr)++;
|
||||
(*saveptr)++;
|
||||
if ((*saveptr)[0] == '\0')
|
||||
*saveptr = NULL;
|
||||
|
||||
*eos = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define ENDPOINT_NUMBER(endp) abs((int)(endp - endp->tcfg->endpoints))
|
||||
|
||||
struct mgcp_msg_ptr {
|
||||
unsigned int start;
|
||||
unsigned int length;
|
||||
/**
|
||||
* Internal structure while parsing a request
|
||||
*/
|
||||
struct mgcp_parse_data {
|
||||
struct mgcp_config *cfg;
|
||||
struct mgcp_endpoint *endp;
|
||||
char *trans;
|
||||
char *save;
|
||||
int found;
|
||||
};
|
||||
|
||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
||||
@@ -260,5 +304,39 @@ enum {
|
||||
MGCP_DEST_BTS,
|
||||
};
|
||||
|
||||
|
||||
#define MGCP_DUMMY_LOAD 0x23
|
||||
|
||||
|
||||
/**
|
||||
* SDP related information
|
||||
*/
|
||||
/* Assume audio frame length of 20ms */
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
|
||||
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
|
||||
#define DEFAULT_RTP_AUDIO_PACKET_DURATION_MS 20
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_RATE 8000
|
||||
#define DEFAULT_RTP_AUDIO_DEFAULT_CHANNELS 1
|
||||
|
||||
#define PTYPE_UNDEFINED (-1)
|
||||
int mgcp_parse_sdp_data(struct mgcp_endpoint *endp, struct mgcp_rtp_end *rtp, struct mgcp_parse_data *p);
|
||||
int mgcp_set_audio_info(void *ctx, struct mgcp_rtp_codec *codec,
|
||||
int payload_type, const char *audio_name);
|
||||
|
||||
|
||||
/**
|
||||
* Internal network related
|
||||
*/
|
||||
static inline const char *mgcp_net_src_addr(struct mgcp_endpoint *endp)
|
||||
{
|
||||
if (endp->cfg->net_ports.bind_addr)
|
||||
return endp->cfg->net_ports.bind_addr;
|
||||
return endp->cfg->source_addr;
|
||||
}
|
||||
|
||||
static inline const char *mgcp_bts_src_addr(struct mgcp_endpoint *endp)
|
||||
{
|
||||
if (endp->cfg->bts_ports.bind_addr)
|
||||
return endp->cfg->bts_ports.bind_addr;
|
||||
return endp->cfg->source_addr;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ enum audio_format {
|
||||
AF_L16,
|
||||
AF_GSM,
|
||||
AF_G729,
|
||||
AF_PCMA
|
||||
AF_PCMA,
|
||||
AF_PCMU
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -92,6 +92,9 @@ struct gsm_call {
|
||||
#define MNCC_FRAME_RECV 0x0201
|
||||
#define MNCC_FRAME_DROP 0x0202
|
||||
#define MNCC_LCHAN_MODIFY 0x0203
|
||||
#define MNCC_RTP_CREATE 0x0204
|
||||
#define MNCC_RTP_CONNECT 0x0205
|
||||
#define MNCC_RTP_FREE 0x0206
|
||||
|
||||
#define GSM_TCHF_FRAME 0x0300
|
||||
#define GSM_TCHF_FRAME_EFR 0x0301
|
||||
@@ -163,7 +166,7 @@ struct gsm_data_frame {
|
||||
unsigned char data[0];
|
||||
};
|
||||
|
||||
#define MNCC_SOCK_VERSION 4
|
||||
#define MNCC_SOCK_VERSION 5
|
||||
struct gsm_mncc_hello {
|
||||
uint32_t msg_type;
|
||||
uint32_t version;
|
||||
@@ -179,7 +182,21 @@ struct gsm_mncc_hello {
|
||||
uint32_t lchan_type_offset;
|
||||
};
|
||||
|
||||
char *get_mncc_name(int value);
|
||||
struct gsm_mncc_rtp {
|
||||
uint32_t msg_type;
|
||||
uint32_t callref;
|
||||
uint32_t ip;
|
||||
uint16_t port;
|
||||
uint32_t payload_type;
|
||||
uint32_t payload_msg_type;
|
||||
};
|
||||
|
||||
struct gsm_mncc_bridge {
|
||||
uint32_t msg_type;
|
||||
uint32_t callref[2];
|
||||
};
|
||||
|
||||
const char *get_mncc_name(int value);
|
||||
void mncc_set_cause(struct gsm_mncc *data, int loc, int val);
|
||||
void cc_tx_to_mncc(struct gsm_network *net, struct msgb *msg);
|
||||
|
||||
@@ -189,7 +206,7 @@ int int_mncc_recv(struct gsm_network *net, struct msgb *msg);
|
||||
/* input from CC code into mncc_sock */
|
||||
int mncc_sock_from_cc(struct gsm_network *net, struct msgb *msg);
|
||||
|
||||
int mncc_sock_init(struct gsm_network *gsmnet);
|
||||
int mncc_sock_init(struct gsm_network *net, const char *sock_path);
|
||||
|
||||
#define mncc_is_data_frame(msg_type) \
|
||||
(msg_type == GSM_TCHF_FRAME \
|
||||
|
||||
@@ -9,4 +9,6 @@ struct mncc_int {
|
||||
|
||||
extern struct mncc_int mncc_int;
|
||||
|
||||
uint8_t mncc_codec_for_mode(int lchan_type);
|
||||
|
||||
#endif
|
||||
|
||||
29
openbsc/include/openbsc/msc_api.h
Normal file
29
openbsc/include/openbsc/msc_api.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
/* These functions receive or send MM|CC|... messages from/to the BSC|RNC
|
||||
* direction, while they are not concerned with which particular external
|
||||
* interface is actually involved (A or IuCS).
|
||||
*
|
||||
* For the interface specific decisions see msc_iface.[hc]
|
||||
*/
|
||||
|
||||
/* MSCSPLIT WIP: this will gradually replace the role that the bsc_api.h had in
|
||||
* OsmoNITB. Actually, osmo_msc.[hc] has the same role as this file, but having
|
||||
* separate files helps me to keep track of how far I've gotten yet. */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
struct msgb;
|
||||
|
||||
enum {
|
||||
MSC_CONN_ACCEPT = 0,
|
||||
MSC_CONN_REJECT = 1,
|
||||
};
|
||||
|
||||
/* receive a Level 3 Complete message and return MSC_CONN_ACCEPT or
|
||||
* MSC_CONN_REJECT */
|
||||
int msc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
|
||||
uint16_t chosen_channel);
|
||||
/* TODO: is chosen_channel BSC land == NITB legacy? */
|
||||
|
||||
40
openbsc/include/openbsc/msc_ifaces.h
Normal file
40
openbsc/include/openbsc/msc_ifaces.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
/* These are the interfaces of the MSC layer towards (from?) the BSC and RNC,
|
||||
* i.e. in the direction towards the mobile device (MS aka UE).
|
||||
*
|
||||
* 2G will use the A-interface,
|
||||
* 3G aka UMTS will use the Iu-interface (for the MSC, it's IuCS).
|
||||
*
|
||||
* To allow linking parts of the MSC code without having to include entire
|
||||
* infrastructures of external libraries, the core transmitting and receiving
|
||||
* functions are left unimplemented. For example, a unit test does not need to
|
||||
* link against external ASN1 libraries if it is never going to encode actual
|
||||
* outgoing messages. It is up to each building scope to implement real world
|
||||
* functions or to plug mere dummy implementations.
|
||||
*
|
||||
* For example, msc_tx_dtap(conn, msg), depending on conn->via_iface, will call
|
||||
* either iu_tx() or a_tx() [note: at time of writing, the A-interface is not
|
||||
* yet implemented]. When you try to link against libmsc, you will find that
|
||||
* the compiler complains about an undefined reference to iu_tx(). If you,
|
||||
* however, link against libiu as well as the osmo-iuh libs (etc.), iu_tx() is
|
||||
* available. A unit test may instead simply implement a dummy iu_tx() function
|
||||
* and not link against osmo-iuh.
|
||||
*/
|
||||
|
||||
/* Each main linkage must implement this function (see comment above). */
|
||||
extern int iu_tx(struct msgb *msg, uint8_t sapi);
|
||||
|
||||
/* So far this is a dummy implemented in libmsc/a_iface.c. When A-interface
|
||||
* gets implemented, it should be in a separate lib (like libiu), this function
|
||||
* should move there, and the following comment should remain here: "
|
||||
* Each main linkage must implement this function (see comment above).
|
||||
* " */
|
||||
extern int a_tx(struct msgb *msg);
|
||||
|
||||
int msc_tx_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg);
|
||||
|
||||
78
openbsc/include/openbsc/oap.h
Normal file
78
openbsc/include/openbsc/oap.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Osmocom Authentication Protocol API */
|
||||
|
||||
/* (C) 2015 by Sysmocom s.f.m.c. GmbH
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Neels Hofmeyr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct msgb;
|
||||
struct osmo_oap_message;
|
||||
|
||||
/* This is the config part for vty. It is essentially copied in oap_state,
|
||||
* where values are copied over once the config is considered valid. */
|
||||
struct oap_config {
|
||||
uint16_t client_id;
|
||||
int secret_k_present;
|
||||
uint8_t secret_k[16];
|
||||
int secret_opc_present;
|
||||
uint8_t secret_opc[16];
|
||||
};
|
||||
|
||||
/* The runtime state of the OAP client. client_id and the secrets are in fact
|
||||
* duplicated from oap_config, so that a separate validation of the config data
|
||||
* is possible, and so that only a struct oap_state* is passed around. */
|
||||
struct oap_state {
|
||||
enum {
|
||||
OAP_UNINITIALIZED = 0, /* just allocated. */
|
||||
OAP_DISABLED, /* disabled by config. */
|
||||
OAP_INITIALIZED, /* enabled, config is valid. */
|
||||
OAP_REQUESTED_CHALLENGE,
|
||||
OAP_SENT_CHALLENGE_RESULT,
|
||||
OAP_REGISTERED
|
||||
} state;
|
||||
uint16_t client_id;
|
||||
uint8_t secret_k[16];
|
||||
uint8_t secret_opc[16];
|
||||
int registration_failures;
|
||||
};
|
||||
|
||||
/* From config, initialize state. Return 0 on success. */
|
||||
int oap_init(struct oap_config *config, struct oap_state *state);
|
||||
|
||||
/* Construct an OAP registration message and return in *msg_tx. Use
|
||||
* state->client_id and update state->state.
|
||||
* Return 0 on success, or a negative value on error.
|
||||
* If an error is returned, *msg_tx is guaranteed to be NULL. */
|
||||
int oap_register(struct oap_state *state, struct msgb **msg_tx);
|
||||
|
||||
/* Decode and act on a received OAP message msg_rx. Update state->state. If a
|
||||
* non-NULL pointer is returned in *msg_tx, that msgb should be sent to the OAP
|
||||
* server (and freed) by the caller. The received msg_rx is not freed.
|
||||
* Return 0 on success, or a negative value on error.
|
||||
* If an error is returned, *msg_tx is guaranteed to be NULL. */
|
||||
int oap_handle(struct oap_state *state, const struct msgb *msg_rx, struct msgb **msg_tx);
|
||||
|
||||
/* Allocate a msgb and in it, return the encoded oap_msg. Return NULL on
|
||||
* error. (Like oap_encode(), but also allocates a msgb.)
|
||||
* About the name: the idea is do_something(oap_encoded(my_struct)) */
|
||||
struct msgb *oap_encoded(const struct osmo_oap_message *oap_msg);
|
||||
|
||||
70
openbsc/include/openbsc/oap_messages.h
Normal file
70
openbsc/include/openbsc/oap_messages.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Osmocom Authentication Protocol message encoder/decoder */
|
||||
|
||||
/* (C) 2015 by Sysmocom s.f.m.c. GmbH
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Neels Hofmeyr
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
||||
/* Some numbers are out of sequence because (so far) they match gprs_gsup_iei.
|
||||
*/
|
||||
enum oap_iei {
|
||||
OAP_CAUSE_IE = 0x02,
|
||||
OAP_RAND_IE = 0x20,
|
||||
OAP_AUTN_IE = 0x23,
|
||||
OAP_XRES_IE = 0x24,
|
||||
OAP_AUTS_IE = 0x25,
|
||||
OAP_CLIENT_ID_IE = 0x30,
|
||||
};
|
||||
|
||||
enum osmo_oap_message_type {
|
||||
OAP_MSGT_REGISTER_REQUEST = 0b00000100,
|
||||
OAP_MSGT_REGISTER_ERROR = 0b00000101,
|
||||
OAP_MSGT_REGISTER_RESULT = 0b00000110,
|
||||
|
||||
OAP_MSGT_CHALLENGE_REQUEST = 0b00001000,
|
||||
OAP_MSGT_CHALLENGE_ERROR = 0b00001001,
|
||||
OAP_MSGT_CHALLENGE_RESULT = 0b00001010,
|
||||
|
||||
OAP_MSGT_SYNC_REQUEST = 0b00001100,
|
||||
OAP_MSGT_SYNC_ERROR = 0b00001101,
|
||||
OAP_MSGT_SYNC_RESULT = 0b00001110,
|
||||
};
|
||||
|
||||
struct osmo_oap_message {
|
||||
enum osmo_oap_message_type message_type;
|
||||
enum gsm48_gmm_cause cause;
|
||||
uint16_t client_id;
|
||||
int rand_present;
|
||||
uint8_t rand[16];
|
||||
int autn_present;
|
||||
uint8_t autn[16];
|
||||
int xres_present;
|
||||
uint8_t xres[8];
|
||||
int auts_present;
|
||||
uint8_t auts[16];
|
||||
};
|
||||
|
||||
int osmo_oap_decode(struct osmo_oap_message *oap_msg,
|
||||
const uint8_t *data, size_t data_len);
|
||||
void osmo_oap_encode(struct msgb *msg, const struct osmo_oap_message *oap_msg);
|
||||
|
||||
@@ -59,13 +59,16 @@ struct osmo_msc_data {
|
||||
|
||||
/* Connection data */
|
||||
char *bsc_token;
|
||||
uint8_t bsc_key[16];
|
||||
uint8_t bsc_key_present;
|
||||
|
||||
int ping_timeout;
|
||||
int pong_timeout;
|
||||
struct osmo_timer_list ping_timer;
|
||||
struct osmo_timer_list pong_timer;
|
||||
int advanced_ping;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
int core_ncc;
|
||||
int core_mnc;
|
||||
int core_mcc;
|
||||
int core_lac;
|
||||
int core_ci;
|
||||
|
||||
@@ -14,6 +14,8 @@ int osmux_init(int role, struct mgcp_config *cfg);
|
||||
int osmux_enable_endpoint(struct mgcp_endpoint *endp, int role,
|
||||
struct in_addr *addr, uint16_t port);
|
||||
void osmux_disable_endpoint(struct mgcp_endpoint *endp);
|
||||
void osmux_allocate_cid(struct mgcp_endpoint *endp);
|
||||
void osmux_release_cid(struct mgcp_endpoint *endp);
|
||||
|
||||
int osmux_xfrm_to_rtp(struct mgcp_endpoint *endp, int type, char *buf, int rc);
|
||||
int osmux_xfrm_to_osmux(int type, char *buf, int rc, struct mgcp_endpoint *endp);
|
||||
@@ -22,6 +24,7 @@ int osmux_send_dummy(struct mgcp_endpoint *endp);
|
||||
|
||||
int osmux_get_cid(void);
|
||||
void osmux_put_cid(uint8_t osmux_cid);
|
||||
int osmux_used_cid(void);
|
||||
|
||||
enum osmux_state {
|
||||
OSMUX_STATE_DISABLED = 0,
|
||||
@@ -29,4 +32,10 @@ enum osmux_state {
|
||||
OSMUX_STATE_ENABLED,
|
||||
};
|
||||
|
||||
enum osmux_usage {
|
||||
OSMUX_USAGE_OFF = 0,
|
||||
OSMUX_USAGE_ON = 1,
|
||||
OSMUX_USAGE_ONLY = 2,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
#ifndef _REST_OCTETS_H
|
||||
#define _REST_OCTETS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
|
||||
#define SI2Q_MAX_LEN 160
|
||||
#define SI2Q_MIN_LEN 18
|
||||
|
||||
/* generate SI1 rest octets */
|
||||
int rest_octets_si1(uint8_t *data, uint8_t *nch_pos, int is1800_net);
|
||||
int rest_octets_si2quater(uint8_t *data, const struct osmo_earfcn_si2q *e,
|
||||
const uint16_t *u, const uint16_t *sc, size_t u_len);
|
||||
|
||||
struct gsm48_si_selection_params {
|
||||
uint16_t penalty_time:5,
|
||||
@@ -43,7 +50,8 @@ struct gsm48_si_ro_info {
|
||||
present:1;
|
||||
} scheduling;
|
||||
struct gsm48_si3_gprs_ind gprs_ind;
|
||||
|
||||
/* SI 3 specific */
|
||||
uint8_t si2quater_indicator;
|
||||
/* SI 4 specific */
|
||||
struct gsm48_lsa_params lsa_params;
|
||||
uint16_t cell_id;
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/oap.h>
|
||||
|
||||
#include <ares.h>
|
||||
|
||||
struct gprs_gsup_client;
|
||||
struct hostent;
|
||||
|
||||
enum sgsn_auth_policy {
|
||||
SGSN_AUTH_POLICY_OPEN,
|
||||
@@ -16,6 +20,11 @@ enum sgsn_auth_policy {
|
||||
SGSN_AUTH_POLICY_REMOTE
|
||||
};
|
||||
|
||||
struct sgsn_cdr {
|
||||
char *filename;
|
||||
int interval;
|
||||
};
|
||||
|
||||
struct sgsn_config {
|
||||
/* parsed from config file */
|
||||
|
||||
@@ -33,6 +42,28 @@ struct sgsn_config {
|
||||
|
||||
int require_authentication;
|
||||
int require_update_location;
|
||||
|
||||
/* CDR configuration */
|
||||
struct sgsn_cdr cdr;
|
||||
|
||||
struct {
|
||||
int T3312;
|
||||
int T3322;
|
||||
int T3350;
|
||||
int T3360;
|
||||
int T3370;
|
||||
int T3313;
|
||||
int T3314;
|
||||
int T3316;
|
||||
int T3385;
|
||||
int T3386;
|
||||
int T3395;
|
||||
int T3397;
|
||||
} timers;
|
||||
|
||||
int dynamic_lookup;
|
||||
|
||||
struct oap_config oap;
|
||||
};
|
||||
|
||||
struct sgsn_instance {
|
||||
@@ -50,6 +81,12 @@ struct sgsn_instance {
|
||||
struct gprs_gsup_client *gsup_client;
|
||||
/* LLME inactivity timer */
|
||||
struct osmo_timer_list llme_timer;
|
||||
|
||||
/* c-ares event loop integration */
|
||||
struct osmo_timer_list ares_timer;
|
||||
struct llist_head ares_fds;
|
||||
ares_channel ares_channel;
|
||||
struct ares_addr_node *ares_servers;
|
||||
};
|
||||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
@@ -85,4 +122,17 @@ int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi
|
||||
int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle,
|
||||
uint8_t *hdr, uint16_t len);
|
||||
|
||||
|
||||
/*
|
||||
* CDR related functionality
|
||||
*/
|
||||
int sgsn_cdr_init(struct sgsn_instance *sgsn);
|
||||
|
||||
|
||||
/*
|
||||
* C-ARES related functionality
|
||||
*/
|
||||
int sgsn_ares_init(struct sgsn_instance *sgsn);
|
||||
int sgsn_ares_query(struct sgsn_instance *sgsm, const char *name, ares_host_callback cb, void *data);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Generic signalling/notification infrastructure */
|
||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
/* (C) 2009-2010, 2015 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
@@ -46,6 +46,7 @@ enum signal_subsystems {
|
||||
SS_MSC,
|
||||
SS_HO,
|
||||
SS_CCCH,
|
||||
SS_SGSN,
|
||||
};
|
||||
|
||||
/* SS_PAGING signals */
|
||||
@@ -141,7 +142,6 @@ struct gsm_subscriber;
|
||||
|
||||
struct paging_signal_data {
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
int paging_result;
|
||||
|
||||
@@ -241,4 +241,22 @@ struct ccch_signal_data {
|
||||
uint16_t rach_access_count;
|
||||
};
|
||||
|
||||
/* GPRS SGSN signals SS_SGSN */
|
||||
enum signal_sgsn {
|
||||
S_SGSN_ATTACH,
|
||||
S_SGSN_DETACH,
|
||||
S_SGSN_UPDATE,
|
||||
S_SGSN_PDP_ACT,
|
||||
S_SGSN_PDP_DEACT,
|
||||
S_SGSN_PDP_TERMINATE,
|
||||
S_SGSN_PDP_FREE,
|
||||
S_SGSN_MM_FREE,
|
||||
};
|
||||
|
||||
struct sgsn_mm_ctx;
|
||||
struct sgsn_signal_data {
|
||||
struct sgsn_mm_ctx *mm;
|
||||
struct sgsn_pdp_ctx *pdp; /* non-NULL for PDP_ACT, PDP_DEACT, PDP_FREE */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int smpp_openbsc_init(void *ctx, uint16_t port);
|
||||
void smpp_openbsc_set_net(struct gsm_network *net);
|
||||
int smpp_openbsc_alloc_init(void *ctx);
|
||||
int smpp_openbsc_start(struct gsm_network *net);
|
||||
|
||||
@@ -6,5 +6,13 @@
|
||||
struct gsm_bts;
|
||||
|
||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
||||
|
||||
uint16_t encode_fdd(uint16_t scramble, bool diversity);
|
||||
unsigned uarfcn_size(const uint16_t *u, const uint16_t *sc, size_t u_len);
|
||||
unsigned earfcn_size(const struct osmo_earfcn_si2q *e);
|
||||
unsigned range1024_p(unsigned n);
|
||||
unsigned range512_q(unsigned m);
|
||||
bool si2q_size_check(const struct gsm_bts *bts);
|
||||
int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);
|
||||
int bts_uarfcn_add(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble,
|
||||
bool diversity);
|
||||
#endif
|
||||
|
||||
@@ -32,17 +32,22 @@ enum bsc_vty_node {
|
||||
TRUNK_NODE,
|
||||
PGROUP_NODE,
|
||||
MNCC_INT_NODE,
|
||||
NITB_NODE,
|
||||
BSC_NODE,
|
||||
SMPP_NODE,
|
||||
SMPP_ESME_NODE,
|
||||
GTPHUB_NODE,
|
||||
CSCN_NODE,
|
||||
};
|
||||
|
||||
extern int bsc_vty_is_config_node(struct vty *vty, int node);
|
||||
extern void bsc_replace_string(void *ctx, char **dst, const char *newstr);
|
||||
|
||||
struct log_info;
|
||||
int bsc_vty_init(const struct log_info *cat);
|
||||
int bsc_vty_init(const struct log_info *cat, struct gsm_network *network);
|
||||
int bsc_vty_init_extra(void);
|
||||
|
||||
void cscn_vty_init(void);
|
||||
|
||||
struct gsm_network *gsmnet_from_vty(struct vty *vty);
|
||||
|
||||
#endif
|
||||
|
||||
23
openbsc/include/openbsc/xsc.h
Normal file
23
openbsc/include/openbsc/xsc.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct msgb;
|
||||
struct gsm_network;
|
||||
struct log_info;
|
||||
struct ctrl_handle;
|
||||
|
||||
typedef int (*mncc_recv_cb_t)(struct gsm_network *, struct msgb *);
|
||||
|
||||
#define MAX_A5_KEY_LEN (128/8)
|
||||
|
||||
struct gsm_encr {
|
||||
uint8_t alg_id;
|
||||
uint8_t key_len;
|
||||
uint8_t key[MAX_A5_KEY_LEN];
|
||||
};
|
||||
|
||||
extern struct gsm_network *vty_global_gsm_network;
|
||||
|
||||
int xsc_vty_init(struct gsm_network *network);
|
||||
|
||||
@@ -31,10 +31,12 @@ app_configs = {
|
||||
"osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg"],
|
||||
"nat": ["doc/examples/osmo-bsc_nat/osmo-bsc_nat.cfg"],
|
||||
"mgcp": ["doc/examples/osmo-bsc_mgcp/mgcp.cfg"],
|
||||
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg"],
|
||||
"gbproxy": ["doc/examples/osmo-gbproxy/osmo-gbproxy.cfg",
|
||||
"doc/examples/osmo-gbproxy/osmo-gbproxy-legacy.cfg"],
|
||||
"sgsn": ["doc/examples/osmo-sgsn/osmo-sgsn.cfg"],
|
||||
"nitb": ["doc/examples/osmo-nitb/nanobts/openbsc-multitrx.cfg",
|
||||
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"]
|
||||
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"],
|
||||
"gtphub": ["doc/examples/osmo-gtphub/osmo-gtphub-1iface.cfg"]
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +45,11 @@ apps = [(4242, "src/osmo-bsc/osmo-bsc", "OsmoBSC", "osmo-bsc"),
|
||||
(4243, "src/osmo-bsc_mgcp/osmo-bsc_mgcp", "OpenBSC MGCP", "mgcp"),
|
||||
(4246, "src/gprs/osmo-gbproxy", "OsmoGbProxy", "gbproxy"),
|
||||
(4245, "src/gprs/osmo-sgsn", "OsmoSGSN", "sgsn"),
|
||||
(4242, "src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb")
|
||||
(4242, "src/osmo-nitb/osmo-nitb", "OpenBSC", "nitb"),
|
||||
(4253, "src/gprs/osmo-gtphub", "OsmoGTPhub", "gtphub")
|
||||
]
|
||||
|
||||
vty_command = ["./src/osmo-nitb/osmo-nitb", "-c",
|
||||
"doc/examples/osmo-nitb/nanobts/openbsc.cfg"]
|
||||
|
||||
vty_app = apps[-1]
|
||||
vty_app = apps[5] # reference apps[] entry for osmo-nitb
|
||||
|
||||
@@ -2,7 +2,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(COVERAGE_LDFLAGS)
|
||||
|
||||
SUBDIRS = libcommon libmgcp libbsc libmsc libtrau libfilter osmo-nitb osmo-bsc_mgcp utils ipaccess gprs
|
||||
SUBDIRS = libcommon libmgcp libbsc libiu libmsc libtrau libfilter libxsc osmo-cscn osmo-bsc_mgcp utils ipaccess gprs
|
||||
|
||||
# Conditional modules
|
||||
if BUILD_NAT
|
||||
|
||||
@@ -1,30 +1,49 @@
|
||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
|
||||
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS)
|
||||
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
|
||||
$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS) $(LIBGTP_CFLAGS) \
|
||||
$(LIBASN1C_CFLAGS) $(LIBOSMOSIGTRAN_CFLAGS) $(LIBOSMORANAP_CFLAGS)
|
||||
|
||||
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
|
||||
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
|
||||
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS) -ltalloc -lm
|
||||
|
||||
noinst_HEADERS = gprs_sndcp.h
|
||||
|
||||
if HAVE_LIBGTP
|
||||
bin_PROGRAMS = osmo-gbproxy osmo-sgsn
|
||||
else
|
||||
bin_PROGRAMS = osmo-gbproxy
|
||||
|
||||
if HAVE_LIBGTP
|
||||
if HAVE_LIBCARES
|
||||
bin_PROGRAMS += osmo-sgsn osmo-gtphub
|
||||
endif
|
||||
endif
|
||||
|
||||
IUHDIR = $(top_srcdir)/../../osmo-iuh
|
||||
|
||||
osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
|
||||
gb_proxy_patch.c gb_proxy_tlli.c gb_proxy_peer.c \
|
||||
gprs_gb_parse.c gprs_llc_parse.c crc24.c gprs_utils.c
|
||||
osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
|
||||
$(OSMO_LIBS) -lrt
|
||||
$(OSMO_LIBS) $(LIBCRYPTO_LIBS) -lrt
|
||||
|
||||
osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
|
||||
sgsn_main.c sgsn_vty.c sgsn_libgtp.c \
|
||||
gprs_llc.c gprs_llc_parse.c gprs_llc_vty.c crc24.c \
|
||||
sgsn_ctrl.c sgsn_auth.c gprs_subscriber.c \
|
||||
gprs_gsup_messages.c gprs_utils.c gprs_gsup_client.c \
|
||||
gsm_04_08_gprs.c
|
||||
gprs_utils.c gprs_gsup_client.c \
|
||||
gsm_04_08_gprs.c sgsn_cdr.c sgsn_ares.c \
|
||||
oap.c oap_messages.c
|
||||
|
||||
osmo_sgsn_LDADD = \
|
||||
$(top_builddir)/src/libcommon/libcommon.a \
|
||||
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) -lrt
|
||||
$(top_builddir)/src/libiu/libiu.a \
|
||||
-lgtp $(OSMO_LIBS) $(LIBOSMOABIS_LIBS) $(LIBCARES_LIBS) \
|
||||
$(LIBCRYPTO_LIBS) -lrt \
|
||||
$(LIBOSMOSIGTRAN_LIBS) $(LIBOSMORANAP_LIBS) $(LIBASN1C_LIBS)
|
||||
|
||||
osmo_gtphub_SOURCES = gtphub_main.c gtphub.c gtphub_sock.c gtphub_ares.c \
|
||||
gtphub_vty.c sgsn_ares.c gprs_utils.c
|
||||
osmo_gtphub_LDADD = \
|
||||
$(top_builddir)/src/libcommon/libcommon.a \
|
||||
-lgtp $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
|
||||
$(LIBCARES_LIBS) -lrt
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
@@ -47,9 +48,11 @@
|
||||
|
||||
#include <openbsc/gprs_llc.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
static const struct rate_ctr_desc global_ctr_description[] = {
|
||||
{ "inv-bvci", "Invalid BVC Identifier " },
|
||||
{ "inv-lai", "Invalid Location Area Identifier" },
|
||||
@@ -70,6 +73,7 @@ static const struct rate_ctr_group_desc global_ctrg_desc = {
|
||||
.group_description = "GBProxy Global Statistics",
|
||||
.num_ctr = ARRAY_SIZE(global_ctr_description),
|
||||
.ctr_desc = global_ctr_description,
|
||||
.class_id = OSMO_STATS_CLASS_GLOBAL,
|
||||
};
|
||||
|
||||
static int gbprox_relay2peer(struct msgb *old_msg, struct gbproxy_peer *peer,
|
||||
@@ -232,7 +236,11 @@ uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
|
||||
bss_ptmsi = sgsn_ptmsi;
|
||||
} else {
|
||||
do {
|
||||
bss_ptmsi = rand_r(&peer->cfg->bss_ptmsi_state);
|
||||
if (RAND_bytes((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)) != 1) {
|
||||
bss_ptmsi = GSM_RESERVED_TMSI;
|
||||
break;
|
||||
}
|
||||
|
||||
bss_ptmsi = bss_ptmsi | 0xC0000000;
|
||||
|
||||
if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi))
|
||||
@@ -265,7 +273,11 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
|
||||
} else {
|
||||
do {
|
||||
/* create random TLLI, 0b01111xxx... */
|
||||
sgsn_tlli = rand_r(&peer->cfg->sgsn_tlli_state);
|
||||
if (RAND_bytes((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)) != 1) {
|
||||
sgsn_tlli = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000;
|
||||
|
||||
if (gbproxy_link_info_by_any_sgsn_tlli(peer, sgsn_tlli))
|
||||
@@ -381,7 +393,7 @@ static void gbproxy_acquire_imsi(struct gbproxy_peer *peer,
|
||||
struct msgb *idreq_msg;
|
||||
|
||||
/* Send IDENT REQ */
|
||||
idreq_msg = gsm48_msgb_alloc();
|
||||
idreq_msg = gsm48_msgb_alloc_name("GSM 04.08 ACQ IMSI");
|
||||
gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI);
|
||||
gbproxy_gsm48_to_peer(peer, link_info, bvci, idreq_msg);
|
||||
}
|
||||
@@ -393,7 +405,7 @@ static void gbproxy_tx_detach_acc(struct gbproxy_peer *peer,
|
||||
struct msgb *detacc_msg;
|
||||
|
||||
/* Send DETACH ACC */
|
||||
detacc_msg = gsm48_msgb_alloc();
|
||||
detacc_msg = gsm48_msgb_alloc_name("GSM 04.08 DET ACC");
|
||||
gprs_put_mo_detach_acc(detacc_msg);
|
||||
gbproxy_gsm48_to_peer(peer, link_info, bvci, detacc_msg);
|
||||
}
|
||||
@@ -450,8 +462,8 @@ static int gbproxy_imsi_acquisition(struct gbproxy_peer *peer,
|
||||
if (link_info->imsi_acq_pending && link_info->imsi_len > 0) {
|
||||
int is_ident_resp =
|
||||
parse_ctx->g48_hdr &&
|
||||
parse_ctx->g48_hdr->proto_discr == GSM48_PDISC_MM_GPRS &&
|
||||
parse_ctx->g48_hdr->msg_type == GSM48_MT_GMM_ID_RESP;
|
||||
gsm48_hdr_pdisc(parse_ctx->g48_hdr) == GSM48_PDISC_MM_GPRS &&
|
||||
gsm48_hdr_msg_type(parse_ctx->g48_hdr) == GSM48_MT_GMM_ID_RESP;
|
||||
|
||||
/* The IMSI is now available */
|
||||
gbproxy_flush_stored_messages(peer, msg, now, link_info,
|
||||
@@ -581,6 +593,27 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
|
||||
case GSM48_MT_GMM_ATTACH_REQ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_DETACH_REQ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_REQS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_ATTACH_COMPL:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_COMPLS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_RA_UPD_REQ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REQS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_RA_UPD_COMPL:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_COMPLS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_STATUS:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_BSS]);
|
||||
break;
|
||||
case GSM48_MT_GSM_ACT_PDP_REQ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REQS]);
|
||||
break;
|
||||
case GSM48_MT_GSM_DEACT_PDP_REQ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_REQS]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -666,9 +699,33 @@ static void gbprox_process_bssgp_dl(struct gbproxy_config *cfg,
|
||||
|
||||
if (parse_ctx.g48_hdr) {
|
||||
switch (parse_ctx.g48_hdr->msg_type) {
|
||||
case GSM48_MT_GMM_ATTACH_ACK:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_ACKS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_ATTACH_REJ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REJS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_DETACH_ACK:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_DETACH_ACKS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_RA_UPD_ACK:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_ACKS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_RA_UPD_REJ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_RA_UPD_REJS]);
|
||||
break;
|
||||
case GSM48_MT_GMM_STATUS:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_GMM_STATUS_SGSN]);
|
||||
break;
|
||||
case GSM48_MT_GSM_ACT_PDP_ACK:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_ACKS]);
|
||||
break;
|
||||
case GSM48_MT_GSM_ACT_PDP_REJ:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_ACT_REJS]);
|
||||
break;
|
||||
case GSM48_MT_GSM_DEACT_PDP_ACK:
|
||||
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_PDP_DEACT_ACKS]);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -1365,8 +1422,6 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
|
||||
INIT_LLIST_HEAD(&cfg->bts_peers);
|
||||
cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
|
||||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
cfg->bss_ptmsi_state = tp.tv_sec + tp.tv_nsec;
|
||||
cfg->sgsn_tlli_state = tp.tv_sec - tp.tv_nsec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/select.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
@@ -48,6 +49,7 @@
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <osmocom/vty/logging.h>
|
||||
#include <osmocom/vty/stats.h>
|
||||
#include <osmocom/vty/ports.h>
|
||||
|
||||
#include "../../bscconfig.h"
|
||||
@@ -189,7 +191,7 @@ static void handle_options(int argc, char **argv)
|
||||
|
||||
extern void *tall_msgb_ctx;
|
||||
|
||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
|
||||
extern int bsc_vty_go_parent(struct vty *vty);
|
||||
|
||||
static struct vty_app_info vty_info = {
|
||||
.name = "OsmoGbProxy",
|
||||
@@ -242,15 +244,13 @@ int main(int argc, char **argv)
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
vty_init(&vty_info);
|
||||
logging_vty_add_cmds(&gprs_log_info);
|
||||
osmo_stats_vty_add_cmds(&gprs_log_info);
|
||||
gbproxy_vty_init();
|
||||
|
||||
handle_options(argc, argv);
|
||||
|
||||
rate_ctr_init(tall_bsc_ctx);
|
||||
|
||||
rc = telnet_init(tall_bsc_ctx, &dummy_network, OSMO_VTY_PORT_GBPROXY);
|
||||
if (rc < 0)
|
||||
exit(1);
|
||||
osmo_stats_init(tall_bsc_ctx);
|
||||
|
||||
bssgp_nsi = gprs_ns_instantiate(&proxy_ns_cb, tall_bsc_ctx);
|
||||
if (!bssgp_nsi) {
|
||||
@@ -270,6 +270,14 @@ int main(int argc, char **argv)
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* start telnet after reading config for vty_get_bind_addr() */
|
||||
LOGP(DGPRS, LOGL_NOTICE, "VTY at %s %d\n",
|
||||
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
|
||||
rc = telnet_init_dynif(tall_bsc_ctx, &dummy_network,
|
||||
vty_get_bind_addr(), OSMO_VTY_PORT_GBPROXY);
|
||||
if (rc < 0)
|
||||
exit(1);
|
||||
|
||||
if (!gprs_nsvc_by_nsei(gbcfg.nsi, gbcfg.nsip_sgsn_nsei)) {
|
||||
LOGP(DGPRS, LOGL_FATAL, "You cannot proxy to NSEI %u "
|
||||
"without creating that NSEI before\n",
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <openbsc/gprs_utils.h>
|
||||
#include <openbsc/gprs_gb_parse.h>
|
||||
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_data_shared.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
#include <osmocom/gprs/protocol/gsm_08_18.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
|
||||
#include <string.h>
|
||||
@@ -50,15 +50,33 @@ static const struct rate_ctr_desc peer_ctr_description[] = {
|
||||
{ "mod-err", "Patch error: other " },
|
||||
{ "attach-reqs", "Attach Request count " },
|
||||
{ "attach-rejs", "Attach Reject count " },
|
||||
{ "attach-acks", "Attach Accept count " },
|
||||
{ "attach-cpls", "Attach Completed count " },
|
||||
{ "ra-upd-reqs", "RoutingArea Update Request count" },
|
||||
{ "ra-upd-rejs", "RoutingArea Update Reject count " },
|
||||
{ "ra-upd-acks", "RoutingArea Update Accept count " },
|
||||
{ "ra-upd-cpls", "RoutingArea Update Compltd count" },
|
||||
{ "gmm-status", "GMM Status count (BSS)" },
|
||||
{ "gmm-status", "GMM Status count (SGSN)" },
|
||||
{ "detach-reqs", "Detach Request count " },
|
||||
{ "detach-acks", "Detach Accept count " },
|
||||
{ "pdp-act-reqs", "PDP Activation Request count " },
|
||||
{ "pdp-act-rejs", "PDP Activation Reject count " },
|
||||
{ "pdp-act-acks", "PDP Activation Accept count " },
|
||||
{ "pdp-deact-reqs","PDP Deactivation Request count " },
|
||||
{ "pdp-deact-acks","PDP Deactivation Accept count " },
|
||||
{ "tlli-unknown", "TLLI from SGSN unknown " },
|
||||
{ "tlli-cache", "TLLI cache size " },
|
||||
};
|
||||
|
||||
osmo_static_assert(ARRAY_SIZE(peer_ctr_description) == GBPROX_PEER_CTR_LAST, everything_described);
|
||||
|
||||
static const struct rate_ctr_group_desc peer_ctrg_desc = {
|
||||
.group_name_prefix = "gbproxy.peer",
|
||||
.group_description = "GBProxy Peer Statistics",
|
||||
.num_ctr = ARRAY_SIZE(peer_ctr_description),
|
||||
.ctr_desc = peer_ctr_description,
|
||||
.class_id = OSMO_STATS_CLASS_PEER,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -746,6 +746,55 @@ DEFUN(delete_gb_link, delete_gb_link_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* legacy commands to provide an upgrade path from "broken" releases
|
||||
* or pre-releases
|
||||
*/
|
||||
DEFUN_DEPRECATED(cfg_gbproxy_broken_apn_match,
|
||||
cfg_gbproxy_broken_apn_match_cmd,
|
||||
"core-access-point-name none match-imsi .REGEXP",
|
||||
GBPROXY_CORE_APN_STR GBPROXY_MATCH_IMSI_STR "Remove APN\n"
|
||||
"Patch MS related information elements on match only\n"
|
||||
"Route to the secondary SGSN on match only\n"
|
||||
"Regular expression for the IMSI match\n")
|
||||
{
|
||||
const char *filter = argv[0];
|
||||
const char *err_msg = NULL;
|
||||
struct gbproxy_match *match;
|
||||
enum gbproxy_match_id match_id = get_string_value(match_ids, "patching");
|
||||
|
||||
/* apply APN none */
|
||||
set_core_apn(vty, "");
|
||||
|
||||
/* do the matching... with copy and paste */
|
||||
OSMO_ASSERT(match_id >= GBPROX_MATCH_PATCHING &&
|
||||
match_id < GBPROX_MATCH_LAST);
|
||||
match = &g_cfg->matches[match_id];
|
||||
|
||||
if (gbproxy_set_patch_filter(match, filter, &err_msg) != 0) {
|
||||
vty_out(vty, "Match expression invalid: %s%s",
|
||||
err_msg, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
g_cfg->acquire_imsi = 1;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define GBPROXY_TLLI_LIST_STR "Set TLLI list parameters\n"
|
||||
#define GBPROXY_MAX_LEN_STR "Limit list length\n"
|
||||
DEFUN_DEPRECATED(cfg_gbproxy_depr_tlli_list_max_len,
|
||||
cfg_gbproxy_depr_tlli_list_max_len_cmd,
|
||||
"tlli-list max-length <1-99999>",
|
||||
GBPROXY_TLLI_LIST_STR GBPROXY_MAX_LEN_STR
|
||||
"Maximum number of TLLIs in the list\n")
|
||||
{
|
||||
g_cfg->tlli_max_len = atoi(argv[0]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int gbproxy_vty_init(void)
|
||||
{
|
||||
install_element_ve(&show_gbproxy_cmd);
|
||||
@@ -780,6 +829,10 @@ int gbproxy_vty_init(void)
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_age_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_link_list_no_max_len_cmd);
|
||||
|
||||
/* broken or deprecated to allow an upgrade path */
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_broken_apn_match_cmd);
|
||||
install_element(GBPROXY_NODE, &cfg_gbproxy_depr_tlli_list_max_len_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
*/
|
||||
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
||||
#include <openbsc/gprs_gb_parse.h>
|
||||
|
||||
#include <openbsc/gprs_utils.h>
|
||||
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
@@ -38,7 +38,7 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
|
||||
parse_ctx->llc_msg_name = "ATTACH_REQ";
|
||||
|
||||
/* Skip MS network capability */
|
||||
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
value_len < 1 || value_len > 8)
|
||||
/* invalid */
|
||||
return 0;
|
||||
@@ -46,10 +46,10 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
|
||||
/* Skip Attach type */
|
||||
/* Skip Ciphering key sequence number */
|
||||
/* Skip DRX parameter */
|
||||
gprs_shift_v_fixed(&data, &data_len, 3, NULL);
|
||||
osmo_shift_v_fixed(&data, &data_len, 3, NULL);
|
||||
|
||||
/* Get Mobile identity */
|
||||
if (gprs_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
|
||||
if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
|
||||
value_len < 5 || value_len > 8)
|
||||
/* invalid */
|
||||
return 0;
|
||||
@@ -61,7 +61,7 @@ static int gprs_gb_parse_gmm_attach_req(uint8_t *data, size_t data_len,
|
||||
parse_ctx->imsi_len = value_len;
|
||||
}
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->old_raid_enc = value;
|
||||
@@ -82,21 +82,21 @@ static int gprs_gb_parse_gmm_attach_ack(uint8_t *data, size_t data_len,
|
||||
/* Skip Periodic RA update timer */
|
||||
/* Skip Radio priority for SMS */
|
||||
/* Skip Spare half octet */
|
||||
gprs_shift_v_fixed(&data, &data_len, 3, NULL);
|
||||
osmo_shift_v_fixed(&data, &data_len, 3, NULL);
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->raid_enc = value;
|
||||
|
||||
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
|
||||
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
|
||||
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
|
||||
|
||||
/* Skip Negotiated READY timer value (GPRS timer, opt, TV, length 2) */
|
||||
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
|
||||
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_TIMER_READY, 1, NULL);
|
||||
|
||||
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
|
||||
if (gprs_match_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
|
||||
if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
|
||||
&value, &value_len) > 0 &&
|
||||
gprs_is_mi_tmsi(value, value_len))
|
||||
parse_ctx->new_ptmsi_enc = value + 1;
|
||||
@@ -111,7 +111,7 @@ static int gprs_gb_parse_gmm_attach_rej(uint8_t *data, size_t data_len,
|
||||
parse_ctx->llc_msg_name = "ATTACH_REJ";
|
||||
|
||||
/* GMM cause */
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->invalidate_tlli = 1;
|
||||
@@ -132,7 +132,7 @@ static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len,
|
||||
|
||||
/* Skip spare half octet */
|
||||
/* Get Detach type */
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
/* invalid */
|
||||
return 0;
|
||||
|
||||
@@ -150,7 +150,7 @@ static int gprs_gb_parse_gmm_detach_req(uint8_t *data, size_t data_len,
|
||||
parse_ctx->invalidate_tlli = 1;
|
||||
|
||||
/* Get P-TMSI (Mobile identity), see GSM 24.008, 9.4.5.2 */
|
||||
if (gprs_match_tlv(&data, &data_len,
|
||||
if (osmo_match_shift_tlv(&data, &data_len,
|
||||
GSM48_IE_GMM_ALLOC_PTMSI, &value, &value_len) > 0)
|
||||
{
|
||||
if (gprs_is_mi_tmsi(value, value_len))
|
||||
@@ -170,9 +170,9 @@ static int gprs_gb_parse_gmm_ra_upd_req(uint8_t *data, size_t data_len,
|
||||
|
||||
/* Skip Update type */
|
||||
/* Skip GPRS ciphering key sequence number */
|
||||
gprs_shift_v_fixed(&data, &data_len, 1, NULL);
|
||||
osmo_shift_v_fixed(&data, &data_len, 1, NULL);
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->old_raid_enc = value;
|
||||
@@ -190,14 +190,14 @@ static int gprs_gb_parse_gmm_ra_upd_rej(uint8_t *data, size_t data_len,
|
||||
parse_ctx->llc_msg_name = "RA_UPD_REJ";
|
||||
|
||||
/* GMM cause */
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
cause = value[0];
|
||||
|
||||
/* Force to standby, 1/2 */
|
||||
/* spare bits, 1/2 */
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 1, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
force_standby = (value[0] & 0x07) == 0x01;
|
||||
@@ -221,18 +221,18 @@ static int gprs_gb_parse_gmm_ra_upd_ack(uint8_t *data, size_t data_len,
|
||||
/* Skip Force to standby */
|
||||
/* Skip Update result */
|
||||
/* Skip Periodic RA update timer */
|
||||
gprs_shift_v_fixed(&data, &data_len, 2, NULL);
|
||||
osmo_shift_v_fixed(&data, &data_len, 2, NULL);
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->raid_enc = value;
|
||||
|
||||
/* Skip P-TMSI signature (P-TMSI signature, opt, TV, length 4) */
|
||||
gprs_match_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
|
||||
osmo_match_shift_tv_fixed(&data, &data_len, GSM48_IE_GMM_PTMSI_SIG, 3, NULL);
|
||||
|
||||
/* Allocated P-TMSI (Mobile identity, opt, TLV, length 7) */
|
||||
if (gprs_match_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
|
||||
if (osmo_match_shift_tlv(&data, &data_len, GSM48_IE_GMM_ALLOC_PTMSI,
|
||||
&value, &value_len) > 0 &&
|
||||
gprs_is_mi_tmsi(value, value_len))
|
||||
parse_ctx->new_ptmsi_enc = value + 1;
|
||||
@@ -252,11 +252,11 @@ static int gprs_gb_parse_gmm_ptmsi_reall_cmd(uint8_t *data, size_t data_len,
|
||||
"Got P-TMSI Reallocation Command which is not covered by unit tests yet.\n");
|
||||
|
||||
/* Allocated P-TMSI */
|
||||
if (gprs_shift_lv(&data, &data_len, &value, &value_len) > 0 &&
|
||||
if (osmo_shift_lv(&data, &data_len, &value, &value_len) > 0 &&
|
||||
gprs_is_mi_tmsi(value, value_len))
|
||||
parse_ctx->new_ptmsi_enc = value + 1;
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, 6, &value) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->raid_enc = value;
|
||||
@@ -273,7 +273,7 @@ static int gprs_gb_parse_gmm_id_resp(uint8_t *data, size_t data_len,
|
||||
parse_ctx->llc_msg_name = "ID_RESP";
|
||||
|
||||
/* Mobile identity, Mobile identity 10.5.1.4, M LV 2-10 */
|
||||
if (gprs_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
|
||||
if (osmo_shift_lv(&data, &data_len, &value, &value_len) <= 0 ||
|
||||
value_len < 1 || value_len > 9)
|
||||
/* invalid */
|
||||
return 0;
|
||||
@@ -299,22 +299,22 @@ static int gprs_gb_parse_gsm_act_pdp_req(uint8_t *data, size_t data_len,
|
||||
|
||||
/* Skip Requested NSAPI */
|
||||
/* Skip Requested LLC SAPI */
|
||||
gprs_shift_v_fixed(&data, &data_len, 2, NULL);
|
||||
osmo_shift_v_fixed(&data, &data_len, 2, NULL);
|
||||
|
||||
/* Skip Requested QoS (support 04.08 and 24.008) */
|
||||
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
value_len < 4 || value_len > 14)
|
||||
/* invalid */
|
||||
return 0;
|
||||
|
||||
/* Skip Requested PDP address */
|
||||
if (gprs_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
if (osmo_shift_lv(&data, &data_len, NULL, &value_len) <= 0 ||
|
||||
value_len < 2 || value_len > 18)
|
||||
/* invalid */
|
||||
return 0;
|
||||
|
||||
/* Access point name */
|
||||
old_len = gprs_match_tlv(&data, &data_len,
|
||||
old_len = osmo_match_shift_tlv(&data, &data_len,
|
||||
GSM48_IE_GSM_APN, &value, &value_len);
|
||||
|
||||
if (old_len > 0 && value_len >=1 && value_len <= 100) {
|
||||
@@ -329,17 +329,20 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
|
||||
struct gprs_gb_parse_context *parse_ctx)
|
||||
{
|
||||
struct gsm48_hdr *g48h;
|
||||
uint8_t pdisc;
|
||||
uint8_t msg_type;
|
||||
|
||||
if (gprs_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
|
||||
if (osmo_shift_v_fixed(&data, &data_len, sizeof(*g48h), (uint8_t **)&g48h) <= 0)
|
||||
return 0;
|
||||
|
||||
parse_ctx->g48_hdr = g48h;
|
||||
|
||||
if ((g48h->proto_discr & 0x0f) != GSM48_PDISC_MM_GPRS &&
|
||||
(g48h->proto_discr & 0x0f) != GSM48_PDISC_SM_GPRS)
|
||||
pdisc = gsm48_hdr_pdisc(g48h);
|
||||
if (pdisc != GSM48_PDISC_MM_GPRS && pdisc != GSM48_PDISC_SM_GPRS)
|
||||
return 1;
|
||||
|
||||
switch (g48h->msg_type) {
|
||||
msg_type = gsm48_hdr_msg_type(g48h);
|
||||
switch (msg_type) {
|
||||
case GSM48_MT_GMM_ATTACH_REQ:
|
||||
return gprs_gb_parse_gmm_attach_req(data, data_len, parse_ctx);
|
||||
|
||||
@@ -376,6 +379,10 @@ int gprs_gb_parse_dtap(uint8_t *data, size_t data_len,
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGP(DLLC, LOGL_NOTICE,
|
||||
"Unknown GSM 04.08 message type 0x%02hhx for protocol"
|
||||
" discriminator 0x%02hhx.\n",
|
||||
msg_type, pdisc);
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,6 +100,28 @@ static void connect_timer_cb(void *gsupc_)
|
||||
gsup_client_connect(gsupc);
|
||||
}
|
||||
|
||||
static void gsup_client_send(struct gprs_gsup_client *gsupc, int proto_ext, struct msgb *msg_tx)
|
||||
{
|
||||
ipa_prepend_header_ext(msg_tx, proto_ext);
|
||||
ipa_msg_push_header(msg_tx, IPAC_PROTO_OSMO);
|
||||
ipa_client_conn_send(gsupc->link, msg_tx);
|
||||
/* msg_tx is now queued and will be freed. */
|
||||
}
|
||||
|
||||
static void gsup_client_oap_register(struct gprs_gsup_client *gsupc)
|
||||
{
|
||||
struct msgb *msg_tx;
|
||||
int rc;
|
||||
rc = oap_register(&gsupc->oap_state, &msg_tx);
|
||||
|
||||
if ((rc < 0) || (!msg_tx)) {
|
||||
LOGP(DGPRS, LOGL_ERROR, "GSUP OAP set up, but cannot register.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gsup_client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
|
||||
}
|
||||
|
||||
static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
|
||||
{
|
||||
struct gprs_gsup_client *gsupc = link->data;
|
||||
@@ -112,6 +134,9 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
|
||||
if (up) {
|
||||
start_test_procedure(gsupc);
|
||||
|
||||
if (gsupc->oap_state.state == OAP_INITIALIZED)
|
||||
gsup_client_oap_register(gsupc);
|
||||
|
||||
osmo_timer_del(&gsupc->connect_timer);
|
||||
} else {
|
||||
osmo_timer_del(&gsupc->ping_timer);
|
||||
@@ -121,6 +146,22 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
|
||||
}
|
||||
}
|
||||
|
||||
static int gsup_client_oap_handle(struct gprs_gsup_client *gsupc, struct msgb *msg_rx)
|
||||
{
|
||||
int rc;
|
||||
struct msgb *msg_tx;
|
||||
|
||||
rc = oap_handle(&gsupc->oap_state, msg_rx, &msg_tx);
|
||||
msgb_free(msg_rx);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (msg_tx)
|
||||
gsup_client_send(gsupc, IPAC_PROTO_EXT_OAP, msg_tx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
|
||||
{
|
||||
struct ipaccess_head *hh = (struct ipaccess_head *) msg->data;
|
||||
@@ -160,16 +201,21 @@ static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
|
||||
if (hh->proto != IPAC_PROTO_OSMO)
|
||||
goto invalid;
|
||||
|
||||
if (!he || msgb_l2len(msg) < sizeof(*he) ||
|
||||
he->proto != IPAC_PROTO_EXT_GSUP)
|
||||
if (!he || msgb_l2len(msg) < sizeof(*he))
|
||||
goto invalid;
|
||||
|
||||
msg->l2h = &he->data[0];
|
||||
|
||||
OSMO_ASSERT(gsupc->read_cb != NULL);
|
||||
gsupc->read_cb(gsupc, msg);
|
||||
if (he->proto == IPAC_PROTO_EXT_GSUP) {
|
||||
OSMO_ASSERT(gsupc->read_cb != NULL);
|
||||
gsupc->read_cb(gsupc, msg);
|
||||
/* expecting read_cb() to free msg */
|
||||
} else if (he->proto == IPAC_PROTO_EXT_OAP) {
|
||||
return gsup_client_oap_handle(gsupc, msg);
|
||||
/* gsup_client_oap_handle frees msg */
|
||||
} else
|
||||
goto invalid;
|
||||
|
||||
/* Not freeing msg here, because that must be done by the read_cb. */
|
||||
return 0;
|
||||
|
||||
invalid:
|
||||
@@ -214,7 +260,8 @@ static void start_test_procedure(struct gprs_gsup_client *gsupc)
|
||||
|
||||
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
|
||||
unsigned int tcp_port,
|
||||
gprs_gsup_read_cb_t read_cb)
|
||||
gprs_gsup_read_cb_t read_cb,
|
||||
struct oap_config *oap_config)
|
||||
{
|
||||
struct gprs_gsup_client *gsupc;
|
||||
int rc;
|
||||
@@ -222,6 +269,10 @@ struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
|
||||
gsupc = talloc_zero(tall_bsc_ctx, struct gprs_gsup_client);
|
||||
OSMO_ASSERT(gsupc);
|
||||
|
||||
rc = oap_init(oap_config, &gsupc->oap_state);
|
||||
if (rc != 0)
|
||||
goto failed;
|
||||
|
||||
gsupc->link = ipa_client_conn_create(gsupc,
|
||||
/* no e1inp */ NULL,
|
||||
0,
|
||||
@@ -275,9 +326,7 @@ int gprs_gsup_client_send(struct gprs_gsup_client *gsupc, struct msgb *msg)
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_GSUP);
|
||||
ipa_msg_push_header(msg, IPAC_PROTO_OSMO);
|
||||
ipa_client_conn_send(gsupc->link, msg);
|
||||
gsup_client_send(gsupc, IPAC_PROTO_EXT_GSUP, msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,439 +0,0 @@
|
||||
/* GPRS Subscriber Update Protocol message encoder/decoder */
|
||||
|
||||
/*
|
||||
* (C) 2014 by Sysmocom s.f.m.c. GmbH
|
||||
* (C) 2015 by Holger Hans Peter Freyther
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Jacob Erlbeck
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/gprs_gsup_messages.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
static uint64_t decode_big_endian(const uint8_t *data, size_t data_len)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
||||
while (data_len > 0) {
|
||||
value = (value << 8) + *data;
|
||||
data += 1;
|
||||
data_len -= 1;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static uint8_t *encode_big_endian(uint64_t value, size_t data_len)
|
||||
{
|
||||
static uint8_t buf[sizeof(uint64_t)];
|
||||
int idx;
|
||||
|
||||
OSMO_ASSERT(data_len <= ARRAY_SIZE(buf));
|
||||
|
||||
for (idx = data_len - 1; idx >= 0; idx--) {
|
||||
buf[idx] = (uint8_t)value;
|
||||
value = value >> 8;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int decode_pdp_info(uint8_t *data, size_t data_len,
|
||||
struct gprs_gsup_pdp_info *pdp_info)
|
||||
{
|
||||
int rc;
|
||||
uint8_t tag;
|
||||
uint8_t *value;
|
||||
size_t value_len;
|
||||
|
||||
/* specific parts */
|
||||
while (data_len > 0) {
|
||||
enum gprs_gsup_iei iei;
|
||||
|
||||
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
|
||||
if (rc < 0)
|
||||
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
|
||||
|
||||
iei = tag;
|
||||
|
||||
switch (iei) {
|
||||
case GPRS_GSUP_PDP_CONTEXT_ID_IE:
|
||||
pdp_info->context_id = decode_big_endian(value, value_len);
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_PDP_TYPE_IE:
|
||||
pdp_info->pdp_type =
|
||||
decode_big_endian(value, value_len) & 0x0fff;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_ACCESS_POINT_NAME_IE:
|
||||
pdp_info->apn_enc = value;
|
||||
pdp_info->apn_enc_len = value_len;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_PDP_QOS_IE:
|
||||
pdp_info->qos_enc = value;
|
||||
pdp_info->qos_enc_len = value_len;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"GSUP IE type %d not expected in PDP info\n", iei);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_auth_info(uint8_t *data, size_t data_len,
|
||||
struct gsm_auth_tuple *auth_tuple)
|
||||
{
|
||||
int rc;
|
||||
uint8_t tag;
|
||||
uint8_t *value;
|
||||
size_t value_len;
|
||||
enum gprs_gsup_iei iei;
|
||||
|
||||
/* specific parts */
|
||||
while (data_len > 0) {
|
||||
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
|
||||
if (rc < 0)
|
||||
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
|
||||
|
||||
iei = tag;
|
||||
|
||||
switch (iei) {
|
||||
case GPRS_GSUP_RAND_IE:
|
||||
if (value_len != sizeof(auth_tuple->rand))
|
||||
goto parse_error;
|
||||
|
||||
memcpy(auth_tuple->rand, value, value_len);
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_SRES_IE:
|
||||
if (value_len != sizeof(auth_tuple->sres))
|
||||
goto parse_error;
|
||||
|
||||
memcpy(auth_tuple->sres, value, value_len);
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_KC_IE:
|
||||
if (value_len != sizeof(auth_tuple->kc))
|
||||
goto parse_error;
|
||||
|
||||
memcpy(auth_tuple->kc, value, value_len);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"GSUP IE type %d not expected in PDP info\n", iei);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
parse_error:
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"GSUP IE type %d, length %zu invalid in PDP info\n", iei, value_len);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gprs_gsup_decode(const uint8_t *const_data, size_t data_len,
|
||||
struct gprs_gsup_message *gsup_msg)
|
||||
{
|
||||
int rc;
|
||||
uint8_t tag;
|
||||
/* the shift/match functions expect non-const pointers, but we'll
|
||||
* either copy the data or cast pointers back to const before returning
|
||||
* them
|
||||
*/
|
||||
uint8_t *data = (uint8_t *)const_data;
|
||||
uint8_t *value;
|
||||
size_t value_len;
|
||||
static const struct gprs_gsup_pdp_info empty_pdp_info = {0};
|
||||
static const struct gsm_auth_tuple empty_auth_info = {0};
|
||||
static const struct gprs_gsup_message empty_gsup_message = {0};
|
||||
|
||||
*gsup_msg = empty_gsup_message;
|
||||
|
||||
/* generic part */
|
||||
rc = gprs_shift_v_fixed(&data, &data_len, 1, &value);
|
||||
if (rc < 0)
|
||||
return -GMM_CAUSE_INV_MAND_INFO;
|
||||
|
||||
gsup_msg->message_type = decode_big_endian(value, 1);
|
||||
|
||||
rc = gprs_match_tlv(&data, &data_len, GPRS_GSUP_IMSI_IE,
|
||||
&value, &value_len);
|
||||
|
||||
if (rc <= 0)
|
||||
return -GMM_CAUSE_INV_MAND_INFO;
|
||||
|
||||
if (value_len * 2 + 1 > sizeof(gsup_msg->imsi))
|
||||
return -GMM_CAUSE_INV_MAND_INFO;
|
||||
|
||||
/* Note that gsm48_decode_bcd_number expects the number of encoded IMSI
|
||||
* octets in the first octet. By coincidence (the TLV encoding) the byte
|
||||
* before the value part already contains this length so we can use it
|
||||
* here.
|
||||
*/
|
||||
OSMO_ASSERT(value[-1] == value_len);
|
||||
gsm48_decode_bcd_number(gsup_msg->imsi, sizeof(gsup_msg->imsi),
|
||||
value - 1, 0);
|
||||
|
||||
/* specific parts */
|
||||
while (data_len > 0) {
|
||||
enum gprs_gsup_iei iei;
|
||||
struct gprs_gsup_pdp_info pdp_info;
|
||||
struct gsm_auth_tuple auth_info;
|
||||
|
||||
rc = gprs_shift_tlv(&data, &data_len, &tag, &value, &value_len);
|
||||
if (rc < 0)
|
||||
return -GMM_CAUSE_PROTO_ERR_UNSPEC;
|
||||
|
||||
iei = tag;
|
||||
|
||||
switch (iei) {
|
||||
case GPRS_GSUP_IMSI_IE:
|
||||
case GPRS_GSUP_PDP_TYPE_IE:
|
||||
case GPRS_GSUP_ACCESS_POINT_NAME_IE:
|
||||
case GPRS_GSUP_RAND_IE:
|
||||
case GPRS_GSUP_SRES_IE:
|
||||
case GPRS_GSUP_KC_IE:
|
||||
LOGP(DGPRS, LOGL_NOTICE,
|
||||
"GSUP IE type %d not expected (ignored)\n", iei);
|
||||
continue;
|
||||
|
||||
case GPRS_GSUP_CAUSE_IE:
|
||||
gsup_msg->cause = decode_big_endian(value, value_len);
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_CANCEL_TYPE_IE:
|
||||
gsup_msg->cancel_type =
|
||||
decode_big_endian(value, value_len) + 1;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_PDP_INFO_COMPL_IE:
|
||||
gsup_msg->pdp_info_compl = 1;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_FREEZE_PTMSI_IE:
|
||||
gsup_msg->freeze_ptmsi = 1;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_PDP_CONTEXT_ID_IE:
|
||||
/* When these IE appear in the top-level part of the
|
||||
* message, they are used by Delete Subscr Info to delete
|
||||
* single entries. We don't have an extra list for
|
||||
* these but use the PDP info list instead */
|
||||
|
||||
/* fall through */
|
||||
|
||||
case GPRS_GSUP_PDP_INFO_IE:
|
||||
if (gsup_msg->num_pdp_infos >= GPRS_GSUP_MAX_NUM_PDP_INFO) {
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"GSUP IE type %d (PDP_INFO) max exceeded\n",
|
||||
iei);
|
||||
return -GMM_CAUSE_COND_IE_ERR;
|
||||
}
|
||||
|
||||
pdp_info = empty_pdp_info;
|
||||
|
||||
if (iei == GPRS_GSUP_PDP_INFO_IE) {
|
||||
rc = decode_pdp_info(value, value_len, &pdp_info);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
pdp_info.have_info = 1;
|
||||
} else {
|
||||
pdp_info.context_id =
|
||||
decode_big_endian(value, value_len);
|
||||
}
|
||||
|
||||
gsup_msg->pdp_infos[gsup_msg->num_pdp_infos++] =
|
||||
pdp_info;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_AUTH_TUPLE_IE:
|
||||
if (gsup_msg->num_auth_tuples >= GPRS_GSUP_MAX_NUM_AUTH_INFO) {
|
||||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"GSUP IE type %d (AUTH_INFO) max exceeded\n",
|
||||
iei);
|
||||
return -GMM_CAUSE_INV_MAND_INFO;
|
||||
}
|
||||
|
||||
auth_info = empty_auth_info;
|
||||
auth_info.key_seq = gsup_msg->num_auth_tuples;
|
||||
|
||||
rc = decode_auth_info(value, value_len, &auth_info);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
gsup_msg->auth_tuples[gsup_msg->num_auth_tuples++] =
|
||||
auth_info;
|
||||
break;
|
||||
|
||||
case GPRS_GSUP_MSISDN_IE:
|
||||
gsup_msg->msisdn_enc = value;
|
||||
gsup_msg->msisdn_enc_len = value_len;
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGP(DGPRS, LOGL_NOTICE,
|
||||
"GSUP IE type %d unknown\n", iei);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void encode_pdp_info(struct msgb *msg, enum gprs_gsup_iei iei,
|
||||
const struct gprs_gsup_pdp_info *pdp_info)
|
||||
{
|
||||
uint8_t *len_field;
|
||||
size_t old_len;
|
||||
uint8_t u8;
|
||||
|
||||
len_field = msgb_tlv_put(msg, iei, 0, NULL) - 1;
|
||||
old_len = msgb_length(msg);
|
||||
|
||||
u8 = pdp_info->context_id;
|
||||
msgb_tlv_put(msg, GPRS_GSUP_PDP_CONTEXT_ID_IE, sizeof(u8), &u8);
|
||||
|
||||
if (pdp_info->pdp_type) {
|
||||
msgb_tlv_put(msg, GPRS_GSUP_PDP_TYPE_IE,
|
||||
GPRS_GSUP_PDP_TYPE_SIZE,
|
||||
encode_big_endian(pdp_info->pdp_type | 0xf000,
|
||||
GPRS_GSUP_PDP_TYPE_SIZE));
|
||||
}
|
||||
|
||||
if (pdp_info->apn_enc) {
|
||||
msgb_tlv_put(msg, GPRS_GSUP_ACCESS_POINT_NAME_IE,
|
||||
pdp_info->apn_enc_len, pdp_info->apn_enc);
|
||||
}
|
||||
|
||||
if (pdp_info->qos_enc) {
|
||||
msgb_tlv_put(msg, GPRS_GSUP_PDP_QOS_IE,
|
||||
pdp_info->qos_enc_len, pdp_info->qos_enc);
|
||||
}
|
||||
|
||||
/* Update length field */
|
||||
*len_field = msgb_length(msg) - old_len;
|
||||
}
|
||||
|
||||
static void encode_auth_info(struct msgb *msg, enum gprs_gsup_iei iei,
|
||||
const struct gsm_auth_tuple *auth_tuple)
|
||||
{
|
||||
uint8_t *len_field;
|
||||
size_t old_len;
|
||||
|
||||
len_field = msgb_tlv_put(msg, iei, 0, NULL) - 1;
|
||||
old_len = msgb_length(msg);
|
||||
|
||||
msgb_tlv_put(msg, GPRS_GSUP_RAND_IE,
|
||||
sizeof(auth_tuple->rand), auth_tuple->rand);
|
||||
|
||||
msgb_tlv_put(msg, GPRS_GSUP_SRES_IE,
|
||||
sizeof(auth_tuple->sres), auth_tuple->sres);
|
||||
|
||||
msgb_tlv_put(msg, GPRS_GSUP_KC_IE,
|
||||
sizeof(auth_tuple->kc), auth_tuple->kc);
|
||||
|
||||
/* Update length field */
|
||||
*len_field = msgb_length(msg) - old_len;
|
||||
}
|
||||
|
||||
void gprs_gsup_encode(struct msgb *msg, const struct gprs_gsup_message *gsup_msg)
|
||||
{
|
||||
uint8_t u8;
|
||||
int idx;
|
||||
uint8_t bcd_buf[GSM48_MI_SIZE] = {0};
|
||||
size_t bcd_len;
|
||||
|
||||
/* generic part */
|
||||
OSMO_ASSERT(gsup_msg->message_type);
|
||||
msgb_v_put(msg, gsup_msg->message_type);
|
||||
|
||||
bcd_len = gsm48_encode_bcd_number(bcd_buf, sizeof(bcd_buf), 0,
|
||||
gsup_msg->imsi);
|
||||
|
||||
OSMO_ASSERT(bcd_len > 1);
|
||||
|
||||
/* Note that gsm48_encode_bcd_number puts the length into the first
|
||||
* octet. Since msgb_tlv_put will add this length byte, we'll have to
|
||||
* skip it */
|
||||
msgb_tlv_put(msg, GPRS_GSUP_IMSI_IE, bcd_len - 1, &bcd_buf[1]);
|
||||
|
||||
/* specific parts */
|
||||
if (gsup_msg->msisdn_enc)
|
||||
msgb_tlv_put(msg, GPRS_GSUP_MSISDN_IE,
|
||||
gsup_msg->msisdn_enc_len, gsup_msg->msisdn_enc);
|
||||
|
||||
if ((u8 = gsup_msg->cause))
|
||||
msgb_tlv_put(msg, GPRS_GSUP_CAUSE_IE, sizeof(u8), &u8);
|
||||
|
||||
if ((u8 = gsup_msg->cancel_type)) {
|
||||
u8 -= 1;
|
||||
msgb_tlv_put(msg, GPRS_GSUP_CANCEL_TYPE_IE, sizeof(u8), &u8);
|
||||
}
|
||||
|
||||
if (gsup_msg->pdp_info_compl)
|
||||
msgb_tlv_put(msg, GPRS_GSUP_PDP_INFO_COMPL_IE, 0, &u8);
|
||||
|
||||
if (gsup_msg->freeze_ptmsi)
|
||||
msgb_tlv_put(msg, GPRS_GSUP_FREEZE_PTMSI_IE, 0, &u8);
|
||||
|
||||
for (idx = 0; idx < gsup_msg->num_pdp_infos; idx++) {
|
||||
const struct gprs_gsup_pdp_info *pdp_info;
|
||||
|
||||
pdp_info = &gsup_msg->pdp_infos[idx];
|
||||
|
||||
if (pdp_info->context_id == 0)
|
||||
continue;
|
||||
|
||||
if (pdp_info->have_info) {
|
||||
encode_pdp_info(msg, GPRS_GSUP_PDP_INFO_IE, pdp_info);
|
||||
} else {
|
||||
u8 = pdp_info->context_id;
|
||||
msgb_tlv_put(msg, GPRS_GSUP_PDP_CONTEXT_ID_IE,
|
||||
sizeof(u8), &u8);
|
||||
}
|
||||
}
|
||||
|
||||
for (idx = 0; idx < gsup_msg->num_auth_tuples; idx++) {
|
||||
const struct gsm_auth_tuple *auth_info;
|
||||
|
||||
auth_info = &gsup_msg->auth_tuples[idx];
|
||||
|
||||
if (auth_info->key_seq == GSM_KEY_SEQ_INVAL)
|
||||
continue;
|
||||
|
||||
encode_auth_info(msg, GPRS_GSUP_AUTH_TUPLE_IE, auth_info);
|
||||
}
|
||||
}
|
||||
@@ -38,21 +38,6 @@
|
||||
|
||||
static struct gprs_llc_llme *llme_alloc(uint32_t tlli);
|
||||
|
||||
/* If the TLLI is foreign, return its local version */
|
||||
static inline uint32_t tlli_foreign2local(uint32_t tlli)
|
||||
{
|
||||
uint32_t new_tlli;
|
||||
|
||||
if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
|
||||
new_tlli = tlli | 0x40000000;
|
||||
LOGP(DLLC, LOGL_NOTICE, "TLLI 0x%08x is foreign, converting to "
|
||||
"local TLLI 0x%08x\n", tlli, new_tlli);
|
||||
} else
|
||||
new_tlli = tlli;
|
||||
|
||||
return new_tlli;
|
||||
}
|
||||
|
||||
/* Entry function from upper level (LLC), asking us to transmit a BSSGP PDU
|
||||
* to a remote MS (identified by TLLI) at a BTS identified by its BVCI and NSEI */
|
||||
static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
|
||||
@@ -71,10 +56,8 @@ static int _bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx)
|
||||
dup.ms_ra_cap.v = mmctx->ms_radio_access_capa.buf;
|
||||
|
||||
/* make sure we only send it to the right llme */
|
||||
OSMO_ASSERT(msgb_tlli(msg) == mmctx->llme->tlli
|
||||
|| msgb_tlli(msg) == mmctx->llme->old_tlli
|
||||
|| tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->tlli
|
||||
|| tlli_foreign2local(msgb_tlli(msg)) == mmctx->llme->old_tlli);
|
||||
OSMO_ASSERT(msgb_tlli(msg) == mmctx->gb.llme->tlli
|
||||
|| msgb_tlli(msg) == mmctx->gb.llme->old_tlli);
|
||||
}
|
||||
memcpy(&dup.qos_profile, qos_profile_default,
|
||||
sizeof(qos_profile_default));
|
||||
@@ -175,10 +158,6 @@ struct gprs_llc_lle *gprs_lle_get_or_create(const uint32_t tlli, uint8_t sapi)
|
||||
if (lle)
|
||||
return lle;
|
||||
|
||||
lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
|
||||
if (lle)
|
||||
return lle;
|
||||
|
||||
LOGP(DLLC, LOGL_NOTICE, "LLC: unknown TLLI 0x%08x, "
|
||||
"creating LLME on the fly\n", tlli);
|
||||
llme = llme_alloc(tlli);
|
||||
@@ -204,7 +183,7 @@ static struct gprs_llc_lle *lle_for_rx_by_tlli_sapi(const uint32_t tlli,
|
||||
|
||||
/* Maybe it is a routing area update but we already know this sapi? */
|
||||
if (gprs_tlli_type(tlli) == TLLI_FOREIGN) {
|
||||
lle = lle_by_tlli_sapi(tlli_foreign2local(tlli), sapi);
|
||||
lle = lle_by_tlli_sapi(tlli, sapi);
|
||||
if (lle) {
|
||||
LOGP(DLLC, LOGL_NOTICE,
|
||||
"LLC RX: Found a local entry for TLLI 0x%08x\n",
|
||||
@@ -679,12 +658,12 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv)
|
||||
return rc;
|
||||
|
||||
/* llhp.data is only set when we need to send LL_[UNIT]DATA_IND up */
|
||||
if (llhp.data) {
|
||||
if (llhp.cmd == GPRS_LLC_UI && llhp.data && llhp.data_len) {
|
||||
msgb_gmmh(msg) = llhp.data;
|
||||
switch (llhp.sapi) {
|
||||
case GPRS_SAPI_GMM:
|
||||
/* send LL_UNITDATA_IND to GMM */
|
||||
rc = gsm0408_gprs_rcvmsg(msg, lle->llme);
|
||||
rc = gsm0408_gprs_rcvmsg_gb(msg, lle->llme);
|
||||
break;
|
||||
case GPRS_SAPI_SNDCP3:
|
||||
case GPRS_SAPI_SNDCP5:
|
||||
|
||||
@@ -25,21 +25,28 @@
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/rate_ctr.h>
|
||||
#include <osmocom/core/stats.h>
|
||||
#include <osmocom/core/backtrace.h>
|
||||
#include <osmocom/gprs/gprs_ns.h>
|
||||
#include <osmocom/gprs/gprs_bssgp.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
|
||||
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
#include <openbsc/sgsn.h>
|
||||
#include <openbsc/gsm_04_08_gprs.h>
|
||||
#include <openbsc/gprs_gmm.h>
|
||||
#include <openbsc/gprs_utils.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include "openbsc/gprs_llc.h"
|
||||
#include <openbsc/iu.h>
|
||||
|
||||
#include <pdp.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#define GPRS_LLME_CHECK_TICK 30
|
||||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
@@ -68,6 +75,7 @@ static const struct rate_ctr_group_desc mmctx_ctrg_desc = {
|
||||
.group_description = "SGSN MM Context Statistics",
|
||||
.num_ctr = ARRAY_SIZE(mmctx_ctr_description),
|
||||
.ctr_desc = mmctx_ctr_description,
|
||||
.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
|
||||
};
|
||||
|
||||
static const struct rate_ctr_desc pdpctx_ctr_description[] = {
|
||||
@@ -82,19 +90,20 @@ static const struct rate_ctr_group_desc pdpctx_ctrg_desc = {
|
||||
.group_description = "SGSN PDP Context Statistics",
|
||||
.num_ctr = ARRAY_SIZE(pdpctx_ctr_description),
|
||||
.ctr_desc = pdpctx_ctr_description,
|
||||
.class_id = OSMO_STATS_CLASS_SUBSCRIBER,
|
||||
};
|
||||
|
||||
static int ra_id_equals(const struct gprs_ra_id *id1,
|
||||
const struct gprs_ra_id *id2)
|
||||
/* look-up a SGSN MM context based on TLLI + RAI */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_ue_ctx(const void *uectx)
|
||||
{
|
||||
return (id1->mcc == id2->mcc && id1->mnc == id2->mnc &&
|
||||
id1->lac == id2->lac && id1->rac == id2->rac);
|
||||
}
|
||||
struct sgsn_mm_ctx *ctx;
|
||||
|
||||
/* See 03.02 Chapter 2.6 */
|
||||
static inline uint32_t tlli_foreign(uint32_t tlli)
|
||||
{
|
||||
return ((tlli | 0x80000000) & ~0x40000000);
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && uectx == ctx->iu.ue_ctx)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* look-up a SGSN MM context based on TLLI + RAI */
|
||||
@@ -102,34 +111,36 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid)
|
||||
{
|
||||
struct sgsn_mm_ctx *ctx;
|
||||
int tlli_type;
|
||||
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if (tlli == ctx->tlli &&
|
||||
ra_id_equals(raid, &ctx->ra))
|
||||
if ((tlli == ctx->gb.tlli || tlli == ctx->gb.tlli_new) &&
|
||||
gprs_ra_id_equals(raid, &ctx->ra))
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_by_tlli_and_ptmsi(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid)
|
||||
{
|
||||
struct sgsn_mm_ctx *ctx;
|
||||
int tlli_type;
|
||||
|
||||
/* TODO: Also check the P_TMSI signature to be safe. That signature
|
||||
* should be different (at least with a sufficiently high probability)
|
||||
* after SGSN restarts and for multiple SGSN instances.
|
||||
*/
|
||||
|
||||
tlli_type = gprs_tlli_type(tlli);
|
||||
switch (tlli_type) {
|
||||
case TLLI_LOCAL:
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if ((ctx->p_tmsi | 0xC0000000) == tlli ||
|
||||
(ctx->p_tmsi_old && (ctx->p_tmsi_old | 0xC0000000) == tlli)) {
|
||||
ctx->tlli = tlli;
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TLLI_FOREIGN:
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if (tlli == tlli_foreign(ctx->tlli) &&
|
||||
ra_id_equals(raid, &ctx->ra))
|
||||
return ctx;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (tlli_type != TLLI_FOREIGN && tlli_type != TLLI_LOCAL)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(ctx, &sgsn_mm_ctxts, list) {
|
||||
if ((gprs_tmsi2tlli(ctx->p_tmsi, tlli_type) == tlli ||
|
||||
gprs_tmsi2tlli(ctx->p_tmsi_old, tlli_type) == tlli) &&
|
||||
gprs_ra_id_equals(raid, &ctx->ra))
|
||||
return ctx;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -170,7 +181,8 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||
return NULL;
|
||||
|
||||
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
|
||||
ctx->tlli = tlli;
|
||||
ctx->ran_type = MM_CTX_T_GERAN_Gb;
|
||||
ctx->gb.tlli = tlli;
|
||||
ctx->mm_state = GMM_DEREGISTERED;
|
||||
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
|
||||
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli);
|
||||
@@ -181,9 +193,37 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||
return ctx;
|
||||
}
|
||||
|
||||
/* Allocate a new SGSN MM context */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc_iu(void *uectx)
|
||||
{
|
||||
struct sgsn_mm_ctx *ctx;
|
||||
|
||||
ctx = talloc_zero(tall_bsc_ctx, struct sgsn_mm_ctx);
|
||||
if (!ctx)
|
||||
return NULL;
|
||||
|
||||
ctx->ran_type = MM_CTX_T_UTRAN_Iu;
|
||||
ctx->iu.ue_ctx = uectx;
|
||||
ctx->iu.new_key = 1;
|
||||
ctx->mm_state = GMM_DEREGISTERED;
|
||||
ctx->pmm_state = PMM_DETACHED;
|
||||
ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
|
||||
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, 0);
|
||||
|
||||
/* Need to get RAID from IU conn */
|
||||
ctx->ra = ctx->iu.ue_ctx->ra_id;
|
||||
|
||||
INIT_LLIST_HEAD(&ctx->pdp_list);
|
||||
|
||||
llist_add(&ctx->list, &sgsn_mm_ctxts);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
/* this is a hard _free_ function, it doesn't clean up the PDP contexts
|
||||
* in libgtp! */
|
||||
void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
|
||||
static void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
|
||||
{
|
||||
struct sgsn_pdp_ctx *pdp, *pdp2;
|
||||
|
||||
@@ -201,9 +241,19 @@ void sgsn_mm_ctx_free(struct sgsn_mm_ctx *mm)
|
||||
|
||||
void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||
{
|
||||
struct gprs_llc_llme *llme = mm->llme;
|
||||
uint32_t tlli = mm->tlli;
|
||||
struct gprs_llc_llme *llme = mm->gb.llme;
|
||||
uint32_t tlli = mm->gb.tlli;
|
||||
struct sgsn_pdp_ctx *pdp, *pdp2;
|
||||
struct sgsn_signal_data sig_data;
|
||||
enum sgsn_ran_type ran_type;
|
||||
|
||||
/* Forget about ongoing look-ups */
|
||||
if (mm->ggsn_lookup) {
|
||||
LOGMMCTXP(LOGL_NOTICE, mm,
|
||||
"Cleaning mmctx with on-going query.\n");
|
||||
mm->ggsn_lookup->mmctx = NULL;
|
||||
mm->ggsn_lookup = NULL;
|
||||
}
|
||||
|
||||
/* delete all existing PDP contexts for this MS */
|
||||
llist_for_each_entry_safe(pdp, pdp2, &mm->pdp_list, list) {
|
||||
@@ -217,6 +267,11 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||
osmo_timer_del(&mm->timer);
|
||||
}
|
||||
|
||||
memset(&sig_data, 0, sizeof(sig_data));
|
||||
sig_data.mm = mm;
|
||||
osmo_signal_dispatch(SS_SGSN, S_SGSN_MM_FREE, &sig_data);
|
||||
|
||||
|
||||
/* Detach from subscriber which is possibly freed then */
|
||||
if (mm->subscr) {
|
||||
struct gsm_subscriber *subscr = subscr_get(mm->subscr);
|
||||
@@ -224,11 +279,15 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm)
|
||||
subscr_put(subscr);
|
||||
}
|
||||
|
||||
ran_type = mm->ran_type;
|
||||
|
||||
sgsn_mm_ctx_free(mm);
|
||||
mm = NULL;
|
||||
|
||||
/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
|
||||
gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
|
||||
if (ran_type == MM_CTX_T_GERAN_Gb) {
|
||||
/* TLLI unassignment, must be called after sgsn_mm_ctx_free */
|
||||
gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +340,6 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
|
||||
return pdp;
|
||||
}
|
||||
|
||||
#include <pdp.h>
|
||||
/*
|
||||
* This function will not trigger any GSM DEACT PDP ACK messages, so you
|
||||
* probably want to call sgsn_delete_pdp_ctx() instead if the connection
|
||||
@@ -289,6 +347,8 @@ struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
|
||||
*/
|
||||
void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
|
||||
{
|
||||
struct sgsn_signal_data sig_data;
|
||||
|
||||
OSMO_ASSERT(pdp->mm != NULL);
|
||||
|
||||
/* There might still be pending callbacks in libgtp. So the parts of
|
||||
@@ -296,8 +356,14 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
|
||||
|
||||
LOGPDPCTXP(LOGL_INFO, pdp, "Forcing release of PDP context\n");
|
||||
|
||||
/* Force the deactivation of the SNDCP layer */
|
||||
sndcp_sm_deactivate_ind(&pdp->mm->llme->lle[pdp->sapi], pdp->nsapi);
|
||||
if (pdp->mm->ran_type == MM_CTX_T_GERAN_Gb) {
|
||||
/* Force the deactivation of the SNDCP layer */
|
||||
sndcp_sm_deactivate_ind(&pdp->mm->gb.llme->lle[pdp->sapi], pdp->nsapi);
|
||||
}
|
||||
|
||||
memset(&sig_data, 0, sizeof(sig_data));
|
||||
sig_data.pdp = pdp;
|
||||
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_TERMINATE, &sig_data);
|
||||
|
||||
/* Detach from MM context */
|
||||
llist_del(&pdp->list);
|
||||
@@ -313,6 +379,12 @@ void sgsn_pdp_ctx_terminate(struct sgsn_pdp_ctx *pdp)
|
||||
*/
|
||||
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
|
||||
{
|
||||
struct sgsn_signal_data sig_data;
|
||||
|
||||
memset(&sig_data, 0, sizeof(sig_data));
|
||||
sig_data.pdp = pdp;
|
||||
osmo_signal_dispatch(SS_SGSN, S_SGSN_PDP_FREE, &sig_data);
|
||||
|
||||
rate_ctr_group_free(pdp->ctrg);
|
||||
if (pdp->mm)
|
||||
llist_del(&pdp->list);
|
||||
@@ -330,6 +402,8 @@ void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp)
|
||||
lib->priv = NULL;
|
||||
}
|
||||
|
||||
if (pdp->destroy_ggsn)
|
||||
sgsn_ggsn_ctx_free(pdp->ggsn);
|
||||
talloc_free(pdp);
|
||||
}
|
||||
|
||||
@@ -496,7 +570,9 @@ uint32_t sgsn_alloc_ptmsi(void)
|
||||
int max_retries = 100;
|
||||
|
||||
restart:
|
||||
ptmsi = rand();
|
||||
if (RAND_bytes((uint8_t *) &ptmsi, sizeof(ptmsi)) != 1)
|
||||
goto failed;
|
||||
|
||||
/* Enforce that the 2 MSB are set without loosing the distance between
|
||||
* identical values. Since rand() has no duplicate values within a
|
||||
* period (because the size of the state is the same like the size of
|
||||
@@ -595,7 +671,8 @@ static void insert_qos(struct tlv_parsed *tp, struct sgsn_subscriber_pdp_data *p
|
||||
*/
|
||||
struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
struct tlv_parsed *tp,
|
||||
enum gsm48_gsm_cause *gsm_cause)
|
||||
enum gsm48_gsm_cause *gsm_cause,
|
||||
char *out_apn_str)
|
||||
{
|
||||
char req_apn_str[GSM_APN_LENGTH] = {0};
|
||||
const struct apn_ctx *apn_ctx = NULL;
|
||||
@@ -604,6 +681,8 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
struct sgsn_ggsn_ctx *ggsn = NULL;
|
||||
int allow_any_apn = 0;
|
||||
|
||||
out_apn_str[0] = '\0';
|
||||
|
||||
if (TLVP_PRESENT(tp, GSM48_IE_GSM_APN)) {
|
||||
if (TLVP_LEN(tp, GSM48_IE_GSM_APN) >= GSM_APN_LENGTH - 1) {
|
||||
LOGMMCTXP(LOGL_ERROR, mmctx, "APN IE too long\n");
|
||||
@@ -619,8 +698,7 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
req_apn_str[0] = 0;
|
||||
}
|
||||
|
||||
if (mmctx->subscr == NULL ||
|
||||
llist_empty(&mmctx->subscr->sgsn_data->pdp_list))
|
||||
if (mmctx->subscr == NULL)
|
||||
allow_any_apn = 1;
|
||||
|
||||
if (strlen(req_apn_str) == 0 && !allow_any_apn) {
|
||||
@@ -677,6 +755,12 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy the selected apn_str */
|
||||
if (selected_apn_str)
|
||||
strcpy(out_apn_str, selected_apn_str);
|
||||
else
|
||||
out_apn_str[0] = '\0';
|
||||
|
||||
if (apn_ctx == NULL && selected_apn_str)
|
||||
apn_ctx = sgsn_apn_ctx_match(selected_apn_str, mmctx->imsi);
|
||||
|
||||
@@ -698,6 +782,13 @@ struct sgsn_ggsn_ctx *sgsn_mm_ctx_find_ggsn_ctx(struct sgsn_mm_ctx *mmctx,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ggsn) {
|
||||
LOGMMCTXP(LOGL_NOTICE, mmctx,
|
||||
"No static GGSN configured. Selected APN '%s'\n",
|
||||
selected_apn_str);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOGMMCTXP(LOGL_INFO, mmctx,
|
||||
"Found GGSN %d for APN '%s' (requested '%s')\n",
|
||||
ggsn->id, selected_apn_str ? selected_apn_str : "---",
|
||||
@@ -711,7 +802,7 @@ static void sgsn_llme_cleanup_free(struct gprs_llc_llme *llme)
|
||||
struct sgsn_mm_ctx *mmctx = NULL;
|
||||
|
||||
llist_for_each_entry(mmctx, &sgsn_mm_ctxts, list) {
|
||||
if (llme == mmctx->llme) {
|
||||
if (llme == mmctx->gb.llme) {
|
||||
gsm0408_gprs_access_cancelled(mmctx, SGSN_ERROR_CAUSE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user