mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-11-02 04:53:24 +00:00
Compare commits
1403 Commits
on-waves/0
...
openbsc/0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c1e6cf5fc | ||
|
|
89976e8285 | ||
|
|
6aa882b515 | ||
|
|
3186892771 | ||
|
|
ebc824cd2e | ||
|
|
d5db12c160 | ||
|
|
3bcbc0c47a | ||
|
|
c597a4eba1 | ||
|
|
98a3877e97 | ||
|
|
294cfcc1e5 | ||
|
|
c2b31ed9cd | ||
|
|
5654c5b090 | ||
|
|
a780a3dc9f | ||
|
|
e1d1f45034 | ||
|
|
59509630df | ||
|
|
1e194a304f | ||
|
|
1ef7ce4fe8 | ||
|
|
4b85a32360 | ||
|
|
aeb45f5186 | ||
|
|
30e1ae923d | ||
|
|
c44db4a534 | ||
|
|
290aaed6e4 | ||
|
|
9fbff4adac | ||
|
|
5f827f4ede | ||
|
|
88f9d98ccc | ||
|
|
417920a660 | ||
|
|
1aa4246bb8 | ||
|
|
380b8711a2 | ||
|
|
12b917d839 | ||
|
|
d0c3229590 | ||
|
|
6b7710739a | ||
|
|
e731e1d6dd | ||
|
|
44d0f19787 | ||
|
|
68d26796ca | ||
|
|
e6373b7f63 | ||
|
|
daf753477e | ||
|
|
742fc70011 | ||
|
|
ac30cc833c | ||
|
|
b02c89e292 | ||
|
|
15ef17e70e | ||
|
|
80dfa75df2 | ||
|
|
ba81ab329c | ||
|
|
6a4b362ceb | ||
|
|
680833e2ba | ||
|
|
fa530cd6d8 | ||
|
|
d30e087521 | ||
|
|
6e95c5ffa1 | ||
|
|
8d7b10ef58 | ||
|
|
4f140649cb | ||
|
|
a97152b242 | ||
|
|
960e81e5bd | ||
|
|
306e2bc724 | ||
|
|
e2c1520a71 | ||
|
|
dbd16fe59a | ||
|
|
e0478de144 | ||
|
|
7dece86a08 | ||
|
|
d340cd3b2f | ||
|
|
d9b18f8c21 | ||
|
|
ca157ed3c3 | ||
|
|
ccc91f3088 | ||
|
|
f957095385 | ||
|
|
c2c4621a5d | ||
|
|
8cb4a0f35d | ||
|
|
c702b7528f | ||
|
|
dbc62db8db | ||
|
|
c354de8f94 | ||
|
|
5eed0a2e01 | ||
|
|
c95cf10d08 | ||
|
|
e39a5912f1 | ||
|
|
af109b9fa9 | ||
|
|
a0b0f36ff0 | ||
|
|
887deabe38 | ||
|
|
549faada21 | ||
|
|
f21e453dc9 | ||
|
|
e8723dcb86 | ||
|
|
c95cfda58d | ||
|
|
a60923821f | ||
|
|
6d2b66e89a | ||
|
|
4f448c97eb | ||
|
|
02d39b2c4d | ||
|
|
d1d45b3b89 | ||
|
|
20ee312d5c | ||
|
|
bec411b9db | ||
|
|
db65bbd515 | ||
|
|
3a77e61033 | ||
|
|
f0945408f5 | ||
|
|
49ab278b6f | ||
|
|
952db280bd | ||
|
|
6f3850fcac | ||
|
|
7a7d364725 | ||
|
|
adea4f1bf8 | ||
|
|
c48ac4750d | ||
|
|
4b6ac1edb9 | ||
|
|
3e2e159707 | ||
|
|
d6f582b352 | ||
|
|
1b8827ae5b | ||
|
|
d07b4f99ce | ||
|
|
496aee463f | ||
|
|
6ed4950d5b | ||
|
|
23c13760ca | ||
|
|
c5d4a0ced1 | ||
|
|
6add7c2009 | ||
|
|
3d6815abd1 | ||
|
|
36f1217f32 | ||
|
|
8b705f2533 | ||
|
|
18d1452a92 | ||
|
|
ab4094ca6b | ||
|
|
60da7d4f88 | ||
|
|
8f0c0a3a3c | ||
|
|
11ff3e8ec2 | ||
|
|
19f9e30eb9 | ||
|
|
b37515e86b | ||
|
|
993697c8d2 | ||
|
|
b87bc86006 | ||
|
|
8911cef81d | ||
|
|
951a12cf4e | ||
|
|
362aea0f4d | ||
|
|
fd29a1f6cc | ||
|
|
65d96783df | ||
|
|
875840c603 | ||
|
|
937a9ecfcd | ||
|
|
f78a3b2a22 | ||
|
|
cacbc73d5e | ||
|
|
ab5135e36a | ||
|
|
5ccab1020c | ||
|
|
ec4bfdc435 | ||
|
|
2f4dbebb20 | ||
|
|
5950236b5e | ||
|
|
bd17b39fd2 | ||
|
|
43ef6483db | ||
|
|
d9c9f07c2c | ||
|
|
f2553a6c3a | ||
|
|
0610947f4c | ||
|
|
88519eaaef | ||
|
|
e071ab70e9 | ||
|
|
d06516557a | ||
|
|
2486663844 | ||
|
|
0379c6d386 | ||
|
|
e38bd6caa3 | ||
|
|
06abe9f383 | ||
|
|
66efcbce65 | ||
|
|
93d50e69d3 | ||
|
|
8fc60f0eb5 | ||
|
|
bd5c91276b | ||
|
|
f7fef48e1b | ||
|
|
c0d59504b4 | ||
|
|
376d5e521e | ||
|
|
a1d39a2a11 | ||
|
|
0f43dbcfc6 | ||
|
|
0aef73efc4 | ||
|
|
8c21c07a65 | ||
|
|
ed83286950 | ||
|
|
4049455d74 | ||
|
|
2412a07965 | ||
|
|
94d625bfa0 | ||
|
|
9d4cca7a0e | ||
|
|
2788b96bf4 | ||
|
|
f7a1c23e1d | ||
|
|
5ba05f4d26 | ||
|
|
4df2ad9ac6 | ||
|
|
c8bf3c178f | ||
|
|
cfa4a01c8f | ||
|
|
a69d923fd7 | ||
|
|
69e8f8285b | ||
|
|
db4ef0d369 | ||
|
|
758f4dfa17 | ||
|
|
1afbd76155 | ||
|
|
34949ae924 | ||
|
|
ad98128e65 | ||
|
|
694a5cfe06 | ||
|
|
9575fd0732 | ||
|
|
abeb951426 | ||
|
|
f87ebe69d5 | ||
|
|
09108bff95 | ||
|
|
c8794b5977 | ||
|
|
9da921b8b0 | ||
|
|
29aca17ed0 | ||
|
|
7401ae6a79 | ||
|
|
fd3708976a | ||
|
|
c2fb3d0c3d | ||
|
|
f3d8e92731 | ||
|
|
a39b0f2bb7 | ||
|
|
6e0cd04725 | ||
|
|
b37e5f8a60 | ||
|
|
b88b6d3ea6 | ||
|
|
2db4d46680 | ||
|
|
71d36b3d04 | ||
|
|
8330c1c386 | ||
|
|
b2c38ebb1f | ||
|
|
f6d0e06940 | ||
|
|
d42c3f25a6 | ||
|
|
3f122bed1e | ||
|
|
dad5724eb3 | ||
|
|
c6bb3c4e33 | ||
|
|
9764331062 | ||
|
|
86481c29d4 | ||
|
|
7b4a53d537 | ||
|
|
9c78697fa2 | ||
|
|
8cc2a6d62d | ||
|
|
75492e6e54 | ||
|
|
a19bdabf22 | ||
|
|
57c4decd1d | ||
|
|
0fbb3eca14 | ||
|
|
4f8340939e | ||
|
|
77008464be | ||
|
|
bddd152049 | ||
|
|
9ce1b27fbf | ||
|
|
b2be195b50 | ||
|
|
ea01ca764f | ||
|
|
0128843591 | ||
|
|
228c1059fd | ||
|
|
e9ed340425 | ||
|
|
667cdd60ca | ||
|
|
280c768f91 | ||
|
|
1c6f394234 | ||
|
|
9fb5abe5cb | ||
|
|
28e2988ce2 | ||
|
|
434a1fd84e | ||
|
|
1398f13a64 | ||
|
|
69d801e23a | ||
|
|
9b0550ce4c | ||
|
|
ab52c84889 | ||
|
|
3d73e0d235 | ||
|
|
27d36de3b9 | ||
|
|
26c3a358d6 | ||
|
|
d77c8171aa | ||
|
|
29c67039fe | ||
|
|
e4900a074a | ||
|
|
f0c3e912e3 | ||
|
|
86c4dc3a0e | ||
|
|
8affef5059 | ||
|
|
078321aaae | ||
|
|
ca999a989d | ||
|
|
b71c23bb0a | ||
|
|
fa20c94456 | ||
|
|
e1fb5670cd | ||
|
|
c58da4b374 | ||
|
|
605f62a16a | ||
|
|
ed775e4c1d | ||
|
|
91246d724f | ||
|
|
234d31218f | ||
|
|
19c0a84fb8 | ||
|
|
66e1ef73c8 | ||
|
|
1f38747cf1 | ||
|
|
48945b18cd | ||
|
|
f192498885 | ||
|
|
87ef2f27e4 | ||
|
|
bcb32a4ad9 | ||
|
|
5f10c6d6f4 | ||
|
|
e6dfb18a79 | ||
|
|
f1012a432c | ||
|
|
1498d2e182 | ||
|
|
e635dab52f | ||
|
|
f76e7ef5e1 | ||
|
|
52c4ba0309 | ||
|
|
a0aeaa799e | ||
|
|
3df0233e5d | ||
|
|
9cc1b83c54 | ||
|
|
b606101011 | ||
|
|
34a96aeb32 | ||
|
|
f830322846 | ||
|
|
12dc89ad37 | ||
|
|
290ed9a98c | ||
|
|
0c08db17bf | ||
|
|
b4af5c9b57 | ||
|
|
d8b82066fa | ||
|
|
c89c030b10 | ||
|
|
2f2d3428d9 | ||
|
|
6b6ecba1a7 | ||
|
|
886d382fea | ||
|
|
c14e09bb2d | ||
|
|
aad82ce7ea | ||
|
|
e47a91b86a | ||
|
|
569ee123a2 | ||
|
|
872d7683d3 | ||
|
|
9e938c680f | ||
|
|
74cfab7b5d | ||
|
|
da35a8da7f | ||
|
|
5078871611 | ||
|
|
906c15ec53 | ||
|
|
314191d75a | ||
|
|
5cdcfa6224 | ||
|
|
3b8798184b | ||
|
|
19c3544f0a | ||
|
|
3a347f0ace | ||
|
|
0b0b31c708 | ||
|
|
b9af2fae51 | ||
|
|
2f9dcf0670 | ||
|
|
4bd2294492 | ||
|
|
fef76122a7 | ||
|
|
3d194d9986 | ||
|
|
a1597f1b29 | ||
|
|
4c683d1215 | ||
|
|
9db7843c06 | ||
|
|
959bbcf0e7 | ||
|
|
9d56d0c45b | ||
|
|
ab7539cc89 | ||
|
|
f42f45bf6a | ||
|
|
7b7eef62c1 | ||
|
|
8151973c73 | ||
|
|
e464ed4e7c | ||
|
|
a34585e296 | ||
|
|
834f1df21e | ||
|
|
62e5843a61 | ||
|
|
b5513caaf8 | ||
|
|
ca0c2f9d1e | ||
|
|
a4376adb54 | ||
|
|
5e63f921f0 | ||
|
|
842c0c020f | ||
|
|
d885b98a05 | ||
|
|
01a0b1b2e0 | ||
|
|
7fc9a27bf1 | ||
|
|
317ae72c47 | ||
|
|
7a773696dc | ||
|
|
c87c8b748e | ||
|
|
08a1b16674 | ||
|
|
eb52e89c3a | ||
|
|
3d0049f4a0 | ||
|
|
8b5100698b | ||
|
|
d6b616a388 | ||
|
|
979a309c94 | ||
|
|
c615c260ea | ||
|
|
6d5a60041a | ||
|
|
8139553962 | ||
|
|
a88742cf5e | ||
|
|
1395948e18 | ||
|
|
d1278c1fc9 | ||
|
|
8bdcf55b22 | ||
|
|
c16cf27bd5 | ||
|
|
a4ed81c8d9 | ||
|
|
bcfebb2c1d | ||
|
|
d4702862d3 | ||
|
|
57f874ad8d | ||
|
|
290d84e15f | ||
|
|
b8a337356a | ||
|
|
0176eb44f5 | ||
|
|
870663af20 | ||
|
|
02aee149f6 | ||
|
|
2896df7605 | ||
|
|
ce512c5473 | ||
|
|
b752761a3d | ||
|
|
7cab16619e | ||
|
|
bba593406b | ||
|
|
af0ff6c46a | ||
|
|
dd16b425c8 | ||
|
|
fb7a934cfc | ||
|
|
6b087d18f5 | ||
|
|
f464ea54d1 | ||
|
|
47dd4944ae | ||
|
|
a7c377d593 | ||
|
|
5f291d5077 | ||
|
|
2066b8c267 | ||
|
|
92febd3ea4 | ||
|
|
4ad5850d63 | ||
|
|
d2dd6e878c | ||
|
|
530c4b1aad | ||
|
|
9d90da9843 | ||
|
|
f46ce5329d | ||
|
|
0a6f62f8e3 | ||
|
|
26a43896cd | ||
|
|
5cc94fb86a | ||
|
|
9d51855f66 | ||
|
|
560af50422 | ||
|
|
3f7c7d07d8 | ||
|
|
b9ac37d22f | ||
|
|
32d343644d | ||
|
|
f05506eceb | ||
|
|
806aca94c2 | ||
|
|
9e5300ada6 | ||
|
|
b3e0a032d0 | ||
|
|
8d20065c4b | ||
|
|
bbb9d398e1 | ||
|
|
3c3bce10bd | ||
|
|
a128d91f98 | ||
|
|
a0df82d48d | ||
|
|
76c8354863 | ||
|
|
fc9bd23000 | ||
|
|
03ca97e458 | ||
|
|
a7f8018eb2 | ||
|
|
241e13005a | ||
|
|
f4cfc4f201 | ||
|
|
d131b79fc2 | ||
|
|
f7d3335817 | ||
|
|
465313e48c | ||
|
|
23fe7be1ca | ||
|
|
49c7fb52f0 | ||
|
|
72ba1624b3 | ||
|
|
d7657ffc84 | ||
|
|
04fd992af3 | ||
|
|
e9be5175ff | ||
|
|
a5784b58f0 | ||
|
|
39ee87783f | ||
|
|
bae9da49b9 | ||
|
|
38f7c75739 | ||
|
|
64622e42ed | ||
|
|
16a6f70834 | ||
|
|
f8048d9f5c | ||
|
|
58a56797a8 | ||
|
|
0dc569abc2 | ||
|
|
ea8cbd5e72 | ||
|
|
dcf8a7db43 | ||
|
|
0ab6babbde | ||
|
|
cd895377ca | ||
|
|
baf2abe4c4 | ||
|
|
6c0a04e196 | ||
|
|
7c99d4fbf0 | ||
|
|
f38e879ca4 | ||
|
|
3025e198ea | ||
|
|
db7ba7db8b | ||
|
|
0fb47e0273 | ||
|
|
747d654189 | ||
|
|
f7cb33cb33 | ||
|
|
ed07a3fc1c | ||
|
|
6f5fbfd6bf | ||
|
|
2d677c6787 | ||
|
|
df6143a08e | ||
|
|
6c45f2e325 | ||
|
|
aad68b5ef8 | ||
|
|
a416776ee3 | ||
|
|
45d1181a82 | ||
|
|
7c11d1df1b | ||
|
|
aa6982445f | ||
|
|
3f37b8fba3 | ||
|
|
6b8763ed9a | ||
|
|
9a85ef3266 | ||
|
|
9f8f3d09a6 | ||
|
|
6db5ce5318 | ||
|
|
45f7dcd9ae | ||
|
|
058eeb7ab0 | ||
|
|
38a77d0098 | ||
|
|
1d6fb18b57 | ||
|
|
0b8f69d839 | ||
|
|
418f394b01 | ||
|
|
600466477a | ||
|
|
6a97b8d188 | ||
|
|
d7fb9545b6 | ||
|
|
8e074ec27c | ||
|
|
c7641c9a70 | ||
|
|
7625506430 | ||
|
|
24614ad1c0 | ||
|
|
5aa25ae9e6 | ||
|
|
da86c0a034 | ||
|
|
49d8068b37 | ||
|
|
6ace522847 | ||
|
|
eef86b5d59 | ||
|
|
9e2c5f572a | ||
|
|
230a4d886d | ||
|
|
2c0f16699e | ||
|
|
580cb83ae3 | ||
|
|
9140174faa | ||
|
|
d521d97976 | ||
|
|
7bc5ba3674 | ||
|
|
dc5db2424d | ||
|
|
9c137a7819 | ||
|
|
f6fb3efcba | ||
|
|
ecd9933826 | ||
|
|
cea722bc51 | ||
|
|
6a3d765bf9 | ||
|
|
43b0909394 | ||
|
|
9c595b7474 | ||
|
|
0cfbe26cb9 | ||
|
|
f7332e012c | ||
|
|
d04b9edfa3 | ||
|
|
eabb142c70 | ||
|
|
e824d9c2a1 | ||
|
|
c593cf100a | ||
|
|
0c873a06b6 | ||
|
|
ba87f458ec | ||
|
|
267fba0a2b | ||
|
|
2030a2a228 | ||
|
|
30a15384f4 | ||
|
|
31ac307130 | ||
|
|
92b2ff5081 | ||
|
|
10bf812a6a | ||
|
|
c614a6a199 | ||
|
|
b48216f9d1 | ||
|
|
993d06065a | ||
|
|
2844144afd | ||
|
|
abcddf1152 | ||
|
|
2a9285c028 | ||
|
|
8e78fa7862 | ||
|
|
4cd5158874 | ||
|
|
05a379b857 | ||
|
|
644a0cac0c | ||
|
|
eda125ca51 | ||
|
|
5914bad40b | ||
|
|
efbdee9a5c | ||
|
|
bb35c45a02 | ||
|
|
bffeff8089 | ||
|
|
c2e88baa5e | ||
|
|
7afac583cd | ||
|
|
ca5702a5c6 | ||
|
|
0afa044c09 | ||
|
|
2e234f524c | ||
|
|
4fe22cc56d | ||
|
|
21e1c0d01c | ||
|
|
e98c635391 | ||
|
|
5bfe499366 | ||
|
|
f54e7e2102 | ||
|
|
588d44ee65 | ||
|
|
60ebc02ba8 | ||
|
|
0897dad300 | ||
|
|
952aba7406 | ||
|
|
6147c5d7d0 | ||
|
|
7670651f49 | ||
|
|
6cb9b230ed | ||
|
|
1a0c2b7509 | ||
|
|
3dac881271 | ||
|
|
62d97986a3 | ||
|
|
62eaf54e7a | ||
|
|
57da4471d1 | ||
|
|
89476f5c8f | ||
|
|
b9a4fcfdaf | ||
|
|
e11b107f76 | ||
|
|
de4b0a207d | ||
|
|
4f5848dc91 | ||
|
|
44752d9f84 | ||
|
|
bddfab1f97 | ||
|
|
f5f512cc59 | ||
|
|
7f573d5668 | ||
|
|
bc10593314 | ||
|
|
f488121058 | ||
|
|
7d3b3d0e71 | ||
|
|
8acedec8c9 | ||
|
|
98b15034b3 | ||
|
|
bdcf45c9aa | ||
|
|
3a7074615f | ||
|
|
ce22f92b6c | ||
|
|
db2c39f888 | ||
|
|
1d9d944310 | ||
|
|
bb1c805718 | ||
|
|
96df60637a | ||
|
|
52421a0551 | ||
|
|
61ca7ce006 | ||
|
|
5cc2bc37a7 | ||
|
|
e300d0021c | ||
|
|
6144452068 | ||
|
|
858491821f | ||
|
|
69996cb534 | ||
|
|
16836a37aa | ||
|
|
f11b6d2f30 | ||
|
|
ebabdea0a6 | ||
|
|
84488245e6 | ||
|
|
807a5d8264 | ||
|
|
1371f7dd2f | ||
|
|
f7b3a219f6 | ||
|
|
dce1255d8f | ||
|
|
56a0145dd8 | ||
|
|
c2e8cc4a10 | ||
|
|
3d379ba589 | ||
|
|
c91ce1a9d3 | ||
|
|
6463232b09 | ||
|
|
72b4b20a2a | ||
|
|
81c9b9ca3e | ||
|
|
14ce8a0fa4 | ||
|
|
f5b4ba367c | ||
|
|
0c8aa73db7 | ||
|
|
4b4dd100f8 | ||
|
|
f30c0dca0d | ||
|
|
d7fd30617f | ||
|
|
dbc5fae576 | ||
|
|
a4b16658d5 | ||
|
|
a6932d2eae | ||
|
|
02ea86fa71 | ||
|
|
6bdee6ada3 | ||
|
|
b12aa4b1ee | ||
|
|
d75d71e95c | ||
|
|
0ede21f547 | ||
|
|
cc540c4a0c | ||
|
|
edcc3b8945 | ||
|
|
ea985a4357 | ||
|
|
dccf55535a | ||
|
|
1641b18c59 | ||
|
|
bf51438a8a | ||
|
|
900aeaf415 | ||
|
|
34b5480a6a | ||
|
|
06e877228b | ||
|
|
bb9a9bf05f | ||
|
|
39231150ad | ||
|
|
d3cf85d57c | ||
|
|
b4a84e11b7 | ||
|
|
71b822b986 | ||
|
|
7ae3f6c30e | ||
|
|
d09446d28e | ||
|
|
c31f480f08 | ||
|
|
4b037e4117 | ||
|
|
237f6241f2 | ||
|
|
4ebdf74728 | ||
|
|
93cf5a38eb | ||
|
|
e352c52ed8 | ||
|
|
ab1b819930 | ||
|
|
3fb0b6f26e | ||
|
|
4f1e81543a | ||
|
|
9ac340ef06 | ||
|
|
fa848d4923 | ||
|
|
3a6fdcd717 | ||
|
|
4752e0c3de | ||
|
|
d6ca49633c | ||
|
|
2fbf12dbeb | ||
|
|
cf4e9c8f07 | ||
|
|
83e0b3f544 | ||
|
|
75bd69bc91 | ||
|
|
9e28ecc325 | ||
|
|
2e22a5d85d | ||
|
|
cbac76ee0e | ||
|
|
8f443710eb | ||
|
|
b9873442c2 | ||
|
|
d92f9aff80 | ||
|
|
972c1f33b9 | ||
|
|
0342540813 | ||
|
|
5af5e320d6 | ||
|
|
8d66dfb603 | ||
|
|
aef49cc510 | ||
|
|
0ebd688746 | ||
|
|
268bed07c0 | ||
|
|
7570c21424 | ||
|
|
6624cae775 | ||
|
|
94ac58e04e | ||
|
|
e72c61cc6f | ||
|
|
ea92ac3777 | ||
|
|
ffe191c477 | ||
|
|
6efc176722 | ||
|
|
e4860d7c48 | ||
|
|
3c2a88dfe4 | ||
|
|
ff3bde8b49 | ||
|
|
5540c4cbd3 | ||
|
|
3a318ab971 | ||
|
|
7af4962e07 | ||
|
|
ab1d5626ac | ||
|
|
119c2baaa6 | ||
|
|
51537eef50 | ||
|
|
b4a3129993 | ||
|
|
cd4dd4d7ff | ||
|
|
6463c0799c | ||
|
|
4e38ac7a8a | ||
|
|
269ae75321 | ||
|
|
3c0b9b9c2a | ||
|
|
77289c202f | ||
|
|
55e0df7c43 | ||
|
|
322a5ee954 | ||
|
|
d764c064bb | ||
|
|
6ffbaab90d | ||
|
|
b61f403dd3 | ||
|
|
2e918a87eb | ||
|
|
68b99a4a08 | ||
|
|
803bd5ceb2 | ||
|
|
b3911a071b | ||
|
|
75827d65a4 | ||
|
|
a7c262ad96 | ||
|
|
8acd88f369 | ||
|
|
6abf94e420 | ||
|
|
d2a9ed2285 | ||
|
|
03800ba868 | ||
|
|
d9a55f67ac | ||
|
|
b1b290862a | ||
|
|
5fa2f44fa0 | ||
|
|
5c90e5cfc6 | ||
|
|
ada466f2a7 | ||
|
|
d193cb327a | ||
|
|
8fc1a46f28 | ||
|
|
2720e7310d | ||
|
|
7363e92cd3 | ||
|
|
394520a8fd | ||
|
|
f53a9d5471 | ||
|
|
410422fb90 | ||
|
|
5bc61dc384 | ||
|
|
7d9f2230a9 | ||
|
|
4f10c25ea8 | ||
|
|
dcccb1818d | ||
|
|
88907a2f92 | ||
|
|
9a87ad923d | ||
|
|
20474ad029 | ||
|
|
08e2bfa920 | ||
|
|
1353f961ef | ||
|
|
3071d6aa7d | ||
|
|
00fd8b0e03 | ||
|
|
9a3dec0c01 | ||
|
|
9564715c24 | ||
|
|
8be8c8fec9 | ||
|
|
3bac9a84ce | ||
|
|
52613a114a | ||
|
|
55c91e411e | ||
|
|
ff56d61dc9 | ||
|
|
b7b9c1d4d3 | ||
|
|
f6903dee89 | ||
|
|
5dcef3c8b1 | ||
|
|
ea504e7bdc | ||
|
|
7bf332a480 | ||
|
|
5d65806472 | ||
|
|
2832606e5c | ||
|
|
9ef9108025 | ||
|
|
54f7424b78 | ||
|
|
93e90207f9 | ||
|
|
62ab20c5dd | ||
|
|
197dea95ff | ||
|
|
d94d6a02d5 | ||
|
|
1ccbf44d79 | ||
|
|
768f2871a5 | ||
|
|
102bcafb58 | ||
|
|
2b36ae1a3d | ||
|
|
3a1bece69c | ||
|
|
1b170d1145 | ||
|
|
c6ecafe60c | ||
|
|
b2e49186ef | ||
|
|
f47dc0b58c | ||
|
|
24c9fc1700 | ||
|
|
4cc605ac24 | ||
|
|
1ae09c7bd6 | ||
|
|
e15ad48a82 | ||
|
|
6fc8791dbf | ||
|
|
42993c26e0 | ||
|
|
c9c42effd8 | ||
|
|
b5be7ac39c | ||
|
|
7373109abc | ||
|
|
c1cb5eb38d | ||
|
|
1384af6522 | ||
|
|
b3c206aa34 | ||
|
|
b715d7f890 | ||
|
|
cf5cc5bb5b | ||
|
|
3d6a5d648e | ||
|
|
029235ea96 | ||
|
|
b8819bb845 | ||
|
|
7b90d4a83b | ||
|
|
3a0a463fa4 | ||
|
|
3863e04918 | ||
|
|
4cf12e9350 | ||
|
|
9aa97fc137 | ||
|
|
d2dce6df04 | ||
|
|
a6fd8f2339 | ||
|
|
8d80d066ec | ||
|
|
c191986691 | ||
|
|
cf734784b0 | ||
|
|
dd178b2dc9 | ||
|
|
73b2359fb0 | ||
|
|
e183345748 | ||
|
|
087fcff9a5 | ||
|
|
8e605b045e | ||
|
|
89deee9b99 | ||
|
|
2279414d1c | ||
|
|
66f793a770 | ||
|
|
f2b4cd7b86 | ||
|
|
7b45d60887 | ||
|
|
0ab535bfc3 | ||
|
|
6df0c5187b | ||
|
|
8272c77231 | ||
|
|
22229d6841 | ||
|
|
39d0bb5f7c | ||
|
|
ea4647d264 | ||
|
|
995a2d36da | ||
|
|
d6adf5e098 | ||
|
|
64278ede35 | ||
|
|
52fd4e4395 | ||
|
|
ebead597ff | ||
|
|
9958f477b4 | ||
|
|
505f20d7c4 | ||
|
|
5fbf5f4f8d | ||
|
|
aa0db809e2 | ||
|
|
b4d5b17a8d | ||
|
|
50a6dfee37 | ||
|
|
d9c69cc7fe | ||
|
|
1194b584be | ||
|
|
f6d67c04ee | ||
|
|
d4eaf80acc | ||
|
|
8c2440e182 | ||
|
|
b778d2cf16 | ||
|
|
811c4979e6 | ||
|
|
bca900dab2 | ||
|
|
34caeb36ab | ||
|
|
cad8301dbe | ||
|
|
9bdb3ba322 | ||
|
|
7d45ea41f4 | ||
|
|
d91b73769a | ||
|
|
72953b884d | ||
|
|
fcc4cc9f65 | ||
|
|
1174c08068 | ||
|
|
615e956328 | ||
|
|
8f0ed55b52 | ||
|
|
e9ea26935e | ||
|
|
7c209ebb86 | ||
|
|
ef1226e827 | ||
|
|
e69b2814e2 | ||
|
|
e5117da715 | ||
|
|
f69c059a0e | ||
|
|
d7c02ad9df | ||
|
|
e9359db580 | ||
|
|
7638af95fd | ||
|
|
6f65696459 | ||
|
|
9ac2225ff4 | ||
|
|
f171a6e4fc | ||
|
|
cd7c1beb6b | ||
|
|
6fab236cbb | ||
|
|
7fc9822a74 | ||
|
|
1389ac7d2a | ||
|
|
a7a3194da8 | ||
|
|
0a4050c63b | ||
|
|
c1c1dd260a | ||
|
|
99e3248192 | ||
|
|
6b72cdf854 | ||
|
|
85801d0294 | ||
|
|
1c0de6802c | ||
|
|
c6ec0406c8 | ||
|
|
5d6e378c35 | ||
|
|
c9a341b248 | ||
|
|
e236596bf4 | ||
|
|
ce662943f3 | ||
|
|
1c77c6e4c2 | ||
|
|
24b31313e8 | ||
|
|
90de93e122 | ||
|
|
199d9df0bb | ||
|
|
05b320a4e3 | ||
|
|
96f71f28eb | ||
|
|
44c4830d5b | ||
|
|
69619e3970 | ||
|
|
672f5c4dfd | ||
|
|
239cf056f0 | ||
|
|
ca3620a707 | ||
|
|
5658a1a766 | ||
|
|
10997d0b9b | ||
|
|
86fda90d03 | ||
|
|
421cba4b08 | ||
|
|
ba850c529e | ||
|
|
ba02110918 | ||
|
|
721961cf50 | ||
|
|
d6c7416c32 | ||
|
|
0c3eae0011 | ||
|
|
d60570991f | ||
|
|
9f1f3ad7bb | ||
|
|
11d7c105f8 | ||
|
|
eaa614cb9e | ||
|
|
e6afd60779 | ||
|
|
fd3fa1d4e0 | ||
|
|
345223ee9e | ||
|
|
dbab1c79e7 | ||
|
|
a26655426d | ||
|
|
6557cd0517 | ||
|
|
288be16587 | ||
|
|
a67cbd6f06 | ||
|
|
f533e13c14 | ||
|
|
169a00403f | ||
|
|
70f38d2a3b | ||
|
|
79fc392751 | ||
|
|
b77c697c0b | ||
|
|
799e0c92c6 | ||
|
|
a977b3d1ee | ||
|
|
7b8255c52d | ||
|
|
9f75c35eb3 | ||
|
|
44f1c27460 | ||
|
|
06aa111fda | ||
|
|
b7bd65ea01 | ||
|
|
cb99163249 | ||
|
|
943c5bc595 | ||
|
|
2977d67d48 | ||
|
|
5434d7ec8d | ||
|
|
ab88a62f66 | ||
|
|
9b455bf801 | ||
|
|
3c69a4cdbe | ||
|
|
bde050e8f8 | ||
|
|
95df5c0179 | ||
|
|
539d8343e3 | ||
|
|
72267f01fd | ||
|
|
35a939463e | ||
|
|
0b484a4fb1 | ||
|
|
9624364b4e | ||
|
|
d66c2bef54 | ||
|
|
f32cc4bee5 | ||
|
|
debf955074 | ||
|
|
a1c4f765ec | ||
|
|
5ba4dc171b | ||
|
|
0809d79ef8 | ||
|
|
e562502e8d | ||
|
|
074c9f904c | ||
|
|
e9dd9b0475 | ||
|
|
bb77c9d6cc | ||
|
|
3120ac3f78 | ||
|
|
52e8da6ea1 | ||
|
|
8f12fe818b | ||
|
|
a581136f73 | ||
|
|
a4b446b459 | ||
|
|
f1af306c94 | ||
|
|
1700c933f2 | ||
|
|
9e282de7c8 | ||
|
|
22ca95cf9a | ||
|
|
50f81b022f | ||
|
|
100224df0b | ||
|
|
a074ec4b89 | ||
|
|
221030fc85 | ||
|
|
f51b9006a1 | ||
|
|
4ac100ec24 | ||
|
|
95c229006e | ||
|
|
d941edaca2 | ||
|
|
277f035dee | ||
|
|
2cdda72b3c | ||
|
|
637b4f6b7f | ||
|
|
32d4e50d46 | ||
|
|
dc41755fc7 | ||
|
|
aa9d3ce97a | ||
|
|
e3d16bb775 | ||
|
|
74076934fb | ||
|
|
b844b876ad | ||
|
|
2fb7ccf95f | ||
|
|
38e9c82114 | ||
|
|
39608dc045 | ||
|
|
5fda90816f | ||
|
|
1803818092 | ||
|
|
439bb828f9 | ||
|
|
a06fea020d | ||
|
|
4511d891dd | ||
|
|
da0586a838 | ||
|
|
2c57232489 | ||
|
|
ad9f7830fb | ||
|
|
57ba7e3093 | ||
|
|
6ba3bcbbc6 | ||
|
|
bb110f91e8 | ||
|
|
3ba36d5b57 | ||
|
|
bda581963d | ||
|
|
8d9833ef83 | ||
|
|
2ba40afc36 | ||
|
|
ba6172a7fd | ||
|
|
81716d5fa8 | ||
|
|
7daa01c434 | ||
|
|
e0ec326867 | ||
|
|
2d425059af | ||
|
|
135f797a37 | ||
|
|
f8eff2e4b5 | ||
|
|
70402a4e4d | ||
|
|
280cd5153f | ||
|
|
2c86c2a726 | ||
|
|
ebaed74e17 | ||
|
|
b54dda4cef | ||
|
|
b998d7b219 | ||
|
|
23ba4747d1 | ||
|
|
63cb447fd5 | ||
|
|
5eec9d91d8 | ||
|
|
63d18b51a7 | ||
|
|
74419497fc | ||
|
|
ccfd572647 | ||
|
|
07ba16fe03 | ||
|
|
e1ffc08f72 | ||
|
|
ef8117883b | ||
|
|
ae80f9291a | ||
|
|
1469600b0d | ||
|
|
c50b836540 | ||
|
|
754e801826 | ||
|
|
19722d4411 | ||
|
|
5615b982c2 | ||
|
|
aff596b8e1 | ||
|
|
163d0ea85b | ||
|
|
1ef041ff1e | ||
|
|
b1ac2b96f8 | ||
|
|
07d838a3bf | ||
|
|
4052c811a9 | ||
|
|
d4e7888ae3 | ||
|
|
6c8c0ddbe2 | ||
|
|
19bab73d79 | ||
|
|
c19a65baae | ||
|
|
1ea8dbec90 | ||
|
|
500ff97c21 | ||
|
|
441273766a | ||
|
|
014136da47 | ||
|
|
91b5a31a2c | ||
|
|
575b89585f | ||
|
|
408cc4ace9 | ||
|
|
b4b135efbf | ||
|
|
54fa799129 | ||
|
|
3c71232b11 | ||
|
|
b4c7b274a1 | ||
|
|
7279d24232 | ||
|
|
ef8253c495 | ||
|
|
6c0729fe70 | ||
|
|
e125d40f66 | ||
|
|
58df0ea9a0 | ||
|
|
8b120f0ef9 | ||
|
|
f2f1591ce7 | ||
|
|
f36a11a35d | ||
|
|
c77efdf057 | ||
|
|
b79994c952 | ||
|
|
616d222518 | ||
|
|
64e4e77558 | ||
|
|
9bdcc9ca75 | ||
|
|
e7d2ae69c9 | ||
|
|
52a66aa27e | ||
|
|
13d67b7ea3 | ||
|
|
b71517f07e | ||
|
|
95e4d34f06 | ||
|
|
f5b6aa60ce | ||
|
|
c38b5884ff | ||
|
|
4079105a6c | ||
|
|
ceb072da34 | ||
|
|
b6e1a40c9c | ||
|
|
82ae7169a4 | ||
|
|
acf8a0c59f | ||
|
|
ca8d0063f9 | ||
|
|
9bb553ee40 | ||
|
|
c0d83b0647 | ||
|
|
4563eab30e | ||
|
|
a3b844cf45 | ||
|
|
01fd5cb3f0 | ||
|
|
cc6313cc69 | ||
|
|
332442d6c7 | ||
|
|
71ba85e4af | ||
|
|
dc5062b185 | ||
|
|
3ae2758fba | ||
|
|
faadfe2b93 | ||
|
|
d788f6688c | ||
|
|
4a2bb9e38b | ||
|
|
99a263ff20 | ||
|
|
3c1221e2b2 | ||
|
|
92e9caed63 | ||
|
|
b464fb4a89 | ||
|
|
3f96458d73 | ||
|
|
d4c16b1080 | ||
|
|
18b63f4b41 | ||
|
|
ec32b5860e | ||
|
|
5179c8ef0b | ||
|
|
e95d4825f5 | ||
|
|
68884aa156 | ||
|
|
fe6bf777c3 | ||
|
|
e95daf1925 | ||
|
|
52b4abdcb3 | ||
|
|
5e6466780f | ||
|
|
9eb6d88d64 | ||
|
|
e9e190a8d8 | ||
|
|
b59f9350f8 | ||
|
|
92b1fe4c2d | ||
|
|
bb7bc1155f | ||
|
|
009ad61dab | ||
|
|
829772d3c4 | ||
|
|
9cc020ab21 | ||
|
|
edee7944a5 | ||
|
|
f99f0930fd | ||
|
|
3e57388305 | ||
|
|
6552d0b596 | ||
|
|
a21a96f987 | ||
|
|
b3121c5b3f | ||
|
|
f5284ae1cf | ||
|
|
ff9d8b42e6 | ||
|
|
dc6af631e5 | ||
|
|
354ef81d80 | ||
|
|
b2eb83fa95 | ||
|
|
7f0f8b92ce | ||
|
|
bb60e225a1 | ||
|
|
4cd3d8a2c7 | ||
|
|
505117b778 | ||
|
|
5a29c7fa89 | ||
|
|
351ec2a178 | ||
|
|
e164d29e7f | ||
|
|
a5731cffc4 | ||
|
|
94036700c1 | ||
|
|
84c6f310ed | ||
|
|
1f89329f45 | ||
|
|
fa58625e3b | ||
|
|
af387633db | ||
|
|
97a282b037 | ||
|
|
d859a24f7d | ||
|
|
38722cca48 | ||
|
|
f63bf4d8f1 | ||
|
|
e6678dcedb | ||
|
|
57e9300142 | ||
|
|
c88181a7df | ||
|
|
6e79b54d7b | ||
|
|
622ab49311 | ||
|
|
91ed1f75c4 | ||
|
|
8e9559d2e1 | ||
|
|
045cc22bae | ||
|
|
cbc8062ef8 | ||
|
|
6214b92f81 | ||
|
|
61b4232c63 | ||
|
|
a49951fed7 | ||
|
|
55c8f35e53 | ||
|
|
1e9086684f | ||
|
|
f8b2ba7dc8 | ||
|
|
cbb29f7c94 | ||
|
|
d3ff15fc81 | ||
|
|
48e17f8951 | ||
|
|
622b718195 | ||
|
|
63d3e396e7 | ||
|
|
380ae25052 | ||
|
|
d9abf01436 | ||
|
|
4e1287938e | ||
|
|
8c8caaa1ac | ||
|
|
6fec514d7b | ||
|
|
ecf9dd0d96 | ||
|
|
fbda4e1fb0 | ||
|
|
afedeabd91 | ||
|
|
61e2bfc5f4 | ||
|
|
a73e2f9acb | ||
|
|
fbc5ca080b | ||
|
|
aebe08c71f | ||
|
|
3c9c5f941d | ||
|
|
eb8bf3915c | ||
|
|
098cd4b503 | ||
|
|
474d19f5c0 | ||
|
|
4fb20757c6 | ||
|
|
f08eabf234 | ||
|
|
fdd0a70093 | ||
|
|
2e411c7b0d | ||
|
|
d284cd9f43 | ||
|
|
774f0723bf | ||
|
|
88c6eeaa7d | ||
|
|
00096acb8f | ||
|
|
8df932a7fd | ||
|
|
8b0079909d | ||
|
|
1d7f2f80b8 | ||
|
|
10ca3799e7 | ||
|
|
1ebad74377 | ||
|
|
140f6e9b12 | ||
|
|
d60c7a895e | ||
|
|
e1d5067789 | ||
|
|
36ed8cc4c3 | ||
|
|
ef6bb25aa5 | ||
|
|
fe86d3c9f8 | ||
|
|
a820c5f89d | ||
|
|
63f2db2ec9 | ||
|
|
154b9553f7 | ||
|
|
2890d102c7 | ||
|
|
590cd98842 | ||
|
|
17a5a28202 | ||
|
|
ac778fb85d | ||
|
|
f7d797424a | ||
|
|
1b0ea97457 | ||
|
|
6414a0cb22 | ||
|
|
8d188eda15 | ||
|
|
7bdc637aae | ||
|
|
3415d41a8c | ||
|
|
ed71b8c597 | ||
|
|
1ed97629ad | ||
|
|
5484480211 | ||
|
|
e94ad58e8e | ||
|
|
3cae0398ea | ||
|
|
26cbdcff24 | ||
|
|
8427e2e5df | ||
|
|
47a0885d78 | ||
|
|
ec8b4501c7 | ||
|
|
7756235562 | ||
|
|
75135413cb | ||
|
|
9ff1eabcd3 | ||
|
|
a3d5514c21 | ||
|
|
13f52974e6 | ||
|
|
5998d114f5 | ||
|
|
5d720b11e8 | ||
|
|
f98a4974d7 | ||
|
|
dfe6c7d910 | ||
|
|
9442c1b9ba | ||
|
|
e2c5028dc4 | ||
|
|
4d2d95b35a | ||
|
|
1fdbf40e8a | ||
|
|
62c87b5237 | ||
|
|
b2abbe8a93 | ||
|
|
8fabf514ef | ||
|
|
7184c2d7d2 | ||
|
|
8a69cb2d99 | ||
|
|
c64d9f7201 | ||
|
|
5e6f52f15a | ||
|
|
6d89dac721 | ||
|
|
245d17bd88 | ||
|
|
6b46c474e5 | ||
|
|
b19dc286aa | ||
|
|
a49ffb4cb4 | ||
|
|
701d175653 | ||
|
|
fb0b6fcaea | ||
|
|
d3d5be1cde | ||
|
|
3bc856bc16 | ||
|
|
301e628761 | ||
|
|
f5b36cac6b | ||
|
|
3cb2890e56 | ||
|
|
6ae657228c | ||
|
|
67f5003caa | ||
|
|
9377528c70 | ||
|
|
92026f1cef | ||
|
|
62e836c533 | ||
|
|
77f7afe08e | ||
|
|
2ada71de64 | ||
|
|
e0955029a1 | ||
|
|
89f3cb8606 | ||
|
|
a18445d262 | ||
|
|
e01ee97cd3 | ||
|
|
9100e1dea4 | ||
|
|
9b28fc8be2 | ||
|
|
bd5130d3c1 | ||
|
|
6c79646089 | ||
|
|
601a67e274 | ||
|
|
caf49b4c14 | ||
|
|
ef84539fb7 | ||
|
|
18c5cadc46 | ||
|
|
ca1d1d1493 | ||
|
|
fe5de4e524 | ||
|
|
88fe6eec76 | ||
|
|
a8cd2e6b0e | ||
|
|
efca5419b7 | ||
|
|
82da7fcf62 | ||
|
|
a692fbcff5 | ||
|
|
1b891fd7ba | ||
|
|
550197fd8c | ||
|
|
93b6c6555c | ||
|
|
1e1c6aa5a3 | ||
|
|
604d851b89 | ||
|
|
f15c276382 | ||
|
|
0677061757 | ||
|
|
714e1a29cc | ||
|
|
6af56d1501 | ||
|
|
ca8dc141eb | ||
|
|
620961983c | ||
|
|
2c492ed276 | ||
|
|
f986cfc508 | ||
|
|
14083bef0f | ||
|
|
98657d5dee | ||
|
|
a855d1f846 | ||
|
|
202259c31e | ||
|
|
39315c4798 | ||
|
|
5078148829 | ||
|
|
6e670aab5a | ||
|
|
2ef156db43 | ||
|
|
cbcfe24fee | ||
|
|
d0c540210a | ||
|
|
17d81e2f95 | ||
|
|
7ec448d031 | ||
|
|
caa14869c0 | ||
|
|
4cffc45cbc | ||
|
|
6a9fa7308d | ||
|
|
f904fa80ee | ||
|
|
7b1dd748ea | ||
|
|
4b054c8788 | ||
|
|
493db4ee3d | ||
|
|
ef24dff2a2 | ||
|
|
65542c7f59 | ||
|
|
b1a83585a2 | ||
|
|
a9923753ea | ||
|
|
ad0140572c | ||
|
|
b74cbcf7ec | ||
|
|
a17324c7fe | ||
|
|
ccea439028 | ||
|
|
c74f953fb9 | ||
|
|
2d6057e8cf | ||
|
|
3930b3f9a9 | ||
|
|
41c32b49b7 | ||
|
|
9a2370b591 | ||
|
|
b3fc1eb53c | ||
|
|
b91a106932 | ||
|
|
424c4f0e29 | ||
|
|
0b11414f38 | ||
|
|
4719307f50 | ||
|
|
d7c9e5cad8 | ||
|
|
8608e7c133 | ||
|
|
bd55a6dd31 | ||
|
|
99792900e8 | ||
|
|
af29264039 | ||
|
|
062d5efc5c | ||
|
|
c5f488b6bc | ||
|
|
e1cb4debb0 | ||
|
|
c863cbb171 | ||
|
|
70881b7e8a | ||
|
|
77d334ac4d | ||
|
|
deebb113ac | ||
|
|
1f6c11fda8 | ||
|
|
15e1024e49 | ||
|
|
504807001d | ||
|
|
b6c273e9e3 | ||
|
|
7de67960e7 | ||
|
|
730bc653d1 | ||
|
|
510087752e | ||
|
|
83579ca8ff | ||
|
|
f31e4745bb | ||
|
|
f7dbd589ab | ||
|
|
7992867f4b | ||
|
|
1356c08cc8 | ||
|
|
2e83782b1c | ||
|
|
f9811defe2 | ||
|
|
322127413e | ||
|
|
dade8980e3 | ||
|
|
1f71d9c4c0 | ||
|
|
af351a21f2 | ||
|
|
0183edd18c | ||
|
|
c9f8a6dca3 | ||
|
|
4a98cad85e | ||
|
|
8f99562474 | ||
|
|
67b05d590b | ||
|
|
1684e79365 | ||
|
|
b1414d99c4 | ||
|
|
1029f84435 | ||
|
|
e29be15ac5 | ||
|
|
086ffa51b4 | ||
|
|
e5198967a6 | ||
|
|
93f4207ce6 | ||
|
|
d48f4ebb24 | ||
|
|
7971d3d281 | ||
|
|
5fe33189a9 | ||
|
|
82ff397e31 | ||
|
|
1887f9d153 | ||
|
|
8e93b7908f | ||
|
|
ebdcee27b8 | ||
|
|
07a4026b38 | ||
|
|
c823c89c76 | ||
|
|
567b3261d9 | ||
|
|
46a920c36c | ||
|
|
615e650fd4 | ||
|
|
304db15bd4 | ||
|
|
0b864db429 | ||
|
|
c7aabcad1b | ||
|
|
66169152f6 | ||
|
|
7b37d9710d | ||
|
|
19ef62a0a5 | ||
|
|
9538efc8a7 | ||
|
|
3e46031f52 | ||
|
|
ccd8845449 | ||
|
|
2f5df85c26 | ||
|
|
91b603db57 | ||
|
|
28f1d37380 | ||
|
|
9fcf6d78b7 | ||
|
|
b29b57a198 | ||
|
|
8f31a8fdae | ||
|
|
326a632c46 | ||
|
|
c5dc0f7ac7 | ||
|
|
5a2291e96a | ||
|
|
71bc11e757 | ||
|
|
64d9ddde5d | ||
|
|
cf269a7f85 | ||
|
|
a6faea83e0 | ||
|
|
ab2c8b109d | ||
|
|
f413a0811a | ||
|
|
30b9ecda33 | ||
|
|
a25b20c174 | ||
|
|
f6f2ef9d24 | ||
|
|
258e2f9a9c | ||
|
|
73b82bbf92 | ||
|
|
fc05750cd8 | ||
|
|
198d5ad6f4 | ||
|
|
93c6284772 | ||
|
|
b79bdd99e5 | ||
|
|
47df39931c | ||
|
|
240ce88185 | ||
|
|
441e483bd4 | ||
|
|
1f3ecd4050 | ||
|
|
6589858167 | ||
|
|
7c639a05a3 | ||
|
|
303e5e0314 | ||
|
|
eaa95d545e | ||
|
|
950eca9b76 | ||
|
|
a06c35e9e3 | ||
|
|
469b001b19 | ||
|
|
42a5652eb2 | ||
|
|
d6c35f6e8a | ||
|
|
c4052cf9a8 | ||
|
|
926fcecc2d | ||
|
|
d0cf7ba687 | ||
|
|
2e6d4684ff | ||
|
|
844eab1df5 | ||
|
|
8410597dd7 | ||
|
|
77563daf79 | ||
|
|
19a3f0b120 | ||
|
|
fb33957405 | ||
|
|
e98d4278d0 | ||
|
|
da956931fa | ||
|
|
5b8ed4398e | ||
|
|
5d24ba1eb4 | ||
|
|
50720e76fe | ||
|
|
d0c19148dd | ||
|
|
ae1f159dc4 | ||
|
|
0b906d0e1a | ||
|
|
426da090db | ||
|
|
9094cbaf9c | ||
|
|
7ed2529c5b | ||
|
|
aa8989c4d5 | ||
|
|
aa6c9ca48b | ||
|
|
3cefa9aaa0 | ||
|
|
28f811c87f | ||
|
|
4c70454bae | ||
|
|
02cbff09df | ||
|
|
d6847a940a | ||
|
|
026a6c3389 | ||
|
|
30d2ebddd6 | ||
|
|
09f7ad0ff7 | ||
|
|
5c706bbaf2 | ||
|
|
3606cc5765 | ||
|
|
a16ef3d23f | ||
|
|
61cc306a55 | ||
|
|
afdca0f3df | ||
|
|
87ed5cd4ad | ||
|
|
2ca7c31429 | ||
|
|
b7bcb79bea | ||
|
|
bf2bdc6e84 | ||
|
|
e0d2ff4c2e | ||
|
|
65d67dc222 | ||
|
|
66e8219f96 | ||
|
|
e7ff91342e | ||
|
|
004e055cfd | ||
|
|
079353ad1f | ||
|
|
6fced2fd0a | ||
|
|
5dbd71e31d | ||
|
|
3b05a7affa | ||
|
|
f9b1f30558 | ||
|
|
b61e3b2158 | ||
|
|
0f9141384b | ||
|
|
e2b8eceee7 | ||
|
|
8387a49e39 | ||
|
|
f9a43c45ea | ||
|
|
ffa55a4e87 | ||
|
|
4983921af1 | ||
|
|
4010f1e6f4 | ||
|
|
ff1f19e199 | ||
|
|
9c4f6b5dca | ||
|
|
b908cb7e0e | ||
|
|
c80210641a | ||
|
|
0a64603db9 |
12
openbsc/.gitignore
vendored
12
openbsc/.gitignore
vendored
@@ -3,8 +3,12 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
bscconfig.h
|
||||
bscconfig.h.in
|
||||
openbsc.pc
|
||||
bsc_hack
|
||||
bsc_msc_ip
|
||||
bsc_mgcp
|
||||
*.*~
|
||||
*.sw?
|
||||
|
||||
@@ -19,6 +23,9 @@ install-sh
|
||||
missing
|
||||
stamp-h1
|
||||
|
||||
# git-version-gen magic
|
||||
.tarball-version
|
||||
.version
|
||||
|
||||
|
||||
# apps and app data
|
||||
@@ -26,7 +33,12 @@ hlr.sqlite3
|
||||
bs11_config
|
||||
ipaccess-config
|
||||
ipaccess-find
|
||||
ipaccess-firmware
|
||||
ipaccess-proxy
|
||||
isdnsync
|
||||
bsc_nat
|
||||
osmo-sgsn
|
||||
osmo-gbproxy
|
||||
|
||||
#tests
|
||||
tests/channel/channel_test
|
||||
|
||||
@@ -3,3 +3,5 @@ Holger Freyther <zecke@selfish.org>
|
||||
Jan Luebbe <jluebbe@debian.org>
|
||||
Stefan Schmidt <stefan@datenfreihafen.org>
|
||||
Daniel Willmann <daniel@totalueberwachung.de>
|
||||
Andreas Eversberg <Andreas.Eversberg@versatel.de>
|
||||
Sylvain Munaut <246tnt@gmail.com>
|
||||
|
||||
@@ -6,5 +6,8 @@ SUBDIRS = include src tests
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
pkgconfig_DATA = openbsc.pc
|
||||
|
||||
#dist-hook:
|
||||
# rm -rf `find $(distdir) -name .svn`
|
||||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
$(top_srcdir)/.version:
|
||||
echo $(VERSION) > $@-t && mv $@-t $@
|
||||
dist-hook:
|
||||
echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
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.
|
||||
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.
|
||||
|
||||
Its only current interface is a mISDN based E1 interface utilizing the A-bis
|
||||
protocol between BSC and BTS. In other words, you can connect an existing
|
||||
GSM Base Transceiver Station (BTS) through E1 to OpenBSC.
|
||||
Its currently supported interfaces towards the BTS are:
|
||||
|
||||
So far, it has only been tested with the Siemens microBTS BS-11. Test reports
|
||||
with other BTS are appreciated!
|
||||
* 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!
|
||||
|
||||
* A-bis over IP as used by the ip.access nanoBTS product family
|
||||
|
||||
You can find the project documentation at http://openbsc.gnumonks.org/
|
||||
|
||||
This project is still in its early days, and there are lots of areas where it
|
||||
doesn't behave as per GSM spec.
|
||||
|
||||
December 29, 2008
|
||||
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
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
dnl Process this file with autoconf to produce a configure script
|
||||
AC_INIT
|
||||
AC_INIT([openbsc],
|
||||
m4_esyscmd([./git-version-gen .tarball-version]),
|
||||
[openbsc-devel@lists.openbsc.org])
|
||||
|
||||
AM_INIT_AUTOMAKE(openbsc, 0.3.2onwaves)
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
|
||||
dnl kernel style compile messages
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
@@ -15,6 +17,34 @@ 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(gtp_new, gtp,
|
||||
[LIBCRYPT="-lgtp"; AC_SUBST([GPRS_LIBGTP], [1])])
|
||||
|
||||
AM_CONDITIONAL(HAVE_LIBGTP, test "x$GPRS_LIBGTP" != "x")
|
||||
|
||||
|
||||
AC_ARG_ENABLE([nat], [AS_HELP_STRING([--enable-nat], [Build the BSC NAT. Requires SCCP])],
|
||||
[
|
||||
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
|
||||
osmo_ac_build_nat="yes"
|
||||
],
|
||||
[
|
||||
osmo_ac_build_nat="no"
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_NAT, test "x$osmo_ac_build_nat" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
|
||||
[
|
||||
PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.2)
|
||||
osmo_ac_build_bsc="yes"
|
||||
],
|
||||
[
|
||||
osmo_ac_build_bsc="no"
|
||||
])
|
||||
AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
|
||||
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.15)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.1.9)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
@@ -39,16 +69,16 @@ AM_CONFIG_HEADER(bscconfig.h)
|
||||
AC_OUTPUT(
|
||||
openbsc.pc
|
||||
include/openbsc/Makefile
|
||||
include/vty/Makefile
|
||||
include/sccp/Makefile
|
||||
include/Makefile
|
||||
src/Makefile
|
||||
src/ipaccess/Makefile
|
||||
src/gprs/Makefile
|
||||
src/nat/Makefile
|
||||
src/bsc/Makefile
|
||||
tests/Makefile
|
||||
tests/debug/Makefile
|
||||
tests/timer/Makefile
|
||||
tests/sms/Makefile
|
||||
tests/gsm0408/Makefile
|
||||
tests/db/Makefile
|
||||
tests/channel/Makefile
|
||||
tests/sccp/Makefile
|
||||
tests/bsc-nat/Makefile
|
||||
Makefile)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
This contains a set of scripts used for the development of the
|
||||
MSC functionality.
|
||||
58
openbsc/contrib/gprs/gb-proxy-unblock-bug.py
Executable file
58
openbsc/contrib/gprs/gb-proxy-unblock-bug.py
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
demonstrate a unblock bug on the GB Proxy..
|
||||
"""
|
||||
|
||||
bts_ns_reset = "\x02\x00\x81\x01\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
|
||||
ns_reset_ack = "\x03\x01\x82\x1f\xe7\x04\x82\x1f\xe7"
|
||||
|
||||
bts_ns_unblock = "\x06"
|
||||
ns_unblock_ack = "\x07"
|
||||
|
||||
bts_bvc_reset_0 = "\x00\x00\x00\x00\x22\x04\x82\x00\x00\x07\x81\x03\x3b\x81\x02"
|
||||
ns_bvc_reset_0_ack = "\x00\x00\x00\x00\x23\x04\x82\x00\x00"
|
||||
|
||||
bts_bvc_reset_8167 = "\x00\x00\x00\x00\x22\x04\x82\x1f\xe7\x07\x81\x08\x08\x88\x72\xf4\x80\x10\x1c\x00\x9c\x40"
|
||||
|
||||
|
||||
import socket
|
||||
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
socket.bind(("0.0.0.0", 0))
|
||||
socket.setblocking(1)
|
||||
|
||||
|
||||
import sys
|
||||
port = int(sys.argv[1])
|
||||
print "Sending data to port: %d" % port
|
||||
|
||||
def send_and_receive(packet):
|
||||
socket.sendto(packet, ("127.0.0.1", port))
|
||||
|
||||
try:
|
||||
data, addr = socket.recvfrom(4096)
|
||||
except socket.error, e:
|
||||
print "ERROR", e
|
||||
import sys
|
||||
sys.exit(0)
|
||||
return data
|
||||
|
||||
#send stuff once
|
||||
|
||||
to_send = [
|
||||
(bts_ns_reset, ns_reset_ack, "reset ack"),
|
||||
(bts_ns_unblock, ns_unblock_ack, "unblock ack"),
|
||||
(bts_bvc_reset_0, ns_bvc_reset_0_ack, "BVCI=0 reset ack"),
|
||||
]
|
||||
|
||||
|
||||
for (out, inp, type) in to_send:
|
||||
res = send_and_receive(out)
|
||||
if res != inp:
|
||||
print "Failed to get the %s" % type
|
||||
sys.exit(-1)
|
||||
|
||||
import time
|
||||
time.sleep(3)
|
||||
res = send_and_receive(bts_bvc_reset_8167)
|
||||
print "Sent all messages... check wireshark for the last response"
|
||||
78
openbsc/contrib/gprs/gprs-bssgp-histogram.lua
Normal file
78
openbsc/contrib/gprs/gprs-bssgp-histogram.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
-- Simple LUA script to print the size of BSSGP messages over their type...
|
||||
|
||||
do
|
||||
local ip_bucket = {}
|
||||
|
||||
local pdu_types = {}
|
||||
pdu_types[ 6] = "PAGING"
|
||||
pdu_types[11] = "SUSPEND"
|
||||
pdu_types[12] = "SUSPEND-ACK"
|
||||
pdu_types[32] = "BVC-BLOCK"
|
||||
pdu_types[33] = "BVC-BLOCK-ACK"
|
||||
pdu_types[34] = "BVC-RESET"
|
||||
pdu_types[35] = "BVC-RESET-ACK"
|
||||
pdu_types[36] = "UNBLOCK"
|
||||
pdu_types[37] = "UNBLOCK-ACK"
|
||||
pdu_types[38] = "FLOW-CONTROL-BVC"
|
||||
pdu_types[39] = "FLOW-CONTROL-BVC-ACK"
|
||||
pdu_types[40] = "FLOW-CONTROL-MS"
|
||||
pdu_types[41] = "FLOW-CONTROL-MS-ACK"
|
||||
pdu_types[44] = "LLC-DISCARDED"
|
||||
|
||||
local function init_listener()
|
||||
-- handle the port as NS over IP
|
||||
local udp_port_table = DissectorTable.get("udp.port")
|
||||
local gprs_ns_dis = Dissector.get("gprs_ns")
|
||||
udp_port_table:add(23000,gprs_ns_dis)
|
||||
|
||||
-- bssgp filters
|
||||
local bssgp_pdu_get = Field.new("bssgp.pdu_type")
|
||||
local udp_length_get = Field.new("udp.length")
|
||||
|
||||
local tap = Listener.new("ip", "udp.port == 23000")
|
||||
function tap.packet(pinfo,tvb,ip)
|
||||
local pdu = bssgp_pdu_get()
|
||||
local len = udp_length_get()
|
||||
|
||||
-- only handle bssgp, but we also want the IP frame
|
||||
if not pdu then
|
||||
return
|
||||
end
|
||||
|
||||
pdu = tostring(pdu)
|
||||
if tonumber(pdu) == 0 or tonumber(pdu) == 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local ip_src = tostring(ip.ip_src)
|
||||
local bssgp_histo = ip_bucket[ip_src]
|
||||
if not bssgp_histo then
|
||||
bssgp_histo = {}
|
||||
ip_bucket[ip_src] = bssgp_histo
|
||||
end
|
||||
|
||||
local key = pdu
|
||||
local bucket = bssgp_histo[key]
|
||||
if not bucket then
|
||||
bucket = {}
|
||||
bssgp_histo[key] = bucket
|
||||
end
|
||||
|
||||
table.insert(bucket, tostring(len))
|
||||
print("IP: " .. ip_src .. " PDU: " .. pdu_types[tonumber(pdu)] .. " Length: " .. tostring(len))
|
||||
end
|
||||
|
||||
function tap.draw()
|
||||
-- well... this will not be called...
|
||||
-- for ip,bssgp_histo in pairs(dumpers) do
|
||||
-- print("IP " .. ip)
|
||||
-- end
|
||||
end
|
||||
|
||||
function tap.reset()
|
||||
-- well... this will not be called...
|
||||
end
|
||||
end
|
||||
|
||||
init_listener()
|
||||
end
|
||||
46
openbsc/contrib/gprs/gprs-split-trace-by-tlli.lua
Normal file
46
openbsc/contrib/gprs/gprs-split-trace-by-tlli.lua
Normal file
@@ -0,0 +1,46 @@
|
||||
-- Create a file named by_ip/''ip_addess''.cap with all ip traffic of each ip host. (works for tshark only)
|
||||
-- Dump files are created for both source and destination hosts
|
||||
do
|
||||
local dir = "by_tlli"
|
||||
local dumpers = {}
|
||||
local function init_listener()
|
||||
local udp_port_table = DissectorTable.get("udp.port")
|
||||
local gprs_ns_dis = Dissector.get("gprs_ns")
|
||||
udp_port_table:add(23000,gprs_ns_dis)
|
||||
|
||||
local field_tlli = Field.new("bssgp.tlli")
|
||||
local tap = Listener.new("ip", "udp.port == 23000")
|
||||
|
||||
-- we will be called once for every IP Header.
|
||||
-- If there's more than one IP header in a given packet we'll dump the packet once per every header
|
||||
function tap.packet(pinfo,tvb,ip)
|
||||
local tlli = field_tlli()
|
||||
if not tlli then
|
||||
return
|
||||
end
|
||||
|
||||
local tlli_str = tostring(tlli)
|
||||
tlli_dmp = dumpers[tlli_str]
|
||||
if not tlli_dmp then
|
||||
local tlli_hex = string.format("0x%x", tonumber(tlli_str))
|
||||
print("Creating dump for TLLI " .. tlli_hex)
|
||||
tlli_dmp = Dumper.new_for_current(dir .. "/" .. tlli_hex .. ".pcap")
|
||||
dumpers[tlli_str] = tlli_dmp
|
||||
end
|
||||
tlli_dmp:dump_current()
|
||||
tlli_dmp:flush()
|
||||
end
|
||||
function tap.draw()
|
||||
for tlli,dumper in pairs(dumpers) do
|
||||
dumper:flush()
|
||||
end
|
||||
end
|
||||
function tap.reset()
|
||||
for tlli,dumper in pairs(dumpers) do
|
||||
dumper:close()
|
||||
end
|
||||
dumpers = {}
|
||||
end
|
||||
end
|
||||
init_listener()
|
||||
end
|
||||
59
openbsc/contrib/gprs/gprs-verify-nu.lua
Normal file
59
openbsc/contrib/gprs/gprs-verify-nu.lua
Normal file
@@ -0,0 +1,59 @@
|
||||
-- This script verifies that the N(U) is increasing...
|
||||
--
|
||||
do
|
||||
local nu_state_src = {}
|
||||
|
||||
local function init_listener()
|
||||
-- handle the port as NS over IP
|
||||
local udp_port_table = DissectorTable.get("udp.port")
|
||||
local gprs_ns_dis = Dissector.get("gprs_ns")
|
||||
udp_port_table:add(23000,gprs_ns_dis)
|
||||
|
||||
-- we want to look here...
|
||||
local llc_sapi_get = Field.new("llcgprs.sapib")
|
||||
local llc_nu_get = Field.new("llcgprs.nu")
|
||||
local bssgp_tlli_get = Field.new("bssgp.tlli")
|
||||
|
||||
local tap = Listener.new("ip", "udp.port == 23000")
|
||||
function tap.packet(pinfo,tvb,ip)
|
||||
local llc_sapi = llc_sapi_get()
|
||||
local llc_nu = llc_nu_get()
|
||||
local bssgp_tlli = bssgp_tlli_get()
|
||||
|
||||
if not llc_sapi or not llc_nu or not bssgp_tlli then
|
||||
return
|
||||
end
|
||||
|
||||
local ip_src = tostring(ip.ip_src)
|
||||
local bssgp_tlli = tostring(bssgp_tlli)
|
||||
local llc_nu = tostring(llc_nu)
|
||||
local llc_sapi = tostring(llc_sapi)
|
||||
|
||||
local src_key = ip_src .. "-" .. bssgp_tlli .. "-" .. llc_sapi
|
||||
local last_nu = nu_state_src[src_key]
|
||||
if not last_nu then
|
||||
-- print("Establishing mapping for " .. src_key)
|
||||
nu_state_src[src_key] = llc_nu
|
||||
return
|
||||
end
|
||||
|
||||
local function tohex(number)
|
||||
return string.format("0x%x", tonumber(number))
|
||||
end
|
||||
|
||||
nu_state_src[src_key] = llc_nu
|
||||
if tonumber(last_nu) + 1 ~= tonumber(llc_nu) then
|
||||
print("JUMP in N(U) on TLLI " .. tohex(bssgp_tlli) .. " and SAPI: " .. llc_sapi .. " src: " .. ip_src)
|
||||
print("\t last: " .. last_nu .. " now: " .. llc_nu)
|
||||
end
|
||||
end
|
||||
|
||||
function tap.draw()
|
||||
end
|
||||
|
||||
function tap.reset()
|
||||
end
|
||||
end
|
||||
init_listener()
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ rsip_resp = """200 321321332\r\n"""
|
||||
audit_packet = """AUEP %d 13@mgw MGCP 1.0\r\n"""
|
||||
crcx_packet = """CRCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n"""
|
||||
dlcx_packet = """DLCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\n"""
|
||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 4400 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
|
||||
mdcx_packet = """MDCX %d 14@mgw MGCP 1.0\r\nC: 4a84ad5d25f\r\nI: %d\r\nL: p:20, a:GSM-EFR, nt:IN\r\nM: recvonly\r\n\r\nv=0\r\no=- 258696477 0 IN IP4 172.16.1.107\r\ns=-\r\nc=IN IP4 172.16.1.107\r\nt=0 0\r\nm=audio 6666 RTP/AVP 127\r\na=rtpmap:127 GSM-EFR/8000/1\r\na=ptime:20\r\na=recvonly\r\nm=image 4402 udptl t38\r\na=T38FaxVersion:0\r\na=T38MaxBitRate:14400\r\n"""
|
||||
|
||||
def hexdump(src, length=8):
|
||||
"""Recipe is from http://code.activestate.com/recipes/142812/"""
|
||||
@@ -25,15 +25,24 @@ def hexdump(src, length=8):
|
||||
|
||||
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
server_socket.bind(("127.0.0.1", MGCP_CALLAGENT_PORT))
|
||||
server_socket.setblocking(0)
|
||||
server_socket.setblocking(1)
|
||||
|
||||
|
||||
def send_receive(packet):
|
||||
last_ci = 1
|
||||
def send_and_receive(packet):
|
||||
global last_ci
|
||||
server_socket.sendto(packet, ("127.0.0.1", MGCP_GATEWAY_PORT))
|
||||
try:
|
||||
data, addr = server_socket.recvfrom(4096)
|
||||
|
||||
# attempt to store the CI of the response
|
||||
list = data.split("\n")
|
||||
for item in list:
|
||||
if item.startswith("I: "):
|
||||
last_ci = int(item[3:])
|
||||
|
||||
print hexdump(data), addr
|
||||
except socket.error:
|
||||
except socket.error, e:
|
||||
print e
|
||||
pass
|
||||
|
||||
def generate_tid():
|
||||
@@ -42,13 +51,10 @@ def generate_tid():
|
||||
|
||||
|
||||
|
||||
i = 1
|
||||
while True:
|
||||
send_receive(rsip_resp)
|
||||
send_receive(audit_packet)
|
||||
send_receive(crcx_packet % generate_tid() )
|
||||
send_receive(mdcx_packet % (generate_tid(), i))
|
||||
send_receive(dlcx_packet % (generate_tid(), i))
|
||||
i = i + 1
|
||||
send_and_receive(audit_packet % generate_tid())
|
||||
send_and_receive(crcx_packet % generate_tid() )
|
||||
send_and_receive(mdcx_packet % (generate_tid(), last_ci))
|
||||
send_and_receive(dlcx_packet % (generate_tid(), last_ci))
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# packages
|
||||
ACK ="\x00\x01\xfe\x06"
|
||||
RESET_ACK = "\x00\x13\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x03\x00\x01\x31"
|
||||
PAGE = "\x00\x20\xfd\x09\x00\x03\x07\x0b\x04\x43\x01\x00\xfe\x04\x43\x5c\x00\xfe\x10\x00\x0e\x52\x08\x08\x29\x42\x08\x05\x03\x12\x23\x42\x1a\x01\x06"
|
||||
|
||||
|
||||
# simple handshake...
|
||||
sys.stdout.write(ACK)
|
||||
sys.stdout.flush()
|
||||
sys.stdin.read(4)
|
||||
|
||||
# wait for some data and send reset ack
|
||||
sys.stdin.read(21)
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
sys.stdout.write(RESET_ACK)
|
||||
sys.stdout.flush()
|
||||
|
||||
# page a subscriber
|
||||
sys.stdout.write(PAGE)
|
||||
sys.stdout.flush()
|
||||
|
||||
while True:
|
||||
sys.stdin.read(1)
|
||||
|
||||
@@ -31,6 +31,8 @@ GSM 04.08 3.4.13: RR connection release procedure
|
||||
|
||||
== Implementation in OpenBSC ==
|
||||
|
||||
THIS IS OUTDATED and will be updated...
|
||||
|
||||
chan_alloc.c:lchan_auto_release()
|
||||
* checks if use count still > 0 (abort)
|
||||
* calls gsm48_send_rr_release()
|
||||
|
||||
151
openbsc/git-version-gen
Executable file
151
openbsc/git-version-gen
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2010-01-28.01
|
||||
|
||||
# Copyright (C) 2007-2010 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
|
||||
# It may be run two ways:
|
||||
# - from a git repository in which the "git describe" command below
|
||||
# produces useful output (thus requiring at least one signed tag)
|
||||
# - from a non-git-repo directory containing a .tarball-version file, which
|
||||
# presumes this script is invoked like "./git-version-gen .tarball-version".
|
||||
|
||||
# In order to use intra-version strings in your project, you will need two
|
||||
# separate generated version string files:
|
||||
#
|
||||
# .tarball-version - present only in a distribution tarball, and not in
|
||||
# a checked-out repository. Created with contents that were learned at
|
||||
# the last time autoconf was run, and used by git-version-gen. Must not
|
||||
# be present in either $(srcdir) or $(builddir) for git-version-gen to
|
||||
# give accurate answers during normal development with a checked out tree,
|
||||
# but must be present in a tarball when there is no version control system.
|
||||
# Therefore, it cannot be used in any dependencies. GNUmakefile has
|
||||
# hooks to force a reconfigure at distribution time to get the value
|
||||
# correct, without penalizing normal development with extra reconfigures.
|
||||
#
|
||||
# .version - present in a checked-out repository and in a distribution
|
||||
# tarball. Usable in dependencies, particularly for files that don't
|
||||
# want to depend on config.h but do want to track version changes.
|
||||
# Delete this file prior to any autoconf run where you want to rebuild
|
||||
# files to pick up a version string change; and leave it stale to
|
||||
# minimize rebuild time after unrelated changes to configure sources.
|
||||
#
|
||||
# It is probably wise to add these two files to .gitignore, so that you
|
||||
# don't accidentally commit either generated file.
|
||||
#
|
||||
# Use the following line in your configure.ac, so that $(VERSION) will
|
||||
# automatically be up-to-date each time configure is run (and note that
|
||||
# since configure.ac no longer includes a version string, Makefile rules
|
||||
# should not depend on configure.ac for version updates).
|
||||
#
|
||||
# AC_INIT([GNU project],
|
||||
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
# [bug-project@example])
|
||||
#
|
||||
# Then use the following lines in your Makefile.am, so that .version
|
||||
# will be present for dependencies, and so that .tarball-version will
|
||||
# exist in distribution tarballs.
|
||||
#
|
||||
# BUILT_SOURCES = $(top_srcdir)/.version
|
||||
# $(top_srcdir)/.version:
|
||||
# echo $(VERSION) > $@-t && mv $@-t $@
|
||||
# dist-hook:
|
||||
# echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
case $# in
|
||||
1) ;;
|
||||
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;;
|
||||
esac
|
||||
|
||||
tarball_version_file=$1
|
||||
nl='
|
||||
'
|
||||
|
||||
# First see if there is a tarball-only version file.
|
||||
# then try "git describe", then default.
|
||||
if test -f $tarball_version_file
|
||||
then
|
||||
v=`cat $tarball_version_file` || exit 1
|
||||
case $v in
|
||||
*$nl*) v= ;; # reject multi-line output
|
||||
[0-9]*) ;;
|
||||
*) v= ;;
|
||||
esac
|
||||
test -z "$v" \
|
||||
&& echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2
|
||||
fi
|
||||
|
||||
if test -n "$v"
|
||||
then
|
||||
: # use $v
|
||||
elif test -d ./../.git \
|
||||
&& v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \
|
||||
|| git describe --abbrev=4 HEAD 2>/dev/null` \
|
||||
&& case $v in
|
||||
[0-9]*) ;;
|
||||
v[0-9]*) ;;
|
||||
*) (exit 1) ;;
|
||||
esac
|
||||
then
|
||||
# Is this a new git that lists number of commits since the last
|
||||
# tag or the previous older version that did not?
|
||||
# Newer: v6.10-77-g0f8faeb
|
||||
# Older: v6.10-g0f8faeb
|
||||
case $v in
|
||||
*-*-*) : git describe is okay three part flavor ;;
|
||||
*-*)
|
||||
: git describe is older two part flavor
|
||||
# Recreate the number of commits and rewrite such that the
|
||||
# result is the same as if we were using the newer version
|
||||
# of git describe.
|
||||
vtag=`echo "$v" | sed 's/-.*//'`
|
||||
numcommits=`git rev-list "$vtag"..HEAD | wc -l`
|
||||
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
|
||||
;;
|
||||
esac
|
||||
|
||||
# Change the first '-' to a '.', so version-comparing tools work properly.
|
||||
# Remove the "g" in git describe's output string, to save a byte.
|
||||
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
|
||||
else
|
||||
v=UNKNOWN
|
||||
fi
|
||||
|
||||
v=`echo "$v" |sed 's/^v//'`
|
||||
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
git status > /dev/null 2>&1
|
||||
|
||||
dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty=
|
||||
case "$dirty" in
|
||||
'') ;;
|
||||
*) # Append the suffix only if there isn't one already.
|
||||
case $v in
|
||||
*-dirty) ;;
|
||||
*) v="$v-dirty" ;;
|
||||
esac ;;
|
||||
esac
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d '\012'
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-end: "$"
|
||||
# End:
|
||||
@@ -1,3 +1,3 @@
|
||||
SUBDIRS = openbsc vty sccp
|
||||
SUBDIRS = openbsc
|
||||
|
||||
noinst_HEADERS = mISDNif.h compat_af_isdn.h
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
noinst_HEADERS = abis_nm.h abis_rsl.h debug.h db.h gsm_04_08.h gsm_data.h \
|
||||
gsm_subscriber.h linuxlist.h msgb.h select.h tlv.h gsm_04_11.h \
|
||||
timer.h misdn.h chan_alloc.h telnet_interface.h paging.h \
|
||||
subchan_demux.h trau_frame.h e1_input.h trau_mux.h signal.h \
|
||||
gsm_utils.h ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
|
||||
bsc_rll.h mncc.h talloc.h transaction.h ussd.h gsm_04_80.h \
|
||||
silent_call.h mgcp.h meas_rep.h bitvec.h rest_octets.h \
|
||||
system_information.h handover.h bssap.h bsc_msc.h bsc_nat.h
|
||||
noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \
|
||||
gsm_subscriber.h gsm_04_11.h debug.h signal.h \
|
||||
misdn.h chan_alloc.h paging.h \
|
||||
subchan_demux.h trau_frame.h e1_input.h trau_mux.h \
|
||||
ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \
|
||||
bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \
|
||||
silent_call.h mgcp.h meas_rep.h rest_octets.h \
|
||||
system_information.h handover.h mgcp_internal.h \
|
||||
vty.h socket.h \
|
||||
crc24.h gprs_bssgp.h gprs_llc.h gprs_ns.h gprs_gmm.h \
|
||||
gb_proxy.h gprs_sgsn.h gsm_04_08_gprs.h sgsn.h \
|
||||
gprs_ns_frgre.h auth.h osmo_msc.h bsc_msc.h bsc_nat.h \
|
||||
osmo_bsc_rf.h osmo_bsc.h network_listen.h bsc_nat_sccp.h
|
||||
|
||||
openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h
|
||||
openbscdir = $(includedir)/openbsc
|
||||
|
||||
@@ -24,665 +24,8 @@
|
||||
#define _NM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openbsc/tlv.h>
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
/* generic header in front of every OML message according to TS 08.59 */
|
||||
struct abis_om_hdr {
|
||||
u_int8_t mdisc;
|
||||
u_int8_t placement;
|
||||
u_int8_t sequence;
|
||||
u_int8_t length;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_MDISC_FOM 0x80
|
||||
#define ABIS_OM_MDISC_MMI 0x40
|
||||
#define ABIS_OM_MDISC_TRAU 0x20
|
||||
#define ABIS_OM_MDISC_MANUF 0x10
|
||||
#define ABIS_OM_PLACEMENT_ONLY 0x80
|
||||
#define ABIS_OM_PLACEMENT_FIRST 0x40
|
||||
#define ABIS_OM_PLACEMENT_MIDDLE 0x20
|
||||
#define ABIS_OM_PLACEMENT_LAST 0x10
|
||||
|
||||
struct abis_om_obj_inst {
|
||||
u_int8_t bts_nr;
|
||||
u_int8_t trx_nr;
|
||||
u_int8_t ts_nr;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct abis_om_fom_hdr {
|
||||
u_int8_t msg_type;
|
||||
u_int8_t obj_class;
|
||||
struct abis_om_obj_inst obj_inst;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define ABIS_OM_FOM_HDR_SIZE (sizeof(struct abis_om_hdr) + sizeof(struct abis_om_fom_hdr))
|
||||
|
||||
/* Section 9.1: Message Types */
|
||||
enum abis_nm_msgtype {
|
||||
/* SW Download Management Messages */
|
||||
NM_MT_LOAD_INIT = 0x01,
|
||||
NM_MT_LOAD_INIT_ACK,
|
||||
NM_MT_LOAD_INIT_NACK,
|
||||
NM_MT_LOAD_SEG,
|
||||
NM_MT_LOAD_SEG_ACK,
|
||||
NM_MT_LOAD_ABORT,
|
||||
NM_MT_LOAD_END,
|
||||
NM_MT_LOAD_END_ACK,
|
||||
NM_MT_LOAD_END_NACK,
|
||||
NM_MT_SW_ACT_REQ, /* BTS->BSC */
|
||||
NM_MT_SW_ACT_REQ_ACK,
|
||||
NM_MT_SW_ACT_REQ_NACK,
|
||||
NM_MT_ACTIVATE_SW, /* BSC->BTS */
|
||||
NM_MT_ACTIVATE_SW_ACK,
|
||||
NM_MT_ACTIVATE_SW_NACK,
|
||||
NM_MT_SW_ACTIVATED_REP, /* 0x10 */
|
||||
/* A-bis Interface Management Messages */
|
||||
NM_MT_ESTABLISH_TEI = 0x21,
|
||||
NM_MT_ESTABLISH_TEI_ACK,
|
||||
NM_MT_ESTABLISH_TEI_NACK,
|
||||
NM_MT_CONN_TERR_SIGN,
|
||||
NM_MT_CONN_TERR_SIGN_ACK,
|
||||
NM_MT_CONN_TERR_SIGN_NACK,
|
||||
NM_MT_DISC_TERR_SIGN,
|
||||
NM_MT_DISC_TERR_SIGN_ACK,
|
||||
NM_MT_DISC_TERR_SIGN_NACK,
|
||||
NM_MT_CONN_TERR_TRAF,
|
||||
NM_MT_CONN_TERR_TRAF_ACK,
|
||||
NM_MT_CONN_TERR_TRAF_NACK,
|
||||
NM_MT_DISC_TERR_TRAF,
|
||||
NM_MT_DISC_TERR_TRAF_ACK,
|
||||
NM_MT_DISC_TERR_TRAF_NACK,
|
||||
/* Transmission Management Messages */
|
||||
NM_MT_CONN_MDROP_LINK = 0x31,
|
||||
NM_MT_CONN_MDROP_LINK_ACK,
|
||||
NM_MT_CONN_MDROP_LINK_NACK,
|
||||
NM_MT_DISC_MDROP_LINK,
|
||||
NM_MT_DISC_MDROP_LINK_ACK,
|
||||
NM_MT_DISC_MDROP_LINK_NACK,
|
||||
/* Air Interface Management Messages */
|
||||
NM_MT_SET_BTS_ATTR = 0x41,
|
||||
NM_MT_SET_BTS_ATTR_ACK,
|
||||
NM_MT_SET_BTS_ATTR_NACK,
|
||||
NM_MT_SET_RADIO_ATTR,
|
||||
NM_MT_SET_RADIO_ATTR_ACK,
|
||||
NM_MT_SET_RADIO_ATTR_NACK,
|
||||
NM_MT_SET_CHAN_ATTR,
|
||||
NM_MT_SET_CHAN_ATTR_ACK,
|
||||
NM_MT_SET_CHAN_ATTR_NACK,
|
||||
/* Test Management Messages */
|
||||
NM_MT_PERF_TEST = 0x51,
|
||||
NM_MT_PERF_TEST_ACK,
|
||||
NM_MT_PERF_TEST_NACK,
|
||||
NM_MT_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP,
|
||||
NM_MT_SEND_TEST_REP_ACK,
|
||||
NM_MT_SEND_TEST_REP_NACK,
|
||||
NM_MT_STOP_TEST,
|
||||
NM_MT_STOP_TEST_ACK,
|
||||
NM_MT_STOP_TEST_NACK,
|
||||
/* State Management and Event Report Messages */
|
||||
NM_MT_STATECHG_EVENT_REP = 0x61,
|
||||
NM_MT_FAILURE_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP,
|
||||
NM_MT_STOP_EVENT_REP_ACK,
|
||||
NM_MT_STOP_EVENT_REP_NACK,
|
||||
NM_MT_REST_EVENT_REP,
|
||||
NM_MT_REST_EVENT_REP_ACK,
|
||||
NM_MT_REST_EVENT_REP_NACK,
|
||||
NM_MT_CHG_ADM_STATE,
|
||||
NM_MT_CHG_ADM_STATE_ACK,
|
||||
NM_MT_CHG_ADM_STATE_NACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ,
|
||||
NM_MT_CHG_ADM_STATE_REQ_ACK,
|
||||
NM_MT_CHG_ADM_STATE_REQ_NACK,
|
||||
NM_MT_REP_OUTST_ALARMS = 0x93,
|
||||
NM_MT_REP_OUTST_ALARMS_ACK,
|
||||
NM_MT_REP_OUTST_ALARMS_NACK,
|
||||
/* Equipment Management Messages */
|
||||
NM_MT_CHANGEOVER = 0x71,
|
||||
NM_MT_CHANGEOVER_ACK,
|
||||
NM_MT_CHANGEOVER_NACK,
|
||||
NM_MT_OPSTART,
|
||||
NM_MT_OPSTART_ACK,
|
||||
NM_MT_OPSTART_NACK,
|
||||
NM_MT_REINIT,
|
||||
NM_MT_REINIT_ACK,
|
||||
NM_MT_REINIT_NACK,
|
||||
NM_MT_SET_SITE_OUT, /* BS11: get alarm ?!? */
|
||||
NM_MT_SET_SITE_OUT_ACK,
|
||||
NM_MT_SET_SITE_OUT_NACK,
|
||||
NM_MT_CHG_HW_CONF = 0x90,
|
||||
NM_MT_CHG_HW_CONF_ACK,
|
||||
NM_MT_CHG_HW_CONF_NACK,
|
||||
/* Measurement Management Messages */
|
||||
NM_MT_MEAS_RES_REQ = 0x8a,
|
||||
NM_MT_MEAS_RES_RESP,
|
||||
NM_MT_STOP_MEAS,
|
||||
NM_MT_START_MEAS,
|
||||
/* Other Messages */
|
||||
NM_MT_GET_ATTR = 0x81,
|
||||
NM_MT_GET_ATTR_RESP,
|
||||
NM_MT_GET_ATTR_NACK,
|
||||
NM_MT_SET_ALARM_THRES,
|
||||
NM_MT_SET_ALARM_THRES_ACK,
|
||||
NM_MT_SET_ALARM_THRES_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_bs11 {
|
||||
NM_MT_BS11_RESET_RESOURCE = 0x74,
|
||||
|
||||
NM_MT_BS11_BEGIN_DB_TX = 0xa3,
|
||||
NM_MT_BS11_BEGIN_DB_TX_ACK,
|
||||
NM_MT_BS11_BEGIN_DB_TX_NACK,
|
||||
NM_MT_BS11_END_DB_TX = 0xa6,
|
||||
NM_MT_BS11_END_DB_TX_ACK,
|
||||
NM_MT_BS11_END_DB_TX_NACK,
|
||||
NM_MT_BS11_CREATE_OBJ = 0xa9,
|
||||
NM_MT_BS11_CREATE_OBJ_ACK,
|
||||
NM_MT_BS11_CREATE_OBJ_NACK,
|
||||
NM_MT_BS11_DELETE_OBJ = 0xac,
|
||||
NM_MT_BS11_DELETE_OBJ_ACK,
|
||||
NM_MT_BS11_DELETE_OBJ_NACK,
|
||||
|
||||
NM_MT_BS11_SET_ATTR = 0xd0,
|
||||
NM_MT_BS11_SET_ATTR_ACK,
|
||||
NM_MT_BS11_SET_ATTR_NACK,
|
||||
NM_MT_BS11_LMT_SESSION = 0xdc,
|
||||
|
||||
NM_MT_BS11_GET_STATE = 0xe3,
|
||||
NM_MT_BS11_GET_STATE_ACK,
|
||||
NM_MT_BS11_LMT_LOGON = 0xe5,
|
||||
NM_MT_BS11_LMT_LOGON_ACK,
|
||||
NM_MT_BS11_RESTART = 0xe7,
|
||||
NM_MT_BS11_RESTART_ACK,
|
||||
NM_MT_BS11_DISCONNECT = 0xe9,
|
||||
NM_MT_BS11_DISCONNECT_ACK,
|
||||
NM_MT_BS11_LMT_LOGOFF = 0xec,
|
||||
NM_MT_BS11_LMT_LOGOFF_ACK,
|
||||
NM_MT_BS11_RECONNECT = 0xf1,
|
||||
NM_MT_BS11_RECONNECT_ACK,
|
||||
};
|
||||
|
||||
enum abis_nm_msgtype_ipacc {
|
||||
NM_MT_IPACC_RESTART = 0x87,
|
||||
NM_MT_IPACC_RESTART_ACK,
|
||||
NM_MT_IPACC_RSL_CONNECT = 0xe0,
|
||||
NM_MT_IPACC_RSL_CONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_CONNECT_NACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT = 0xe3,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_ACK,
|
||||
NM_MT_IPACC_RSL_DISCONNECT_NACK,
|
||||
NM_MT_IPACC_CONN_TRAF = 0xe6,
|
||||
NM_MT_IPACC_CONN_TRAF_ACK,
|
||||
NM_MT_IPACC_CONN_TRAF_NACK,
|
||||
NM_MT_IPACC_DEF_BOOT_SW = 0xec,
|
||||
NM_MT_IPACC_DEF_BOOT_SW_ACK,
|
||||
MN_MT_IPACC_DEF_BOOT_SW_NACK,
|
||||
NM_MT_IPACC_SET_NVATTR = 0xef,
|
||||
NM_MT_IPACC_SET_NVATTR_ACK,
|
||||
NM_MT_IPACC_SET_NVATTR_NACK,
|
||||
NM_MT_IPACC_GET_NVATTR = 0xf2,
|
||||
NM_MT_IPACC_GET_NVATTR_ACK,
|
||||
NM_MT_IPACC_GET_NVATTR_NACK,
|
||||
NM_MT_IPACC_SET_ATTR = 0xf5,
|
||||
NM_MT_IPACC_SET_ATTR_ACK,
|
||||
NM_MT_IPACC_SET_ATTR_NACK,
|
||||
};
|
||||
|
||||
enum abis_nm_bs11_cell_alloc {
|
||||
NM_BS11_CANR_GSM = 0x00,
|
||||
NM_BS11_CANR_DCS1800 = 0x01,
|
||||
};
|
||||
|
||||
/* Section 9.2: Object Class */
|
||||
enum abis_nm_obj_class {
|
||||
NM_OC_SITE_MANAGER = 0x00,
|
||||
NM_OC_BTS,
|
||||
NM_OC_RADIO_CARRIER,
|
||||
NM_OC_CHANNEL,
|
||||
NM_OC_BASEB_TRANSC,
|
||||
/* RFU: 05-FE */
|
||||
|
||||
NM_OC_IPAC_E1_TRUNK = 0x0e,
|
||||
NM_OC_IPAC_E1_PORT = 0x0f,
|
||||
NM_OC_IPAC_E1_CHAN = 0x10,
|
||||
NM_OC_IPAC_CLK_MODULE = 0x22,
|
||||
|
||||
NM_OC_BS11_ADJC = 0xa0,
|
||||
NM_OC_BS11_HANDOVER = 0xa1,
|
||||
NM_OC_BS11_PWR_CTRL = 0xa2,
|
||||
NM_OC_BS11_BTSE = 0xa3, /* LMT? */
|
||||
NM_OC_BS11_RACK = 0xa4,
|
||||
NM_OC_BS11 = 0xa5, /* 01: ALCO */
|
||||
NM_OC_BS11_TEST = 0xa6,
|
||||
NM_OC_BS11_ENVABTSE = 0xa8,
|
||||
NM_OC_BS11_BPORT = 0xa9,
|
||||
|
||||
NM_OC_GPRS_NSE = 0xf0,
|
||||
NM_OC_GPRS_CELL = 0xf1,
|
||||
NM_OC_GPRS_NSVC = 0xf2,
|
||||
|
||||
NM_OC_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4: Attributes */
|
||||
enum abis_nm_attr {
|
||||
NM_ATT_ABIS_CHANNEL = 0x01,
|
||||
NM_ATT_ADD_INFO,
|
||||
NM_ATT_ADD_TEXT,
|
||||
NM_ATT_ADM_STATE,
|
||||
NM_ATT_ARFCN_LIST,
|
||||
NM_ATT_AUTON_REPORT,
|
||||
NM_ATT_AVAIL_STATUS,
|
||||
NM_ATT_BCCH_ARFCN,
|
||||
NM_ATT_BSIC,
|
||||
NM_ATT_BTS_AIR_TIMER,
|
||||
NM_ATT_CCCH_L_I_P,
|
||||
NM_ATT_CCCH_L_T,
|
||||
NM_ATT_CHAN_COMB,
|
||||
NM_ATT_CONN_FAIL_CRIT,
|
||||
NM_ATT_DEST,
|
||||
/* res */
|
||||
NM_ATT_EVENT_TYPE = 0x11, /* BS11: file data ?!? */
|
||||
NM_ATT_FILE_ID,
|
||||
NM_ATT_FILE_VERSION,
|
||||
NM_ATT_GSM_TIME,
|
||||
NM_ATT_HSN,
|
||||
NM_ATT_HW_CONFIG,
|
||||
NM_ATT_HW_DESC,
|
||||
NM_ATT_INTAVE_PARAM,
|
||||
NM_ATT_INTERF_BOUND,
|
||||
NM_ATT_LIST_REQ_ATTR,
|
||||
NM_ATT_MAIO,
|
||||
NM_ATT_MANUF_STATE,
|
||||
NM_ATT_MANUF_THRESH,
|
||||
NM_ATT_MANUF_ID,
|
||||
NM_ATT_MAX_TA,
|
||||
NM_ATT_MDROP_LINK, /* 0x20 */
|
||||
NM_ATT_MDROP_NEXT,
|
||||
NM_ATT_NACK_CAUSES,
|
||||
NM_ATT_NY1,
|
||||
NM_ATT_OPER_STATE,
|
||||
NM_ATT_OVERL_PERIOD,
|
||||
NM_ATT_PHYS_CONF,
|
||||
NM_ATT_POWER_CLASS,
|
||||
NM_ATT_POWER_THRESH,
|
||||
NM_ATT_PROB_CAUSE,
|
||||
NM_ATT_RACH_B_THRESH,
|
||||
NM_ATT_LDAVG_SLOTS,
|
||||
NM_ATT_RAD_SUBC,
|
||||
NM_ATT_RF_MAXPOWR_R,
|
||||
NM_ATT_SITE_INPUTS,
|
||||
NM_ATT_SITE_OUTPUTS,
|
||||
NM_ATT_SOURCE, /* 0x30 */
|
||||
NM_ATT_SPEC_PROB,
|
||||
NM_ATT_START_TIME,
|
||||
NM_ATT_T200,
|
||||
NM_ATT_TEI,
|
||||
NM_ATT_TEST_DUR,
|
||||
NM_ATT_TEST_NO,
|
||||
NM_ATT_TEST_REPORT,
|
||||
NM_ATT_VSWR_THRESH,
|
||||
NM_ATT_WINDOW_SIZE,
|
||||
/* Res */
|
||||
NM_ATT_BS11_RSSI_OFFS = 0x3d,
|
||||
NM_ATT_BS11_TXPWR = 0x3e,
|
||||
NM_ATT_BS11_DIVERSITY = 0x3f,
|
||||
/* Res */
|
||||
NM_ATT_TSC = 0x40,
|
||||
NM_ATT_SW_CONFIG,
|
||||
NM_ATT_SW_DESCR,
|
||||
NM_ATT_SEVERITY,
|
||||
NM_ATT_GET_ARI,
|
||||
NM_ATT_HW_CONF_CHG,
|
||||
NM_ATT_OUTST_ALARM,
|
||||
NM_ATT_FILE_DATA,
|
||||
NM_ATT_MEAS_RES,
|
||||
NM_ATT_MEAS_TYPE,
|
||||
|
||||
NM_ATT_BS11_ESN_FW_CODE_NO = 0x4c,
|
||||
NM_ATT_BS11_ESN_HW_CODE_NO = 0x4f,
|
||||
|
||||
NM_ATT_BS11_ESN_PCB_SERIAL = 0x55,
|
||||
NM_ATT_BS11_EXCESSIVE_DISTANCE = 0x58,
|
||||
|
||||
NM_ATT_BS11_ALL_TEST_CATG = 0x60,
|
||||
NM_ATT_BS11_BTSLS_HOPPING,
|
||||
NM_ATT_BS11_CELL_ALLOC_NR,
|
||||
NM_ATT_BS11_CELL_GLOBAL_ID,
|
||||
NM_ATT_BS11_ENA_INTERF_CLASS = 0x66,
|
||||
NM_ATT_BS11_ENA_INT_INTEC_HANDO = 0x67,
|
||||
NM_ATT_BS11_ENA_INT_INTRC_HANDO = 0x68,
|
||||
NM_ATT_BS11_ENA_MS_PWR_CTRL = 0x69,
|
||||
NM_ATT_BS11_ENA_PWR_BDGT_HO = 0x6a,
|
||||
NM_ATT_BS11_ENA_PWR_CTRL_RLFW = 0x6b,
|
||||
NM_ATT_BS11_ENA_RXLEV_HO = 0x6c,
|
||||
NM_ATT_BS11_ENA_RXQUAL_HO = 0x6d,
|
||||
NM_ATT_BS11_FACCH_QUAL = 0x6e,
|
||||
|
||||
NM_ATT_IPACC_DST_IP = 0x80,
|
||||
NM_ATT_IPACC_DST_IP_PORT = 0x81,
|
||||
NM_ATT_IPACC_SSRC = 0x82,
|
||||
NM_ATT_IPACC_RTP_PAYLD_TYPE = 0x83,
|
||||
NM_ATT_IPACC_BASEB_ID = 0x84,
|
||||
NM_ATT_IPACC_STREAM_ID = 0x85,
|
||||
NM_ATT_IPACC_NV_FLAGS = 0x86,
|
||||
NM_ATT_IPACC_FREQ_CTRL = 0x87,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG = 0x88,
|
||||
NM_ATT_IPACC_SEC_OML_CFG = 0x89,
|
||||
NM_ATT_IPACC_IP_IF_CFG = 0x8a, /* IP interface */
|
||||
NM_ATT_IPACC_IP_GW_CFG = 0x8b, /* IP gateway */
|
||||
NM_ATT_IPACC_IN_SERV_TIME = 0x8c,
|
||||
NM_ATT_IPACC_TRX_BTS_ASS = 0x8d,
|
||||
NM_ATT_IPACC_LOCATION = 0x8e, /* string describing location */
|
||||
NM_ATT_IPACC_PAGING_CFG = 0x8f,
|
||||
NM_ATT_IPACC_FILE_DATA = 0x90,
|
||||
NM_ATT_IPACC_UNIT_ID = 0x91, /* Site/BTS/TRX */
|
||||
NM_ATT_IPACC_PARENT_UNIT_ID = 0x92,
|
||||
NM_ATT_IPACC_UNIT_NAME = 0x93, /* default: nbts-<mac-as-string> */
|
||||
NM_ATT_IPACC_SNMP_CFG = 0x94,
|
||||
NM_ATT_IPACC_PRIM_OML_CFG_LIST = 0x95,
|
||||
NM_ATT_IPACC_PRIM_OML_FB_TOUT = 0x96,
|
||||
NM_ATT_IPACC_CUR_SW_CFG = 0x97,
|
||||
NM_ATT_IPACC_TIMING_BUS = 0x98,
|
||||
NM_ATT_IPACC_CGI = 0x99,
|
||||
NM_ATT_IPACC_RAC = 0x9a,
|
||||
NM_ATT_IPACC_OBJ_VERSION = 0x9b,
|
||||
NM_ATT_IPACC_GPRS_PAGING_CFG = 0x9c,
|
||||
NM_ATT_IPACC_NSEI = 0x9d,
|
||||
NM_ATT_IPACC_BVCI = 0x9e,
|
||||
NM_ATT_IPACC_NSVCI = 0x9f,
|
||||
NM_ATT_IPACC_NS_CFG = 0xa0,
|
||||
NM_ATT_IPACC_BSSGP_CFG = 0xa1,
|
||||
NM_ATT_IPACC_NS_LINK_CFG = 0xa2,
|
||||
NM_ATT_IPACC_RLC_CFG = 0xa3,
|
||||
NM_ATT_IPACC_ALM_THRESH_LIST = 0xa4,
|
||||
NM_ATT_IPACC_MONIT_VAL_LIST = 0xa5,
|
||||
NM_ATT_IPACC_TIB_CONTROL = 0xa6,
|
||||
NM_ATT_IPACC_SUPP_FEATURES = 0xa7,
|
||||
NM_ATT_IPACC_CODING_SCHEMES = 0xa8,
|
||||
NM_ATT_IPACC_RLC_CFG_2 = 0xa9,
|
||||
NM_ATT_IPACC_HEARTB_TOUT = 0xaa,
|
||||
NM_ATT_IPACC_UPTIME = 0xab,
|
||||
NM_ATT_IPACC_RLC_CFG_3 = 0xac,
|
||||
NM_ATT_IPACC_SSL_CFG = 0xad,
|
||||
NM_ATT_IPACC_SEC_POSSIBLE = 0xae,
|
||||
NM_ATT_IPACC_IML_SSL_STATE = 0xaf,
|
||||
NM_ATT_IPACC_REVOC_DATE = 0xb0,
|
||||
|
||||
|
||||
NM_ATT_BS11_RF_RES_IND_PER = 0x8f,
|
||||
|
||||
NM_ATT_BS11_RX_LEV_MIN_CELL = 0x90,
|
||||
NM_ATT_BS11_ABIS_EXT_TIME = 0x91,
|
||||
NM_ATT_BS11_TIMER_HO_REQUEST = 0x92,
|
||||
NM_ATT_BS11_TIMER_NCELL = 0x93,
|
||||
NM_ATT_BS11_TSYNC = 0x94,
|
||||
NM_ATT_BS11_TTRAU = 0x95,
|
||||
NM_ATT_BS11_EMRG_CFG_MEMBER = 0x9b,
|
||||
NM_ATT_BS11_TRX_AREA = 0x9f,
|
||||
|
||||
NM_ATT_BS11_BCCH_RECONF = 0xd7,
|
||||
NM_ATT_BS11_BIT_ERR_THESH = 0xa0,
|
||||
NM_ATT_BS11_BOOT_SW_VERS = 0xa1,
|
||||
NM_ATT_BS11_CCLK_ACCURACY = 0xa3,
|
||||
NM_ATT_BS11_CCLK_TYPE = 0xa4,
|
||||
NM_ATT_BS11_INP_IMPEDANCE = 0xaa,
|
||||
NM_ATT_BS11_L1_PROT_TYPE = 0xab,
|
||||
NM_ATT_BS11_LINE_CFG = 0xac,
|
||||
NM_ATT_BS11_LI_PORT_1 = 0xad,
|
||||
NM_ATT_BS11_LI_PORT_2 = 0xae,
|
||||
|
||||
NM_ATT_BS11_L1_REM_ALM_TYPE = 0xb0,
|
||||
NM_ATT_BS11_SW_LOAD_INTENDED = 0xbb,
|
||||
NM_ATT_BS11_SW_LOAD_SAFETY = 0xbc,
|
||||
NM_ATT_BS11_SW_LOAD_STORED = 0xbd,
|
||||
|
||||
NM_ATT_BS11_VENDOR_NAME = 0xc1,
|
||||
NM_ATT_BS11_HOPPING_MODE = 0xc5,
|
||||
NM_ATT_BS11_LMT_LOGON_SESSION = 0xc6,
|
||||
NM_ATT_BS11_LMT_LOGIN_TIME = 0xc7,
|
||||
NM_ATT_BS11_LMT_USER_ACC_LEV = 0xc8,
|
||||
NM_ATT_BS11_LMT_USER_NAME = 0xc9,
|
||||
|
||||
NM_ATT_BS11_L1_CONTROL_TS = 0xd8,
|
||||
NM_ATT_BS11_RADIO_MEAS_GRAN = 0xdc, /* in SACCH multiframes */
|
||||
NM_ATT_BS11_RADIO_MEAS_REP = 0xdd,
|
||||
|
||||
NM_ATT_BS11_SH_LAPD_INT_TIMER = 0xe8,
|
||||
|
||||
NM_ATT_BS11_BTS_STATE = 0xf0,
|
||||
NM_ATT_BS11_E1_STATE = 0xf1,
|
||||
NM_ATT_BS11_PLL = 0xf2,
|
||||
NM_ATT_BS11_RX_OFFSET = 0xf3,
|
||||
NM_ATT_BS11_ANT_TYPE = 0xf4,
|
||||
NM_ATT_BS11_PLL_MODE = 0xfc,
|
||||
NM_ATT_BS11_PASSWORD = 0xfd,
|
||||
};
|
||||
#define NM_ATT_BS11_FILE_DATA NM_ATT_EVENT_TYPE
|
||||
|
||||
/* Section 9.4.4: Administrative State */
|
||||
enum abis_nm_adm_state {
|
||||
NM_STATE_LOCKED = 0x01,
|
||||
NM_STATE_UNLOCKED = 0x02,
|
||||
NM_STATE_SHUTDOWN = 0x03,
|
||||
NM_STATE_NULL = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.7: Administrative State */
|
||||
enum abis_nm_avail_state {
|
||||
NM_AVSTATE_IN_TEST = 1,
|
||||
NM_AVSTATE_POWER_OFF = 2,
|
||||
NM_AVSTATE_OFF_LINE = 3,
|
||||
NM_AVSTATE_DEPENDENCY = 5,
|
||||
NM_AVSTATE_DEGRADED = 6,
|
||||
NM_AVSTATE_NOT_INSTALLED= 7,
|
||||
NM_AVSTATE_OK = 0xff,
|
||||
};
|
||||
|
||||
/* Section 9.4.13: Channel Combination */
|
||||
enum abis_nm_chan_comb {
|
||||
NM_CHANC_TCHFull = 0x00, /* TCH/F + TCH/H + SACCH/TF */
|
||||
NM_CHANC_TCHHalf = 0x01, /* TCH/H(0,1) + FACCH/H(0,1) +
|
||||
SACCH/TH(0,1) */
|
||||
NM_CHANC_TCHHalf2 = 0x02, /* TCH/H(0) + FACCH/H(0) + SACCH/TH(0) +
|
||||
TCH/H(1) */
|
||||
NM_CHANC_SDCCH = 0x03, /* SDCCH/8 + SACCH/8 */
|
||||
NM_CHANC_mainBCCH = 0x04, /* FCCH + SCH + BCCH + CCCH */
|
||||
NM_CHANC_BCCHComb = 0x05, /* FCCH + SCH + BCCH + CCCH + SDCCH/4 +
|
||||
SACCH/C4 */
|
||||
NM_CHANC_BCCH = 0x06, /* BCCH + CCCH */
|
||||
NM_CHANC_BCCH_CBCH = 0x07, /* CHANC_BCCHComb + CBCH */
|
||||
NM_CHANC_SDCCH_CBCH = 0x08, /* CHANC_SDCCH8 + CBCH */
|
||||
/* ip.access */
|
||||
NM_CHANC_IPAC_bPDCH = 0x0b, /* PBCCH + PCCCH + PDTCH/F + PACCH/F +
|
||||
PTCCH/F */
|
||||
NM_CHANC_IPAC_cPDCH = 0x0c, /* PBCCH + PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_PDCH = 0x0d, /* PDTCH/F + PACCH/F + PTCCH/F */
|
||||
NM_CHANC_IPAC_TCHFull_PDCH = 0x80,
|
||||
NM_CHANC_IPAC_TCHFull_TCHHalf = 0x81,
|
||||
};
|
||||
|
||||
/* Section 9.4.16: Event Type */
|
||||
enum abis_nm_event_type {
|
||||
NM_EVT_COMM_FAIL = 0x00,
|
||||
NM_EVT_QOS_FAIL = 0x01,
|
||||
NM_EVT_PROC_FAIL = 0x02,
|
||||
NM_EVT_EQUIP_FAIL = 0x03,
|
||||
NM_EVT_ENV_FAIL = 0x04,
|
||||
};
|
||||
|
||||
/* Section: 9.4.63: Perceived Severity */
|
||||
enum abis_nm_severity {
|
||||
NM_SEVER_CEASED = 0x00,
|
||||
NM_SEVER_CRITICAL = 0x01,
|
||||
NM_SEVER_MAJOR = 0x02,
|
||||
NM_SEVER_MINOR = 0x03,
|
||||
NM_SEVER_WARNING = 0x04,
|
||||
NM_SEVER_INDETERMINATE = 0x05,
|
||||
};
|
||||
|
||||
/* Section 9.4.43: Probable Cause Type */
|
||||
enum abis_nm_pcause_type {
|
||||
NM_PCAUSE_T_X721 = 0x01,
|
||||
NM_PCAUSE_T_GSM = 0x02,
|
||||
NM_PCAUSE_T_MANUF = 0x03,
|
||||
};
|
||||
|
||||
/* Section 9.4.36: NACK Causes */
|
||||
enum abis_nm_nack_cause {
|
||||
/* General Nack Causes */
|
||||
NM_NACK_INCORR_STRUCT = 0x01,
|
||||
NM_NACK_MSGTYPE_INVAL = 0x02,
|
||||
NM_NACK_OBJCLASS_INVAL = 0x05,
|
||||
NM_NACK_OBJCLASS_NOTSUPP = 0x06,
|
||||
NM_NACK_BTSNR_UNKN = 0x07,
|
||||
NM_NACK_TRXNR_UNKN = 0x08,
|
||||
NM_NACK_OBJINST_UNKN = 0x09,
|
||||
NM_NACK_ATTRID_INVAL = 0x0c,
|
||||
NM_NACK_ATTRID_NOTSUPP = 0x0d,
|
||||
NM_NACK_PARAM_RANGE = 0x0e,
|
||||
NM_NACK_ATTRLIST_INCONSISTENT = 0x0f,
|
||||
NM_NACK_SPEC_IMPL_NOTSUPP = 0x10,
|
||||
NM_NACK_CANT_PERFORM = 0x11,
|
||||
/* Specific Nack Causes */
|
||||
NM_NACK_RES_NOTIMPL = 0x19,
|
||||
NM_NACK_RES_NOTAVAIL = 0x1a,
|
||||
NM_NACK_FREQ_NOTAVAIL = 0x1b,
|
||||
NM_NACK_TEST_NOTSUPP = 0x1c,
|
||||
NM_NACK_CAPACITY_RESTR = 0x1d,
|
||||
NM_NACK_PHYSCFG_NOTPERFORM = 0x1e,
|
||||
NM_NACK_TEST_NOTINIT = 0x1f,
|
||||
NM_NACK_PHYSCFG_NOTRESTORE = 0x20,
|
||||
NM_NACK_TEST_NOSUCH = 0x21,
|
||||
NM_NACK_TEST_NOSTOP = 0x22,
|
||||
NM_NACK_MSGINCONSIST_PHYSCFG = 0x23,
|
||||
NM_NACK_FILE_INCOMPLETE = 0x25,
|
||||
NM_NACK_FILE_NOTAVAIL = 0x26,
|
||||
NM_NACK_FILE_NOTACTIVATE = 0x27,
|
||||
NM_NACK_REQ_NOT_GRANT = 0x28,
|
||||
NM_NACK_WAIT = 0x29,
|
||||
NM_NACK_NOTH_REPORT_EXIST = 0x2a,
|
||||
NM_NACK_MEAS_NOTSUPP = 0x2b,
|
||||
NM_NACK_MEAS_NOTSTART = 0x2c,
|
||||
};
|
||||
|
||||
/* Section 9.4.1 */
|
||||
struct abis_nm_channel {
|
||||
u_int8_t attrib;
|
||||
u_int8_t bts_port;
|
||||
u_int8_t timeslot;
|
||||
u_int8_t subslot;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Siemens BS-11 specific objects in the SienemsHW (0xA5) object class */
|
||||
enum abis_bs11_objtype {
|
||||
BS11_OBJ_ALCO = 0x01,
|
||||
BS11_OBJ_BBSIG = 0x02, /* obj_class: 0,1 */
|
||||
BS11_OBJ_TRX1 = 0x03, /* only DEACTIVATE TRX1 */
|
||||
BS11_OBJ_CCLK = 0x04,
|
||||
BS11_OBJ_GPSU = 0x06,
|
||||
BS11_OBJ_LI = 0x07,
|
||||
BS11_OBJ_PA = 0x09, /* obj_class: 0, 1*/
|
||||
};
|
||||
|
||||
enum abis_bs11_trx_power {
|
||||
BS11_TRX_POWER_GSM_2W = 0x06,
|
||||
BS11_TRX_POWER_GSM_250mW= 0x07,
|
||||
BS11_TRX_POWER_GSM_80mW = 0x08,
|
||||
BS11_TRX_POWER_GSM_30mW = 0x09,
|
||||
BS11_TRX_POWER_DCS_3W = 0x0a,
|
||||
BS11_TRX_POWER_DCS_1W6 = 0x0b,
|
||||
BS11_TRX_POWER_DCS_500mW= 0x0c,
|
||||
BS11_TRX_POWER_DCS_160mW= 0x0d,
|
||||
};
|
||||
|
||||
enum abis_bs11_li_pll_mode {
|
||||
BS11_LI_PLL_LOCKED = 2,
|
||||
BS11_LI_PLL_STANDALONE = 3,
|
||||
};
|
||||
|
||||
enum abis_bs11_line_cfg {
|
||||
BS11_LINE_CFG_STAR = 0x00,
|
||||
BS11_LINE_CFG_MULTIDROP = 0x01,
|
||||
BS11_LINE_CFG_LOOP = 0x02,
|
||||
};
|
||||
|
||||
enum abis_bs11_phase {
|
||||
BS11_STATE_SOFTWARE_RQD = 0x01,
|
||||
BS11_STATE_LOAD_SMU_INTENDED = 0x11,
|
||||
BS11_STATE_LOAD_SMU_SAFETY = 0x21,
|
||||
BS11_STATE_LOAD_FAILED = 0x31,
|
||||
BS11_STATE_LOAD_DIAGNOSTIC = 0x41,
|
||||
BS11_STATE_WARM_UP = 0x51,
|
||||
BS11_STATE_WARM_UP_2 = 0x52,
|
||||
BS11_STATE_WAIT_MIN_CFG = 0x62,
|
||||
BS11_STATE_MAINTENANCE = 0x72,
|
||||
BS11_STATE_LOAD_MBCCU = 0x92,
|
||||
BS11_STATE_WAIT_MIN_CFG_2 = 0xA2,
|
||||
BS11_STATE_NORMAL = 0x03,
|
||||
BS11_STATE_ABIS_LOAD = 0x13,
|
||||
};
|
||||
|
||||
enum abis_nm_ipacc_test_no {
|
||||
NM_IPACC_TESTNO_RLOOP_ANT = 0x01,
|
||||
NM_IPACC_TESTNO_RLOOP_XCVR = 0x02,
|
||||
NM_IPACC_TESTNO_FUNC_OBJ = 0x03,
|
||||
NM_IPACC_TESTNO_CHAN_USAGE = 0x40,
|
||||
NM_IPACC_TESTNO_BCCH_CHAN_USAGE = 0x41,
|
||||
NM_IPACC_TESTNO_FREQ_SYNC = 0x42,
|
||||
NM_IPACC_TESTNO_BCCH_INFO = 0x43,
|
||||
NM_IPACC_TESTNO_TX_BEACON = 0x44,
|
||||
NM_IPACC_TESTNO_SYSINFO_MONITOR = 0x45,
|
||||
NM_IPACC_TESTNO_BCCCH_MONITOR = 0x46,
|
||||
};
|
||||
|
||||
/* first byte after length inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_test_res {
|
||||
NM_IPACC_TESTRES_SUCCESS = 0,
|
||||
NM_IPACC_TESTRES_TIMEOUT = 1,
|
||||
NM_IPACC_TESTRES_NO_CHANS = 2,
|
||||
NM_IPACC_TESTRES_PARTIAL = 3,
|
||||
NM_IPACC_TESTRES_STOPPED = 4,
|
||||
};
|
||||
|
||||
/* internal IE inside NM_ATT_TEST_REPORT */
|
||||
enum abis_nm_ipacc_testres_ie {
|
||||
NM_IPACC_TR_IE_FREQ_ERR_LIST = 3,
|
||||
NM_IPACC_TR_IE_CHAN_USAGE = 4,
|
||||
NM_IPACC_TR_IE_BCCH_INFO = 6,
|
||||
NM_IPACC_TR_IE_RESULT_DETAILS = 8,
|
||||
NM_IPACC_TR_IE_FREQ_ERR = 18,
|
||||
};
|
||||
|
||||
enum ipac_eie {
|
||||
NM_IPAC_EIE_ARFCN_WHITE = 0x01,
|
||||
NM_IPAC_EIE_ARFCH_BLACK = 0x02,
|
||||
NM_IPAC_EIE_FREQ_ERR_LIST = 0x03,
|
||||
NM_IPAC_EIE_CHAN_USE_LIST = 0x04,
|
||||
NM_IPAC_EIE_BCCH_INFO_TYPE = 0x05,
|
||||
NM_IPAC_EIE_BCCH_INFO = 0x06,
|
||||
/* FIXME */
|
||||
};
|
||||
|
||||
enum ipac_bcch_info_type {
|
||||
IPAC_BINF_RXLEV = (1 << 8),
|
||||
IPAC_BINF_RXQUAL = (1 << 9),
|
||||
IPAC_BINF_FREQ_ERR_QUAL = (1 << 10),
|
||||
IPAC_BINF_FRAME_OFFSET = (1 << 11),
|
||||
IPAC_BINF_FRAME_NR_OFFSET = (1 << 12),
|
||||
IPAC_BINF_BSIC = (1 << 13),
|
||||
IPAC_BINF_CGI = (1 << 14),
|
||||
IPAC_BINF_NEIGH_BA_SI2 = (1 << 15),
|
||||
IPAC_BINF_NEIGH_BA_SI2bis = (1 << 0),
|
||||
IPAC_BINF_NEIGH_BA_SI2ter = (1 << 1),
|
||||
IPAC_BINF_CELL_ALLOC = (1 << 2),
|
||||
};
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/protocol/gsm_12_21.h>
|
||||
|
||||
struct cell_global_id {
|
||||
u_int16_t mcc;
|
||||
@@ -712,6 +55,10 @@ struct ipac_bcch_info {
|
||||
u_int8_t ca_list_si1[16];
|
||||
};
|
||||
|
||||
extern const struct value_string abis_nm_adm_state_names[];
|
||||
extern const struct value_string abis_nm_obj_class_names[];
|
||||
extern const struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
/* PUBLIC */
|
||||
|
||||
struct msgb;
|
||||
@@ -726,7 +73,7 @@ struct abis_nm_cfg {
|
||||
|
||||
extern int abis_nm_rcvmsg(struct msgb *msg);
|
||||
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, const u_int8_t *buf, int len);
|
||||
int abis_nm_tlv_parse(struct tlv_parsed *tp, struct gsm_bts *bts, const u_int8_t *buf, int len);
|
||||
int abis_nm_rx(struct msgb *msg);
|
||||
int abis_nm_opstart(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0, u_int8_t i1, u_int8_t i2);
|
||||
int abis_nm_chg_adm_state(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i0,
|
||||
@@ -747,7 +94,7 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i1,
|
||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, u_int8_t *msg);
|
||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
|
||||
int abis_nm_reset_resource(struct gsm_bts *bts);
|
||||
int abis_nm_software_load(struct gsm_bts *bts, const char *fname,
|
||||
int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
|
||||
u_int8_t win_size, int forced,
|
||||
gsm_cbfn *cbfn, void *cb_data);
|
||||
int abis_nm_software_load_status(struct gsm_bts *bts);
|
||||
@@ -759,8 +106,7 @@ int abis_nm_conn_mdrop_link(struct gsm_bts *bts, u_int8_t e1_port0, u_int8_t ts0
|
||||
|
||||
int abis_nm_perform_test(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t test_nr, u_int8_t auton_report,
|
||||
u_int8_t *phys_config, u_int16_t phys_config_len);
|
||||
u_int8_t test_nr, u_int8_t auton_report, struct msgb *msg);
|
||||
|
||||
int abis_nm_chcomb4pchan(enum gsm_phys_chan_config pchan);
|
||||
|
||||
@@ -780,10 +126,13 @@ int abis_nm_bs11_get_oml_tei_ts(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_serno(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_set_trx_power(struct gsm_bts_trx *trx, u_int8_t level);
|
||||
int abis_nm_bs11_get_trx_power(struct gsm_bts_trx *trx);
|
||||
int abis_nm_bs11_logon(struct gsm_bts *bts, u_int8_t level, const char *name, int on);
|
||||
int abis_nm_bs11_factory_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_infield_logon(struct gsm_bts *bts, int on);
|
||||
int abis_nm_bs11_set_trx1_pw(struct gsm_bts *bts, const char *password);
|
||||
int abis_nm_bs11_set_pll_locked(struct gsm_bts *bts, int locked);
|
||||
int abis_nm_bs11_get_pll_mode(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_set_pll(struct gsm_bts *bts, int value);
|
||||
int abis_nm_bs11_get_cclk(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_get_state(struct gsm_bts *bts);
|
||||
int abis_nm_bs11_load_swl(struct gsm_bts *bts, const char *fname,
|
||||
@@ -798,14 +147,15 @@ int abis_nm_ipaccess_msg(struct gsm_bts *bts, u_int8_t msg_type,
|
||||
u_int8_t obj_class, u_int8_t bts_nr,
|
||||
u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t *attr, int attr_len);
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts *bts, u_int8_t *attr,
|
||||
int abis_nm_ipaccess_set_nvattr(struct gsm_bts_trx *trx, u_int8_t *attr,
|
||||
int attr_len);
|
||||
int abis_nm_ipaccess_restart(struct gsm_bts *bts);
|
||||
int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx);
|
||||
int abis_nm_ipaccess_set_attr(struct gsm_bts *bts, u_int8_t obj_class,
|
||||
u_int8_t bts_nr, u_int8_t trx_nr, u_int8_t ts_nr,
|
||||
u_int8_t *attr, u_int8_t attr_len);
|
||||
int abis_nm_ipaccess_rsl_connect(struct gsm_bts_trx *trx,
|
||||
u_int32_t ip, u_int16_t port, u_int8_t stream);
|
||||
void abis_nm_ipaccess_cgi(u_int8_t *buf, struct gsm_bts *bts);
|
||||
int ipac_parse_bcch_info(struct ipac_bcch_info *binf, u_int8_t *buf);
|
||||
const char *ipacc_testres_name(u_int8_t res);
|
||||
|
||||
@@ -815,8 +165,13 @@ enum nm_evt {
|
||||
EVT_STATECHG_ADM,
|
||||
};
|
||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state);
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
|
||||
struct abis_om_obj_inst *obj_inst);
|
||||
|
||||
const char *nm_opstate_name(u_int8_t os);
|
||||
const char *nm_avail_name(u_int8_t avail);
|
||||
int nm_is_running(struct gsm_nm_state *s);
|
||||
|
||||
int abis_nm_vty_init(void);
|
||||
|
||||
#endif /* _NM_H */
|
||||
|
||||
@@ -23,468 +23,9 @@
|
||||
#ifndef _RSL_H
|
||||
#define _RSL_H
|
||||
|
||||
struct abis_rsl_common_hdr {
|
||||
u_int8_t msg_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
#include <osmocore/protocol/gsm_08_58.h>
|
||||
|
||||
/* Chapter 8.3 */
|
||||
struct abis_rsl_rll_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
u_int8_t ie_chan;
|
||||
u_int8_t chan_nr;
|
||||
u_int8_t ie_link_id;
|
||||
u_int8_t link_id;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 8.3 and 8.4 */
|
||||
struct abis_rsl_dchan_hdr {
|
||||
struct abis_rsl_common_hdr c;
|
||||
u_int8_t ie_chan;
|
||||
u_int8_t chan_nr;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* Chapter 9.1 */
|
||||
#define ABIS_RSL_MDISC_RLL 0x02
|
||||
#define ABIS_RSL_MDISC_DED_CHAN 0x08
|
||||
#define ABIS_RSL_MDISC_COM_CHAN 0x0c
|
||||
#define ABIS_RSL_MDISC_TRX 0x10
|
||||
#define ABIS_RSL_MDISC_LOC 0x20
|
||||
#define ABIS_RSL_MDISC_IPACCESS 0x7e
|
||||
#define ABIS_RSL_MDISC_TRANSP 0x01
|
||||
|
||||
#define ABIS_RSL_MDISC_IS_TRANSP(x) (x & 0x01)
|
||||
|
||||
/* Chapter 9.1 */
|
||||
enum abis_rsl_msgtype {
|
||||
/* Radio Link Layer Management */
|
||||
RSL_MT_DATA_REQ = 0x01,
|
||||
RSL_MT_DATA_IND,
|
||||
RSL_MT_ERROR_IND,
|
||||
RSL_MT_EST_REQ,
|
||||
RSL_MT_EST_CONF,
|
||||
RSL_MT_EST_IND,
|
||||
RSL_MT_REL_REQ,
|
||||
RSL_MT_REL_CONF,
|
||||
RSL_MT_REL_IND,
|
||||
RSL_MT_UNIT_DATA_REQ,
|
||||
RSL_MT_UNIT_DATA_IND, /* 0x0b */
|
||||
|
||||
/* Common Channel Management / TRX Management */
|
||||
RSL_MT_BCCH_INFO = 0x11,
|
||||
RSL_MT_CCCH_LOAD_IND,
|
||||
RSL_MT_CHAN_RQD,
|
||||
RSL_MT_DELETE_IND,
|
||||
RSL_MT_PAGING_CMD,
|
||||
RSL_MT_IMMEDIATE_ASSIGN_CMD,
|
||||
RSL_MT_SMS_BC_REQ,
|
||||
/* empty */
|
||||
RSL_MT_RF_RES_IND = 0x19,
|
||||
RSL_MT_SACCH_FILL,
|
||||
RSL_MT_OVERLOAD,
|
||||
RSL_MT_ERROR_REPORT,
|
||||
RSL_MT_SMS_BC_CMD,
|
||||
RSL_MT_CBCH_LOAD_IND,
|
||||
RSL_MT_NOT_CMD, /* 0x1f */
|
||||
|
||||
/* Dedicate Channel Management */
|
||||
RSL_MT_CHAN_ACTIV = 0x21,
|
||||
RSL_MT_CHAN_ACTIV_ACK,
|
||||
RSL_MT_CHAN_ACTIV_NACK,
|
||||
RSL_MT_CONN_FAIL,
|
||||
RSL_MT_DEACTIVATE_SACCH,
|
||||
RSL_MT_ENCR_CMD,
|
||||
RSL_MT_HANDO_DET,
|
||||
RSL_MT_MEAS_RES,
|
||||
RSL_MT_MODE_MODIFY_REQ,
|
||||
RSL_MT_MODE_MODIFY_ACK,
|
||||
RSL_MT_MODE_MODIFY_NACK,
|
||||
RSL_MT_PHY_CONTEXT_REQ,
|
||||
RSL_MT_PHY_CONTEXT_CONF,
|
||||
RSL_MT_RF_CHAN_REL,
|
||||
RSL_MT_MS_POWER_CONTROL,
|
||||
RSL_MT_BS_POWER_CONTROL, /* 0x30 */
|
||||
RSL_MT_PREPROC_CONFIG,
|
||||
RSL_MT_PREPROC_MEAS_RES,
|
||||
RSL_MT_RF_CHAN_REL_ACK,
|
||||
RSL_MT_SACCH_INFO_MODIFY,
|
||||
RSL_MT_TALKER_DET,
|
||||
RSL_MT_LISTENER_DET,
|
||||
RSL_MT_REMOTE_CODEC_CONF_REP,
|
||||
RSL_MT_RTD_REP,
|
||||
RSL_MT_PRE_HANDO_NOTIF,
|
||||
RSL_MT_MR_CODEC_MOD_REQ,
|
||||
RSL_MT_MR_CODEC_MOD_ACK,
|
||||
RSL_MT_MR_CODEC_MOD_NACK,
|
||||
RSL_MT_MR_CODEC_MOD_PER,
|
||||
RSL_MT_TFO_REP,
|
||||
RSL_MT_TFO_MOD_REQ, /* 0x3f */
|
||||
RSL_MT_LOCATION_INFO = 0x41,
|
||||
|
||||
/* ip.access specific RSL message types */
|
||||
RSL_MT_IPAC_DIR_RETR_ENQ = 0x40,
|
||||
RSL_MT_IPAC_PDCH_ACT = 0x48,
|
||||
RSL_MT_IPAC_PDCH_ACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_ACT_NACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT = 0x4b,
|
||||
RSL_MT_IPAC_PDCH_DEACT_ACK,
|
||||
RSL_MT_IPAC_PDCH_DEACT_NACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX = 0x50,
|
||||
RSL_MT_IPAC_CONNECT_MUX_ACK,
|
||||
RSL_MT_IPAC_CONNECT_MUX_NACK,
|
||||
RSL_MT_IPAC_BIND_MUX = 0x53,
|
||||
RSL_MT_IPAC_BIND_MUX_ACK,
|
||||
RSL_MT_IPAC_BIND_MUX_NACK,
|
||||
RSL_MT_IPAC_DISC_MUX = 0x56,
|
||||
RSL_MT_IPAC_DISC_MUX_ACK,
|
||||
RSL_MT_IPAC_DISC_MUX_NACK,
|
||||
RSL_MT_IPAC_CRCX = 0x70, /* Bind to local BTS RTP port */
|
||||
RSL_MT_IPAC_CRCX_ACK,
|
||||
RSL_MT_IPAC_CRCX_NACK,
|
||||
RSL_MT_IPAC_MDCX = 0x73,
|
||||
RSL_MT_IPAC_MDCX_ACK,
|
||||
RSL_MT_IPAC_MDCX_NACK,
|
||||
RSL_MT_IPAC_DLCX_IND = 0x76,
|
||||
RSL_MT_IPAC_DLCX = 0x77,
|
||||
RSL_MT_IPAC_DLCX_ACK,
|
||||
RSL_MT_IPAC_DLCX_NACK,
|
||||
};
|
||||
|
||||
/* Siemens vendor-specific */
|
||||
enum abis_rsl_msgtype_siemens {
|
||||
RSL_MT_SIEMENS_MRPCI = 0x41,
|
||||
RSL_MT_SIEMENS_INTRAC_HO_COND_IND = 0x42,
|
||||
RSL_MT_SIEMENS_INTERC_HO_COND_IND = 0x43,
|
||||
RSL_MT_SIEMENS_FORCED_HO_REQ = 0x44,
|
||||
RSL_MT_SIEMENS_PREF_AREA_REQ = 0x45,
|
||||
RSL_MT_SIEMENS_PREF_AREA = 0x46,
|
||||
RSL_MT_SIEMENS_START_TRACE = 0x47,
|
||||
RSL_MT_SIEMENS_START_TRACE_ACK = 0x48,
|
||||
RSL_MT_SIEMENS_STOP_TRACE = 0x49,
|
||||
RSL_MT_SIEMENS_TRMR = 0x4a,
|
||||
RSL_MT_SIEMENS_HO_FAIL_IND = 0x4b,
|
||||
RSL_MT_SIEMENS_STOP_TRACE_ACK = 0x4c,
|
||||
RSL_MT_SIEMENS_UPLF = 0x4d,
|
||||
RSL_MT_SIEMENS_UPLB = 0x4e,
|
||||
RSL_MT_SIEMENS_SET_SYS_INFO_10 = 0x4f,
|
||||
RSL_MT_SIEMENS_MODIF_COND_IND = 0x50,
|
||||
};
|
||||
|
||||
/* Chapter 9.3 */
|
||||
enum abis_rsl_ie {
|
||||
RSL_IE_CHAN_NR = 0x01,
|
||||
RSL_IE_LINK_IDENT,
|
||||
RSL_IE_ACT_TYPE,
|
||||
RSL_IE_BS_POWER,
|
||||
RSL_IE_CHAN_IDENT,
|
||||
RSL_IE_CHAN_MODE,
|
||||
RSL_IE_ENCR_INFO,
|
||||
RSL_IE_FRAME_NUMBER,
|
||||
RSL_IE_HANDO_REF,
|
||||
RSL_IE_L1_INFO,
|
||||
RSL_IE_L3_INFO,
|
||||
RSL_IE_MS_IDENTITY,
|
||||
RSL_IE_MS_POWER,
|
||||
RSL_IE_PAGING_GROUP,
|
||||
RSL_IE_PAGING_LOAD,
|
||||
RSL_IE_PYHS_CONTEXT = 0x10,
|
||||
RSL_IE_ACCESS_DELAY,
|
||||
RSL_IE_RACH_LOAD,
|
||||
RSL_IE_REQ_REFERENCE,
|
||||
RSL_IE_RELEASE_MODE,
|
||||
RSL_IE_RESOURCE_INFO,
|
||||
RSL_IE_RLM_CAUSE,
|
||||
RSL_IE_STARTNG_TIME,
|
||||
RSL_IE_TIMING_ADVANCE,
|
||||
RSL_IE_UPLINK_MEAS,
|
||||
RSL_IE_CAUSE,
|
||||
RSL_IE_MEAS_RES_NR,
|
||||
RSL_IE_MSG_ID,
|
||||
/* reserved */
|
||||
RSL_IE_SYSINFO_TYPE = 0x1e,
|
||||
RSL_IE_MS_POWER_PARAM,
|
||||
RSL_IE_BS_POWER_PARAM,
|
||||
RSL_IE_PREPROC_PARAM,
|
||||
RSL_IE_PREPROC_MEAS,
|
||||
RSL_IE_IMM_ASS_INFO, /* Phase 1 (3.6.0), later Full below */
|
||||
RSL_IE_SMSCB_INFO = 0x24,
|
||||
RSL_IE_MS_TIMING_OFFSET,
|
||||
RSL_IE_ERR_MSG,
|
||||
RSL_IE_FULL_BCCH_INFO,
|
||||
RSL_IE_CHAN_NEEDED,
|
||||
RSL_IE_CB_CMD_TYPE,
|
||||
RSL_IE_SMSCB_MSG,
|
||||
RSL_IE_FULL_IMM_ASS_INFO,
|
||||
RSL_IE_SACCH_INFO,
|
||||
RSL_IE_CBCH_LOAD_INFO,
|
||||
RSL_IE_SMSCB_CHAN_INDICATOR,
|
||||
RSL_IE_GROUP_CALL_REF,
|
||||
RSL_IE_CHAN_DESC = 0x30,
|
||||
RSL_IE_NCH_DRX_INFO,
|
||||
RSL_IE_CMD_INDICATOR,
|
||||
RSL_IE_EMLPP_PRIO,
|
||||
RSL_IE_UIC,
|
||||
RSL_IE_MAIN_CHAN_REF,
|
||||
RSL_IE_MR_CONFIG,
|
||||
RSL_IE_MR_CONTROL,
|
||||
RSL_IE_SUP_CODEC_TYPES,
|
||||
RSL_IE_CODEC_CONFIG,
|
||||
RSL_IE_RTD,
|
||||
RSL_IE_TFO_STATUS,
|
||||
RSL_IE_LLP_APDU,
|
||||
/* Siemens vendor-specific */
|
||||
RSL_IE_SIEMENS_MRPCI = 0x40,
|
||||
RSL_IE_SIEMENS_PREF_AREA_TYPE = 0x43,
|
||||
RSL_IE_SIEMENS_ININ_CELL_HO_PAR = 0x45,
|
||||
RSL_IE_SIEMENS_TRACE_REF_NR = 0x46,
|
||||
RSL_IE_SIEMENS_INT_TRACE_IDX = 0x47,
|
||||
RSL_IE_SIEMENS_L2_HDR_INFO = 0x48,
|
||||
RSL_IE_SIEMENS_HIGHEST_RATE = 0x4e,
|
||||
RSL_IE_SIEMENS_SUGGESTED_RATE = 0x4f,
|
||||
|
||||
/* ip.access */
|
||||
RSL_IE_IPAC_SRTP_CONFIG = 0xe0,
|
||||
RSL_IE_IPAC_PROXY_UDP = 0xe1,
|
||||
RSL_IE_IPAC_BSCMPL_TOUT = 0xe2,
|
||||
RSL_IE_IPAC_REMOTE_IP = 0xf0,
|
||||
RSL_IE_IPAC_REMOTE_PORT = 0xf1,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD = 0xf2,
|
||||
RSL_IE_IPAC_LOCAL_PORT = 0xf3,
|
||||
RSL_IE_IPAC_SPEECH_MODE = 0xf4,
|
||||
RSL_IE_IPAC_LOCAL_IP = 0xf5,
|
||||
RSL_IE_IPAC_CONN_STAT = 0xf6,
|
||||
RSL_IE_IPAC_HO_C_PARMS = 0xf7,
|
||||
RSL_IE_IPAC_CONN_ID = 0xf8,
|
||||
RSL_IE_IPAC_RTP_CSD_FMT = 0xf9,
|
||||
RSL_IE_IPAC_RTP_JIT_BUF = 0xfa,
|
||||
RSL_IE_IPAC_RTP_COMPR = 0xfb,
|
||||
RSL_IE_IPAC_RTP_PAYLOAD2= 0xfc,
|
||||
RSL_IE_IPAC_RTP_MPLEX = 0xfd,
|
||||
RSL_IE_IPAC_RTP_MPLEX_ID= 0xfe,
|
||||
};
|
||||
|
||||
/* Chapter 9.3.1 */
|
||||
#define RSL_CHAN_NR_MASK 0xf8
|
||||
#define RSL_CHAN_Bm_ACCHs 0x08
|
||||
#define RSL_CHAN_Lm_ACCHs 0x10 /* .. 0x18 */
|
||||
#define RSL_CHAN_SDCCH4_ACCH 0x20 /* .. 0x38 */
|
||||
#define RSL_CHAN_SDCCH8_ACCH 0x40 /* ...0x78 */
|
||||
#define RSL_CHAN_BCCH 0x80
|
||||
#define RSL_CHAN_RACH 0x88
|
||||
#define RSL_CHAN_PCH_AGCH 0x90
|
||||
|
||||
/* Chapter 9.3.3 */
|
||||
#define RSL_ACT_TYPE_INITIAL 0x00
|
||||
#define RSL_ACT_TYPE_REACT 0x80
|
||||
#define RSL_ACT_INTRA_IMM_ASS 0x00
|
||||
#define RSL_ACT_INTRA_NORM_ASS 0x01
|
||||
#define RSL_ACT_INTER_ASYNC 0x02
|
||||
#define RSL_ACT_INTER_SYNC 0x03
|
||||
#define RSL_ACT_SECOND_ADD 0x04
|
||||
#define RSL_ACT_SECOND_MULTI 0x05
|
||||
|
||||
/* Chapter 9.3.6 */
|
||||
struct rsl_ie_chan_mode {
|
||||
u_int8_t dtx_dtu;
|
||||
u_int8_t spd_ind;
|
||||
u_int8_t chan_rt;
|
||||
u_int8_t chan_rate;
|
||||
} __attribute__ ((packed));
|
||||
#define RSL_CMOD_DTXu 0x01 /* uplink */
|
||||
#define RSL_CMOD_DTXd 0x02 /* downlink */
|
||||
enum rsl_cmod_spd {
|
||||
RSL_CMOD_SPD_SPEECH = 0x01,
|
||||
RSL_CMOD_SPD_DATA = 0x02,
|
||||
RSL_CMOD_SPD_SIGN = 0x03,
|
||||
};
|
||||
#define RSL_CMOD_CRT_SDCCH 0x01
|
||||
#define RSL_CMOD_CRT_TCH_Bm 0x08 /* full-rate */
|
||||
#define RSL_CMOD_CRT_TCH_Lm 0x09 /* half-rate */
|
||||
/* FIXME: More CRT types */
|
||||
/* Speech */
|
||||
#define RSL_CMOD_SP_GSM1 0x01
|
||||
#define RSL_CMOD_SP_GSM2 0x11
|
||||
#define RSL_CMOD_SP_GSM3 0x21
|
||||
/* Data */
|
||||
#define RSL_CMOD_SP_NT_14k5 0x58
|
||||
#define RSL_CMOD_SP_NT_12k0 0x50
|
||||
#define RSL_CMOD_SP_NT_6k0 0x51
|
||||
|
||||
/* Chapter 9.3.5 */
|
||||
struct rsl_ie_chan_ident {
|
||||
/* GSM 04.08 10.5.2.5 */
|
||||
struct {
|
||||
u_int8_t iei;
|
||||
u_int8_t chan_nr; /* enc_chan_nr */
|
||||
u_int8_t oct3;
|
||||
u_int8_t oct4;
|
||||
} chan_desc;
|
||||
#if 0 /* spec says we need this but Abissim doesn't use it */
|
||||
struct {
|
||||
u_int8_t tag;
|
||||
u_int8_t len;
|
||||
} mobile_alloc;
|
||||
#endif
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 9.3.22 */
|
||||
#define RLL_CAUSE_T200_EXPIRED 0x01
|
||||
#define RLL_CAUSE_REEST_REQ 0x02
|
||||
#define RLL_CAUSE_UNSOL_UA_RESP 0x03
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP 0x04
|
||||
#define RLL_CAUSE_UNSOL_DM_RESP_MF 0x05
|
||||
#define RLL_CAUSE_UNSOL_SPRV_RESP 0x06
|
||||
#define RLL_CAUSE_SEQ_ERR 0x07
|
||||
#define RLL_CAUSE_UFRM_INC_PARAM 0x08
|
||||
#define RLL_CAUSE_SFRM_INC_PARAM 0x09
|
||||
#define RLL_CAUSE_IFRM_INC_MBITS 0x0a
|
||||
#define RLL_CAUSE_IFRM_INC_LEN 0x0b
|
||||
#define RLL_CAUSE_FRM_UNIMPL 0x0c
|
||||
#define RLL_CAUSE_SABM_MF 0x0d
|
||||
#define RLL_CAUSE_SABM_INFO_NOTALL 0x0e
|
||||
|
||||
/* Chapter 9.3.26 */
|
||||
#define RSL_ERRCLS_NORMAL 0x00
|
||||
#define RSL_ERRCLS_RESOURCE_UNAVAIL 0x20
|
||||
#define RSL_ERRCLS_SERVICE_UNAVAIL 0x30
|
||||
#define RSL_ERRCLS_SERVICE_UNIMPL 0x40
|
||||
#define RSL_ERRCLS_INVAL_MSG 0x50
|
||||
#define RSL_ERRCLS_PROTO_ERROR 0x60
|
||||
#define RSL_ERRCLS_INTERWORKING 0x70
|
||||
|
||||
/* normal event */
|
||||
#define RSL_ERR_RADIO_IF_FAIL 0x00
|
||||
#define RSL_ERR_RADIO_LINK_FAIL 0x01
|
||||
#define RSL_ERR_HANDOVER_ACC_FAIL 0x02
|
||||
#define RSL_ERR_TALKER_ACC_FAIL 0x03
|
||||
#define RSL_ERR_OM_INTERVENTION 0x07
|
||||
#define RSL_ERR_NORMAL_UNSPEC 0x0f
|
||||
#define RSL_ERR_T_MSRFPCI_EXP 0x18
|
||||
/* resource unavailable */
|
||||
#define RSL_ERR_EQUIPMENT_FAIL 0x20
|
||||
#define RSL_ERR_RR_UNAVAIL 0x21
|
||||
#define RSL_ERR_TERR_CH_FAIL 0x22
|
||||
#define RSL_ERR_CCCH_OVERLOAD 0x23
|
||||
#define RSL_ERR_ACCH_OVERLOAD 0x24
|
||||
#define RSL_ERR_PROCESSOR_OVERLOAD 0x25
|
||||
#define RSL_ERR_RES_UNAVAIL 0x2f
|
||||
/* service or option not available */
|
||||
#define RSL_ERR_TRANSC_UNAVAIL 0x30
|
||||
#define RSL_ERR_SERV_OPT_UNAVAIL 0x3f
|
||||
/* service or option not implemented */
|
||||
#define RSL_ERR_ENCR_UNIMPL 0x40
|
||||
#define RSL_ERR_SERV_OPT_UNIMPL 0x4f
|
||||
/* invalid message */
|
||||
#define RSL_ERR_RCH_ALR_ACTV_ALLOC 0x50
|
||||
#define RSL_ERR_INVALID_MESSAGE 0x5f
|
||||
/* protocol error */
|
||||
#define RSL_ERR_MSG_DISCR 0x60
|
||||
#define RSL_ERR_MSG_TYPE 0x61
|
||||
#define RSL_ERR_MSG_SEQ 0x62
|
||||
#define RSL_ERR_IE_ERROR 0x63
|
||||
#define RSL_ERR_MAND_IE_ERROR 0x64
|
||||
#define RSL_ERR_OPT_IE_ERROR 0x65
|
||||
#define RSL_ERR_IE_NONEXIST 0x66
|
||||
#define RSL_ERR_IE_LENGTH 0x67
|
||||
#define RSL_ERR_IE_CONTENT 0x68
|
||||
#define RSL_ERR_PROTO 0x6f
|
||||
/* interworking */
|
||||
#define RSL_ERR_INTERWORKING 0x7f
|
||||
|
||||
/* Chapter 9.3.30 */
|
||||
#define RSL_SYSTEM_INFO_8 0x00
|
||||
#define RSL_SYSTEM_INFO_1 0x01
|
||||
#define RSL_SYSTEM_INFO_2 0x02
|
||||
#define RSL_SYSTEM_INFO_3 0x03
|
||||
#define RSL_SYSTEM_INFO_4 0x04
|
||||
#define RSL_SYSTEM_INFO_5 0x05
|
||||
#define RSL_SYSTEM_INFO_6 0x06
|
||||
#define RSL_SYSTEM_INFO_7 0x07
|
||||
#define RSL_SYSTEM_INFO_16 0x08
|
||||
#define RSL_SYSTEM_INFO_17 0x09
|
||||
#define RSL_SYSTEM_INFO_2bis 0x0a
|
||||
#define RSL_SYSTEM_INFO_2ter 0x0b
|
||||
#define RSL_SYSTEM_INFO_5bis 0x0d
|
||||
#define RSL_SYSTEM_INFO_5ter 0x0e
|
||||
#define RSL_SYSTEM_INFO_10 0x0f
|
||||
#define REL_EXT_MEAS_ORDER 0x47
|
||||
#define RSL_MEAS_INFO 0x48
|
||||
#define RSL_SYSTEM_INFO_13 0x28
|
||||
#define RSL_SYSTEM_INFO_2quater 0x29
|
||||
#define RSL_SYSTEM_INFO_9 0x2a
|
||||
#define RSL_SYSTEM_INFO_18 0x2b
|
||||
#define RSL_SYSTEM_INFO_19 0x2c
|
||||
#define RSL_SYSTEM_INFO_20 0x2d
|
||||
|
||||
/* Chapter 9.3.40 */
|
||||
#define RSL_CHANNEED_ANY 0x00
|
||||
#define RSL_CHANNEED_SDCCH 0x01
|
||||
#define RSL_CHANNEED_TCH_F 0x02
|
||||
#define RSL_CHANNEED_TCH_ForH 0x03
|
||||
|
||||
/* Chapter 3.3.2.3 Brocast control channel */
|
||||
/* CCCH-CONF, NC is not combined */
|
||||
#define RSL_BCCH_CCCH_CONF_1_NC 0x00
|
||||
#define RSL_BCCH_CCCH_CONF_1_C 0x01
|
||||
#define RSL_BCCH_CCCH_CONF_2_NC 0x02
|
||||
#define RSL_BCCH_CCCH_CONF_3_NC 0x04
|
||||
#define RSL_BCCH_CCCH_CONF_4_NC 0x06
|
||||
|
||||
/* BS-PA-MFRMS */
|
||||
#define RSL_BS_PA_MFRMS_2 0x00
|
||||
#define RSL_BS_PA_MFRMS_3 0x01
|
||||
#define RSL_BS_PA_MFRMS_4 0x02
|
||||
#define RSL_BS_PA_MFRMS_5 0x03
|
||||
#define RSL_BS_PA_MFRMS_6 0x04
|
||||
#define RSL_BS_PA_MFRMS_7 0x05
|
||||
#define RSL_BS_PA_MFRMS_8 0x06
|
||||
#define RSL_BS_PA_MFRMS_9 0x07
|
||||
|
||||
/* RSL_IE_IPAC_RTP_PAYLOAD[2] */
|
||||
enum rsl_ipac_rtp_payload {
|
||||
RSL_IPAC_RTP_GSM = 1,
|
||||
RSL_IPAC_RTP_EFR,
|
||||
RSL_IPAC_RTP_AMR,
|
||||
RSL_IPAC_RTP_CSD,
|
||||
RSL_IPAC_RTP_MUX,
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, lower four bits */
|
||||
enum rsl_ipac_speech_mode_s {
|
||||
RSL_IPAC_SPEECH_GSM_FR = 0, /* GSM FR (Type 1, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_EFR = 1, /* GSM EFR (Type 2, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_FR = 2, /* GSM AMR/FR (Type 3, FS) */
|
||||
RSL_IPAC_SPEECH_GSM_HR = 3, /* GSM HR (Type 1, HS) */
|
||||
RSL_IPAC_SPEECH_GSM_AMR_HR = 5, /* GSM AMR/hr (Type 3, HS) */
|
||||
RSL_IPAC_SPEECH_AS_RTP = 0xf, /* As specified by RTP Payload IE */
|
||||
};
|
||||
/* RSL_IE_IPAC_SPEECH_MODE, upper four bits */
|
||||
enum rsl_ipac_speech_mode_m {
|
||||
RSL_IPAC_SPEECH_M_RXTX = 0, /* Send and Receive */
|
||||
RSL_IPAC_SPEECH_M_RX = 1, /* Receive only */
|
||||
RSL_IPAC_SPEECH_M_TX = 2, /* Send only */
|
||||
};
|
||||
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, lower four bits */
|
||||
enum rsl_ipac_rtp_csd_format_d {
|
||||
RSL_IPAC_RTP_CSD_EXT_TRAU = 0,
|
||||
RSL_IPAC_RTP_CSD_NON_TRAU = 1,
|
||||
RSL_IPAC_RTP_CSD_TRAU_BTS = 2,
|
||||
RSL_IPAC_RTP_CSD_IWF_FREE = 3,
|
||||
};
|
||||
/* RSL_IE_IPAC_RTP_CSD_FMT, upper four bits */
|
||||
enum rsl_ipac_rtp_csd_format_ir {
|
||||
RSL_IPAC_RTP_CSD_IR_8k = 0,
|
||||
RSL_IPAC_RTP_CSD_IR_16k = 1,
|
||||
RSL_IPAC_RTP_CSD_IR_32k = 2,
|
||||
RSL_IPAC_RTP_CSD_IR_64k = 3,
|
||||
};
|
||||
|
||||
#include "msgb.h"
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
int rsl_bcch_info(struct gsm_bts_trx *trx, u_int8_t type,
|
||||
const u_int8_t *data, int len);
|
||||
@@ -511,27 +52,6 @@ int rsl_establish_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_relase_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
struct rsl_mrpci {
|
||||
u_int8_t power_class:3,
|
||||
vgcs_capable:1,
|
||||
vbs_capable:1,
|
||||
gsm_phase:2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum rsl_mrpci_pwrclass {
|
||||
RSL_MRPCI_PWRC_1 = 0,
|
||||
RSL_MRPCI_PWRC_2 = 1,
|
||||
RSL_MRPCI_PWRC_3 = 2,
|
||||
RSL_MRPCI_PWRC_4 = 3,
|
||||
RSL_MRPCI_PWRC_5 = 4,
|
||||
};
|
||||
enum rsl_mrpci_phase {
|
||||
RSL_MRPCI_PHASE_1 = 0,
|
||||
/* reserved */
|
||||
RSL_MRPCI_PHASE_2 = 2,
|
||||
RSL_MRPCI_PHASE_2PLUS = 3,
|
||||
};
|
||||
|
||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
|
||||
|
||||
/* ip.access specfic RSL extensions */
|
||||
@@ -539,7 +59,7 @@ int rsl_ipacc_crcx(struct gsm_lchan *lchan);
|
||||
int rsl_ipacc_mdcx(struct gsm_lchan *lchan, u_int32_t ip,
|
||||
u_int16_t port, u_int8_t rtp_payload2);
|
||||
int rsl_ipacc_mdcx_to_rtpsock(struct gsm_lchan *lchan);
|
||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan);
|
||||
int rsl_ipacc_pdch_activate(struct gsm_lchan *lchan, int act);
|
||||
|
||||
int abis_rsl_rcvmsg(struct msgb *msg);
|
||||
|
||||
@@ -548,12 +68,14 @@ unsigned int get_paging_group(u_int64_t imsi, unsigned int bs_cc_chans,
|
||||
unsigned int n_pag_blocks(int bs_ccch_sdcch_comb, unsigned int bs_ag_blks_res);
|
||||
u_int64_t str_to_imsi(const char *imsi_str);
|
||||
u_int8_t lchan2chan_nr(const struct gsm_lchan *lchan);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t reason);
|
||||
|
||||
int rsl_lchan_set_state(struct gsm_lchan *lchan, int);
|
||||
|
||||
/* to be provided by external code */
|
||||
int abis_rsl_sendmsg(struct msgb *msg);
|
||||
int rsl_deact_sacch(struct gsm_lchan *lchan);
|
||||
int rsl_chan_release(struct gsm_lchan *lchan);
|
||||
int rsl_lchan_rll_release(struct gsm_lchan *lchan, u_int8_t link_id);
|
||||
|
||||
/* BCCH related code */
|
||||
int rsl_ccch_conf_to_bs_cc_chans(int ccch_conf);
|
||||
@@ -563,5 +85,9 @@ int rsl_number_of_paging_subchannels(struct gsm_bts *bts);
|
||||
int rsl_chan_bs_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int db);
|
||||
int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan, unsigned int fpc, int dbm);
|
||||
|
||||
/* SMSCB functionality */
|
||||
int rsl_sms_cb_command(struct gsm_bts *bts, uint8_t chan_number,
|
||||
uint8_t cb_command, const uint8_t *data, int len);
|
||||
|
||||
#endif /* RSL_MT_H */
|
||||
|
||||
|
||||
10
openbsc/include/openbsc/auth.h
Normal file
10
openbsc/include/openbsc/auth.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef _AUTH_H
|
||||
#define _AUTH_H
|
||||
|
||||
struct gsm_auth_tuple;
|
||||
struct gsm_subscriber;
|
||||
|
||||
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr, int key_seq);
|
||||
|
||||
#endif /* _AUTH_H */
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef _BITVEC_H
|
||||
#define _BITVEC_H
|
||||
|
||||
/* bit vector utility routines */
|
||||
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* In GSM mac blocks, every bit can be 0 or 1, or L or H. L/H are
|
||||
* defined relative to the 0x2b padding pattern */
|
||||
enum bit_value {
|
||||
ZERO = 0,
|
||||
ONE = 1,
|
||||
L = 2,
|
||||
H = 3,
|
||||
};
|
||||
|
||||
struct bitvec {
|
||||
unsigned int cur_bit; /* curser to the next unused bit */
|
||||
unsigned int data_len; /* length of data array in bytes */
|
||||
u_int8_t *data; /* pointer to data array */
|
||||
};
|
||||
|
||||
/* check if the bit is 0 or 1 for a given position inside a bitvec */
|
||||
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr);
|
||||
|
||||
/* get the Nth set bit inside the bit vector */
|
||||
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n);
|
||||
|
||||
/* Set a bit at given position */
|
||||
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum,
|
||||
enum bit_value bit);
|
||||
|
||||
/* Set the next bit in the vector */
|
||||
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit);
|
||||
|
||||
/* Set multiple bits at the current position */
|
||||
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count);
|
||||
|
||||
/* Add an unsigned integer (of length count bits) to current position */
|
||||
int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count);
|
||||
|
||||
|
||||
/* Pad the bit vector up to a certain bit position */
|
||||
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit);
|
||||
|
||||
#endif /* _BITVEC_H */
|
||||
38
openbsc/include/openbsc/bsc_api.h
Normal file
38
openbsc/include/openbsc/bsc_api.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* GSM 08.08 like API for OpenBSC */
|
||||
|
||||
#ifndef OPENBSC_BSC_API_H
|
||||
#define OPENBSC_BSC_API_H
|
||||
|
||||
#include "gsm_data.h"
|
||||
|
||||
#define BSC_API_CONN_POL_ACCEPT 0
|
||||
#define BSC_API_CONN_POL_REJECT 1
|
||||
|
||||
struct bsc_api {
|
||||
void (*sapi_n_reject)(struct gsm_subscriber_connection *conn, int dlci);
|
||||
void (*cipher_mode_compl)(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, uint8_t chosen_encr);
|
||||
void (*cipher_mode_reject)(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, uint16_t reason);
|
||||
int (*compl_l3)(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, uint16_t chosen_channel);
|
||||
void (*dtap)(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
void (*assign_compl)(struct gsm_subscriber_connection *conn,
|
||||
uint16_t rr_cause);
|
||||
void (*assign_fail)(struct gsm_subscriber_connection *conn,
|
||||
uint16_t rr_cause);
|
||||
void (*clear_request)(struct gsm_subscriber_connection *conn,
|
||||
uint32_t cause);
|
||||
void (*clear_compl)(struct gsm_subscriber_connection *conn);
|
||||
};
|
||||
|
||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api);
|
||||
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn, struct msgb *msg, int link_id);
|
||||
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_type, int audio);
|
||||
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
|
||||
uint8_t *key, int len);
|
||||
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);
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Routines to talk to the MSC using the IPA Protocol */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -23,8 +23,30 @@
|
||||
#ifndef BSC_MSC_H
|
||||
#define BSC_MSC_H
|
||||
|
||||
#include "select.h"
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/timer.h>
|
||||
|
||||
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port);
|
||||
struct bsc_msc_connection {
|
||||
struct write_queue write_queue;
|
||||
int is_connected;
|
||||
int is_authenticated;
|
||||
int first_contact;
|
||||
const char *ip;
|
||||
int port;
|
||||
int prio;
|
||||
|
||||
void (*connection_loss) (struct bsc_msc_connection *);
|
||||
void (*connected) (struct bsc_msc_connection *);
|
||||
struct timer_list reconnect_timer;
|
||||
struct timer_list timeout_timer;
|
||||
};
|
||||
|
||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio);
|
||||
int bsc_msc_connect(struct bsc_msc_connection *);
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -22,12 +22,260 @@
|
||||
#ifndef BSC_NAT_H
|
||||
#define BSC_NAT_H
|
||||
|
||||
#include "mgcp.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "msgb.h"
|
||||
|
||||
#include <osmocore/select.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/rate_ctr.h>
|
||||
#include <osmocore/statistics.h>
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#define DIR_BSC 1
|
||||
#define DIR_MSC 2
|
||||
|
||||
#define NAT_IPAC_PROTO_MGCP 0xfc
|
||||
|
||||
struct sccp_connections;
|
||||
struct bsc_nat_parsed;
|
||||
struct bsc_nat;
|
||||
|
||||
enum {
|
||||
NAT_CON_TYPE_NONE,
|
||||
NAT_CON_TYPE_LU,
|
||||
NAT_CON_TYPE_CM_SERV_REQ,
|
||||
NAT_CON_TYPE_PAG_RESP,
|
||||
NAT_CON_TYPE_LOCAL_REJECT,
|
||||
NAT_CON_TYPE_OTHER,
|
||||
};
|
||||
|
||||
/*
|
||||
* Per BSC data structure
|
||||
*/
|
||||
struct bsc_connection {
|
||||
struct llist_head list_entry;
|
||||
|
||||
/* do we know anything about this BSC? */
|
||||
int authenticated;
|
||||
|
||||
/* the fd we use to communicate */
|
||||
struct write_queue write_queue;
|
||||
|
||||
/* the BSS associated */
|
||||
struct bsc_config *cfg;
|
||||
|
||||
/* a timeout node */
|
||||
struct timer_list id_timeout;
|
||||
|
||||
/* pong timeout */
|
||||
struct timer_list ping_timeout;
|
||||
struct timer_list pong_timeout;
|
||||
|
||||
/* a back pointer */
|
||||
struct bsc_nat *nat;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stats per BSC
|
||||
*/
|
||||
struct bsc_config_stats {
|
||||
struct rate_ctr_group *ctrg;
|
||||
};
|
||||
|
||||
enum bsc_cfg_ctr {
|
||||
BCFG_CTR_SCCP_CONN,
|
||||
BCFG_CTR_SCCP_CALLS,
|
||||
BCFG_CTR_NET_RECONN,
|
||||
BCFG_CTR_DROPPED_SCCP,
|
||||
BCFG_CTR_DROPPED_CALLS,
|
||||
};
|
||||
|
||||
/**
|
||||
* One BSC entry in the config
|
||||
*/
|
||||
struct bsc_config {
|
||||
struct llist_head entry;
|
||||
|
||||
char *token;
|
||||
unsigned int lac;
|
||||
int nr;
|
||||
|
||||
char *description;
|
||||
|
||||
/* imsi white and blacklist */
|
||||
char *acc_lst_name;
|
||||
|
||||
int forbid_paging;
|
||||
|
||||
/* backpointer */
|
||||
struct bsc_nat *nat;
|
||||
|
||||
struct bsc_config_stats stats;
|
||||
};
|
||||
|
||||
/**
|
||||
* BSCs point of view of endpoints
|
||||
*/
|
||||
struct bsc_endpoint {
|
||||
/* the pending transaction id */
|
||||
char *transaction_id;
|
||||
/* the bsc we are talking to */
|
||||
struct bsc_connection *bsc;
|
||||
};
|
||||
|
||||
/**
|
||||
* Statistic for the nat.
|
||||
*/
|
||||
struct bsc_nat_statistics {
|
||||
struct {
|
||||
struct counter *conn;
|
||||
struct counter *calls;
|
||||
} sccp;
|
||||
|
||||
struct {
|
||||
struct counter *reconn;
|
||||
struct counter *auth_fail;
|
||||
} bsc;
|
||||
|
||||
struct {
|
||||
struct counter *reconn;
|
||||
} msc;
|
||||
};
|
||||
|
||||
struct bsc_nat_acc_lst {
|
||||
struct llist_head list;
|
||||
|
||||
/* the name of the list */
|
||||
const char *name;
|
||||
struct llist_head fltr_list;
|
||||
};
|
||||
|
||||
struct bsc_nat_acc_lst_entry {
|
||||
struct llist_head list;
|
||||
|
||||
/* the filter */
|
||||
char *imsi_allow;
|
||||
regex_t imsi_allow_re;
|
||||
char *imsi_deny;
|
||||
regex_t imsi_deny_re;
|
||||
};
|
||||
|
||||
/**
|
||||
* the structure of the "nat" network
|
||||
*/
|
||||
struct bsc_nat {
|
||||
/* active SCCP connections that need patching */
|
||||
struct llist_head sccp_connections;
|
||||
|
||||
/* active BSC connections that need patching */
|
||||
struct llist_head bsc_connections;
|
||||
|
||||
/* access lists */
|
||||
struct llist_head access_lists;
|
||||
|
||||
/* known BSC's */
|
||||
struct llist_head bsc_configs;
|
||||
int num_bsc;
|
||||
int bsc_ip_dscp;
|
||||
|
||||
/* MGCP config */
|
||||
struct mgcp_config *mgcp_cfg;
|
||||
struct write_queue mgcp_queue;
|
||||
uint8_t mgcp_msg[4096];
|
||||
int mgcp_length;
|
||||
|
||||
/* msc things */
|
||||
char *msc_ip;
|
||||
int msc_port;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
char *token;
|
||||
|
||||
/* timeouts */
|
||||
int auth_timeout;
|
||||
int ping_timeout;
|
||||
int pong_timeout;
|
||||
|
||||
struct bsc_endpoint *bsc_endpoints;
|
||||
|
||||
/* filter */
|
||||
char *acc_lst_name;
|
||||
|
||||
/* statistics */
|
||||
struct bsc_nat_statistics stats;
|
||||
};
|
||||
|
||||
/* create and init the structures */
|
||||
struct bsc_config *bsc_config_alloc(struct bsc_nat *nat, const char *token, unsigned int lac);
|
||||
struct bsc_config *bsc_config_num(struct bsc_nat *nat, int num);
|
||||
struct bsc_nat *bsc_nat_alloc(void);
|
||||
struct bsc_connection *bsc_connection_alloc(struct bsc_nat *nat);
|
||||
void bsc_nat_set_msc_ip(struct bsc_nat *bsc, const char *ip);
|
||||
|
||||
void sccp_connection_destroy(struct sccp_connections *);
|
||||
void bsc_close_connection(struct bsc_connection *);
|
||||
|
||||
const char *bsc_con_type_to_string(int type);
|
||||
|
||||
/**
|
||||
* parse the given message into the above structure
|
||||
*/
|
||||
struct bsc_nat_parsed *bsc_nat_parse(struct msgb *msg);
|
||||
|
||||
/**
|
||||
* filter based on IP Access header in both directions
|
||||
*/
|
||||
int bsc_nat_filter_ipa(struct msgb *msg);
|
||||
int bsc_nat_filter_ipa(int direction, struct msgb *msg, struct bsc_nat_parsed *parsed);
|
||||
int bsc_nat_vty_init(struct bsc_nat *nat);
|
||||
struct bsc_connection *bsc_nat_find_bsc(struct bsc_nat *nat, struct msgb *msg, int *_lac);
|
||||
|
||||
/**
|
||||
* Content filtering.
|
||||
*/
|
||||
int bsc_nat_filter_sccp_cr(struct bsc_connection *bsc, struct msgb *msg,
|
||||
struct bsc_nat_parsed *, int *con_type);
|
||||
|
||||
/**
|
||||
* SCCP patching and handling
|
||||
*/
|
||||
struct sccp_connections *create_sccp_src_ref(struct bsc_connection *bsc, struct bsc_nat_parsed *parsed);
|
||||
int update_sccp_src_ref(struct sccp_connections *sccp, struct bsc_nat_parsed *parsed);
|
||||
void remove_sccp_src_ref(struct bsc_connection *bsc, struct msgb *msg, struct bsc_nat_parsed *parsed);
|
||||
struct sccp_connections *patch_sccp_src_ref_to_bsc(struct msgb *, struct bsc_nat_parsed *, struct bsc_nat *);
|
||||
struct sccp_connections *patch_sccp_src_ref_to_msc(struct msgb *, struct bsc_nat_parsed *, struct bsc_connection *);
|
||||
|
||||
/**
|
||||
* MGCP/Audio handling
|
||||
*/
|
||||
int bsc_write_mgcp(struct bsc_connection *bsc, const uint8_t *data, unsigned int length);
|
||||
int bsc_mgcp_assign(struct sccp_connections *, struct msgb *msg);
|
||||
void bsc_mgcp_init(struct sccp_connections *);
|
||||
void bsc_mgcp_dlcx(struct sccp_connections *);
|
||||
void bsc_mgcp_free_endpoints(struct bsc_nat *nat);
|
||||
int bsc_mgcp_nat_init(struct bsc_nat *nat);
|
||||
|
||||
struct sccp_connections *bsc_mgcp_find_con(struct bsc_nat *, int endpoint_number);
|
||||
struct msgb *bsc_mgcp_rewrite(char *input, int length, const char *ip, int port);
|
||||
void bsc_mgcp_forward(struct bsc_connection *bsc, struct msgb *msg);
|
||||
|
||||
void bsc_mgcp_clear_endpoints_for(struct bsc_connection *bsc);
|
||||
int bsc_mgcp_parse_response(const char *str, int *code, char transaction[60]);
|
||||
int bsc_mgcp_extract_ci(const char *resp);
|
||||
|
||||
|
||||
int bsc_write(struct bsc_connection *bsc, struct msgb *msg, int id);
|
||||
|
||||
/* IMSI allow/deny handling */
|
||||
void bsc_parse_reg(void *ctx, regex_t *reg, char **imsi, int argc, const char **argv);
|
||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_find(struct bsc_nat *nat, const char *name);
|
||||
struct bsc_nat_acc_lst *bsc_nat_acc_lst_get(struct bsc_nat *nat, const char *name);
|
||||
void bsc_nat_acc_lst_delete(struct bsc_nat_acc_lst *lst);
|
||||
|
||||
struct bsc_nat_acc_lst_entry *bsc_nat_acc_lst_entry_create(struct bsc_nat_acc_lst *);
|
||||
|
||||
int bsc_nat_msc_is_connected(struct bsc_nat *nat);
|
||||
|
||||
#endif
|
||||
|
||||
92
openbsc/include/openbsc/bsc_nat_sccp.h
Normal file
92
openbsc/include/openbsc/bsc_nat_sccp.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* NAT utilities using SCCP types */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BSC_NAT_SCCP_H
|
||||
#define BSC_NAT_SCCP_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocom/sccp/sccp_types.h>
|
||||
|
||||
/*
|
||||
* For the NAT we will need to analyze and later patch
|
||||
* the received message. This would require us to parse
|
||||
* the IPA and SCCP header twice. Instead of doing this
|
||||
* we will have one analyze structure and have the patching
|
||||
* and filter operate on the same structure.
|
||||
*/
|
||||
struct bsc_nat_parsed {
|
||||
/* ip access prototype */
|
||||
int ipa_proto;
|
||||
|
||||
/* source local reference */
|
||||
struct sccp_source_reference *src_local_ref;
|
||||
|
||||
/* destination local reference */
|
||||
struct sccp_source_reference *dest_local_ref;
|
||||
|
||||
/* called ssn number */
|
||||
int called_ssn;
|
||||
|
||||
/* calling ssn number */
|
||||
int calling_ssn;
|
||||
|
||||
/* sccp message type */
|
||||
int sccp_type;
|
||||
|
||||
/* bssap type, e.g. 0 for BSS Management */
|
||||
int bssap;
|
||||
|
||||
/* the gsm0808 message type */
|
||||
int gsm_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Per SCCP source local reference patch table. It needs to
|
||||
* be updated on new SCCP connections, connection confirm and reject,
|
||||
* and on the loss of the BSC connection.
|
||||
*/
|
||||
struct sccp_connections {
|
||||
struct llist_head list_entry;
|
||||
|
||||
struct bsc_connection *bsc;
|
||||
struct bsc_msc_connection *msc_con;
|
||||
|
||||
struct sccp_source_reference real_ref;
|
||||
struct sccp_source_reference patched_ref;
|
||||
struct sccp_source_reference remote_ref;
|
||||
int has_remote_ref;
|
||||
|
||||
/* status */
|
||||
int con_type;
|
||||
int con_local;
|
||||
|
||||
/* GSM audio handling. That is 32 * multiplex + ts */
|
||||
int crcx;
|
||||
int msc_timeslot;
|
||||
int bsc_timeslot;
|
||||
|
||||
/* timeout handling */
|
||||
struct timespec creation_time;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,334 +0,0 @@
|
||||
/* From GSM08.08 */
|
||||
|
||||
#ifndef BSSAP_H
|
||||
#define BSSAP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
/*
|
||||
* this is from GSM 03.03 CGI but is copied in GSM 08.08
|
||||
* in § 3.2.2.27 for Cell Identifier List
|
||||
*/
|
||||
enum CELL_IDENT {
|
||||
CELL_IDENT_WHOLE_GLOBAL = 0,
|
||||
CELL_IDENT_LAC_AND_CI = 1,
|
||||
CELL_IDENT_CI = 2,
|
||||
CELL_IDENT_NO_CELL = 3,
|
||||
CELL_IDENT_LAI_AND_LAC = 4,
|
||||
CELL_IDENT_LAC = 5,
|
||||
CELL_IDENT_BSS = 6,
|
||||
CELL_IDENT_UTRAN_PLMN_LAC_RNC = 8,
|
||||
CELL_IDENT_UTRAN_RNC = 9,
|
||||
CELL_IDENT_UTRAN_LAC_RNC = 10,
|
||||
};
|
||||
|
||||
|
||||
/* GSM 08.06 § 6.3 */
|
||||
enum BSSAP_MSG_TYPE {
|
||||
BSSAP_MSG_BSS_MANAGEMENT = 0x0,
|
||||
BSSAP_MSG_DTAP = 0x1,
|
||||
};
|
||||
|
||||
struct bssmap_header {
|
||||
u_int8_t type;
|
||||
u_int8_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct dtap_header {
|
||||
u_int8_t type;
|
||||
u_int8_t link_id;
|
||||
u_int8_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
enum BSS_MAP_MSG_TYPE {
|
||||
BSS_MAP_MSG_RESERVED_0 = 0,
|
||||
|
||||
/* ASSIGNMENT MESSAGES */
|
||||
BSS_MAP_MSG_ASSIGMENT_RQST = 1,
|
||||
BSS_MAP_MSG_ASSIGMENT_COMPLETE = 2,
|
||||
BSS_MAP_MSG_ASSIGMENT_FAILURE = 3,
|
||||
|
||||
/* HANDOVER MESSAGES */
|
||||
BSS_MAP_MSG_HANDOVER_RQST = 16,
|
||||
BSS_MAP_MSG_HANDOVER_REQUIRED = 17,
|
||||
BSS_MAP_MSG_HANDOVER_RQST_ACKNOWLEDGE= 18,
|
||||
BSS_MAP_MSG_HANDOVER_CMD = 19,
|
||||
BSS_MAP_MSG_HANDOVER_COMPLETE = 20,
|
||||
BSS_MAP_MSG_HANDOVER_SUCCEEDED = 21,
|
||||
BSS_MAP_MSG_HANDOVER_FAILURE = 22,
|
||||
BSS_MAP_MSG_HANDOVER_PERFORMED = 23,
|
||||
BSS_MAP_MSG_HANDOVER_CANDIDATE_ENQUIRE = 24,
|
||||
BSS_MAP_MSG_HANDOVER_CANDIDATE_RESPONSE = 25,
|
||||
BSS_MAP_MSG_HANDOVER_REQUIRED_REJECT = 26,
|
||||
BSS_MAP_MSG_HANDOVER_DETECT = 27,
|
||||
|
||||
/* RELEASE MESSAGES */
|
||||
BSS_MAP_MSG_CLEAR_CMD = 32,
|
||||
BSS_MAP_MSG_CLEAR_COMPLETE = 33,
|
||||
BSS_MAP_MSG_CLEAR_RQST = 34,
|
||||
BSS_MAP_MSG_RESERVED_1 = 35,
|
||||
BSS_MAP_MSG_RESERVED_2 = 36,
|
||||
BSS_MAP_MSG_SAPI_N_REJECT = 37,
|
||||
BSS_MAP_MSG_CONFUSION = 38,
|
||||
|
||||
/* OTHER CONNECTION RELATED MESSAGES */
|
||||
BSS_MAP_MSG_SUSPEND = 40,
|
||||
BSS_MAP_MSG_RESUME = 41,
|
||||
BSS_MAP_MSG_CONNECTION_ORIENTED_INFORMATION = 42,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_RQST = 43,
|
||||
BSS_MAP_MSG_LSA_INFORMATION = 44,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_RESPONSE = 45,
|
||||
BSS_MAP_MSG_PERFORM_LOCATION_ABORT = 46,
|
||||
BSS_MAP_MSG_COMMON_ID = 47,
|
||||
|
||||
/* GENERAL MESSAGES */
|
||||
BSS_MAP_MSG_RESET = 48,
|
||||
BSS_MAP_MSG_RESET_ACKNOWLEDGE = 49,
|
||||
BSS_MAP_MSG_OVERLOAD = 50,
|
||||
BSS_MAP_MSG_RESERVED_3 = 51,
|
||||
BSS_MAP_MSG_RESET_CIRCUIT = 52,
|
||||
BSS_MAP_MSG_RESET_CIRCUIT_ACKNOWLEDGE = 53,
|
||||
BSS_MAP_MSG_MSC_INVOKE_TRACE = 54,
|
||||
BSS_MAP_MSG_BSS_INVOKE_TRACE = 55,
|
||||
BSS_MAP_MSG_CONNECTIONLESS_INFORMATION = 58,
|
||||
|
||||
/* TERRESTRIAL RESOURCE MESSAGES */
|
||||
BSS_MAP_MSG_BLOCK = 64,
|
||||
BSS_MAP_MSG_BLOCKING_ACKNOWLEDGE = 65,
|
||||
BSS_MAP_MSG_UNBLOCK = 66,
|
||||
BSS_MAP_MSG_UNBLOCKING_ACKNOWLEDGE = 67,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCK = 68,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_BLOCKING_ACKNOWLEDGE = 69,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCK = 70,
|
||||
BSS_MAP_MSG_CIRCUIT_GROUP_UNBLOCKING_ACKNOWLEDGE = 71,
|
||||
BSS_MAP_MSG_UNEQUIPPED_CIRCUIT = 72,
|
||||
BSS_MAP_MSG_CHANGE_CIRCUIT = 78,
|
||||
BSS_MAP_MSG_CHANGE_CIRCUIT_ACKNOWLEDGE = 79,
|
||||
|
||||
/* RADIO RESOURCE MESSAGES */
|
||||
BSS_MAP_MSG_RESOURCE_RQST = 80,
|
||||
BSS_MAP_MSG_RESOURCE_INDICATION = 81,
|
||||
BSS_MAP_MSG_PAGING = 82,
|
||||
BSS_MAP_MSG_CIPHER_MODE_CMD = 83,
|
||||
BSS_MAP_MSG_CLASSMARK_UPDATE = 84,
|
||||
BSS_MAP_MSG_CIPHER_MODE_COMPLETE = 85,
|
||||
BSS_MAP_MSG_QUEUING_INDICATION = 86,
|
||||
BSS_MAP_MSG_COMPLETE_LAYER_3 = 87,
|
||||
BSS_MAP_MSG_CLASSMARK_RQST = 88,
|
||||
BSS_MAP_MSG_CIPHER_MODE_REJECT = 89,
|
||||
BSS_MAP_MSG_LOAD_INDICATION = 90,
|
||||
|
||||
/* VGCS/VBS */
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP = 4,
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP_ACK = 5,
|
||||
BSS_MAP_MSG_VGCS_VBS_SETUP_REFUSE = 6,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST = 7,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RESULT = 28,
|
||||
BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_FAILURE = 29,
|
||||
BSS_MAP_MSG_VGCS_VBS_QUEUING_INDICATION = 30,
|
||||
BSS_MAP_MSG_UPLINK_RQST = 31,
|
||||
BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE = 39,
|
||||
BSS_MAP_MSG_UPLINK_RQST_CONFIRMATION = 73,
|
||||
BSS_MAP_MSG_UPLINK_RELEASE_INDICATION = 74,
|
||||
BSS_MAP_MSG_UPLINK_REJECT_CMD = 75,
|
||||
BSS_MAP_MSG_UPLINK_RELEASE_CMD = 76,
|
||||
BSS_MAP_MSG_UPLINK_SEIZED_CMD = 77,
|
||||
};
|
||||
|
||||
enum GSM0808_IE_CODING {
|
||||
GSM0808_IE_CIRCUIT_IDENTITY_CODE = 1,
|
||||
GSM0808_IE_RESERVED_0 = 2,
|
||||
GSM0808_IE_RESOURCE_AVAILABLE = 3,
|
||||
GSM0808_IE_CAUSE = 4,
|
||||
GSM0808_IE_CELL_IDENTIFIER = 5,
|
||||
GSM0808_IE_PRIORITY = 6,
|
||||
GSM0808_IE_LAYER_3_HEADER_INFORMATION = 7,
|
||||
GSM0808_IE_IMSI = 8,
|
||||
GSM0808_IE_TMSI = 9,
|
||||
GSM0808_IE_ENCRYPTION_INFORMATION = 10,
|
||||
GSM0808_IE_CHANNEL_TYPE = 11,
|
||||
GSM0808_IE_PERIODICITY = 12,
|
||||
GSM0808_IE_EXTENDED_RESOURCE_INDICATOR = 13,
|
||||
GSM0808_IE_NUMBER_OF_MSS = 14,
|
||||
GSM0808_IE_RESERVED_1 = 15,
|
||||
GSM0808_IE_RESERVED_2 = 16,
|
||||
GSM0808_IE_RESERVED_3 = 17,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_T2 = 18,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_T3 = 19,
|
||||
GSM0808_IE_INTERFERENCE_BAND_TO_USE = 20,
|
||||
GSM0808_IE_RR_CAUSE = 21,
|
||||
GSM0808_IE_RESERVED_4 = 22,
|
||||
GSM0808_IE_LAYER_3_INFORMATION = 23,
|
||||
GSM0808_IE_DLCI = 24,
|
||||
GSM0808_IE_DOWNLINK_DTX_FLAG = 25,
|
||||
GSM0808_IE_CELL_IDENTIFIER_LIST = 26,
|
||||
GSM0808_IE_RESPONSE_RQST = 27,
|
||||
GSM0808_IE_RESOURCE_INDICATION_METHOD = 28,
|
||||
GSM0808_IE_CLASSMARK_INFORMATION_TYPE_1 = 29,
|
||||
GSM0808_IE_CIRCUIT_IDENTITY_CODE_LIST = 30,
|
||||
GSM0808_IE_DIAGNOSTIC = 31,
|
||||
GSM0808_IE_LAYER_3_MESSAGE_CONTENTS = 32,
|
||||
GSM0808_IE_CHOSEN_CHANNEL = 33,
|
||||
GSM0808_IE_TOTAL_RESOURCE_ACCESSIBLE = 34,
|
||||
GSM0808_IE_CIPHER_RESPONSE_MODE = 35,
|
||||
GSM0808_IE_CHANNEL_NEEDED = 36,
|
||||
GSM0808_IE_TRACE_TYPE = 37,
|
||||
GSM0808_IE_TRIGGERID = 38,
|
||||
GSM0808_IE_TRACE_REFERENCE = 39,
|
||||
GSM0808_IE_TRANSACTIONID = 40,
|
||||
GSM0808_IE_MOBILE_IDENTITY = 41,
|
||||
GSM0808_IE_OMCID = 42,
|
||||
GSM0808_IE_FORWARD_INDICATOR = 43,
|
||||
GSM0808_IE_CHOSEN_ENCR_ALG = 44,
|
||||
GSM0808_IE_CIRCUIT_POOL = 45,
|
||||
GSM0808_IE_CIRCUIT_POOL_LIST = 46,
|
||||
GSM0808_IE_TIME_INDICATION = 47,
|
||||
GSM0808_IE_RESOURCE_SITUATION = 48,
|
||||
GSM0808_IE_CURRENT_CHANNEL_TYPE_1 = 49,
|
||||
GSM0808_IE_QUEUEING_INDICATOR = 50,
|
||||
GSM0808_IE_SPEECH_VERSION = 64,
|
||||
GSM0808_IE_ASSIGNMENT_REQUIREMENT = 51,
|
||||
GSM0808_IE_TALKER_FLAG = 53,
|
||||
GSM0808_IE_CONNECTION_RELEASE_RQSTED = 54,
|
||||
GSM0808_IE_GROUP_CALL_REFERENCE = 55,
|
||||
GSM0808_IE_EMLPP_PRIORITY = 56,
|
||||
GSM0808_IE_CONFIG_EVO_INDI = 57,
|
||||
GSM0808_IE_OLD_BSS_TO_NEW_BSS_INFORMATION = 58,
|
||||
GSM0808_IE_LSA_IDENTIFIER = 59,
|
||||
GSM0808_IE_LSA_IDENTIFIER_LIST = 60,
|
||||
GSM0808_IE_LSA_INFORMATION = 61,
|
||||
GSM0808_IE_LCS_QOS = 62,
|
||||
GSM0808_IE_LSA_ACCESS_CTRL_SUPPR = 63,
|
||||
GSM0808_IE_LCS_PRIORITY = 67,
|
||||
GSM0808_IE_LOCATION_TYPE = 68,
|
||||
GSM0808_IE_LOCATION_ESTIMATE = 69,
|
||||
GSM0808_IE_POSITIONING_DATA = 70,
|
||||
GSM0808_IE_LCS_CAUSE = 71,
|
||||
GSM0808_IE_LCS_CLIENT_TYPE = 72,
|
||||
GSM0808_IE_APDU = 73,
|
||||
GSM0808_IE_NETWORK_ELEMENT_IDENTITY = 74,
|
||||
GSM0808_IE_GPS_ASSISTANCE_DATA = 75,
|
||||
GSM0808_IE_DECIPHERING_KEYS = 76,
|
||||
GSM0808_IE_RETURN_ERROR_RQST = 77,
|
||||
GSM0808_IE_RETURN_ERROR_CAUSE = 78,
|
||||
GSM0808_IE_SEGMENTATION = 79,
|
||||
GSM0808_IE_SERVICE_HANDOVER = 80,
|
||||
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_UMTS = 81,
|
||||
GSM0808_IE_SOURCE_RNC_TO_TARGET_RNC_TRANSPARENT_CDMA2000= 82,
|
||||
GSM0808_IE_RESERVED_5 = 65,
|
||||
GSM0808_IE_RESERVED_6 = 66,
|
||||
};
|
||||
|
||||
enum gsm0808_cause {
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE = 0,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE = 1,
|
||||
GSM0808_CAUSE_UPLINK_QUALITY = 2,
|
||||
GSM0808_CAUSE_UPLINK_STRENGTH = 3,
|
||||
GSM0808_CAUSE_DOWNLINK_QUALITY = 4,
|
||||
GSM0808_CAUSE_DOWNLINK_STRENGTH = 5,
|
||||
GSM0808_CAUSE_DISTANCE = 6,
|
||||
GSM0808_CAUSE_O_AND_M_INTERVENTION = 7,
|
||||
GSM0808_CAUSE_RESPONSE_TO_MSC_INVOCATION = 8,
|
||||
GSM0808_CAUSE_CALL_CONTROL = 9,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION = 10,
|
||||
GSM0808_CAUSE_HANDOVER_SUCCESSFUL = 11,
|
||||
GSM0808_CAUSE_BETTER_CELL = 12,
|
||||
GSM0808_CAUSE_DIRECTED_RETRY = 13,
|
||||
GSM0808_CAUSE_JOINED_GROUP_CALL_CHANNEL = 14,
|
||||
GSM0808_CAUSE_TRAFFIC = 15,
|
||||
GSM0808_CAUSE_EQUIPMENT_FAILURE = 32,
|
||||
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE = 33,
|
||||
GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE = 34,
|
||||
GSM0808_CAUSE_CCCH_OVERLOAD = 35,
|
||||
GSM0808_CAUSE_PROCESSOR_OVERLOAD = 36,
|
||||
GSM0808_CAUSE_BSS_NOT_EQUIPPED = 37,
|
||||
GSM0808_CAUSE_MS_NOT_EQUIPPED = 38,
|
||||
GSM0808_CAUSE_INVALID_CELL = 39,
|
||||
GSM0808_CAUSE_TRAFFIC_LOAD = 40,
|
||||
GSM0808_CAUSE_PREEMPTION = 41,
|
||||
GSM0808_CAUSE_RQSTED_TRANSCODING_RATE_ADAPTION_UNAVAILABLE = 48,
|
||||
GSM0808_CAUSE_CIRCUIT_POOL_MISMATCH = 49,
|
||||
GSM0808_CAUSE_SWITCH_CIRCUIT_POOL = 50,
|
||||
GSM0808_CAUSE_RQSTED_SPEECH_VERSION_UNAVAILABLE = 51,
|
||||
GSM0808_CAUSE_LSA_NOT_ALLOWED = 52,
|
||||
GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED = 64,
|
||||
GSM0808_CAUSE_TERRESTRIAL_CIRCUIT_ALREADY_ALLOCATED = 80,
|
||||
GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS = 81,
|
||||
GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING = 82,
|
||||
GSM0808_CAUSE_INCORRECT_VALUE = 83,
|
||||
GSM0808_CAUSE_UNKNOWN_MESSAGE_TYPE = 84,
|
||||
GSM0808_CAUSE_UNKNOWN_INFORMATION_ELEMENT = 85,
|
||||
GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC = 96,
|
||||
};
|
||||
|
||||
/* GSM 08.08 3.2.2.11 Channel Type */
|
||||
enum gsm0808_chan_indicator {
|
||||
GSM0808_CHAN_SPEECH = 1,
|
||||
GSM0808_CHAN_DATA = 2,
|
||||
GSM0808_CHAN_SIGN = 3,
|
||||
};
|
||||
|
||||
enum gsm0808_chan_rate_type_data {
|
||||
GSM0808_DATA_FULL_BM = 0x8,
|
||||
GSM0808_DATA_HALF_LM = 0x9,
|
||||
GSM0808_DATA_FULL_RPREF = 0xa,
|
||||
GSM0808_DATA_HALF_PREF = 0xb,
|
||||
GSM0808_DATA_FULL_PREF_NO_CHANGE = 0x1a,
|
||||
GSM0808_DATA_HALF_PREF_NO_CHANGE = 0x1b,
|
||||
GSM0808_DATA_MULTI_MASK = 0x20,
|
||||
GSM0808_DATA_MULTI_MASK_NO_CHANGE = 0x30,
|
||||
};
|
||||
|
||||
enum gsm0808_chan_rate_type_speech {
|
||||
GSM0808_SPEECH_FULL_BM = 0x8,
|
||||
GSM0808_SPEECH_HALF_LM = 0x9,
|
||||
GSM0808_SPEECH_FULL_PREF= 0xa,
|
||||
GSM0808_SPEECH_HALF_PREF= 0xb,
|
||||
GSM0808_SPEECH_FULL_PREF_NO_CHANGE = 0x1a,
|
||||
GSM0808_SPEECH_HALF_PREF_NO_CHANGE = 0x1b,
|
||||
GSM0808_SPEECH_PERM = 0xf,
|
||||
GSM0808_SPEECH_PERM_NO_CHANGE = 0x1f,
|
||||
};
|
||||
|
||||
enum gsm0808_permitted_speech {
|
||||
GSM0808_PERM_FR1 = 0x01,
|
||||
GSM0808_PERM_FR2 = 0x11,
|
||||
GSM0808_PERM_FR3 = 0x21,
|
||||
GSM0808_PERM_HR1 = GSM0808_PERM_FR1 | 0x4,
|
||||
GSM0808_PERM_HR2 = GSM0808_PERM_FR2 | 0x4,
|
||||
GSM0808_PERM_HR3 = GSM0808_PERM_FR3 | 0x4,
|
||||
};
|
||||
|
||||
int bssmap_rcvmsg_dt1(struct sccp_connection *conn, struct msgb *msg, unsigned int length);
|
||||
int bssmap_rcvmsg_udt(struct gsm_network *net, struct msgb *msg, unsigned int length);
|
||||
|
||||
struct msgb *bssmap_create_layer3(struct msgb *msg);
|
||||
struct msgb *bssmap_create_reset(void);
|
||||
struct msgb *bssmap_create_clear_complete(void);
|
||||
struct msgb *bssmap_create_cipher_complete(struct msgb *layer3);
|
||||
struct msgb *bssmap_create_cipher_reject(u_int8_t cause);
|
||||
struct msgb *bssmap_create_sapi_reject(u_int8_t link_id);
|
||||
struct msgb *bssmap_create_assignment_completed(struct gsm_lchan *lchan, u_int8_t rr_cause);
|
||||
struct msgb *bssmap_create_assignment_failure(u_int8_t cause, u_int8_t *rr_cause);
|
||||
struct msgb *bssmap_create_classmark_update(const u_int8_t *classmark, u_int8_t length);
|
||||
|
||||
void gsm0808_send_assignment_failure(struct gsm_lchan *l, u_int8_t cause, u_int8_t *rr_value);
|
||||
void gsm0808_send_assignment_compl(struct gsm_lchan *l, u_int8_t rr_value);
|
||||
|
||||
int dtap_rcvmsg(struct gsm_lchan *lchan, struct msgb *msg, unsigned int length);
|
||||
struct msgb *dtap_create_msg(struct msgb *msg_l3, u_int8_t link_id);
|
||||
|
||||
void bsc_queue_connection_write(struct sccp_connection *conn, struct msgb *msg);
|
||||
void bsc_free_queued(struct sccp_connection *conn);
|
||||
void bsc_send_queued(struct sccp_connection *conn);
|
||||
|
||||
void bts_queue_send(struct msgb *msg, int link_id);
|
||||
void bts_send_queued(struct bss_sccp_connection_data*);
|
||||
void bts_free_queued(struct bss_sccp_connection_data*);
|
||||
void bts_unblock_queue(struct bss_sccp_connection_data*);
|
||||
|
||||
#endif
|
||||
@@ -23,27 +23,7 @@
|
||||
|
||||
#include "gsm_subscriber.h"
|
||||
|
||||
/*
|
||||
* Refcounting for the lchan. If the refcount drops to zero
|
||||
* the channel will send a RSL release request.
|
||||
*/
|
||||
#define use_lchan(lchan) \
|
||||
do { lchan->use_count++; \
|
||||
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) increases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
} while(0);
|
||||
|
||||
#define put_lchan(lchan) \
|
||||
do { lchan->use_count--; \
|
||||
DEBUGP(DCC, "lchan (bts=%d,trx=%d,ts=%d,ch=%d) decreases usage to: %d\n", \
|
||||
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, \
|
||||
lchan->nr, lchan->use_count); \
|
||||
if (lchan->use_count <= 0) \
|
||||
_lchan_release(lchan); \
|
||||
} while(0);
|
||||
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
/* Special allocator for C0 of BTS */
|
||||
struct gsm_bts_trx_ts *ts_c0_alloc(struct gsm_bts *bts,
|
||||
@@ -56,19 +36,31 @@ struct gsm_bts_trx_ts *ts_alloc(struct gsm_bts *bts,
|
||||
/* Regular physical channel (TS) */
|
||||
void ts_free(struct gsm_bts_trx_ts *ts);
|
||||
|
||||
/* Find an allocated channel */
|
||||
struct gsm_lchan *lchan_find(struct gsm_bts *bts, struct gsm_subscriber *subscr);
|
||||
|
||||
/* Find an allocated channel for a specified subscriber */
|
||||
struct gsm_lchan *lchan_for_subscr(struct gsm_subscriber *subscr);
|
||||
struct gsm_subscriber_connection *connection_for_subscr(struct gsm_subscriber *subscr);
|
||||
|
||||
/* Allocate a logical channel (SDCCH, TCH, ...) */
|
||||
struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type);
|
||||
|
||||
/* Free a logical channel (SDCCH, TCH, ...) */
|
||||
void lchan_free(struct gsm_lchan *lchan);
|
||||
void lchan_reset(struct gsm_lchan *lchan);
|
||||
|
||||
/* internal.. do not use */
|
||||
int _lchan_release(struct gsm_lchan *lchan);
|
||||
/* Release the given lchan */
|
||||
int lchan_release(struct gsm_lchan *lchan, int sach_deact, int reason);
|
||||
|
||||
struct load_counter {
|
||||
unsigned int total;
|
||||
unsigned int used;
|
||||
};
|
||||
|
||||
struct pchan_load {
|
||||
struct load_counter pchan[GSM_PCHAN_UNKNOWN];
|
||||
};
|
||||
|
||||
void bts_chan_load(struct pchan_load *cl, const struct gsm_bts *bts);
|
||||
void network_chan_load(struct pchan_load *pl, struct gsm_network *net);
|
||||
|
||||
int trx_is_usable(struct gsm_bts_trx *trx);
|
||||
|
||||
#endif /* _CHAN_ALLOC_H */
|
||||
|
||||
8
openbsc/include/openbsc/crc24.h
Normal file
8
openbsc/include/openbsc/crc24.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _CRC24_H
|
||||
#define _CRC24_H
|
||||
|
||||
#define INIT_CRC24 0xffffff
|
||||
|
||||
u_int32_t crc24_calc(u_int32_t fcs, u_int8_t *cp, unsigned int len);
|
||||
|
||||
#endif
|
||||
@@ -43,9 +43,20 @@ int db_subscriber_alloc_token(struct gsm_subscriber* subscriber, u_int32_t* toke
|
||||
int db_subscriber_assoc_imei(struct gsm_subscriber* subscriber, char *imei);
|
||||
int db_sync_equipment(struct gsm_equipment *equip);
|
||||
|
||||
/* auth info */
|
||||
int db_get_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_sync_authinfo_for_subscr(struct gsm_auth_info *ainfo,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_get_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
int db_sync_lastauthtuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr);
|
||||
|
||||
/* SMS store-and-forward */
|
||||
int db_sms_store(struct gsm_sms *sms);
|
||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, int min_id);
|
||||
struct gsm_sms *db_sms_get_unsent(struct gsm_network *net, unsigned long long min_id);
|
||||
struct gsm_sms *db_sms_get_unsent_by_subscr(struct gsm_network *net, unsigned long long min_subscr_id);
|
||||
struct gsm_sms *db_sms_get_unsent_for_subscr(struct gsm_subscriber *subscr);
|
||||
int db_sms_mark_sent(struct gsm_sms *sms);
|
||||
|
||||
@@ -53,4 +64,11 @@ int db_sms_mark_sent(struct gsm_sms *sms);
|
||||
int db_apdu_blob_store(struct gsm_subscriber *subscr,
|
||||
u_int8_t apdu_id_flags, u_int8_t len,
|
||||
u_int8_t *apdu);
|
||||
|
||||
/* Statistics counter storage */
|
||||
struct counter;
|
||||
int db_store_counter(struct counter *ctr);
|
||||
struct rate_ctr_group;
|
||||
int db_store_rate_ctr_group(struct rate_ctr_group *ctrg);
|
||||
|
||||
#endif /* _DB_H */
|
||||
|
||||
@@ -1,58 +1,70 @@
|
||||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define DEBUG
|
||||
#include <osmocore/logging.h>
|
||||
|
||||
#define DRLL 0x0001
|
||||
#define DCC 0x0002
|
||||
#define DMM 0x0004
|
||||
#define DRR 0x0008
|
||||
#define DRSL 0x0010
|
||||
#define DNM 0x0020
|
||||
/* Debug Areas of the code */
|
||||
enum {
|
||||
DRLL,
|
||||
DCC,
|
||||
DMM,
|
||||
DRR,
|
||||
DRSL,
|
||||
DNM,
|
||||
DMNCC,
|
||||
DSMS,
|
||||
DPAG,
|
||||
DMEAS,
|
||||
DMI,
|
||||
DMIB,
|
||||
DMUX,
|
||||
DINP,
|
||||
DSCCP,
|
||||
DMSC,
|
||||
DMGCP,
|
||||
DHO,
|
||||
DDB,
|
||||
DREF,
|
||||
DGPRS,
|
||||
DNS,
|
||||
DBSSGP,
|
||||
DLLC,
|
||||
DSNDCP,
|
||||
DNAT,
|
||||
Debug_LastEntry,
|
||||
};
|
||||
|
||||
#define DMNCC 0x0080
|
||||
#define DSMS 0x0100
|
||||
#define DPAG 0x0200
|
||||
#define DMEAS 0x0400
|
||||
/* context */
|
||||
#define BSC_CTX_LCHAN 0
|
||||
#define BSC_CTX_SUBSCR 1
|
||||
#define BSC_CTX_BTS 2
|
||||
#define BSC_CTX_SCCP 3
|
||||
#define BSC_CTX_NSVC 4
|
||||
#define BSC_CTX_BVC 5
|
||||
|
||||
#define DMI 0x1000
|
||||
#define DMIB 0x2000
|
||||
#define DMUX 0x4000
|
||||
#define DINP 0x8000
|
||||
/* target */
|
||||
|
||||
#define DSCCP 0x10000
|
||||
#define DMSC 0x20000
|
||||
enum {
|
||||
//DEBUG_FILTER_ALL = 1 << 0,
|
||||
LOG_FILTER_IMSI = 1 << 1,
|
||||
LOG_FILTER_NSVC = 1 << 2,
|
||||
LOG_FILTER_BVC = 1 << 3,
|
||||
};
|
||||
|
||||
#define DMGCP 0x40000
|
||||
/* we don't need a header dependency for this... */
|
||||
struct gprs_nsvc;
|
||||
struct bssgp_bvc_ctx;
|
||||
|
||||
#define DHO 0x80000
|
||||
void log_set_imsi_filter(struct log_target *target, const char *imsi);
|
||||
void log_set_nsvc_filter(struct log_target *target,
|
||||
struct gprs_nsvc *nsvc);
|
||||
void log_set_bvc_filter(struct log_target *target,
|
||||
struct bssgp_bvc_ctx *bctx);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUGP(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ## args)
|
||||
#define DEBUGPC(ss, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ## args)
|
||||
#else
|
||||
#define DEBUGP(xss, fmt, args...)
|
||||
#define DEBUGPC(ss, fmt, args...)
|
||||
#endif
|
||||
|
||||
#define static_assert(exp, name) typedef int dummy##name [(exp) ? 1 : -1];
|
||||
|
||||
char *hexdump(const unsigned char *buf, int len);
|
||||
void debugp(unsigned int subsys, char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
|
||||
void debug_parse_category_mask(const char* mask);
|
||||
void debug_use_color(int use_color);
|
||||
void debug_timestamp(int enable);
|
||||
extern unsigned int debug_mask;
|
||||
|
||||
/* new logging interface */
|
||||
#define LOGP(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 0, fmt, ##args)
|
||||
#define LOGPC(ss, level, fmt, args...) debugp(ss, __FILE__, __LINE__, 1, fmt, ##args)
|
||||
|
||||
/* different levels */
|
||||
#define LOGL_DEBUG 1 /* debugging information */
|
||||
#define LOGL_INFO 3
|
||||
#define LOGL_NOTICE 5 /* abnormal/unexpected condition */
|
||||
#define LOGL_ERROR 7 /* error condition, requires user action */
|
||||
#define LOGL_FATAL 8 /* fatal, program aborted */
|
||||
extern const struct log_info log_info;
|
||||
|
||||
#endif /* _DEBUG_H */
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/subchan_demux.h>
|
||||
|
||||
#define NUM_E1_TS 32
|
||||
|
||||
39
openbsc/include/openbsc/gb_proxy.h
Normal file
39
openbsc/include/openbsc/gb_proxy.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef _GB_PROXY_H
|
||||
#define _GB_PROXY_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
#include <openbsc/gprs_ns.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
struct gbproxy_config {
|
||||
/* parsed from config file */
|
||||
u_int16_t nsip_sgsn_nsei;
|
||||
|
||||
/* misc */
|
||||
struct gprs_ns_inst *nsi;
|
||||
};
|
||||
|
||||
extern struct gbproxy_config gbcfg;
|
||||
extern struct cmd_element show_gbproxy_cmd;
|
||||
|
||||
/* gb_proxy_vty .c */
|
||||
|
||||
int gbproxy_vty_init(void);
|
||||
int gbproxy_parse_config(const char *config_file, struct gbproxy_config *cfg);
|
||||
|
||||
|
||||
/* gb_proxy.c */
|
||||
|
||||
/* Main input function for Gb proxy */
|
||||
int gbprox_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
|
||||
|
||||
int gbprox_signal(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data);
|
||||
|
||||
/* Reset all persistent NS-VC's */
|
||||
int gbprox_reset_persistent_nsvcs(struct gprs_ns_inst *nsi);
|
||||
|
||||
#endif
|
||||
232
openbsc/include/openbsc/gprs_bssgp.h
Normal file
232
openbsc/include/openbsc/gprs_bssgp.h
Normal file
@@ -0,0 +1,232 @@
|
||||
#ifndef _GPRS_BSSGP_H
|
||||
#define _GPRS_BSSGP_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* Section 5.4.1 */
|
||||
#define BVCI_SIGNALLING 0x0000
|
||||
#define BVCI_PTM 0x0001
|
||||
|
||||
/* Section 11.3.26 / Table 11.27 */
|
||||
enum bssgp_pdu_type {
|
||||
/* PDUs between RL and BSSGP SAPs */
|
||||
BSSGP_PDUT_DL_UNITDATA = 0x00,
|
||||
BSSGP_PDUT_UL_UNITDATA = 0x01,
|
||||
BSSGP_PDUT_RA_CAPABILITY = 0x02,
|
||||
BSSGP_PDUT_PTM_UNITDATA = 0x03,
|
||||
/* PDUs between GMM SAPs */
|
||||
BSSGP_PDUT_PAGING_PS = 0x06,
|
||||
BSSGP_PDUT_PAGING_CS = 0x07,
|
||||
BSSGP_PDUT_RA_CAPA_UDPATE = 0x08,
|
||||
BSSGP_PDUT_RA_CAPA_UPDATE_ACK = 0x09,
|
||||
BSSGP_PDUT_RADIO_STATUS = 0x0a,
|
||||
BSSGP_PDUT_SUSPEND = 0x0b,
|
||||
BSSGP_PDUT_SUSPEND_ACK = 0x0c,
|
||||
BSSGP_PDUT_SUSPEND_NACK = 0x0d,
|
||||
BSSGP_PDUT_RESUME = 0x0e,
|
||||
BSSGP_PDUT_RESUME_ACK = 0x0f,
|
||||
BSSGP_PDUT_RESUME_NACK = 0x10,
|
||||
/* PDus between NM SAPs */
|
||||
BSSGP_PDUT_BVC_BLOCK = 0x20,
|
||||
BSSGP_PDUT_BVC_BLOCK_ACK = 0x21,
|
||||
BSSGP_PDUT_BVC_RESET = 0x22,
|
||||
BSSGP_PDUT_BVC_RESET_ACK = 0x23,
|
||||
BSSGP_PDUT_BVC_UNBLOCK = 0x24,
|
||||
BSSGP_PDUT_BVC_UNBLOCK_ACK = 0x25,
|
||||
BSSGP_PDUT_FLOW_CONTROL_BVC = 0x26,
|
||||
BSSGP_PDUT_FLOW_CONTROL_BVC_ACK = 0x27,
|
||||
BSSGP_PDUT_FLOW_CONTROL_MS = 0x28,
|
||||
BSSGP_PDUT_FLOW_CONTROL_MS_ACK = 0x29,
|
||||
BSSGP_PDUT_FLUSH_LL = 0x2a,
|
||||
BSSGP_PDUT_FLUSH_LL_ACK = 0x2b,
|
||||
BSSGP_PDUT_LLC_DISCARD = 0x2c,
|
||||
BSSGP_PDUT_SGSN_INVOKE_TRACE = 0x40,
|
||||
BSSGP_PDUT_STATUS = 0x41,
|
||||
/* PDUs between PFM SAP's */
|
||||
BSSGP_PDUT_DOWNLOAD_BSS_PFC = 0x50,
|
||||
BSSGP_PDUT_CREATE_BSS_PFC = 0x51,
|
||||
BSSGP_PDUT_CREATE_BSS_PFC_ACK = 0x52,
|
||||
BSSGP_PDUT_CREATE_BSS_PFC_NACK = 0x53,
|
||||
BSSGP_PDUT_MODIFY_BSS_PFC = 0x54,
|
||||
BSSGP_PDUT_MODIFY_BSS_PFC_ACK = 0x55,
|
||||
BSSGP_PDUT_DELETE_BSS_PFC = 0x56,
|
||||
BSSGP_PDUT_DELETE_BSS_PFC_ACK = 0x57,
|
||||
};
|
||||
|
||||
/* Section 10.2.1 and 10.2.2 */
|
||||
struct bssgp_ud_hdr {
|
||||
uint8_t pdu_type;
|
||||
uint32_t tlli;
|
||||
uint8_t qos_profile[3];
|
||||
uint8_t data[0]; /* TLV's */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct bssgp_normal_hdr {
|
||||
uint8_t pdu_type;
|
||||
uint8_t data[0]; /* TLV's */
|
||||
};
|
||||
|
||||
enum bssgp_iei_type {
|
||||
BSSGP_IE_ALIGNMENT = 0x00,
|
||||
BSSGP_IE_BMAX_DEFAULT_MS = 0x01,
|
||||
BSSGP_IE_BSS_AREA_ID = 0x02,
|
||||
BSSGP_IE_BUCKET_LEAK_RATE = 0x03,
|
||||
BSSGP_IE_BVCI = 0x04,
|
||||
BSSGP_IE_BVC_BUCKET_SIZE = 0x05,
|
||||
BSSGP_IE_BVC_MEASUREMENT = 0x06,
|
||||
BSSGP_IE_CAUSE = 0x07,
|
||||
BSSGP_IE_CELL_ID = 0x08,
|
||||
BSSGP_IE_CHAN_NEEDED = 0x09,
|
||||
BSSGP_IE_DRX_PARAMS = 0x0a,
|
||||
BSSGP_IE_EMLPP_PRIO = 0x0b,
|
||||
BSSGP_IE_FLUSH_ACTION = 0x0c,
|
||||
BSSGP_IE_IMSI = 0x0d,
|
||||
BSSGP_IE_LLC_PDU = 0x0e,
|
||||
BSSGP_IE_LLC_FRAMES_DISCARDED = 0x0f,
|
||||
BSSGP_IE_LOCATION_AREA = 0x10,
|
||||
BSSGP_IE_MOBILE_ID = 0x11,
|
||||
BSSGP_IE_MS_BUCKET_SIZE = 0x12,
|
||||
BSSGP_IE_MS_RADIO_ACCESS_CAP = 0x13,
|
||||
BSSGP_IE_OMC_ID = 0x14,
|
||||
BSSGP_IE_PDU_IN_ERROR = 0x15,
|
||||
BSSGP_IE_PDU_LIFETIME = 0x16,
|
||||
BSSGP_IE_PRIORITY = 0x17,
|
||||
BSSGP_IE_QOS_PROFILE = 0x18,
|
||||
BSSGP_IE_RADIO_CAUSE = 0x19,
|
||||
BSSGP_IE_RA_CAP_UPD_CAUSE = 0x1a,
|
||||
BSSGP_IE_ROUTEING_AREA = 0x1b,
|
||||
BSSGP_IE_R_DEFAULT_MS = 0x1c,
|
||||
BSSGP_IE_SUSPEND_REF_NR = 0x1d,
|
||||
BSSGP_IE_TAG = 0x1e,
|
||||
BSSGP_IE_TLLI = 0x1f,
|
||||
BSSGP_IE_TMSI = 0x20,
|
||||
BSSGP_IE_TRACE_REFERENC = 0x21,
|
||||
BSSGP_IE_TRACE_TYPE = 0x22,
|
||||
BSSGP_IE_TRANSACTION_ID = 0x23,
|
||||
BSSGP_IE_TRIGGER_ID = 0x24,
|
||||
BSSGP_IE_NUM_OCT_AFF = 0x25,
|
||||
BSSGP_IE_LSA_ID_LIST = 0x26,
|
||||
BSSGP_IE_LSA_INFORMATION = 0x27,
|
||||
BSSGP_IE_PACKET_FLOW_ID = 0x28,
|
||||
BSSGP_IE_PACKET_FLOW_TIMER = 0x29,
|
||||
BSSGP_IE_AGG_BSS_QOS_PROFILE = 0x3a,
|
||||
BSSGP_IE_FEATURE_BITMAP = 0x3b,
|
||||
BSSGP_IE_BUCKET_FULL_RATIO = 0x3c,
|
||||
BSSGP_IE_SERVICE_UTRAN_CCO = 0x3d,
|
||||
};
|
||||
|
||||
/* Section 11.3.8 / Table 11.10: Cause coding */
|
||||
enum gprs_bssgp_cause {
|
||||
BSSGP_CAUSE_PROC_OVERLOAD = 0x00,
|
||||
BSSGP_CAUSE_EQUIP_FAIL = 0x01,
|
||||
BSSGP_CAUSE_TRASIT_NET_FAIL = 0x02,
|
||||
BSSGP_CAUSE_CAPA_GREATER_0KPBS = 0x03,
|
||||
BSSGP_CAUSE_UNKNOWN_MS = 0x04,
|
||||
BSSGP_CAUSE_UNKNOWN_BVCI = 0x05,
|
||||
BSSGP_CAUSE_CELL_TRAF_CONG = 0x06,
|
||||
BSSGP_CAUSE_SGSN_CONG = 0x07,
|
||||
BSSGP_CAUSE_OML_INTERV = 0x08,
|
||||
BSSGP_CAUSE_BVCI_BLOCKED = 0x09,
|
||||
BSSGP_CAUSE_PFC_CREATE_FAIL = 0x0a,
|
||||
BSSGP_CAUSE_SEM_INCORR_PDU = 0x20,
|
||||
BSSGP_CAUSE_INV_MAND_INF = 0x21,
|
||||
BSSGP_CAUSE_MISSING_MAND_IE = 0x22,
|
||||
BSSGP_CAUSE_MISSING_COND_IE = 0x23,
|
||||
BSSGP_CAUSE_UNEXP_COND_IE = 0x24,
|
||||
BSSGP_CAUSE_COND_IE_ERR = 0x25,
|
||||
BSSGP_CAUSE_PDU_INCOMP_STATE = 0x26,
|
||||
BSSGP_CAUSE_PROTO_ERR_UNSPEC = 0x27,
|
||||
BSSGP_CAUSE_PDU_INCOMP_FEAT = 0x28,
|
||||
};
|
||||
|
||||
/* Our implementation */
|
||||
|
||||
/* gprs_bssgp_util.c */
|
||||
extern struct gprs_ns_inst *bssgp_nsi;
|
||||
struct msgb *bssgp_msgb_alloc(void);
|
||||
const char *bssgp_cause_str(enum gprs_bssgp_cause cause);
|
||||
/* Transmit a simple response such as BLOCK/UNBLOCK/RESET ACK/NACK */
|
||||
int bssgp_tx_simple_bvci(uint8_t pdu_type, uint16_t nsei,
|
||||
uint16_t bvci, uint16_t ns_bvci);
|
||||
/* Chapter 10.4.14: Status */
|
||||
int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);
|
||||
|
||||
/* gprs_bssgp.c */
|
||||
|
||||
#define BVC_S_BLOCKED 0x0001
|
||||
|
||||
/* The per-BTS context that we keep on the SGSN side of the BSSGP link */
|
||||
struct bssgp_bvc_ctx {
|
||||
struct llist_head list;
|
||||
|
||||
/* parsed RA ID and Cell ID of the remote BTS */
|
||||
struct gprs_ra_id ra_id;
|
||||
uint16_t cell_id;
|
||||
|
||||
/* NSEI and BVCI of underlying Gb link. Together they
|
||||
* uniquely identify a link to a BTS (5.4.4) */
|
||||
uint16_t bvci;
|
||||
uint16_t nsei;
|
||||
|
||||
uint32_t state;
|
||||
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
/* we might want to add this as a shortcut later, avoiding the NSVC
|
||||
* lookup for every packet, similar to a routing cache */
|
||||
//struct gprs_nsvc *nsvc;
|
||||
};
|
||||
extern struct llist_head bssgp_bvc_ctxts;
|
||||
/* Find a BTS Context based on parsed RA ID and Cell ID */
|
||||
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid);
|
||||
/* Find a BTS context based on BVCI+NSEI tuple */
|
||||
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei);
|
||||
|
||||
#include <osmocore/tlv.h>
|
||||
|
||||
/* BSSGP-UL-UNITDATA.ind */
|
||||
int gprs_bssgp_rcvmsg(struct msgb *msg);
|
||||
|
||||
/* BSSGP-DL-UNITDATA.req */
|
||||
struct sgsn_mm_ctx;
|
||||
int gprs_bssgp_tx_dl_ud(struct msgb *msg, struct sgsn_mm_ctx *mmctx);
|
||||
|
||||
uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf);
|
||||
|
||||
/* Wrapper around TLV parser to parse BSSGP IEs */
|
||||
static inline int bssgp_tlv_parse(struct tlv_parsed *tp, uint8_t *buf, int len)
|
||||
{
|
||||
return tlv_parse(tp, &tvlv_att_def, buf, len, 0, 0);
|
||||
}
|
||||
|
||||
enum bssgp_paging_mode {
|
||||
BSSGP_PAGING_PS,
|
||||
BSSGP_PAGING_CS,
|
||||
};
|
||||
|
||||
enum bssgp_paging_scope {
|
||||
BSSGP_PAGING_BSS_AREA, /* all cells in BSS */
|
||||
BSSGP_PAGING_LOCATION_AREA, /* all cells in LA */
|
||||
BSSGP_PAGING_ROUTEING_AREA, /* all cells in RA */
|
||||
BSSGP_PAGING_BVCI, /* one cell */
|
||||
};
|
||||
|
||||
struct bssgp_paging_info {
|
||||
enum bssgp_paging_mode mode;
|
||||
enum bssgp_paging_scope scope;
|
||||
struct gprs_ra_id raid;
|
||||
uint16_t bvci;
|
||||
const char *imsi;
|
||||
uint32_t *ptmsi;
|
||||
uint16_t drx_params;
|
||||
uint8_t qos[3];
|
||||
};
|
||||
|
||||
/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
|
||||
int gprs_bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
|
||||
struct bssgp_paging_info *pinfo);
|
||||
|
||||
/* gprs_bssgp_vty.c */
|
||||
int gprs_bssgp_vty_init(void);
|
||||
|
||||
#endif /* _GPRS_BSSGP_H */
|
||||
18
openbsc/include/openbsc/gprs_gmm.h
Normal file
18
openbsc/include/openbsc/gprs_gmm.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _GPRS_GMM_H
|
||||
#define _GPRS_GMM_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
int gsm48_tx_gsm_act_pdp_rej(struct sgsn_mm_ctx *mm, uint8_t tid,
|
||||
uint8_t cause, uint8_t pco_len, uint8_t *pco_v);
|
||||
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 gprs_gmm_rx_suspend(struct gprs_ra_id *raid, uint32_t tlli);
|
||||
int gprs_gmm_rx_resume(struct gprs_ra_id *raid, uint32_t tlli,
|
||||
uint8_t suspend_ref);
|
||||
|
||||
#endif /* _GPRS_GMM_H */
|
||||
162
openbsc/include/openbsc/gprs_llc.h
Normal file
162
openbsc/include/openbsc/gprs_llc.h
Normal file
@@ -0,0 +1,162 @@
|
||||
#ifndef _GPRS_LLC_H
|
||||
#define _GPRS_LLC_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
/* Section 4.7 LLC Layer Structure */
|
||||
enum gprs_llc_sapi {
|
||||
GPRS_SAPI_GMM = 1,
|
||||
GPRS_SAPI_TOM2 = 2,
|
||||
GPRS_SAPI_SNDCP3 = 3,
|
||||
GPRS_SAPI_SNDCP5 = 5,
|
||||
GPRS_SAPI_SMS = 7,
|
||||
GPRS_SAPI_TOM8 = 8,
|
||||
GPRS_SAPI_SNDCP9 = 9,
|
||||
GPRS_SAPI_SNDCP11 = 11,
|
||||
};
|
||||
|
||||
/* Section 6.4 Commands and Responses */
|
||||
enum gprs_llc_u_cmd {
|
||||
GPRS_LLC_U_DM_RESP = 0x01,
|
||||
GPRS_LLC_U_DISC_CMD = 0x04,
|
||||
GPRS_LLC_U_UA_RESP = 0x06,
|
||||
GPRS_LLC_U_SABM_CMD = 0x07,
|
||||
GPRS_LLC_U_FRMR_RESP = 0x08,
|
||||
GPRS_LLC_U_XID = 0x0b,
|
||||
GPRS_LLC_U_NULL_CMD = 0x00,
|
||||
};
|
||||
|
||||
/* TS 04.64 Section 7.1.2 Table 7: LLC layer primitives (GMM/SNDCP/SMS/TOM) */
|
||||
/* TS 04.65 Section 5.1.2 Table 2: Service primitives used by SNDCP */
|
||||
enum gprs_llc_primitive {
|
||||
/* GMM <-> LLME */
|
||||
LLGMM_ASSIGN_REQ, /* GMM tells us new TLLI: TLLI old, TLLI new, Kc, CiphAlg */
|
||||
LLGMM_RESET_REQ, /* GMM tells us to perform XID negotiation: TLLI */
|
||||
LLGMM_RESET_CNF, /* LLC informs GMM that XID has completed: TLLI */
|
||||
LLGMM_SUSPEND_REQ, /* GMM tells us MS has suspended: TLLI, Page */
|
||||
LLGMM_RESUME_REQ, /* GMM tells us MS has resumed: TLLI */
|
||||
LLGMM_PAGE_IND, /* LLC asks GMM to page MS: TLLI */
|
||||
LLGMM_IOV_REQ, /* GMM tells us to perform XID: TLLI */
|
||||
LLGMM_STATUS_IND, /* LLC informs GMM about error: TLLI, Cause */
|
||||
/* LLE <-> (GMM/SNDCP/SMS/TOM) */
|
||||
LL_RESET_IND, /* TLLI */
|
||||
LL_ESTABLISH_REQ, /* TLLI, XID Req */
|
||||
LL_ESTABLISH_IND, /* TLLI, XID Req, N201-I, N201-U */
|
||||
LL_ESTABLISH_RESP, /* TLLI, XID Negotiated */
|
||||
LL_ESTABLISH_CONF, /* TLLI, XID Neg, N201-i, N201-U */
|
||||
LL_RELEASE_REQ, /* TLLI, Local */
|
||||
LL_RELEASE_IND, /* TLLI, Cause */
|
||||
LL_RELEASE_CONF, /* TLLI */
|
||||
LL_XID_REQ, /* TLLI, XID Requested */
|
||||
LL_XID_IND, /* TLLI, XID Req, N201-I, N201-U */
|
||||
LL_XID_RESP, /* TLLI, XID Negotiated */
|
||||
LL_XID_CONF, /* TLLI, XID Neg, N201-I, N201-U */
|
||||
LL_DATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
|
||||
LL_DATA_IND, /* TLLI, SN-PDU */
|
||||
LL_DATA_CONF, /* TLLI, Ref */
|
||||
LL_UNITDATA_REQ, /* TLLI, SN-PDU, Ref, QoS, Radio Prio, Ciph */
|
||||
LL_UNITDATA_IND, /* TLLI, SN-PDU */
|
||||
LL_STATUS_IND, /* TLLI, Cause */
|
||||
};
|
||||
|
||||
/* Section 4.5.2 Logical Link States + Annex C.2 */
|
||||
enum gprs_llc_lle_state {
|
||||
GPRS_LLES_UNASSIGNED = 1, /* No TLLI yet */
|
||||
GPRS_LLES_ASSIGNED_ADM = 2, /* TLLI assigned */
|
||||
GPRS_LLES_LOCAL_EST = 3, /* Local Establishment */
|
||||
GPRS_LLES_REMOTE_EST = 4, /* Remote Establishment */
|
||||
GPRS_LLES_ABM = 5,
|
||||
GPRS_LLES_LOCAL_REL = 6, /* Local Release */
|
||||
GPRS_LLES_TIMER_REC = 7, /* Timer Recovery */
|
||||
};
|
||||
|
||||
enum gprs_llc_llme_state {
|
||||
GPRS_LLMS_UNASSIGNED = 1, /* No TLLI yet */
|
||||
GPRS_LLMS_ASSIGNED = 2, /* TLLI assigned */
|
||||
};
|
||||
|
||||
/* Section 8.9.9 LLC layer parameter default values */
|
||||
struct gprs_llc_params {
|
||||
uint16_t iov_i_exp;
|
||||
uint16_t t200_201;
|
||||
uint16_t n200;
|
||||
uint16_t n201_u;
|
||||
uint16_t n201_i;
|
||||
uint16_t mD;
|
||||
uint16_t mU;
|
||||
uint16_t kD;
|
||||
uint16_t kU;
|
||||
};
|
||||
|
||||
/* Section 4.7.1: Logical Link Entity: One per DLCI (TLLI + SAPI) */
|
||||
struct gprs_llc_lle {
|
||||
struct llist_head list;
|
||||
|
||||
uint32_t sapi;
|
||||
|
||||
struct gprs_llc_llme *llme;
|
||||
|
||||
enum gprs_llc_lle_state state;
|
||||
|
||||
struct timer_list t200;
|
||||
struct timer_list t201; /* wait for acknowledgement */
|
||||
|
||||
uint16_t v_sent;
|
||||
uint16_t v_ack;
|
||||
uint16_t v_recv;
|
||||
|
||||
uint16_t vu_send;
|
||||
uint16_t vu_recv;
|
||||
|
||||
/* Overflow Counter for ABM */
|
||||
uint32_t oc_i_send;
|
||||
uint32_t oc_i_recv;
|
||||
|
||||
/* Overflow Counter for unconfirmed transfer */
|
||||
uint32_t oc_ui_send;
|
||||
uint32_t oc_ui_recv;
|
||||
|
||||
unsigned int retrans_ctr;
|
||||
|
||||
struct gprs_llc_params params;
|
||||
};
|
||||
|
||||
#define NUM_SAPIS 16
|
||||
|
||||
struct gprs_llc_llme {
|
||||
struct llist_head list;
|
||||
|
||||
enum gprs_llc_llme_state state;
|
||||
|
||||
uint32_t tlli;
|
||||
uint32_t old_tlli;
|
||||
|
||||
/* Crypto parameters */
|
||||
enum gprs_ciph_algo algo;
|
||||
uint8_t kc[8];
|
||||
|
||||
/* over which BSSGP BTS ctx do we need to transmit */
|
||||
uint16_t bvci;
|
||||
uint16_t nsei;
|
||||
struct gprs_llc_lle lle[NUM_SAPIS];
|
||||
};
|
||||
|
||||
extern struct llist_head gprs_llc_llmes;
|
||||
|
||||
/* BSSGP-UL-UNITDATA.ind */
|
||||
int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv);
|
||||
|
||||
/* LL-UNITDATA.req */
|
||||
int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command,
|
||||
void *mmctx);
|
||||
|
||||
/* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */
|
||||
int gprs_llgmm_assign(struct gprs_llc_llme *llme,
|
||||
uint32_t old_tlli, uint32_t new_tlli,
|
||||
enum gprs_ciph_algo alg, const uint8_t *kc);
|
||||
|
||||
int gprs_llc_init(const char *cipher_plugin_path);
|
||||
int gprs_llc_vty_init(void);
|
||||
|
||||
#endif
|
||||
232
openbsc/include/openbsc/gprs_ns.h
Normal file
232
openbsc/include/openbsc/gprs_ns.h
Normal file
@@ -0,0 +1,232 @@
|
||||
#ifndef _GPRS_NS_H
|
||||
#define _GPRS_NS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* GPRS Networks Service (NS) messages on the Gb interface
|
||||
* 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
|
||||
* 3GPP TS 48.016 version 6.5.0 Release 6 / ETSI TS 148 016 V6.5.0 (2005-11) */
|
||||
|
||||
struct gprs_ns_hdr {
|
||||
uint8_t pdu_type;
|
||||
uint8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* TS 08.16, Section 10.3.7, Table 14 */
|
||||
enum ns_pdu_type {
|
||||
NS_PDUT_UNITDATA = 0x00,
|
||||
NS_PDUT_RESET = 0x02,
|
||||
NS_PDUT_RESET_ACK = 0x03,
|
||||
NS_PDUT_BLOCK = 0x04,
|
||||
NS_PDUT_BLOCK_ACK = 0x05,
|
||||
NS_PDUT_UNBLOCK = 0x06,
|
||||
NS_PDUT_UNBLOCK_ACK = 0x07,
|
||||
NS_PDUT_STATUS = 0x08,
|
||||
NS_PDUT_ALIVE = 0x0a,
|
||||
NS_PDUT_ALIVE_ACK = 0x0b,
|
||||
/* TS 48.016 Section 10.3.7, Table 10.3.7.1 */
|
||||
SNS_PDUT_ACK = 0x0c,
|
||||
SNS_PDUT_ADD = 0x0d,
|
||||
SNS_PDUT_CHANGE_WEIGHT = 0x0e,
|
||||
SNS_PDUT_CONFIG = 0x0f,
|
||||
SNS_PDUT_CONFIG_ACK = 0x10,
|
||||
SNS_PDUT_DELETE = 0x11,
|
||||
SNS_PDUT_SIZE = 0x12,
|
||||
SNS_PDUT_SIZE_ACK = 0x13,
|
||||
};
|
||||
|
||||
/* TS 08.16, Section 10.3, Table 12 */
|
||||
enum ns_ctrl_ie {
|
||||
NS_IE_CAUSE = 0x00,
|
||||
NS_IE_VCI = 0x01,
|
||||
NS_IE_PDU = 0x02,
|
||||
NS_IE_BVCI = 0x03,
|
||||
NS_IE_NSEI = 0x04,
|
||||
/* TS 48.016 Section 10.3, Table 10.3.1 */
|
||||
NS_IE_IPv4_LIST = 0x05,
|
||||
NS_IE_IPv6_LIST = 0x06,
|
||||
NS_IE_MAX_NR_NSVC = 0x07,
|
||||
NS_IE_IPv4_EP_NR = 0x08,
|
||||
NS_IE_IPv6_EP_NR = 0x09,
|
||||
NS_IE_RESET_FLAG = 0x0a,
|
||||
NS_IE_IP_ADDR = 0x0b,
|
||||
};
|
||||
|
||||
/* TS 08.16, Section 10.3.2, Table 13 */
|
||||
enum ns_cause {
|
||||
NS_CAUSE_TRANSIT_FAIL = 0x00,
|
||||
NS_CAUSE_OM_INTERVENTION = 0x01,
|
||||
NS_CAUSE_EQUIP_FAIL = 0x02,
|
||||
NS_CAUSE_NSVC_BLOCKED = 0x03,
|
||||
NS_CAUSE_NSVC_UNKNOWN = 0x04,
|
||||
NS_CAUSE_BVCI_UNKNOWN = 0x05,
|
||||
NS_CAUSE_SEM_INCORR_PDU = 0x08,
|
||||
NS_CAUSE_PDU_INCOMP_PSTATE = 0x0a,
|
||||
NS_CAUSE_PROTO_ERR_UNSPEC = 0x0b,
|
||||
NS_CAUSE_INVAL_ESSENT_IE = 0x0c,
|
||||
NS_CAUSE_MISSING_ESSENT_IE = 0x0d,
|
||||
/* TS 48.016 Section 10.3.2, Table 10.3.2.1 */
|
||||
NS_CAUSE_INVAL_NR_IPv4_EP = 0x0e,
|
||||
NS_CAUSE_INVAL_NR_IPv6_EP = 0x0f,
|
||||
NS_CAUSE_INVAL_NR_NS_VC = 0x10,
|
||||
NS_CAUSE_INVAL_WEIGH = 0x11,
|
||||
NS_CAUSE_UNKN_IP_EP = 0x12,
|
||||
NS_CAUSE_UNKN_IP_ADDR = 0x13,
|
||||
NS_CAUSE_UNKN_IP_TEST_FAILED = 0x14,
|
||||
};
|
||||
|
||||
/* Our Implementation */
|
||||
#include <netinet/in.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#define NS_TIMERS_COUNT 7
|
||||
#define NS_TIMERS "(tns-block|tns-block-retries|tns-reset|tns-reset-retries|tns-test|tns-alive|tns-alive-retries)"
|
||||
#define NS_TIMERS_HELP \
|
||||
"(un)blocking Timer (Tns-block) timeout\n" \
|
||||
"(un)blocking Timer (Tns-block) number of retries\n" \
|
||||
"Reset Timer (Tns-reset) timeout\n" \
|
||||
"Reset Timer (Tns-reset) number of retries\n" \
|
||||
"Test Timer (Tns-test) timeout\n" \
|
||||
|
||||
enum ns_timeout {
|
||||
NS_TOUT_TNS_BLOCK,
|
||||
NS_TOUT_TNS_BLOCK_RETRIES,
|
||||
NS_TOUT_TNS_RESET,
|
||||
NS_TOUT_TNS_RESET_RETRIES,
|
||||
NS_TOUT_TNS_TEST,
|
||||
NS_TOUT_TNS_ALIVE,
|
||||
NS_TOUT_TNS_ALIVE_RETRIES,
|
||||
};
|
||||
|
||||
#define NSE_S_BLOCKED 0x0001
|
||||
#define NSE_S_ALIVE 0x0002
|
||||
|
||||
enum gprs_ns_ll {
|
||||
GPRS_NS_LL_UDP,
|
||||
GPRS_NS_LL_E1,
|
||||
GPRS_NS_LL_FR_GRE,
|
||||
};
|
||||
|
||||
enum gprs_ns_evt {
|
||||
GPRS_NS_EVT_UNIT_DATA,
|
||||
};
|
||||
|
||||
struct gprs_nsvc;
|
||||
typedef int gprs_ns_cb_t(enum gprs_ns_evt event, struct gprs_nsvc *nsvc,
|
||||
struct msgb *msg, uint16_t bvci);
|
||||
|
||||
/* An instance of the NS protocol stack */
|
||||
struct gprs_ns_inst {
|
||||
/* callback to the user for incoming UNIT DATA IND */
|
||||
gprs_ns_cb_t *cb;
|
||||
|
||||
/* linked lists of all NSVC in this instance */
|
||||
struct llist_head gprs_nsvcs;
|
||||
|
||||
/* a NSVC object that's needed to deal with packets for unknown NSVC */
|
||||
struct gprs_nsvc *unknown_nsvc;
|
||||
|
||||
uint16_t timeout[NS_TIMERS_COUNT];
|
||||
|
||||
/* NS-over-IP specific bits */
|
||||
struct {
|
||||
struct bsc_fd fd;
|
||||
uint32_t local_ip;
|
||||
uint16_t local_port;
|
||||
} nsip;
|
||||
/* NS-over-FR-over-GRE-over-IP specific bits */
|
||||
struct {
|
||||
struct bsc_fd fd;
|
||||
uint32_t local_ip;
|
||||
int enabled:1;
|
||||
} frgre;
|
||||
};
|
||||
|
||||
enum nsvc_timer_mode {
|
||||
/* standard timers */
|
||||
NSVC_TIMER_TNS_TEST,
|
||||
NSVC_TIMER_TNS_ALIVE,
|
||||
NSVC_TIMER_TNS_RESET,
|
||||
_NSVC_TIMER_NR,
|
||||
};
|
||||
|
||||
struct gprs_nsvc {
|
||||
struct llist_head list;
|
||||
struct gprs_ns_inst *nsi;
|
||||
|
||||
uint16_t nsei; /* end-to-end significance */
|
||||
uint16_t nsvci; /* uniquely identifies NS-VC at SGSN */
|
||||
|
||||
uint32_t state;
|
||||
uint32_t remote_state;
|
||||
|
||||
struct timer_list timer;
|
||||
enum nsvc_timer_mode timer_mode;
|
||||
int alive_retries;
|
||||
|
||||
unsigned int remote_end_is_sgsn:1;
|
||||
unsigned int persistent:1;
|
||||
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
/* which link-layer are we based on? */
|
||||
enum gprs_ns_ll ll;
|
||||
|
||||
union {
|
||||
struct {
|
||||
struct sockaddr_in bts_addr;
|
||||
} ip;
|
||||
struct {
|
||||
struct sockaddr_in bts_addr;
|
||||
} frgre;
|
||||
};
|
||||
};
|
||||
|
||||
/* Create a new NS protocol instance */
|
||||
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb);
|
||||
|
||||
/* Destroy a NS protocol instance */
|
||||
void gprs_ns_destroy(struct gprs_ns_inst *nsi);
|
||||
|
||||
/* Listen for incoming GPRS packets via NS/UDP */
|
||||
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi);
|
||||
|
||||
struct sockaddr_in;
|
||||
|
||||
/* main function for higher layers (BSSGP) to send NS messages */
|
||||
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg);
|
||||
|
||||
int gprs_ns_tx_reset(struct gprs_nsvc *nsvc, uint8_t cause);
|
||||
int gprs_ns_tx_block(struct gprs_nsvc *nsvc, uint8_t cause);
|
||||
int gprs_ns_tx_unblock(struct gprs_nsvc *nsvc);
|
||||
|
||||
/* Listen for incoming GPRS packets via NS/FR/GRE */
|
||||
int gprs_ns_frgre_listen(struct gprs_ns_inst *nsi);
|
||||
|
||||
/* Establish a connection (from the BSS) to the SGSN */
|
||||
struct gprs_nsvc *nsip_connect(struct gprs_ns_inst *nsi,
|
||||
struct sockaddr_in *dest, uint16_t nsei,
|
||||
uint16_t nsvci);
|
||||
|
||||
struct gprs_nsvc *nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci);
|
||||
void nsvc_delete(struct gprs_nsvc *nsvc);
|
||||
struct gprs_nsvc *nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei);
|
||||
struct gprs_nsvc *nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci);
|
||||
|
||||
/* Initiate a RESET procedure (including timer start, ...)*/
|
||||
void gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause);
|
||||
|
||||
/* Add NS-specific VTY stuff */
|
||||
int gprs_ns_vty_init(struct gprs_ns_inst *nsi);
|
||||
|
||||
#define NS_ALLOC_SIZE 2048
|
||||
#define NS_ALLOC_HEADROOM 20
|
||||
static inline struct msgb *gprs_ns_msgb_alloc(void)
|
||||
{
|
||||
return msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM, "GPRS/NS");
|
||||
}
|
||||
|
||||
#endif
|
||||
6
openbsc/include/openbsc/gprs_ns_frgre.h
Normal file
6
openbsc/include/openbsc/gprs_ns_frgre.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef _GPRS_NS_FRGRE_H
|
||||
#define _GPRS_NS_FRGRE_H
|
||||
|
||||
int gprs_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
|
||||
|
||||
#endif
|
||||
205
openbsc/include/openbsc/gprs_sgsn.h
Normal file
205
openbsc/include/openbsc/gprs_sgsn.h
Normal file
@@ -0,0 +1,205 @@
|
||||
#ifndef _GPRS_SGSN_H
|
||||
#define _GPRS_SGSN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <osmocore/gsm48.h>
|
||||
|
||||
#include <osmocom/crypt/gprs_cipher.h>
|
||||
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_EXTENSION_LENGTH 15
|
||||
|
||||
struct gprs_llc_lle;
|
||||
|
||||
/* TS 04.08 4.1.3.3 GMM mobility management states on the network side */
|
||||
enum gprs_mm_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 */
|
||||
GMM_REGISTERED_SUSPENDED, /* 4.1.3.3.2.2 */
|
||||
GMM_DEREGISTERED_INIT, /* 4.1.3.3.1.4 */
|
||||
};
|
||||
|
||||
enum gprs_mm_ctr {
|
||||
GMM_CTR_PKTS_SIG_IN,
|
||||
GMM_CTR_PKTS_SIG_OUT,
|
||||
GMM_CTR_PKTS_UDATA_IN,
|
||||
GMM_CTR_PKTS_UDATA_OUT,
|
||||
GMM_CTR_BYTES_UDATA_IN,
|
||||
GMM_CTR_BYTES_UDATA_OUT,
|
||||
GMM_CTR_PDP_CTX_ACT,
|
||||
GMM_CTR_SUSPEND,
|
||||
GMM_CTR_PAGING_PS,
|
||||
GMM_CTR_PAGING_CS,
|
||||
GMM_CTR_RA_UPDATE,
|
||||
};
|
||||
|
||||
enum gprs_pdp_ctx {
|
||||
PDP_CTR_PKTS_UDATA_IN,
|
||||
PDP_CTR_PKTS_UDATA_OUT,
|
||||
PDP_CTR_BYTES_UDATA_IN,
|
||||
PDP_CTR_BYTES_UDATA_OUT,
|
||||
};
|
||||
|
||||
enum gprs_t3350_mode {
|
||||
GMM_T3350_MODE_ATT,
|
||||
GMM_T3350_MODE_RAU,
|
||||
GMM_T3350_MODE_PTMSI_REALL,
|
||||
};
|
||||
|
||||
#define MS_RADIO_ACCESS_CAPA
|
||||
|
||||
/* 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;
|
||||
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];
|
||||
/* 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 */
|
||||
/* VLR number */
|
||||
uint32_t new_sgsn_addr;
|
||||
/* Authentication Triplets */
|
||||
/* Kc */
|
||||
/* Iu: CK, IK, KSI */
|
||||
/* CKSN */
|
||||
enum gprs_ciph_algo ciph_algo;
|
||||
struct {
|
||||
uint8_t buf[14]; /* 10.5.5.12a */
|
||||
uint8_t len;
|
||||
} ms_radio_access_capa;
|
||||
struct {
|
||||
uint8_t buf[4]; /* 10.5.5.12 */
|
||||
uint8_t len;
|
||||
} ms_network_capa;
|
||||
uint16_t drx_parms;
|
||||
int mnrg; /* MS reported to HLR? */
|
||||
int ngaf; /* MS reported to MSC/VLR? */
|
||||
int ppf; /* paging for GPRS + non-GPRS? */
|
||||
/* SMS Parameters */
|
||||
int recovery;
|
||||
uint8_t radio_prio_sms;
|
||||
|
||||
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 timer_list timer;
|
||||
unsigned int T; /* Txxxx number */
|
||||
unsigned int num_T_exp; /* number of consecutive T expirations */
|
||||
|
||||
enum gprs_t3350_mode t3350_mode;
|
||||
uint8_t t3370_id_type;
|
||||
};
|
||||
|
||||
/* look-up a SGSN MM context based on TLLI + RAI */
|
||||
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);
|
||||
|
||||
/* Allocate a new SGSN MM context */
|
||||
struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
|
||||
const struct gprs_ra_id *raid);
|
||||
|
||||
|
||||
enum pdp_ctx_state {
|
||||
PDP_STATE_NONE,
|
||||
PDP_STATE_CR_REQ,
|
||||
PDP_STATE_CR_CONF,
|
||||
};
|
||||
|
||||
enum pdp_type {
|
||||
PDP_TYPE_NONE,
|
||||
PDP_TYPE_ETSI_PPP,
|
||||
PDP_TYPE_IANA_IPv4,
|
||||
PDP_TYPE_IANA_IPv6,
|
||||
};
|
||||
|
||||
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 */
|
||||
struct sgsn_ggsn_ctx *ggsn; /* which GGSN serves this PDP */
|
||||
struct rate_ctr_group *ctrg;
|
||||
|
||||
//unsigned int id;
|
||||
struct pdp_t *lib; /* pointer to libgtp PDP ctx */
|
||||
enum pdp_ctx_state state;
|
||||
enum pdp_type type;
|
||||
uint32_t address;
|
||||
char *apn_subscribed;
|
||||
//char *apn_used;
|
||||
uint16_t nsapi; /* SNDCP */
|
||||
uint16_t sapi; /* LLC */
|
||||
uint8_t ti; /* transaction identifier */
|
||||
int vplmn_allowed;
|
||||
uint32_t qos_profile_subscr;
|
||||
//uint32_t qos_profile_req;
|
||||
//uint32_t qos_profile_neg;
|
||||
uint8_t radio_prio;
|
||||
uint32_t tx_npdu_nr;
|
||||
uint32_t rx_npdu_nr;
|
||||
uint32_t tx_gtp_snd;
|
||||
uint32_t rx_gtp_snu;
|
||||
//uint32_t charging_id;
|
||||
int reordering_reqd;
|
||||
};
|
||||
|
||||
|
||||
/* look up PDP context by MM context and NSAPI */
|
||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_nsapi(const struct sgsn_mm_ctx *mm,
|
||||
uint8_t nsapi);
|
||||
/* look up PDP context by MM context and transaction ID */
|
||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_by_tid(const struct sgsn_mm_ctx *mm,
|
||||
uint8_t tid);
|
||||
|
||||
struct sgsn_pdp_ctx *sgsn_pdp_ctx_alloc(struct sgsn_mm_ctx *mm,
|
||||
uint8_t nsapi);
|
||||
void sgsn_pdp_ctx_free(struct sgsn_pdp_ctx *pdp);
|
||||
|
||||
|
||||
struct sgsn_ggsn_ctx {
|
||||
struct llist_head list;
|
||||
uint32_t id;
|
||||
unsigned int gtp_version;
|
||||
struct in_addr remote_addr;
|
||||
struct gsn_t *gsn;
|
||||
};
|
||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_alloc(uint32_t id);
|
||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_by_id(uint32_t id);
|
||||
struct sgsn_ggsn_ctx *sgsn_ggsn_ctx_find_alloc(uint32_t id);
|
||||
|
||||
struct apn_ctx {
|
||||
struct llist_head list;
|
||||
struct sgsn_ggsn_ctx *ggsn;
|
||||
char *name;
|
||||
char *description;
|
||||
};
|
||||
|
||||
extern struct llist_head sgsn_mm_ctxts;
|
||||
extern struct llist_head sgsn_ggsn_ctxts;
|
||||
extern struct llist_head sgsn_apn_ctxts;
|
||||
extern struct llist_head sgsn_pdp_ctxts;
|
||||
|
||||
uint32_t sgsn_alloc_ptmsi(void);
|
||||
|
||||
#endif /* _GPRS_SGSN_H */
|
||||
@@ -3,770 +3,41 @@
|
||||
|
||||
#include <openbsc/meas_rep.h>
|
||||
|
||||
/* GSM TS 04.08 definitions */
|
||||
struct gsm_lchan;
|
||||
|
||||
struct gsm48_classmark1 {
|
||||
u_int8_t spare:1,
|
||||
rev_level:2,
|
||||
es_ind:1,
|
||||
a5_1:1,
|
||||
pwr_lev:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.5 */
|
||||
struct gsm48_chan_desc {
|
||||
u_int8_t chan_nr;
|
||||
union {
|
||||
struct {
|
||||
u_int8_t maio_high:4,
|
||||
h:1,
|
||||
tsc:3;
|
||||
u_int8_t hsn:6,
|
||||
maio_low:2;
|
||||
} h1;
|
||||
struct {
|
||||
u_int8_t arfcn_high:2,
|
||||
spare:2,
|
||||
h:1,
|
||||
tsc:3;
|
||||
u_int8_t arfcn_low;
|
||||
} h0;
|
||||
};
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.2.21aa */
|
||||
struct gsm48_multi_rate_conf {
|
||||
u_int8_t smod : 2,
|
||||
spare: 1,
|
||||
icmi : 1,
|
||||
nscb : 1,
|
||||
ver : 3;
|
||||
u_int8_t m4_75 : 1,
|
||||
m5_15 : 1,
|
||||
m5_90 : 1,
|
||||
m6_70 : 1,
|
||||
m7_40 : 1,
|
||||
m7_95 : 1,
|
||||
m10_2 : 1,
|
||||
m12_2 : 1;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.30 */
|
||||
struct gsm48_req_ref {
|
||||
u_int8_t ra;
|
||||
u_int8_t t3_high:3,
|
||||
t1_:5;
|
||||
u_int8_t t2:5,
|
||||
t3_low:3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* Chapter 9.1.5/9.1.6
|
||||
*
|
||||
* For 9.1.6 the chan_desc has the meaning of 10.5.2.5a
|
||||
*/
|
||||
struct gsm48_chan_mode_modify {
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t mode;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum gsm48_chan_mode {
|
||||
GSM48_CMODE_SIGN = 0x00,
|
||||
GSM48_CMODE_SPEECH_V1 = 0x01,
|
||||
GSM48_CMODE_SPEECH_EFR = 0x21,
|
||||
GSM48_CMODE_SPEECH_AMR = 0x41,
|
||||
GSM48_CMODE_DATA_14k5 = 0x0f,
|
||||
GSM48_CMODE_DATA_12k0 = 0x03,
|
||||
GSM48_CMODE_DATA_6k0 = 0x0b,
|
||||
GSM48_CMODE_DATA_3k6 = 0x23,
|
||||
};
|
||||
|
||||
/* Chapter 9.1.2 */
|
||||
struct gsm48_ass_cmd {
|
||||
/* Semantic is from 10.5.2.5a */
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t power_command;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 10.5.2.2 */
|
||||
struct gsm48_cell_desc {
|
||||
u_int8_t bcc:3,
|
||||
ncc:3,
|
||||
arfcn_hi:2;
|
||||
u_int8_t arfcn_lo;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.15 */
|
||||
struct gsm48_ho_cmd {
|
||||
struct gsm48_cell_desc cell_desc;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
u_int8_t ho_ref;
|
||||
u_int8_t power_command;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Chapter 9.1.18 */
|
||||
struct gsm48_imm_ass {
|
||||
u_int8_t l2_plen;
|
||||
u_int8_t proto_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t page_mode;
|
||||
struct gsm48_chan_desc chan_desc;
|
||||
struct gsm48_req_ref req_ref;
|
||||
u_int8_t timing_advance;
|
||||
u_int8_t mob_alloc_len;
|
||||
u_int8_t mob_alloc[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Chapter 10.5.1.3 */
|
||||
struct gsm48_loc_area_id {
|
||||
u_int8_t digits[3]; /* BCD! */
|
||||
u_int16_t lac;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.2 */
|
||||
struct gsm48_auth_req {
|
||||
u_int8_t key_seq:4,
|
||||
spare:4;
|
||||
u_int8_t rand[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.15 */
|
||||
struct gsm48_loc_upd_req {
|
||||
u_int8_t type:4,
|
||||
key_seq:4;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_classmark1 classmark1;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.1 */
|
||||
struct gsm48_hdr {
|
||||
u_int8_t proto_discr;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.3x System information Type header */
|
||||
struct gsm48_system_information_type_header {
|
||||
u_int8_t l2_plen;
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_rach_control {
|
||||
u_int8_t re :1,
|
||||
cell_bar :1,
|
||||
tx_integer :4,
|
||||
max_trans :2;
|
||||
u_int8_t t2;
|
||||
u_int8_t t3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.4 Cell Selection Parameters */
|
||||
struct gsm48_cell_sel_par {
|
||||
u_int8_t ms_txpwr_max_ccch:5, /* GSM 05.08 MS-TXPWR-MAX-CCCH */
|
||||
cell_resel_hyst:3; /* GSM 05.08 CELL-RESELECT-HYSTERESIS */
|
||||
u_int8_t rxlev_acc_min:6, /* GSM 05.08 RXLEV-ACCESS-MIN */
|
||||
neci:1,
|
||||
acs:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.5.2.11 Control Channel Description , Figure 10.5.33 */
|
||||
struct gsm48_control_channel_descr {
|
||||
u_int8_t ccch_conf :3,
|
||||
bs_ag_blks_res :3,
|
||||
att :1,
|
||||
spare1 :1;
|
||||
u_int8_t bs_pa_mfrms : 3,
|
||||
spare2 :5;
|
||||
u_int8_t t3212;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm48_cell_options {
|
||||
u_int8_t radio_link_timeout:4,
|
||||
dtx:2,
|
||||
pwrc:1,
|
||||
spare:1;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.9 CM service request */
|
||||
struct gsm48_service_request {
|
||||
u_int8_t cm_service_type : 4,
|
||||
cipher_key_seq : 4;
|
||||
/* length + 3 bytes */
|
||||
u_int32_t classmark;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
/* optional priority level */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.31 System information Type 1 */
|
||||
struct gsm48_system_information_type_1 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t cell_channel_description[16];
|
||||
struct gsm48_rach_control rach_control;
|
||||
u_int8_t rest_octets[0]; /* NCH position on the CCCH */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.32 System information Type 2 */
|
||||
struct gsm48_system_information_type_2 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t bcch_frequency_list[16];
|
||||
u_int8_t ncc_permitted;
|
||||
struct gsm48_rach_control rach_control;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.35 System information Type 3 */
|
||||
struct gsm48_system_information_type_3 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_control_channel_descr control_channel_desc;
|
||||
struct gsm48_cell_options cell_options;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.36 System information Type 4 */
|
||||
struct gsm48_system_information_type_4 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_sel_par cell_sel_par;
|
||||
struct gsm48_rach_control rach_control;
|
||||
/* optional CBCH conditional CBCH... followed by
|
||||
mandantory SI 4 Reset Octets
|
||||
*/
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.37 System information Type 5 */
|
||||
struct gsm48_system_information_type_5 {
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
u_int8_t bcch_frequency_list[16];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.40 System information Type 6 */
|
||||
struct gsm48_system_information_type_6 {
|
||||
u_int8_t rr_protocol_discriminator :4,
|
||||
skip_indicator:4;
|
||||
u_int8_t system_information;
|
||||
u_int16_t cell_identity;
|
||||
struct gsm48_loc_area_id lai;
|
||||
struct gsm48_cell_options cell_options;
|
||||
u_int8_t ncc_permitted;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.1.43a System Information type 13 */
|
||||
struct gsm48_system_information_type_13 {
|
||||
struct gsm48_system_information_type_header header;
|
||||
u_int8_t rest_octets[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 9.2.12 IMSI Detach Indication */
|
||||
struct gsm48_imsi_detach_ind {
|
||||
struct gsm48_classmark1 classmark1;
|
||||
u_int8_t mi_len;
|
||||
u_int8_t mi[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Section 10.2 + GSM 04.07 12.2.3.1.1 */
|
||||
#define GSM48_PDISC_GROUP_CC 0x00
|
||||
#define GSM48_PDISC_BCAST_CC 0x01
|
||||
#define GSM48_PDISC_PDSS1 0x02
|
||||
#define GSM48_PDISC_CC 0x03
|
||||
#define GSM48_PDISC_PDSS2 0x04
|
||||
#define GSM48_PDISC_MM 0x05
|
||||
#define GSM48_PDISC_RR 0x06
|
||||
#define GSM48_PDISC_MM_GPRS 0x08
|
||||
#define GSM48_PDISC_SMS 0x09
|
||||
#define GSM48_PDISC_SM_GPRS 0x0a
|
||||
#define GSM48_PDISC_NC_SS 0x0b
|
||||
#define GSM48_PDISC_LOC 0x0c
|
||||
#define GSM48_PDISC_MASK 0x0f
|
||||
#define GSM48_PDISC_USSD 0x11
|
||||
|
||||
/* Section 10.4 */
|
||||
#define GSM48_MT_RR_INIT_REQ 0x3c
|
||||
#define GSM48_MT_RR_ADD_ASS 0x3b
|
||||
#define GSM48_MT_RR_IMM_ASS 0x3f
|
||||
#define GSM48_MT_RR_IMM_ASS_EXT 0x39
|
||||
#define GSM48_MT_RR_IMM_ASS_REJ 0x3a
|
||||
|
||||
#define GSM48_MT_RR_CIPH_M_CMD 0x35
|
||||
#define GSM48_MT_RR_CIPH_M_COMPL 0x32
|
||||
|
||||
#define GSM48_MT_RR_CFG_CHG_CMD 0x30
|
||||
#define GSM48_MT_RR_CFG_CHG_ACK 0x31
|
||||
#define GSM48_MT_RR_CFG_CHG_REJ 0x33
|
||||
|
||||
#define GSM48_MT_RR_ASS_CMD 0x2e
|
||||
#define GSM48_MT_RR_ASS_COMPL 0x29
|
||||
#define GSM48_MT_RR_ASS_FAIL 0x2f
|
||||
#define GSM48_MT_RR_HANDO_CMD 0x2b
|
||||
#define GSM48_MT_RR_HANDO_COMPL 0x2c
|
||||
#define GSM48_MT_RR_HANDO_FAIL 0x28
|
||||
#define GSM48_MT_RR_HANDO_INFO 0x2d
|
||||
|
||||
#define GSM48_MT_RR_CELL_CHG_ORDER 0x08
|
||||
#define GSM48_MT_RR_PDCH_ASS_CMD 0x23
|
||||
|
||||
#define GSM48_MT_RR_CHAN_REL 0x0d
|
||||
#define GSM48_MT_RR_PART_REL 0x0a
|
||||
#define GSM48_MT_RR_PART_REL_COMP 0x0f
|
||||
|
||||
#define GSM48_MT_RR_PAG_REQ_1 0x21
|
||||
#define GSM48_MT_RR_PAG_REQ_2 0x22
|
||||
#define GSM48_MT_RR_PAG_REQ_3 0x24
|
||||
#define GSM48_MT_RR_PAG_RESP 0x27
|
||||
#define GSM48_MT_RR_NOTIF_NCH 0x20
|
||||
#define GSM48_MT_RR_NOTIF_FACCH 0x25
|
||||
#define GSM48_MT_RR_NOTIF_RESP 0x26
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_8 0x18
|
||||
#define GSM48_MT_RR_SYSINFO_1 0x19
|
||||
#define GSM48_MT_RR_SYSINFO_2 0x1a
|
||||
#define GSM48_MT_RR_SYSINFO_3 0x1b
|
||||
#define GSM48_MT_RR_SYSINFO_4 0x1c
|
||||
#define GSM48_MT_RR_SYSINFO_5 0x1d
|
||||
#define GSM48_MT_RR_SYSINFO_6 0x1e
|
||||
#define GSM48_MT_RR_SYSINFO_7 0x1f
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_2bis 0x02
|
||||
#define GSM48_MT_RR_SYSINFO_2ter 0x03
|
||||
#define GSM48_MT_RR_SYSINFO_5bis 0x05
|
||||
#define GSM48_MT_RR_SYSINFO_5ter 0x06
|
||||
#define GSM48_MT_RR_SYSINFO_9 0x04
|
||||
#define GSM48_MT_RR_SYSINFO_13 0x00
|
||||
|
||||
#define GSM48_MT_RR_SYSINFO_16 0x3d
|
||||
#define GSM48_MT_RR_SYSINFO_17 0x3e
|
||||
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF 0x10
|
||||
#define GSM48_MT_RR_STATUS 0x12
|
||||
#define GSM48_MT_RR_CHAN_MODE_MODIF_ACK 0x17
|
||||
#define GSM48_MT_RR_FREQ_REDEF 0x14
|
||||
#define GSM48_MT_RR_MEAS_REP 0x15
|
||||
#define GSM48_MT_RR_CLSM_CHG 0x16
|
||||
#define GSM48_MT_RR_CLSM_ENQ 0x13
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP 0x36
|
||||
#define GSM48_MT_RR_EXT_MEAS_REP_ORD 0x37
|
||||
#define GSM48_MT_RR_GPRS_SUSP_REQ 0x34
|
||||
|
||||
#define GSM48_MT_RR_VGCS_UPL_GRANT 0x08
|
||||
#define GSM48_MT_RR_UPLINK_RELEASE 0x0e
|
||||
#define GSM48_MT_RR_UPLINK_FREE 0x0c
|
||||
#define GSM48_MT_RR_UPLINK_BUSY 0x2a
|
||||
#define GSM48_MT_RR_TALKER_IND 0x11
|
||||
|
||||
#define GSM48_MT_RR_APP_INFO 0x38
|
||||
|
||||
/* Table 10.2/3GPP TS 04.08 */
|
||||
#define GSM48_MT_MM_IMSI_DETACH_IND 0x01
|
||||
#define GSM48_MT_MM_LOC_UPD_ACCEPT 0x02
|
||||
#define GSM48_MT_MM_LOC_UPD_REJECT 0x04
|
||||
#define GSM48_MT_MM_LOC_UPD_REQUEST 0x08
|
||||
|
||||
#define GSM48_MT_MM_AUTH_REJ 0x11
|
||||
#define GSM48_MT_MM_AUTH_REQ 0x12
|
||||
#define GSM48_MT_MM_AUTH_RESP 0x14
|
||||
#define GSM48_MT_MM_ID_REQ 0x18
|
||||
#define GSM48_MT_MM_ID_RESP 0x19
|
||||
#define GSM48_MT_MM_TMSI_REALL_CMD 0x1a
|
||||
#define GSM48_MT_MM_TMSI_REALL_COMPL 0x1b
|
||||
|
||||
#define GSM48_MT_MM_CM_SERV_ACC 0x21
|
||||
#define GSM48_MT_MM_CM_SERV_REJ 0x22
|
||||
#define GSM48_MT_MM_CM_SERV_ABORT 0x23
|
||||
#define GSM48_MT_MM_CM_SERV_REQ 0x24
|
||||
#define GSM48_MT_MM_CM_SERV_PROMPT 0x25
|
||||
#define GSM48_MT_MM_CM_REEST_REQ 0x28
|
||||
#define GSM48_MT_MM_ABORT 0x29
|
||||
|
||||
#define GSM48_MT_MM_NULL 0x30
|
||||
#define GSM48_MT_MM_STATUS 0x31
|
||||
#define GSM48_MT_MM_INFO 0x32
|
||||
|
||||
/* Table 10.3/3GPP TS 04.08 */
|
||||
#define GSM48_MT_CC_ALERTING 0x01
|
||||
#define GSM48_MT_CC_CALL_CONF 0x08
|
||||
#define GSM48_MT_CC_CALL_PROC 0x02
|
||||
#define GSM48_MT_CC_CONNECT 0x07
|
||||
#define GSM48_MT_CC_CONNECT_ACK 0x0f
|
||||
#define GSM48_MT_CC_EMERG_SETUP 0x0e
|
||||
#define GSM48_MT_CC_PROGRESS 0x03
|
||||
#define GSM48_MT_CC_ESTAB 0x04
|
||||
#define GSM48_MT_CC_ESTAB_CONF 0x06
|
||||
#define GSM48_MT_CC_RECALL 0x0b
|
||||
#define GSM48_MT_CC_START_CC 0x09
|
||||
#define GSM48_MT_CC_SETUP 0x05
|
||||
|
||||
#define GSM48_MT_CC_MODIFY 0x17
|
||||
#define GSM48_MT_CC_MODIFY_COMPL 0x1f
|
||||
#define GSM48_MT_CC_MODIFY_REJECT 0x13
|
||||
#define GSM48_MT_CC_USER_INFO 0x10
|
||||
#define GSM48_MT_CC_HOLD 0x18
|
||||
#define GSM48_MT_CC_HOLD_ACK 0x19
|
||||
#define GSM48_MT_CC_HOLD_REJ 0x1a
|
||||
#define GSM48_MT_CC_RETR 0x1c
|
||||
#define GSM48_MT_CC_RETR_ACK 0x1d
|
||||
#define GSM48_MT_CC_RETR_REJ 0x1e
|
||||
|
||||
#define GSM48_MT_CC_DISCONNECT 0x25
|
||||
#define GSM48_MT_CC_RELEASE 0x2d
|
||||
#define GSM48_MT_CC_RELEASE_COMPL 0x2a
|
||||
|
||||
#define GSM48_MT_CC_CONG_CTRL 0x39
|
||||
#define GSM48_MT_CC_NOTIFY 0x3e
|
||||
#define GSM48_MT_CC_STATUS 0x3d
|
||||
#define GSM48_MT_CC_STATUS_ENQ 0x34
|
||||
#define GSM48_MT_CC_START_DTMF 0x35
|
||||
#define GSM48_MT_CC_STOP_DTMF 0x31
|
||||
#define GSM48_MT_CC_STOP_DTMF_ACK 0x32
|
||||
#define GSM48_MT_CC_START_DTMF_ACK 0x36
|
||||
#define GSM48_MT_CC_START_DTMF_REJ 0x37
|
||||
#define GSM48_MT_CC_FACILITY 0x3a
|
||||
|
||||
/* FIXME: Table 10.4 / 10.4a (GPRS) */
|
||||
|
||||
/* Section 10.5.2.26, Table 10.5.64 */
|
||||
#define GSM48_PM_MASK 0x03
|
||||
#define GSM48_PM_NORMAL 0x00
|
||||
#define GSM48_PM_EXTENDED 0x01
|
||||
#define GSM48_PM_REORG 0x02
|
||||
#define GSM48_PM_SAME 0x03
|
||||
|
||||
/* Chapter 10.5.3.5 / Table 10.5.93 */
|
||||
#define GSM48_LUPD_NORMAL 0x0
|
||||
#define GSM48_LUPD_PERIODIC 0x1
|
||||
#define GSM48_LUPD_IMSI_ATT 0x2
|
||||
#define GSM48_LUPD_RESERVED 0x3
|
||||
|
||||
/* Table 10.5.4 */
|
||||
#define GSM_MI_TYPE_MASK 0x07
|
||||
#define GSM_MI_TYPE_NONE 0x00
|
||||
#define GSM_MI_TYPE_IMSI 0x01
|
||||
#define GSM_MI_TYPE_IMEI 0x02
|
||||
#define GSM_MI_TYPE_IMEISV 0x03
|
||||
#define GSM_MI_TYPE_TMSI 0x04
|
||||
#define GSM_MI_ODD 0x08
|
||||
|
||||
#define GSM48_IE_MUL_RATE_CFG 0x03 /* 10.5.2.21aa */
|
||||
#define GSM48_IE_MOBILE_ID 0x17
|
||||
#define GSM48_IE_NAME_LONG 0x43 /* 10.5.3.5a */
|
||||
#define GSM48_IE_NAME_SHORT 0x45 /* 10.5.3.5a */
|
||||
#define GSM48_IE_UTC 0x46 /* 10.5.3.8 */
|
||||
#define GSM48_IE_NET_TIME_TZ 0x47 /* 10.5.3.9 */
|
||||
#define GSM48_IE_LSA_IDENT 0x48 /* 10.5.3.11 */
|
||||
|
||||
#define GSM48_IE_BEARER_CAP 0x04 /* 10.5.4.5 */
|
||||
#define GSM48_IE_CAUSE 0x08 /* 10.5.4.11 */
|
||||
#define GSM48_IE_CC_CAP 0x15 /* 10.5.4.5a */
|
||||
#define GSM48_IE_ALERT 0x19 /* 10.5.4.26 */
|
||||
#define GSM48_IE_FACILITY 0x1c /* 10.5.4.15 */
|
||||
#define GSM48_IE_PROGR_IND 0x1e /* 10.5.4.21 */
|
||||
#define GSM48_IE_AUX_STATUS 0x24 /* 10.5.4.4 */
|
||||
#define GSM48_IE_NOTIFY 0x27 /* 10.5.4.20 */
|
||||
#define GSM48_IE_KPD_FACILITY 0x2c /* 10.5.4.17 */
|
||||
#define GSM48_IE_SIGNAL 0x34 /* 10.5.4.23 */
|
||||
#define GSM48_IE_CONN_BCD 0x4c /* 10.5.4.13 */
|
||||
#define GSM48_IE_CONN_SUB 0x4d /* 10.5.4.14 */
|
||||
#define GSM48_IE_CALLING_BCD 0x5c /* 10.5.4.9 */
|
||||
#define GSM48_IE_CALLING_SUB 0x5d /* 10.5.4.10 */
|
||||
#define GSM48_IE_CALLED_BCD 0x5e /* 10.5.4.7 */
|
||||
#define GSM48_IE_CALLED_SUB 0x6d /* 10.5.4.8 */
|
||||
#define GSM48_IE_REDIR_BCD 0x74 /* 10.5.4.21a */
|
||||
#define GSM48_IE_REDIR_SUB 0x75 /* 10.5.4.21b */
|
||||
#define GSM48_IE_LOWL_COMPAT 0x7c /* 10.5.4.18 */
|
||||
#define GSM48_IE_HIGHL_COMPAT 0x7d /* 10.5.4.16 */
|
||||
#define GSM48_IE_USER_USER 0x7e /* 10.5.4.25 */
|
||||
#define GSM48_IE_SS_VERS 0x7f /* 10.5.4.24 */
|
||||
#define GSM48_IE_MORE_DATA 0xa0 /* 10.5.4.19 */
|
||||
#define GSM48_IE_CLIR_SUPP 0xa1 /* 10.5.4.11a */
|
||||
#define GSM48_IE_CLIR_INVOC 0xa2 /* 10.5.4.11b */
|
||||
#define GSM48_IE_REV_C_SETUP 0xa3 /* 10.5.4.22a */
|
||||
#define GSM48_IE_REPEAT_CIR 0xd1 /* 10.5.4.22 */
|
||||
#define GSM48_IE_REPEAT_SEQ 0xd3 /* 10.5.4.22 */
|
||||
|
||||
/* Section 10.5.4.11 / Table 10.5.122 */
|
||||
#define GSM48_CAUSE_CS_GSM 0x60
|
||||
|
||||
/* Section 9.1.2 / Table 9.3 */
|
||||
#define GSM48_IE_FRQLIST_AFTER 0x05
|
||||
#define GSM48_IE_CELL_CH_DESC 0x62
|
||||
#define GSM48_IE_MSLOT_DESC 0x10
|
||||
#define GSM48_IE_CHANMODE_1 0x63
|
||||
#define GSM48_IE_CHANMODE_2 0x11
|
||||
#define GSM48_IE_CHANMODE_3 0x13
|
||||
#define GSM48_IE_CHANMODE_4 0x14
|
||||
#define GSM48_IE_CHANMODE_5 0x15
|
||||
#define GSM48_IE_CHANMODE_6 0x16
|
||||
#define GSM48_IE_CHANMODE_7 0x17
|
||||
#define GSM48_IE_CHANMODE_8 0x18
|
||||
#define GSM48_IE_CHANDESC_2 0x64
|
||||
/* FIXME */
|
||||
|
||||
/* Section 10.5.4.23 / Table 10.5.130 */
|
||||
enum gsm48_signal_val {
|
||||
GSM48_SIGNAL_DIALTONE = 0x00,
|
||||
GSM48_SIGNAL_RINGBACK = 0x01,
|
||||
GSM48_SIGNAL_INTERCEPT = 0x02,
|
||||
GSM48_SIGNAL_NET_CONG = 0x03,
|
||||
GSM48_SIGNAL_BUSY = 0x04,
|
||||
GSM48_SIGNAL_CONFIRM = 0x05,
|
||||
GSM48_SIGNAL_ANSWER = 0x06,
|
||||
GSM48_SIGNAL_CALL_WAIT = 0x07,
|
||||
GSM48_SIGNAL_OFF_HOOK = 0x08,
|
||||
GSM48_SIGNAL_OFF = 0x3f,
|
||||
GSM48_SIGNAL_ALERT_OFF = 0x4f,
|
||||
};
|
||||
|
||||
enum gsm48_cause_loc {
|
||||
GSM48_CAUSE_LOC_USER = 0x00,
|
||||
GSM48_CAUSE_LOC_PRN_S_LU = 0x01,
|
||||
GSM48_CAUSE_LOC_PUN_S_LU = 0x02,
|
||||
GSM48_CAUSE_LOC_TRANS_NET = 0x03,
|
||||
GSM48_CAUSE_LOC_PUN_S_RU = 0x04,
|
||||
GSM48_CAUSE_LOC_PRN_S_RU = 0x05,
|
||||
/* not defined */
|
||||
GSM48_CAUSE_LOC_INN_NET = 0x07,
|
||||
GSM48_CAUSE_LOC_NET_BEYOND = 0x0a,
|
||||
};
|
||||
|
||||
/* Section 10.5.2.31 RR Cause / Table 10.5.70 */
|
||||
enum gsm48_rr_cause {
|
||||
GSM48_RR_CAUSE_NORMAL = 0x00,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNSPEC = 0x01,
|
||||
GSM48_RR_CAUSE_ABNORMAL_UNACCT = 0x02,
|
||||
GSM48_RR_CAUSE_ABNORMAL_TIMER = 0x03,
|
||||
GSM48_RR_CAUSE_ABNORMAL_NOACT = 0x04,
|
||||
GSM48_RR_CAUSE_PREMPTIVE_REL = 0x05,
|
||||
GSM48_RR_CAUSE_HNDOVER_IMP = 0x06,
|
||||
GSM48_RR_CAUSE_CHAN_MODE_UNACCT = 0x07,
|
||||
GSM48_RR_CAUSE_FREQ_NOT_IMPL = 0x08,
|
||||
GSM48_RR_CAUSE_CALL_CLEARED = 0x41,
|
||||
GSM48_RR_CAUSE_SEMANT_INCORR = 0x5f,
|
||||
GSM48_RR_CAUSE_INVALID_MAND_INF = 0x60,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N = 0x61,
|
||||
GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT= 0x62,
|
||||
GSM48_RR_CAUSE_COND_IE_ERROR = 0x64,
|
||||
GSM48_RR_CAUSE_NO_CELL_ALLOC_A = 0x65,
|
||||
GSM48_RR_CAUSE_PROT_ERROR_UNSPC = 0x6f,
|
||||
};
|
||||
|
||||
/* Section 10.5.4.11 CC Cause / Table 10.5.123 */
|
||||
enum gsm48_cc_cause {
|
||||
GSM48_CC_CAUSE_UNASSIGNED_NR = 1,
|
||||
GSM48_CC_CAUSE_NO_ROUTE = 3,
|
||||
GSM48_CC_CAUSE_CHAN_UNACCEPT = 6,
|
||||
GSM48_CC_CAUSE_OP_DET_BARRING = 8,
|
||||
GSM48_CC_CAUSE_NORM_CALL_CLEAR = 16,
|
||||
GSM48_CC_CAUSE_USER_BUSY = 17,
|
||||
GSM48_CC_CAUSE_USER_NOTRESPOND = 18,
|
||||
GSM48_CC_CAUSE_USER_ALERTING_NA = 19,
|
||||
GSM48_CC_CAUSE_CALL_REJECTED = 21,
|
||||
GSM48_CC_CAUSE_NUMBER_CHANGED = 22,
|
||||
GSM48_CC_CAUSE_PRE_EMPTION = 25,
|
||||
GSM48_CC_CAUSE_NONSE_USER_CLR = 26,
|
||||
GSM48_CC_CAUSE_DEST_OOO = 27,
|
||||
GSM48_CC_CAUSE_INV_NR_FORMAT = 28,
|
||||
GSM48_CC_CAUSE_FACILITY_REJ = 29,
|
||||
GSM48_CC_CAUSE_RESP_STATUS_INQ = 30,
|
||||
GSM48_CC_CAUSE_NORMAL_UNSPEC = 31,
|
||||
GSM48_CC_CAUSE_NO_CIRCUIT_CHAN = 34,
|
||||
GSM48_CC_CAUSE_NETWORK_OOO = 38,
|
||||
GSM48_CC_CAUSE_TEMP_FAILURE = 41,
|
||||
GSM48_CC_CAUSE_SWITCH_CONG = 42,
|
||||
GSM48_CC_CAUSE_ACC_INF_DISCARD = 43,
|
||||
GSM48_CC_CAUSE_REQ_CHAN_UNAVAIL = 44,
|
||||
GSM48_CC_CAUSE_RESOURCE_UNAVAIL = 47,
|
||||
GSM48_CC_CAUSE_QOS_UNAVAIL = 49,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOT_SUBSC= 50,
|
||||
GSM48_CC_CAUSE_INC_BARRED_CUG = 55,
|
||||
GSM48_CC_CAUSE_BEARER_CAP_UNAUTH= 57,
|
||||
GSM48_CC_CAUSE_BEARER_CA_UNAVAIL= 58,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNAVAIL = 63,
|
||||
GSM48_CC_CAUSE_BEARERSERV_UNIMPL= 65,
|
||||
GSM48_CC_CAUSE_ACM_GE_ACM_MAX = 68,
|
||||
GSM48_CC_CAUSE_REQ_FAC_NOTIMPL = 69,
|
||||
GSM48_CC_CAUSE_RESTR_BCAP_AVAIL = 70,
|
||||
GSM48_CC_CAUSE_SERV_OPT_UNIMPL = 79,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_ID = 81,
|
||||
GSM48_CC_CAUSE_USER_NOT_IN_CUG = 87,
|
||||
GSM48_CC_CAUSE_INCOMPAT_DEST = 88,
|
||||
GSM48_CC_CAUSE_INVAL_TRANS_NET = 91,
|
||||
GSM48_CC_CAUSE_SEMANTIC_INCORR = 95,
|
||||
GSM48_CC_CAUSE_INVAL_MAND_INF = 96,
|
||||
GSM48_CC_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM48_CC_CAUSE_MSGTYPE_INCOMPAT = 98,
|
||||
GSM48_CC_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM48_CC_CAUSE_COND_IE_ERR = 100,
|
||||
GSM48_CC_CAUSE_MSG_INCOMP_STATE = 101,
|
||||
GSM48_CC_CAUSE_RECOVERY_TIMER = 102,
|
||||
GSM48_CC_CAUSE_PROTO_ERR = 111,
|
||||
GSM48_CC_CAUSE_INTERWORKING = 127,
|
||||
};
|
||||
|
||||
/* Annex G, GSM specific cause values for mobility management */
|
||||
enum gsm48_reject_value {
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_HLR = 2,
|
||||
GSM48_REJECT_ILLEGAL_MS = 3,
|
||||
GSM48_REJECT_IMSI_UNKNOWN_IN_VLR = 4,
|
||||
GSM48_REJECT_IMEI_NOT_ACCEPTED = 5,
|
||||
GSM48_REJECT_ILLEGAL_ME = 6,
|
||||
GSM48_REJECT_PLMN_NOT_ALLOWED = 11,
|
||||
GSM48_REJECT_LOC_NOT_ALLOWED = 12,
|
||||
GSM48_REJECT_ROAMING_NOT_ALLOWED = 13,
|
||||
GSM48_REJECT_NETWORK_FAILURE = 17,
|
||||
GSM48_REJECT_CONGESTION = 22,
|
||||
GSM48_REJECT_SRV_OPT_NOT_SUPPORTED = 32,
|
||||
GSM48_REJECT_RQD_SRV_OPT_NOT_SUPPORTED = 33,
|
||||
GSM48_REJECT_SRV_OPT_TMP_OUT_OF_ORDER = 34,
|
||||
GSM48_REJECT_CALL_CAN_NOT_BE_IDENTIFIED = 38,
|
||||
GSM48_REJECT_INCORRECT_MESSAGE = 95,
|
||||
GSM48_REJECT_INVALID_MANDANTORY_INF = 96,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_IMPLEMENTED = 97,
|
||||
GSM48_REJECT_MSG_TYPE_NOT_COMPATIBLE = 98,
|
||||
GSM48_REJECT_INF_ELEME_NOT_IMPLEMENTED = 99,
|
||||
GSM48_REJECT_CONDTIONAL_IE_ERROR = 100,
|
||||
GSM48_REJECT_MSG_NOT_COMPATIBLE = 101,
|
||||
GSM48_REJECT_PROTOCOL_ERROR = 111,
|
||||
|
||||
/* according to G.6 Additional cause codes for GMM */
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED = 7,
|
||||
GSM48_REJECT_SERVICES_NOT_ALLOWED = 8,
|
||||
GSM48_REJECT_MS_IDENTITY_NOT_DERVIVABLE = 9,
|
||||
GSM48_REJECT_IMPLICITLY_DETACHED = 10,
|
||||
GSM48_REJECT_GPRS_NOT_ALLOWED_IN_PLMN = 14,
|
||||
GSM48_REJECT_MSC_TMP_NOT_REACHABLE = 16,
|
||||
};
|
||||
|
||||
enum chreq_type {
|
||||
CHREQ_T_EMERG_CALL,
|
||||
CHREQ_T_CALL_REEST_TCH_F,
|
||||
CHREQ_T_CALL_REEST_TCH_H,
|
||||
CHREQ_T_CALL_REEST_TCH_H_DBL,
|
||||
CHREQ_T_SDCCH,
|
||||
CHREQ_T_TCH_F,
|
||||
CHREQ_T_VOICE_CALL_TCH_H,
|
||||
CHREQ_T_DATA_CALL_TCH_H,
|
||||
CHREQ_T_LOCATION_UPD,
|
||||
CHREQ_T_PAG_R_ANY_NECI0,
|
||||
CHREQ_T_PAG_R_ANY_NECI1,
|
||||
CHREQ_T_PAG_R_TCH_F,
|
||||
CHREQ_T_PAG_R_TCH_FH,
|
||||
CHREQ_T_LMU,
|
||||
CHREQ_T_RESERVED_SDCCH,
|
||||
CHREQ_T_RESERVED_IGNORE,
|
||||
};
|
||||
|
||||
/* Chapter 11.3 */
|
||||
#define GSM48_T301 180, 0
|
||||
#define GSM48_T303 30, 0
|
||||
#define GSM48_T305 30, 0
|
||||
#define GSM48_T306 30, 0
|
||||
#define GSM48_T308 10, 0
|
||||
#define GSM48_T310 180, 0
|
||||
#define GSM48_T313 30, 0
|
||||
#define GSM48_T323 30, 0
|
||||
#define GSM48_T331 30, 0
|
||||
#define GSM48_T333 30, 0
|
||||
#define GSM48_T334 25, 0 /* min 15 */
|
||||
#define GSM48_T338 30, 0
|
||||
|
||||
/* Chapter 5.1.2.2 */
|
||||
#define GSM_CSTATE_NULL 0
|
||||
#define GSM_CSTATE_INITIATED 1
|
||||
#define GSM_CSTATE_MO_CALL_PROC 3
|
||||
#define GSM_CSTATE_CALL_DELIVERED 4
|
||||
#define GSM_CSTATE_CALL_PRESENT 6
|
||||
#define GSM_CSTATE_CALL_RECEIVED 7
|
||||
#define GSM_CSTATE_CONNECT_REQUEST 8
|
||||
#define GSM_CSTATE_MO_TERM_CALL_CONF 9
|
||||
#define GSM_CSTATE_ACTIVE 10
|
||||
#define GSM_CSTATE_DISCONNECT_REQ 12
|
||||
#define GSM_CSTATE_DISCONNECT_IND 12
|
||||
#define GSM_CSTATE_RELEASE_REQ 19
|
||||
#define GSM_CSTATE_MO_ORIG_MODIFY 26
|
||||
#define GSM_CSTATE_MO_TERM_MODIFY 27
|
||||
#define GSM_CSTATE_CONNECT_IND 28
|
||||
|
||||
#define SBIT(a) (1 << a)
|
||||
#define ALL_STATES 0xffffffff
|
||||
|
||||
/* Table 10.5.3/3GPP TS 04.08: Location Area Identification information element */
|
||||
#define GSM_LAC_RESERVED_DETACHED 0x0
|
||||
#define GSM_LAC_RESERVED_ALL_BTS 0xfffe
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Information Transfer Capability */
|
||||
enum gsm48_bcap_itcap {
|
||||
GSM48_BCAP_ITCAP_SPEECH = 0,
|
||||
GSM48_BCAP_ITCAP_UNR_DIG_INF = 1,
|
||||
GSM48_BCAP_ITCAP_3k1_AUDIO = 2,
|
||||
GSM48_BCAP_ITCAP_FAX_G3 = 3,
|
||||
GSM48_BCAP_ITCAP_OTHER = 5,
|
||||
GSM48_BCAP_ITCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Transfer Mode */
|
||||
enum gsm48_bcap_tmod {
|
||||
GSM48_BCAP_TMOD_CIRCUIT = 0,
|
||||
GSM48_BCAP_TMOD_PACKET = 1,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Coding Standard */
|
||||
enum gsm48_bcap_coding {
|
||||
GSM48_BCAP_CODING_GSM_STD = 0,
|
||||
};
|
||||
|
||||
/* GSM 04.08 Bearer Capability: Radio Channel Requirements */
|
||||
enum gsm48_bcap_rrq {
|
||||
GSM48_BCAP_RRQ_FR_ONLY = 1,
|
||||
GSM48_BCAP_RRQ_DUAL_HR = 2,
|
||||
GSM48_BCAP_RRQ_DUAL_FR = 3,
|
||||
};
|
||||
|
||||
|
||||
#define GSM48_TMSI_LEN 5
|
||||
#define GSM48_MID_TMSI_LEN (GSM48_TMSI_LEN + 2)
|
||||
#define GSM48_MI_SIZE 32
|
||||
|
||||
#include <osmocore/protocol/gsm_04_08.h>
|
||||
#include <osmocore/gsm48.h>
|
||||
|
||||
struct msgb;
|
||||
struct gsm_bts;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_network;
|
||||
struct gsm_trans;
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
#define GSM48_ALLOC_SIZE 1024
|
||||
#define GSM48_ALLOC_HEADROOM 128
|
||||
|
||||
static inline struct msgb *gsm48_msgb_alloc(void)
|
||||
{
|
||||
return msgb_alloc_headroom(GSM48_ALLOC_SIZE, GSM48_ALLOC_HEADROOM,
|
||||
"GSM 04.08");
|
||||
}
|
||||
|
||||
/* config options controlling the behaviour of the lower leves */
|
||||
void gsm0408_allow_everyone(int allow);
|
||||
void gsm0408_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
|
||||
int gsm0408_dispatch(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id);
|
||||
void gsm0408_generate_lai(struct gsm48_loc_area_id *lai48, u_int16_t mcc,
|
||||
u_int16_t mnc, u_int16_t lac);
|
||||
int gsm0408_new_conn(struct gsm_subscriber_connection *conn);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
enum gsm_chreq_reason_t get_reason_by_chreq(struct gsm_bts *bts, u_int8_t ra, int neci);
|
||||
|
||||
int gsm48_tx_mm_info(struct gsm_lchan *lchan);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_lchan *lchan, u_int8_t *rand);
|
||||
int gsm48_tx_mm_auth_rej(struct gsm_lchan *lchan);
|
||||
struct msgb *gsm48_msgb_alloc(void);
|
||||
int gsm48_sendmsg(struct msgb *msg, struct gsm_trans *trans);
|
||||
int gsm48_generate_mid_from_tmsi(u_int8_t *buf, u_int32_t tmsi);
|
||||
int gsm48_generate_mid_from_imsi(u_int8_t *buf, const char* imsi);
|
||||
int gsm48_mi_to_string(char *string, const int str_len, const u_int8_t *mi, const int mi_len);
|
||||
|
||||
int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_tx_mm_auth_req(struct gsm_subscriber_connection *conn, u_int8_t *rand, int key_seq);
|
||||
int gsm48_tx_mm_auth_rej(struct gsm_subscriber_connection *conn);
|
||||
int gsm48_send_rr_release(struct gsm_lchan *lchan);
|
||||
int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv);
|
||||
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, u_int8_t apdu_id,
|
||||
int gsm48_send_rr_app_info(struct gsm_subscriber_connection *conn, u_int8_t apdu_id,
|
||||
u_int8_t apdu_len, const u_int8_t *apdu);
|
||||
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, u_int8_t power_class);
|
||||
int gsm48_send_ho_cmd(struct gsm_lchan *old_lchan, struct gsm_lchan *new_lchan,
|
||||
@@ -782,15 +53,18 @@ int encode_bcd_number(u_int8_t *bcd_lv, u_int8_t max_len,
|
||||
int decode_bcd_number(char *output, int output_len, const u_int8_t *bcd_lv,
|
||||
int h_len);
|
||||
|
||||
extern const char *gsm0408_cc_msg_names[];
|
||||
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan, u_int8_t *classmark2_lv);
|
||||
int gsm48_paging_extract_mi(struct msgb *msg, char *mi_string, u_int8_t *mi_type);
|
||||
int gsm48_handle_paging_resp(struct msgb *msg, struct gsm_subscriber *subscr);
|
||||
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, u_int8_t *mi_type);
|
||||
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, u_int8_t lchan_mode);
|
||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
|
||||
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
|
||||
|
||||
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
|
||||
struct msgb *gsm48_create_loc_upd_rej(uint8_t cause);
|
||||
void gsm48_lchan2chan_desc(struct gsm48_chan_desc *cd,
|
||||
const struct gsm_lchan *lchan);
|
||||
|
||||
#endif
|
||||
|
||||
383
openbsc/include/openbsc/gsm_04_08_gprs.h
Normal file
383
openbsc/include/openbsc/gsm_04_08_gprs.h
Normal file
@@ -0,0 +1,383 @@
|
||||
#ifndef _GSM48_GPRS_H
|
||||
#define _GSM48_GPRS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <osmocore/protocol/gsm_04_08.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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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
|
||||
|
||||
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_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 */
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
/* 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 = 3 << 5,
|
||||
};
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
||||
/* 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,
|
||||
};
|
||||
|
||||
/* 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;
|
||||
};
|
||||
|
||||
|
||||
int gprs_tlli_type(uint32_t tlli);
|
||||
|
||||
#endif /* _GSM48_GPRS_H */
|
||||
@@ -1,187 +1,9 @@
|
||||
#ifndef _GSM_04_11_H
|
||||
#define _GSM_04_11_H
|
||||
|
||||
/* GSM TS 04.11 definitions */
|
||||
#include <osmocore/protocol/gsm_04_11.h>
|
||||
|
||||
/* Chapter 5.2.3: SMC-CS states at the network side */
|
||||
enum gsm411_cp_state {
|
||||
GSM411_CPS_IDLE = 0,
|
||||
GSM411_CPS_MM_CONN_PENDING = 1, /* only MT ! */
|
||||
GSM411_CPS_WAIT_CP_ACK = 2,
|
||||
GSM411_CPS_MM_ESTABLISHED = 3,
|
||||
};
|
||||
|
||||
/* Chapter 6.2.2: SMR states at the network side */
|
||||
enum gsm411_rp_state {
|
||||
GSM411_RPS_IDLE = 0,
|
||||
GSM411_RPS_WAIT_FOR_RP_ACK = 1,
|
||||
GSM411_RPS_WAIT_TO_TX_RP_ACK = 3,
|
||||
};
|
||||
|
||||
/* Chapter 8.1.2 (refers to GSM 04.07 Chapter 11.2.3.1.1 */
|
||||
#define GSM411_PDISC_SMS 0x09
|
||||
|
||||
/* Chapter 8.1.3 */
|
||||
#define GSM411_MT_CP_DATA 0x01
|
||||
#define GSM411_MT_CP_ACK 0x04
|
||||
#define GSM411_MT_CP_ERROR 0x10
|
||||
|
||||
enum gsm411_cp_ie {
|
||||
GSM411_CP_IE_USER_DATA = 0x01, /* 8.1.4.1 */
|
||||
GSM411_CP_IE_CAUSE = 0x02, /* 8.1.4.2. */
|
||||
};
|
||||
|
||||
/* Section 8.1.4.2 / Table 8.2 */
|
||||
enum gsm411_cp_cause {
|
||||
GSM411_CP_CAUSE_NET_FAIL = 17,
|
||||
GSM411_CP_CAUSE_CONGESTION = 22,
|
||||
GSM411_CP_CAUSE_INV_TRANS_ID = 81,
|
||||
GSM411_CP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_CP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_CP_CAUSE_MSGTYPE_NOTEXIST= 97,
|
||||
GSM411_CP_CAUSE_MSG_INCOMP_STATE= 98,
|
||||
GSM411_CP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_CP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 8.2.2 */
|
||||
#define GSM411_MT_RP_DATA_MO 0x00
|
||||
#define GSM411_MT_RP_DATA_MT 0x01
|
||||
#define GSM411_MT_RP_ACK_MO 0x02
|
||||
#define GSM411_MT_RP_ACK_MT 0x03
|
||||
#define GSM411_MT_RP_ERROR_MO 0x04
|
||||
#define GSM411_MT_RP_ERROR_MT 0x05
|
||||
#define GSM411_MT_RP_SMMA_MO 0x06
|
||||
|
||||
enum gsm411_rp_ie {
|
||||
GSM411_IE_RP_USER_DATA = 0x41, /* 8.2.5.3 */
|
||||
GSM411_IE_RP_CAUSE = 0x42, /* 8.2.5.4 */
|
||||
};
|
||||
|
||||
/* Chapter 8.2.5.4 Table 8.4 */
|
||||
enum gsm411_rp_cause {
|
||||
/* valid only for MO */
|
||||
GSM411_RP_CAUSE_MO_NUM_UNASSIGNED = 1,
|
||||
GSM411_RP_CAUSE_MO_OP_DET_BARR = 8,
|
||||
GSM411_RP_CAUSE_MO_CALL_BARRED = 10,
|
||||
GSM411_RP_CAUSE_MO_SMS_REJECTED = 21,
|
||||
GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER = 27,
|
||||
GSM411_RP_CAUSE_MO_UNIDENTIFIED_SUBSCR = 28,
|
||||
GSM411_RP_CAUSE_MO_FACILITY_REJ = 29,
|
||||
GSM411_RP_CAUSE_MO_UNKNOWN_SUBSCR = 30,
|
||||
GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER = 38,
|
||||
GSM411_RP_CAUSE_MO_TEMP_FAIL = 41,
|
||||
GSM411_RP_CAUSE_MO_CONGESTION = 42,
|
||||
GSM411_RP_CAUSE_MO_RES_UNAVAIL = 47,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTSUBSCR = 50,
|
||||
GSM411_RP_CAUSE_MO_REQ_FAC_NOTIMPL = 69,
|
||||
GSM411_RP_CAUSE_MO_INTERWORKING = 127,
|
||||
/* valid only for MT */
|
||||
GSM411_RP_CAUSE_MT_MEM_EXCEEDED = 22,
|
||||
/* valid for both directions */
|
||||
GSM411_RP_CAUSE_INV_TRANS_REF = 81,
|
||||
GSM411_RP_CAUSE_SEMANT_INC_MSG = 95,
|
||||
GSM411_RP_CAUSE_INV_MAND_INF = 96,
|
||||
GSM411_RP_CAUSE_MSGTYPE_NOTEXIST = 97,
|
||||
GSM411_RP_CAUSE_MSG_INCOMP_STATE = 98,
|
||||
GSM411_RP_CAUSE_IE_NOTEXIST = 99,
|
||||
GSM411_RP_CAUSE_PROTOCOL_ERR = 111,
|
||||
};
|
||||
|
||||
/* Chapter 10: Timers */
|
||||
#define GSM411_TMR_TR1M 40, 0 /* 35 < x < 45 seconds */
|
||||
#define GSM411_TMR_TRAM 30, 0 /* 25 < x < 35 seconds */
|
||||
#define GSM411_TMR_TR2M 15, 0 /* 12 < x < 20 seconds */
|
||||
|
||||
#define GSM411_TMR_TC1A 30, 0
|
||||
|
||||
/* Chapter 8.2.1 */
|
||||
struct gsm411_rp_hdr {
|
||||
u_int8_t len;
|
||||
u_int8_t msg_type;
|
||||
u_int8_t msg_ref;
|
||||
u_int8_t data[0];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* our own enum, not related to on-air protocol */
|
||||
enum sms_alphabet {
|
||||
DCS_NONE,
|
||||
DCS_7BIT_DEFAULT,
|
||||
DCS_UCS2,
|
||||
DCS_8BIT_DATA,
|
||||
};
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.1: TP-Message-Type-Indicator */
|
||||
#define GSM340_SMS_DELIVER_SC2MS 0x00
|
||||
#define GSM340_SMS_DELIVER_REP_MS2SC 0x00
|
||||
#define GSM340_SMS_STATUS_REP_SC2MS 0x02
|
||||
#define GSM340_SMS_COMMAND_MS2SC 0x02
|
||||
#define GSM340_SMS_SUBMIT_MS2SC 0x01
|
||||
#define GSM340_SMS_SUBMIT_REP_SC2MS 0x01
|
||||
#define GSM340_SMS_RESSERVED 0x03
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.2: TP-More-Messages-to-Send */
|
||||
#define GSM340_TP_MMS_MORE 0
|
||||
#define GSM340_TP_MMS_NO_MORE 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.3: TP-Validity-Period-Format */
|
||||
#define GSM340_TP_VPF_NONE 0
|
||||
#define GSM340_TP_VPF_RELATIVE 2
|
||||
#define GSM340_TP_VPF_ENHANCED 1
|
||||
#define GSM340_TP_VPF_ABSOLUTE 3
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.4: TP-Status-Report-Indication */
|
||||
#define GSM340_TP_SRI_NONE 0
|
||||
#define GSM340_TP_SRI_PRESENT 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.5: TP-Status-Report-Request */
|
||||
#define GSM340_TP_SRR_NONE 0
|
||||
#define GSM340_TP_SRR_REQUESTED 1
|
||||
|
||||
/* GSM 03.40 / Chapter 9.2.3.9: TP-Protocol-Identifier */
|
||||
/* telematic interworking (001 or 111 in bits 7-5) */
|
||||
#define GSM340_TP_PID_IMPLICIT 0x00
|
||||
#define GSM340_TP_PID_TELEX 0x01
|
||||
#define GSM340_TP_PID_FAX_G3 0x02
|
||||
#define GSM340_TP_PID_FAX_G4 0x03
|
||||
#define GSM340_TP_PID_VOICE 0x04
|
||||
#define GSM430_TP_PID_ERMES 0x05
|
||||
#define GSM430_TP_PID_NATIONAL_PAGING 0x06
|
||||
#define GSM430_TP_PID_VIDEOTEX 0x07
|
||||
#define GSM430_TP_PID_TELETEX_UNSPEC 0x08
|
||||
#define GSM430_TP_PID_TELETEX_PSPDN 0x09
|
||||
#define GSM430_TP_PID_TELETEX_CSPDN 0x0a
|
||||
#define GSM430_TP_PID_TELETEX_PSTN 0x0b
|
||||
#define GSM430_TP_PID_TELETEX_ISDN 0x0c
|
||||
#define GSM430_TP_PID_TELETEX_UCI 0x0d
|
||||
#define GSM430_TP_PID_MSG_HANDLING 0x10
|
||||
#define GSM430_TP_PID_MSG_X400 0x11
|
||||
#define GSM430_TP_PID_EMAIL 0x12
|
||||
#define GSM430_TP_PID_GSM_MS 0x1f
|
||||
/* if bit 7 = 0 and bit 6 = 1 */
|
||||
#define GSM430_TP_PID_SMS_TYPE_0 0
|
||||
#define GSM430_TP_PID_SMS_TYPE_1 1
|
||||
#define GSM430_TP_PID_SMS_TYPE_2 2
|
||||
#define GSM430_TP_PID_SMS_TYPE_3 3
|
||||
#define GSM430_TP_PID_SMS_TYPE_4 4
|
||||
#define GSM430_TP_PID_SMS_TYPE_5 5
|
||||
#define GSM430_TP_PID_SMS_TYPE_6 6
|
||||
#define GSM430_TP_PID_SMS_TYPE_7 7
|
||||
#define GSM430_TP_PID_RETURN_CALL_MSG 0x1f
|
||||
#define GSM430_TP_PID_ME_DATA_DNLOAD 0x3d
|
||||
#define GSM430_TP_PID_ME_DE_PERSONAL 0x3e
|
||||
#define GSM430_TP_PID_ME_SIM_DNLOAD 0x3f
|
||||
|
||||
/* GSM 03.38 Chapter 4: SMS Data Coding Scheme */
|
||||
#define GSM338_DCS_00_
|
||||
|
||||
#define GSM338_DCS_1110_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_7BIT (0 << 2)
|
||||
#define GSM338_DCS_1111_8BIT_DATA (1 << 2)
|
||||
#define GSM338_DCS_1111_CLASS0 0
|
||||
#define GSM338_DCS_1111_CLASS1_ME 1
|
||||
#define GSM338_DCS_1111_CLASS2_SIM 2
|
||||
#define GSM338_DCS_1111_CLASS3_TE 3 /* See TS 07.05 */
|
||||
#define UM_SAPI_SMS 3 /* See GSM 04.05/04.06 */
|
||||
|
||||
/* SMS deliver PDU */
|
||||
struct sms_deliver {
|
||||
@@ -203,9 +25,7 @@ struct sms_deliver {
|
||||
|
||||
struct msgb;
|
||||
|
||||
int gsm0411_rcv_sms(struct msgb *msg, u_int8_t link_id);
|
||||
|
||||
int gsm411_send_sms_lchan(struct gsm_lchan *lchan, struct gsm_sms *sms);
|
||||
int gsm0411_rcv_sms(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
struct gsm_sms *sms_alloc(void);
|
||||
void sms_free(struct gsm_sms *sms);
|
||||
@@ -213,4 +33,5 @@ void sms_free(struct gsm_sms *sms);
|
||||
void _gsm411_sms_trans_free(struct gsm_trans *trans);
|
||||
int gsm411_send_sms_subscr(struct gsm_subscriber *subscr,
|
||||
struct gsm_sms *sms);
|
||||
void gsm411_sapi_n_reject(struct gsm_subscriber_connection *conn);
|
||||
#endif
|
||||
|
||||
@@ -1,132 +1,13 @@
|
||||
#ifndef _GSM_04_80_H
|
||||
#define _GSM_04_80_H
|
||||
|
||||
/* GSM TS 04.80 definitions (Supplementary Services Specification, Formats and Coding) */
|
||||
|
||||
/* Section 3.4 */
|
||||
#define GSM0480_MTYPE_RELEASE_COMPLETE 0x2A
|
||||
#define GSM0480_MTYPE_FACILITY 0x3A
|
||||
#define GSM0480_MTYPE_REGISTER 0x3B
|
||||
|
||||
/* Section 3.5 */
|
||||
#define GSM0480_IE_FACILITY 0x1C
|
||||
#define GSM0480_IE_SS_VERSION 0x7F
|
||||
|
||||
/* Section 3.6.2 */
|
||||
#define GSM0480_CTYPE_INVOKE 0xA1
|
||||
#define GSM0480_CTYPE_RETURN_RESULT 0xA2
|
||||
#define GSM0480_CTYPE_RETURN_ERROR 0xA3
|
||||
#define GSM0480_CTYPE_REJECT 0xA4
|
||||
|
||||
/* Section 3.6.3 */
|
||||
#define GSM0480_COMPIDTAG_INVOKE_ID 0x02
|
||||
#define GSM0480_COMPIDTAG_LINKED_ID 0x80
|
||||
|
||||
/* Section 3.6.4 */
|
||||
#define GSM0480_OPERATION_CODE 0x02
|
||||
|
||||
/* Section 3.6.5 */
|
||||
#define GSM_0480_SEQUENCE_TAG 0x30
|
||||
#define GSM_0480_SET_TAG 0x31
|
||||
|
||||
/* Section 3.6.6 */
|
||||
#define GSM_0480_ERROR_CODE_TAG 0x02
|
||||
|
||||
/* Section 3.6.7 */
|
||||
/* Table 3.13 */
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_GENERAL 0x80
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_INVOKE 0x81
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_RESULT 0x82
|
||||
#define GSM_0480_PROBLEM_CODE_TAG_RETURN_ERROR 0x83
|
||||
|
||||
/* Table 3.14 */
|
||||
#define GSM_0480_GEN_PROB_CODE_UNRECOGNISED 0x00
|
||||
#define GSM_0480_GEN_PROB_CODE_MISTYPED 0x01
|
||||
#define GSM_0480_GEN_PROB_CODE_BAD_STRUCTURE 0x02
|
||||
|
||||
/* Table 3.15 */
|
||||
#define GSM_0480_INVOKE_PROB_CODE_DUPLICATE_INVOKE_ID 0x00
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_OPERATION 0x01
|
||||
#define GSM_0480_INVOKE_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
#define GSM_0480_INVOKE_PROB_CODE_RESOURCE_LIMITATION 0x03
|
||||
#define GSM_0480_INVOKE_PROB_CODE_INITIATING_RELEASE 0x04
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNRECOGNISED_LINKED_ID 0x05
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_RESPONSE 0x06
|
||||
#define GSM_0480_INVOKE_PROB_CODE_UNEXPECTED_LINKED_OPERATION 0x07
|
||||
|
||||
/* Table 3.16 */
|
||||
#define GSM_0480_RESULT_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_RESULT_PROB_CODE_RETURN_RESULT_UNEXPECTED 0x01
|
||||
#define GSM_0480_RESULT_PROB_CODE_MISTYPED_PARAMETER 0x02
|
||||
|
||||
/* Table 3.17 */
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_INVOKE_ID 0x00
|
||||
#define GSM_0480_ERROR_PROB_CODE_RETURN_ERROR_UNEXPECTED 0x01
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNRECOGNISED_ERROR 0x02
|
||||
#define GSM_0480_ERROR_PROB_CODE_UNEXPECTED_ERROR 0x03
|
||||
#define GSM_0480_ERROR_PROB_CODE_MISTYPED_PARAMETER 0x04
|
||||
|
||||
/* Section 4.5 */
|
||||
#define GSM0480_OP_CODE_REGISTER_SS 0x0A
|
||||
#define GSM0480_OP_CODE_ERASE_SS 0x0B
|
||||
#define GSM0480_OP_CODE_ACTIVATE_SS 0x0C
|
||||
#define GSM0480_OP_CODE_DEACTIVATE_SS 0x0D
|
||||
#define GSM0480_OP_CODE_INTERROGATE_SS 0x0E
|
||||
#define GSM0480_OP_CODE_NOTIFY_SS 0x10
|
||||
#define GSM0480_OP_CODE_REGISTER_PASSWORD 0x11
|
||||
#define GSM0480_OP_CODE_GET_PASSWORD 0x12
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_DATA 0x13
|
||||
#define GSM0480_OP_CODE_FORWARD_CHECK_SS_IND 0x26
|
||||
#define GSM0480_OP_CODE_PROCESS_USS_REQ 0x3B
|
||||
#define GSM0480_OP_CODE_USS_REQUEST 0x3C
|
||||
#define GSM0480_OP_CODE_USS_NOTIFY 0x3D
|
||||
#define GSM0480_OP_CODE_FORWARD_CUG_INFO 0x78
|
||||
#define GSM0480_OP_CODE_SPLIT_MPTY 0x79
|
||||
#define GSM0480_OP_CODE_RETRIEVE_MPTY 0x7A
|
||||
#define GSM0480_OP_CODE_HOLD_MPTY 0x7B
|
||||
#define GSM0480_OP_CODE_BUILD_MPTY 0x7C
|
||||
#define GSM0480_OP_CODE_FORWARD_CHARGE_ADVICE 0x7D
|
||||
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_SUBSCRIBER 0x01
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SUBSCRIBER 0x09
|
||||
#define GSM0480_ERR_CODE_BEARER_SERVICE_NOT_PROVISIONED 0x0A
|
||||
#define GSM0480_ERR_CODE_TELESERVICE_NOT_PROVISIONED 0x0B
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_EQUIPMENT 0x0C
|
||||
#define GSM0480_ERR_CODE_CALL_BARRED 0x0D
|
||||
#define GSM0480_ERR_CODE_ILLEGAL_SS_OPERATION 0x10
|
||||
#define GSM0480_ERR_CODE_SS_ERROR_STATUS 0x11
|
||||
#define GSM0480_ERR_CODE_SS_NOT_AVAILABLE 0x12
|
||||
#define GSM0480_ERR_CODE_SS_SUBSCRIPTION_VIOLATION 0x13
|
||||
#define GSM0480_ERR_CODE_SS_INCOMPATIBILITY 0x14
|
||||
#define GSM0480_ERR_CODE_FACILITY_NOT_SUPPORTED 0x15
|
||||
#define GSM0480_ERR_CODE_ABSENT_SUBSCRIBER 0x1B
|
||||
#define GSM0480_ERR_CODE_SYSTEM_FAILURE 0x22
|
||||
#define GSM0480_ERR_CODE_DATA_MISSING 0x23
|
||||
#define GSM0480_ERR_CODE_UNEXPECTED_DATA_VALUE 0x24
|
||||
#define GSM0480_ERR_CODE_PW_REGISTRATION_FAILURE 0x25
|
||||
#define GSM0480_ERR_CODE_NEGATIVE_PW_CHECK 0x26
|
||||
#define GSM0480_ERR_CODE_NUM_PW_ATTEMPTS_VIOLATION 0x2B
|
||||
#define GSM0480_ERR_CODE_UNKNOWN_ALPHABET 0x47
|
||||
#define GSM0480_ERR_CODE_USSD_BUSY 0x48
|
||||
#define GSM0480_ERR_CODE_MAX_MPTY_PARTICIPANTS 0x7E
|
||||
#define GSM0480_ERR_CODE_RESOURCES_NOT_AVAILABLE 0x7F
|
||||
|
||||
/* ASN.1 type-tags */
|
||||
#define ASN1_BOOLEAN_TAG 0x01
|
||||
#define ASN1_INTEGER_TAG 0x02
|
||||
#define ASN1_BIT_STRING_TAG 0x03
|
||||
#define ASN1_OCTET_STRING_TAG 0x04
|
||||
#define ASN1_NULL_TYPE_TAG 0x05
|
||||
#define ASN1_OBJECT_ID_TAG 0x06
|
||||
#define ASN1_UTF8_STRING_TAG 0x0C
|
||||
#define ASN1_PRINTABLE_STRING_TAG 0x13
|
||||
#define ASN1_IA5_STRING_TAG 0x16
|
||||
#define ASN1_UNICODE_STRING_TAG 0x1E
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/protocol/gsm_04_80.h>
|
||||
|
||||
#define MAX_LEN_USSD_STRING 31
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
struct ussd_request {
|
||||
char text[MAX_LEN_USSD_STRING + 1];
|
||||
u_int8_t transaction_id;
|
||||
@@ -135,9 +16,20 @@ struct ussd_request {
|
||||
|
||||
int gsm0480_decode_ussd_request(const struct msgb *msg,
|
||||
struct ussd_request *request);
|
||||
int gsm0480_send_ussd_response(const struct msgb *in_msg, const char* response_text,
|
||||
const struct ussd_request *req);
|
||||
int gsm0480_send_ussd_reject(const struct msgb *msg,
|
||||
const struct ussd_request *request);
|
||||
int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *in_msg, const char* response_text,
|
||||
const struct ussd_request *req);
|
||||
int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
|
||||
const struct msgb *msg,
|
||||
const struct ussd_request *request);
|
||||
|
||||
struct msgb *gsm0480_create_notifySS(const char *text);
|
||||
struct msgb *gsm0480_create_unstructuredSS_Notify(int alertLevel, const char *text);
|
||||
|
||||
int gsm0480_wrap_invoke(struct msgb *msg, int op, int link_id);
|
||||
int gsm0480_wrap_facility(struct msgb *msg);
|
||||
|
||||
int gsm0480_send_ussdNotify(struct gsm_subscriber_connection *conn, int level, const char *text);
|
||||
int gsm0480_send_releaseComplete(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,21 +3,6 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
struct value_string {
|
||||
unsigned int value;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
const char *get_value_string(const struct value_string *vs, u_int32_t val);
|
||||
|
||||
enum gsm_band {
|
||||
GSM_BAND_400,
|
||||
GSM_BAND_850,
|
||||
GSM_BAND_900,
|
||||
GSM_BAND_1800,
|
||||
GSM_BAND_1900,
|
||||
};
|
||||
|
||||
enum gsm_phys_chan_config {
|
||||
GSM_PCHAN_NONE,
|
||||
GSM_PCHAN_CCCH,
|
||||
@@ -55,14 +40,18 @@ enum gsm_chreq_reason_t {
|
||||
GSM_CHREQ_REASON_OTHER,
|
||||
};
|
||||
|
||||
#include <openbsc/timer.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/system_information.h>
|
||||
#include <openbsc/mncc.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <openbsc/bitvec.h>
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/bitvec.h>
|
||||
#include <osmocore/statistics.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <osmocore/utils.h>
|
||||
#include <osmocore/rxlev_stat.h>
|
||||
|
||||
#define TRX_NR_TS 8
|
||||
#define TS_MAX_LCHAN 8
|
||||
@@ -79,6 +68,7 @@ enum gsm_chreq_reason_t {
|
||||
enum gsm_hooks {
|
||||
GSM_HOOK_NM_SWLOAD,
|
||||
GSM_HOOK_RR_PAGING,
|
||||
GSM_HOOK_RR_SECURITY,
|
||||
};
|
||||
|
||||
enum gsm_paging_event {
|
||||
@@ -87,56 +77,79 @@ enum gsm_paging_event {
|
||||
GSM_PAGING_OOM,
|
||||
};
|
||||
|
||||
enum bts_gprs_mode {
|
||||
BTS_GPRS_NONE = 0,
|
||||
BTS_GPRS_GPRS = 1,
|
||||
BTS_GPRS_EGPRS = 2,
|
||||
};
|
||||
|
||||
/* the data structure stored in msgb->cb for openbsc apps */
|
||||
struct openbsc_msgb_cb {
|
||||
unsigned char *bssgph;
|
||||
unsigned char *llch;
|
||||
|
||||
/* Cell Identifier */
|
||||
unsigned char *bssgp_cell_id;
|
||||
|
||||
/* Identifiers of a BTS, equal to 'struct bssgp_bts_ctx' */
|
||||
u_int16_t nsei;
|
||||
u_int16_t bvci;
|
||||
|
||||
/* Identifier of a MS (inside BTS), equal to 'struct sgsn_mm_ctx' */
|
||||
u_int32_t tlli;
|
||||
} __attribute__((packed));
|
||||
#define OBSC_MSGB_CB(__msgb) ((struct openbsc_msgb_cb *)&((__msgb)->cb[0]))
|
||||
#define msgb_tlli(__x) OBSC_MSGB_CB(__x)->tlli
|
||||
#define msgb_nsei(__x) OBSC_MSGB_CB(__x)->nsei
|
||||
#define msgb_bvci(__x) OBSC_MSGB_CB(__x)->bvci
|
||||
#define msgb_gmmh(__x) (__x)->l3h
|
||||
#define msgb_bssgph(__x) OBSC_MSGB_CB(__x)->bssgph
|
||||
#define msgb_bssgp_len(__x) ((__x)->tail - (uint8_t *)msgb_bssgph(__x))
|
||||
#define msgb_bcid(__x) OBSC_MSGB_CB(__x)->bssgp_cell_id
|
||||
#define msgb_llch(__x) OBSC_MSGB_CB(__x)->llch
|
||||
|
||||
#define OBSC_LINKID_CB(__msgb) (__msgb)->cb[3]
|
||||
|
||||
enum gsm_security_event {
|
||||
GSM_SECURITY_NOAVAIL,
|
||||
GSM_SECURITY_AUTH_FAILED,
|
||||
GSM_SECURITY_SUCCEEDED,
|
||||
};
|
||||
|
||||
struct msgb;
|
||||
typedef int gsm_cbfn(unsigned int hooknum,
|
||||
unsigned int event,
|
||||
struct msgb *msg,
|
||||
void *data, void *param);
|
||||
|
||||
/* communications link with a BTS */
|
||||
struct gsm_bts_link {
|
||||
struct gsm_bts *bts;
|
||||
/* Real authentication information containing Ki */
|
||||
enum gsm_auth_algo {
|
||||
AUTH_ALGO_NONE,
|
||||
AUTH_ALGO_XOR,
|
||||
AUTH_ALGO_COMP128v1,
|
||||
};
|
||||
|
||||
struct sccp_connection;
|
||||
struct gsm_auth_info {
|
||||
enum gsm_auth_algo auth_algo;
|
||||
unsigned int a3a8_ki_len;
|
||||
u_int8_t a3a8_ki[16];
|
||||
};
|
||||
|
||||
struct gsm_auth_tuple {
|
||||
int use_count;
|
||||
int key_seq;
|
||||
u_int8_t rand[16];
|
||||
u_int8_t sres[4];
|
||||
u_int8_t kc[8];
|
||||
};
|
||||
#define GSM_KEY_SEQ_INVAL 7 /* GSM 04.08 - 10.5.1.2 */
|
||||
|
||||
|
||||
struct gsm_lchan;
|
||||
struct gsm_subscriber;
|
||||
struct gsm_mncc;
|
||||
struct rtp_socket;
|
||||
|
||||
/* BSC/MSC data holding them together */
|
||||
struct bss_sccp_connection_data {
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_lchan *secondary_lchan;
|
||||
struct sccp_connection *sccp;
|
||||
int ciphering_handled : 1;
|
||||
|
||||
/* Timers... */
|
||||
|
||||
/* for assginment command */
|
||||
struct timer_list T10;
|
||||
|
||||
/* for SCCP ... */
|
||||
struct timer_list sccp_it;
|
||||
|
||||
/* audio handling */
|
||||
int rtp_port;
|
||||
|
||||
/* Queue SCCP and GSM0408 messages */
|
||||
int block_gsm;
|
||||
struct llist_head gsm_queue;
|
||||
unsigned int gsm_queue_size;
|
||||
|
||||
struct llist_head sccp_queue;
|
||||
unsigned int sccp_queue_size;
|
||||
};
|
||||
|
||||
#define GSM0808_T10_VALUE 6, 0
|
||||
#define sccp_get_lchan(data_ctx) ((struct bss_sccp_connection_data *)data_ctx)->lchan
|
||||
#define lchan_get_sccp(lchan) lchan->msc_data->sccp
|
||||
struct bss_sccp_connection_data *bss_sccp_create_data();
|
||||
void bss_sccp_free_data(struct bss_sccp_connection_data *);
|
||||
|
||||
struct bsc_api;
|
||||
|
||||
/* Network Management State */
|
||||
struct gsm_nm_state {
|
||||
@@ -156,6 +169,24 @@ struct gsm_loc_updating_operation {
|
||||
struct timer_list updating_timer;
|
||||
unsigned int waiting_for_imsi : 1;
|
||||
unsigned int waiting_for_imei : 1;
|
||||
unsigned int key_seq : 4;
|
||||
};
|
||||
|
||||
/*
|
||||
* AUTHENTICATION/CIPHERING state
|
||||
*/
|
||||
struct gsm_security_operation {
|
||||
struct gsm_auth_tuple atuple;
|
||||
gsm_cbfn *cb;
|
||||
void *cb_data;
|
||||
};
|
||||
|
||||
/*
|
||||
* A dummy to keep a connection up for at least
|
||||
* a couple of seconds to work around MSC issues.
|
||||
*/
|
||||
struct gsm_anchor_operation {
|
||||
struct timer_list timeout;
|
||||
};
|
||||
|
||||
/* Maximum number of neighbor cells whose average we track */
|
||||
@@ -173,6 +204,9 @@ struct neigh_meas_proc {
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
/* is the data link established? who established it? */
|
||||
@@ -183,10 +217,35 @@ struct neigh_meas_proc {
|
||||
/* state of a logical channel */
|
||||
enum gsm_lchan_state {
|
||||
LCHAN_S_NONE, /* channel is not active */
|
||||
LCHAN_S_ACT_REQ, /* channel activatin requested */
|
||||
LCHAN_S_ACTIVE, /* channel is active and operational */
|
||||
LCHAN_S_REL_REQ, /* channel release has been requested */
|
||||
LCHAN_S_REL_ERR, /* channel is in an error state */
|
||||
LCHAN_S_INACTIVE, /* channel is set inactive */
|
||||
};
|
||||
|
||||
/* the per subscriber data for lchan */
|
||||
struct gsm_subscriber_connection {
|
||||
/* To whom we are allocated at the moment */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/*
|
||||
* Operations that have a state and might be pending
|
||||
*/
|
||||
struct gsm_loc_updating_operation *loc_operation;
|
||||
struct gsm_security_operation *sec_operation;
|
||||
struct gsm_anchor_operation *anch_operation;
|
||||
|
||||
/* Are we part of a special "silent" call */
|
||||
int silent_call;
|
||||
|
||||
/* back pointers */
|
||||
int in_release;
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_lchan *ho_lchan;
|
||||
struct gsm_bts *bts;
|
||||
};
|
||||
|
||||
struct gsm_lchan {
|
||||
/* The TS that we're part of */
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
@@ -210,30 +269,21 @@ struct gsm_lchan {
|
||||
u_int8_t key[MAX_A5_KEY_LEN];
|
||||
} encr;
|
||||
|
||||
struct timer_list T3101;
|
||||
struct timer_list T3111;
|
||||
struct timer_list error_timer;
|
||||
|
||||
/* AMR bits */
|
||||
struct gsm48_multi_rate_conf mr_conf;
|
||||
|
||||
/* To whom we are allocated at the moment */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
struct timer_list T3101;
|
||||
|
||||
/* Established data link layer services */
|
||||
u_int8_t sapis[8];
|
||||
int sach_deact;
|
||||
int release_reason;
|
||||
|
||||
/*
|
||||
* Operations that have a state and might be pending
|
||||
*/
|
||||
struct gsm_loc_updating_operation *loc_operation;
|
||||
|
||||
/*
|
||||
* MSC handling...
|
||||
*/
|
||||
struct bss_sccp_connection_data *msc_data;
|
||||
|
||||
|
||||
/* use count. how many users use this channel */
|
||||
unsigned int use_count;
|
||||
/* GSM Random Access data */
|
||||
struct gsm48_req_ref *rqd_ref;
|
||||
uint8_t rqd_ta;
|
||||
|
||||
/* cache of last measurement reports on this lchan */
|
||||
struct gsm_meas_rep meas_rep[6];
|
||||
@@ -248,10 +298,13 @@ struct gsm_lchan {
|
||||
u_int16_t bound_port;
|
||||
u_int16_t connect_port;
|
||||
u_int16_t conn_id;
|
||||
u_int8_t rtp_payload;
|
||||
u_int8_t rtp_payload2;
|
||||
u_int8_t speech_mode;
|
||||
struct rtp_socket *rtp_socket;
|
||||
} abis_ip;
|
||||
|
||||
struct gsm_subscriber_connection *conn;
|
||||
};
|
||||
|
||||
struct gsm_e1_subslot {
|
||||
@@ -263,7 +316,7 @@ struct gsm_e1_subslot {
|
||||
u_int8_t e1_ts_ss;
|
||||
};
|
||||
|
||||
#define BTS_TRX_F_ACTIVATED 0x0001
|
||||
#define TS_F_PDCH_MODE 0x1000
|
||||
/* One Timeslot in a TRX */
|
||||
struct gsm_bts_trx_ts {
|
||||
struct gsm_bts_trx *trx;
|
||||
@@ -277,6 +330,19 @@ struct gsm_bts_trx_ts {
|
||||
struct tlv_parsed nm_attr;
|
||||
u_int8_t nm_chan_comb;
|
||||
|
||||
struct {
|
||||
/* Parameters below are configured by VTY */
|
||||
int enabled;
|
||||
u_int8_t maio;
|
||||
u_int8_t hsn;
|
||||
struct bitvec arfcns;
|
||||
u_int8_t arfcns_data[1024/8];
|
||||
/* This is the pre-computed MA for channel assignments */
|
||||
struct bitvec ma;
|
||||
u_int8_t ma_len; /* part of ma_data that is used */
|
||||
u_int8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
|
||||
} hopping;
|
||||
|
||||
/* To which E1 subslot are we connected */
|
||||
struct gsm_e1_subslot e1_link;
|
||||
|
||||
@@ -291,6 +357,8 @@ struct gsm_bts_trx {
|
||||
struct gsm_bts *bts;
|
||||
/* number of this TRX in the BTS */
|
||||
u_int8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* how do we talk RSL with this TRX? */
|
||||
struct gsm_e1_subslot rsl_e1_link;
|
||||
u_int8_t rsl_tei;
|
||||
@@ -315,19 +383,43 @@ struct gsm_bts_trx {
|
||||
struct gsm_nm_state nm_state;
|
||||
} pa;
|
||||
} bs11;
|
||||
struct {
|
||||
unsigned int test_state;
|
||||
u_int8_t test_nr;
|
||||
struct rxlev_stats rxlev_stat;
|
||||
} ipaccess;
|
||||
};
|
||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||
|
||||
/* NM state */
|
||||
int rf_locked;
|
||||
};
|
||||
|
||||
#define GSM_BTS_SI(bts, i) (void *)(bts->si_buf[i])
|
||||
|
||||
enum gsm_bts_type {
|
||||
GSM_BTS_TYPE_UNKNOWN,
|
||||
GSM_BTS_TYPE_BS11,
|
||||
GSM_BTS_TYPE_NANOBTS,
|
||||
};
|
||||
|
||||
struct gsm_bts_model {
|
||||
struct llist_head list;
|
||||
|
||||
enum gsm_bts_type type;
|
||||
const char *name;
|
||||
|
||||
struct tlv_definition nm_att_tlvdef;
|
||||
|
||||
struct bitvec features;
|
||||
uint8_t _features_data[128/8];
|
||||
};
|
||||
|
||||
enum gsm_bts_features {
|
||||
BTS_FEAT_HSCSD,
|
||||
BTS_FEAT_GPRS,
|
||||
BTS_FEAT_EGPRS,
|
||||
BTS_FEAT_ECSD,
|
||||
BTS_FEAT_HOPPING,
|
||||
};
|
||||
|
||||
/**
|
||||
* A pending paging request
|
||||
*/
|
||||
@@ -358,7 +450,6 @@ struct gsm_paging_request {
|
||||
struct gsm_bts_paging_state {
|
||||
/* pending requests */
|
||||
struct llist_head pending_requests;
|
||||
struct gsm_paging_request *last_request;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
struct timer_list work_timer;
|
||||
@@ -373,7 +464,14 @@ struct gsm_envabtse {
|
||||
|
||||
struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_bts *bts;
|
||||
/* data read via VTY config file, to configure the BTS
|
||||
* via OML from BSC */
|
||||
int id;
|
||||
u_int16_t nsvci;
|
||||
u_int16_t local_port; /* on the BTS */
|
||||
u_int16_t remote_port; /* on the SGSN */
|
||||
u_int32_t remote_ip; /* on the SGSN */
|
||||
|
||||
struct gsm_nm_state nm_state;
|
||||
};
|
||||
|
||||
@@ -385,6 +483,8 @@ struct gsm_bts {
|
||||
struct gsm_network *network;
|
||||
/* number of ths BTS in network */
|
||||
u_int8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* Cell Identity */
|
||||
u_int16_t cell_identity;
|
||||
/* location area code of this BTS */
|
||||
@@ -395,6 +495,7 @@ struct gsm_bts {
|
||||
u_int8_t bsic;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type type;
|
||||
struct gsm_bts_model *model;
|
||||
enum gsm_band band;
|
||||
/* should the channel allocator allocate channels from high TRX to TRX0,
|
||||
* rather than starting from TRX0 and go upwards? */
|
||||
@@ -441,6 +542,13 @@ struct gsm_bts {
|
||||
} data;
|
||||
} si_common;
|
||||
|
||||
/* do we use static (user-defined) system information messages? (bitmask) */
|
||||
uint32_t si_mode_static;
|
||||
/* bitmask of all SI that are present/valid in si_buf */
|
||||
uint32_t si_valid;
|
||||
/* buffers where we put the pre-computed SI */
|
||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
|
||||
|
||||
/* ip.accesss Unit ID's have Site/BTS/TRX layout */
|
||||
union {
|
||||
struct {
|
||||
@@ -461,14 +569,24 @@ struct gsm_bts {
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
enum bts_gprs_mode mode;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t nsei;
|
||||
uint8_t timer[7];
|
||||
} nse;
|
||||
struct {
|
||||
struct gsm_nm_state nm_state;
|
||||
u_int16_t bvci;
|
||||
uint8_t timer[11];
|
||||
} cell;
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
u_int8_t rac;
|
||||
} gprs;
|
||||
|
||||
/* RACH NM values */
|
||||
int rach_b_thresh;
|
||||
int rach_ldavg_slots;
|
||||
|
||||
/* transceivers */
|
||||
int num_trx;
|
||||
@@ -478,44 +596,52 @@ struct gsm_bts {
|
||||
/* Some statistics of our network */
|
||||
struct gsmnet_stats {
|
||||
struct {
|
||||
unsigned long total;
|
||||
unsigned long no_channel;
|
||||
struct counter *total;
|
||||
struct counter *no_channel;
|
||||
} chreq;
|
||||
struct {
|
||||
unsigned long attempted;
|
||||
unsigned long no_channel; /* no channel available */
|
||||
unsigned long timeout; /* T3103 timeout */
|
||||
unsigned long completed; /* HO COMPL received */
|
||||
unsigned long failed; /* HO FAIL received */
|
||||
struct counter *attempted;
|
||||
struct counter *no_channel; /* no channel available */
|
||||
struct counter *timeout; /* T3103 timeout */
|
||||
struct counter *completed; /* HO COMPL received */
|
||||
struct counter *failed; /* HO FAIL received */
|
||||
} handover;
|
||||
struct {
|
||||
unsigned long attach;
|
||||
unsigned long normal;
|
||||
unsigned long periodic;
|
||||
unsigned long detach;
|
||||
struct counter *attach;
|
||||
struct counter *normal;
|
||||
struct counter *periodic;
|
||||
struct counter *detach;
|
||||
} loc_upd_type;
|
||||
struct {
|
||||
unsigned long reject;
|
||||
unsigned long accept;
|
||||
struct counter *reject;
|
||||
struct counter *accept;
|
||||
} loc_upd_resp;
|
||||
struct {
|
||||
unsigned long attempted;
|
||||
unsigned long detached;
|
||||
unsigned long completed;
|
||||
unsigned long expired;
|
||||
struct counter *attempted;
|
||||
struct counter *detached;
|
||||
struct counter *completed;
|
||||
struct counter *expired;
|
||||
} paging;
|
||||
struct {
|
||||
unsigned long submitted; /* MO SMS submissions */
|
||||
unsigned long no_receiver;
|
||||
unsigned long delivered; /* MT SMS deliveries */
|
||||
unsigned long rp_err_mem;
|
||||
unsigned long rp_err_other;
|
||||
struct counter *submitted; /* MO SMS submissions */
|
||||
struct counter *no_receiver;
|
||||
struct counter *delivered; /* MT SMS deliveries */
|
||||
struct counter *rp_err_mem;
|
||||
struct counter *rp_err_other;
|
||||
} sms;
|
||||
struct {
|
||||
unsigned long dialled; /* total number of dialled calls */
|
||||
unsigned long alerted; /* we alerted the other end */
|
||||
unsigned long connected;/* how many calls were accepted */
|
||||
struct counter *dialled; /* total number of dialled calls */
|
||||
struct counter *alerted; /* we alerted the other end */
|
||||
struct counter *connected;/* how many calls were accepted */
|
||||
} call;
|
||||
struct {
|
||||
struct counter *rf_fail;
|
||||
struct counter *rll_err;
|
||||
} chan;
|
||||
struct {
|
||||
struct counter *oml_fail;
|
||||
struct counter *rsl_fail;
|
||||
} bts;
|
||||
};
|
||||
|
||||
enum gsm_auth_policy {
|
||||
@@ -527,14 +653,6 @@ enum gsm_auth_policy {
|
||||
#define GSM_T3101_DEFAULT 10
|
||||
#define GSM_T3113_DEFAULT 60
|
||||
|
||||
/*
|
||||
* internal data for audio management
|
||||
*/
|
||||
struct gsm_audio_support {
|
||||
u_int8_t hr : 1,
|
||||
ver : 7;
|
||||
};
|
||||
|
||||
struct gsm_network {
|
||||
/* global parameters */
|
||||
u_int16_t country_code;
|
||||
@@ -565,15 +683,11 @@ struct gsm_network {
|
||||
|
||||
struct gsmnet_stats stats;
|
||||
|
||||
struct gsm_audio_support **audio_support;
|
||||
int audio_length;
|
||||
int rtp_payload;
|
||||
int rtp_base_port;
|
||||
|
||||
/* layer 4 */
|
||||
int (*mncc_recv) (struct gsm_network *net, int msg_type, void *arg);
|
||||
struct llist_head upqueue;
|
||||
struct llist_head trans_list;
|
||||
struct bsc_api *bsc_api;
|
||||
|
||||
unsigned int num_bts;
|
||||
struct llist_head bts_list;
|
||||
@@ -595,10 +709,7 @@ struct gsm_network {
|
||||
struct {
|
||||
enum rrlp_mode mode;
|
||||
} rrlp;
|
||||
|
||||
/* a hack for On Waves. It must be signed */
|
||||
int32_t core_country_code;
|
||||
int32_t core_network_code;
|
||||
int msc_prio;
|
||||
};
|
||||
|
||||
#define SMS_HDR_SIZE 128
|
||||
@@ -623,11 +734,13 @@ struct gsm_sms {
|
||||
char text[SMS_TEXT_SIZE];
|
||||
};
|
||||
|
||||
|
||||
struct gsm_network *gsm_network_init(u_int16_t country_code, u_int16_t network_code,
|
||||
int (*mncc_recv)(struct gsm_network *, int, void *));
|
||||
struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
|
||||
u_int8_t tsc, u_int8_t bsic);
|
||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||
int gsm_set_bts_type(struct gsm_bts *bts, enum gsm_bts_type type);
|
||||
|
||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
||||
|
||||
@@ -639,9 +752,12 @@ struct gsm_bts_trx *gsm_bts_trx_num(struct gsm_bts *bts, int num);
|
||||
|
||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
|
||||
const char *gsm_lchan_name(enum gsm_chan_t c);
|
||||
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(struct gsm_bts_trx *trx);
|
||||
char *gsm_ts_name(struct gsm_bts_trx_ts *ts);
|
||||
char *gsm_lchan_name(struct gsm_lchan *lchan);
|
||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||
|
||||
enum gsm_e1_event {
|
||||
EVT_E1_NONE,
|
||||
@@ -653,12 +769,10 @@ void set_ts_e1link(struct gsm_bts_trx_ts *ts, u_int8_t e1_nr,
|
||||
u_int8_t e1_ts, u_int8_t e1_ts_ss);
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
const char *btstype2str(enum gsm_bts_type type);
|
||||
struct gsm_bts_trx *gsm_bts_trx_by_nr(struct gsm_bts *bts, int nr);
|
||||
struct gsm_bts *gsm_bts_by_lac(struct gsm_network *net, unsigned int lac,
|
||||
struct gsm_bts *start_bts);
|
||||
|
||||
char *gsm_band_name(enum gsm_band band);
|
||||
enum gsm_band gsm_band_parse(const char *mhz);
|
||||
|
||||
extern void *tall_bsc_ctx;
|
||||
extern int ipacc_rtp_direct;
|
||||
|
||||
@@ -692,8 +806,20 @@ const char *gsm_auth_policy_name(enum gsm_auth_policy policy);
|
||||
enum rrlp_mode rrlp_mode_parse(const char *arg);
|
||||
const char *rrlp_mode_name(enum rrlp_mode mode);
|
||||
|
||||
enum bts_gprs_mode bts_gprs_mode_parse(const char *arg);
|
||||
const char *bts_gprs_mode_name(enum bts_gprs_mode mode);
|
||||
|
||||
void gsm_trx_lock_rf(struct gsm_bts_trx *trx, int locked);
|
||||
|
||||
int gsm48_ra_id_by_bts(u_int8_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_has_feature(struct gsm_bts *bts, 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);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "gsm_data.h"
|
||||
#include "linuxlist.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define GSM_IMEI_LENGTH 17
|
||||
#define GSM_IMSI_LENGTH 17
|
||||
#define GSM_NAME_LENGTH 128
|
||||
#define GSM_NAME_LENGTH 160
|
||||
|
||||
#define GSM_EXTENSION_LENGTH 15 /* MSISDN can only be 15 digits length */
|
||||
#define GSM_MIN_EXTEN 20000
|
||||
@@ -81,13 +81,13 @@ struct gsm_subscriber *subscr_get_by_extension(struct gsm_network *net,
|
||||
const char *ext);
|
||||
struct gsm_subscriber *subscr_get_by_id(struct gsm_network *net,
|
||||
unsigned long long id);
|
||||
struct gsm_subscriber *subscr_get_or_create(struct gsm_network *net,
|
||||
const char *imsi);
|
||||
int subscr_update(struct gsm_subscriber *s, struct gsm_bts *bts, int reason);
|
||||
void subscr_put_channel(struct gsm_lchan *lchan);
|
||||
void subscr_put_channel(struct gsm_subscriber_connection *conn);
|
||||
void subscr_get_channel(struct gsm_subscriber *subscr,
|
||||
int type, gsm_cbfn *cbfn, void *param);
|
||||
|
||||
char *subscr_name(struct gsm_subscriber *subscr);
|
||||
|
||||
/* internal */
|
||||
struct gsm_subscriber *subscr_alloc(void);
|
||||
extern struct llist_head active_subscribers;
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
#ifndef _HANDOVER_H
|
||||
#define _HANDOVER_H
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
/* Hand over the specified logical channel to the specified new BTS.
|
||||
* This is the main entry point for the actual handover algorithm,
|
||||
* after it has decided it wants to initiate HO to a specific BTS */
|
||||
int bsc_handover_start(struct gsm_lchan *old_lchan, struct gsm_bts *bts);
|
||||
|
||||
/* clear any operation for this connection */
|
||||
void bsc_clear_handover(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif /* _HANDOVER_H */
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
#define _IPACCESS_H
|
||||
|
||||
#include "e1_input.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define IPA_TCP_PORT_OML 3002
|
||||
#define IPA_TCP_PORT_RSL 3003
|
||||
|
||||
struct ipaccess_head {
|
||||
u_int16_t len; /* network byte order */
|
||||
@@ -45,5 +49,61 @@ int ipaccess_rcvmsg_base(struct msgb *msg, struct bsc_fd *bfd);
|
||||
struct msgb *ipaccess_read_msg(struct bsc_fd *bfd, int *error);
|
||||
void ipaccess_prepend_header(struct msgb *msg, int proto);
|
||||
int ipaccess_send_id_ack(int fd);
|
||||
int ipaccess_send_id_req(int fd);
|
||||
|
||||
int ipaccess_idtag_parse(struct tlv_parsed *dec, unsigned char *buf, int len);
|
||||
|
||||
int ipaccess_drop_oml(struct gsm_bts *bts);
|
||||
int ipaccess_drop_rsl(struct gsm_bts_trx *trx);
|
||||
|
||||
/*
|
||||
* Firmware specific header
|
||||
*/
|
||||
struct sdp_firmware {
|
||||
char magic[4];
|
||||
char more_magic[2];
|
||||
u_int16_t more_more_magic;
|
||||
u_int32_t header_length;
|
||||
u_int32_t file_length;
|
||||
char sw_part[20];
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int16_t table_offset;
|
||||
/* stuff i don't know */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_entry {
|
||||
u_int16_t something1;
|
||||
char text1[64];
|
||||
char time[12];
|
||||
char date[14];
|
||||
char text2[10];
|
||||
char version[20];
|
||||
u_int32_t length;
|
||||
u_int32_t addr1;
|
||||
u_int32_t addr2;
|
||||
u_int32_t start;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sdp_header_item {
|
||||
struct sdp_header_entry header_entry;
|
||||
struct llist_head entry;
|
||||
off_t absolute_offset;
|
||||
};
|
||||
|
||||
struct sdp_header {
|
||||
struct sdp_firmware firmware_info;
|
||||
|
||||
/* for more_magic a list of sdp_header_entry_list */
|
||||
struct llist_head header_list;
|
||||
|
||||
/* the entry of the sdp_header */
|
||||
struct llist_head entry;
|
||||
};
|
||||
|
||||
int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned base_offset, struct llist_head *list);
|
||||
|
||||
#endif /* _IPACCESS_H */
|
||||
|
||||
@@ -1,360 +0,0 @@
|
||||
#ifndef _LINUX_LLIST_H
|
||||
#define _LINUX_LLIST_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef inline
|
||||
#define inline __inline__
|
||||
#endif
|
||||
|
||||
static inline void prefetch(const void *x) {;}
|
||||
|
||||
/**
|
||||
* container_of - cast a member of a structure out to the containing structure
|
||||
*
|
||||
* @ptr: the pointer to the member.
|
||||
* @type: the type of the container struct this is embedded in.
|
||||
* @member: the name of the member within the struct.
|
||||
*
|
||||
*/
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (typeof( ((type *)0)->member ) *)(ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type, member) );})
|
||||
|
||||
|
||||
/*
|
||||
* These are non-NULL pointers that will result in page faults
|
||||
* under normal circumstances, used to verify that nobody uses
|
||||
* non-initialized llist entries.
|
||||
*/
|
||||
#define LLIST_POISON1 ((void *) 0x00100100)
|
||||
#define LLIST_POISON2 ((void *) 0x00200200)
|
||||
|
||||
/*
|
||||
* Simple doubly linked llist implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole llists rather than single entries, as
|
||||
* sometimes we already know the next/prev entries and we can
|
||||
* generate better code by using them directly rather than
|
||||
* using the generic single-entry routines.
|
||||
*/
|
||||
|
||||
struct llist_head {
|
||||
struct llist_head *next, *prev;
|
||||
};
|
||||
|
||||
#define LLIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LLIST_HEAD(name) \
|
||||
struct llist_head name = LLIST_HEAD_INIT(name)
|
||||
|
||||
#define INIT_LLIST_HEAD(ptr) do { \
|
||||
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal llist manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __llist_add(struct llist_head *_new,
|
||||
struct llist_head *prev,
|
||||
struct llist_head *next)
|
||||
{
|
||||
next->prev = _new;
|
||||
_new->next = next;
|
||||
_new->prev = prev;
|
||||
prev->next = _new;
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_add - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: llist head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void llist_add(struct llist_head *_new, struct llist_head *head)
|
||||
{
|
||||
__llist_add(_new, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_add_tail - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @head: llist head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void llist_add_tail(struct llist_head *_new, struct llist_head *head)
|
||||
{
|
||||
__llist_add(_new, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a llist entry by making the prev/next entries
|
||||
* point to each other.
|
||||
*
|
||||
* This is only for internal llist manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __llist_del(struct llist_head * prev, struct llist_head * next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_del - deletes entry from llist.
|
||||
* @entry: the element to delete from the llist.
|
||||
* Note: llist_empty on entry does not return true after this, the entry is
|
||||
* in an undefined state.
|
||||
*/
|
||||
static inline void llist_del(struct llist_head *entry)
|
||||
{
|
||||
__llist_del(entry->prev, entry->next);
|
||||
entry->next = (struct llist_head *)LLIST_POISON1;
|
||||
entry->prev = (struct llist_head *)LLIST_POISON2;
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_del_init - deletes entry from llist and reinitialize it.
|
||||
* @entry: the element to delete from the llist.
|
||||
*/
|
||||
static inline void llist_del_init(struct llist_head *entry)
|
||||
{
|
||||
__llist_del(entry->prev, entry->next);
|
||||
INIT_LLIST_HEAD(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_move - delete from one llist and add as another's head
|
||||
* @llist: the entry to move
|
||||
* @head: the head that will precede our entry
|
||||
*/
|
||||
static inline void llist_move(struct llist_head *llist, struct llist_head *head)
|
||||
{
|
||||
__llist_del(llist->prev, llist->next);
|
||||
llist_add(llist, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_move_tail - delete from one llist and add as another's tail
|
||||
* @llist: the entry to move
|
||||
* @head: the head that will follow our entry
|
||||
*/
|
||||
static inline void llist_move_tail(struct llist_head *llist,
|
||||
struct llist_head *head)
|
||||
{
|
||||
__llist_del(llist->prev, llist->next);
|
||||
llist_add_tail(llist, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_empty - tests whether a llist is empty
|
||||
* @head: the llist to test.
|
||||
*/
|
||||
static inline int llist_empty(const struct llist_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
static inline void __llist_splice(struct llist_head *llist,
|
||||
struct llist_head *head)
|
||||
{
|
||||
struct llist_head *first = llist->next;
|
||||
struct llist_head *last = llist->prev;
|
||||
struct llist_head *at = head->next;
|
||||
|
||||
first->prev = head;
|
||||
head->next = first;
|
||||
|
||||
last->next = at;
|
||||
at->prev = last;
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_splice - join two llists
|
||||
* @llist: the new llist to add.
|
||||
* @head: the place to add it in the first llist.
|
||||
*/
|
||||
static inline void llist_splice(struct llist_head *llist, struct llist_head *head)
|
||||
{
|
||||
if (!llist_empty(llist))
|
||||
__llist_splice(llist, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_splice_init - join two llists and reinitialise the emptied llist.
|
||||
* @llist: the new llist to add.
|
||||
* @head: the place to add it in the first llist.
|
||||
*
|
||||
* The llist at @llist is reinitialised
|
||||
*/
|
||||
static inline void llist_splice_init(struct llist_head *llist,
|
||||
struct llist_head *head)
|
||||
{
|
||||
if (!llist_empty(llist)) {
|
||||
__llist_splice(llist, head);
|
||||
INIT_LLIST_HEAD(llist);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* llist_entry - get the struct for this entry
|
||||
* @ptr: the &struct llist_head pointer.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_entry(ptr, type, member) \
|
||||
container_of(ptr, type, member)
|
||||
|
||||
/**
|
||||
* llist_for_each - iterate over a llist
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each(pos, head) \
|
||||
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
|
||||
pos = pos->next, prefetch(pos->next))
|
||||
|
||||
/**
|
||||
* __llist_for_each - iterate over a llist
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
*
|
||||
* This variant differs from llist_for_each() in that it's the
|
||||
* simplest possible llist iteration code, no prefetching is done.
|
||||
* Use this for code that knows the llist to be very short (empty
|
||||
* or 1 entry) most of the time.
|
||||
*/
|
||||
#define __llist_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||
|
||||
/**
|
||||
* llist_for_each_prev - iterate over a llist backwards
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each_prev(pos, head) \
|
||||
for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
|
||||
pos = pos->prev, prefetch(pos->prev))
|
||||
|
||||
/**
|
||||
* llist_for_each_safe - iterate over a llist safe against removal of llist entry
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @n: another &struct llist_head to use as temporary storage
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* llist_for_each_entry - iterate over llist of given type
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_for_each_entry(pos, head, member) \
|
||||
for (pos = llist_entry((head)->next, typeof(*pos), member), \
|
||||
prefetch(pos->member.next); \
|
||||
&pos->member != (head); \
|
||||
pos = llist_entry(pos->member.next, typeof(*pos), member), \
|
||||
prefetch(pos->member.next))
|
||||
|
||||
/**
|
||||
* llist_for_each_entry_reverse - iterate backwards over llist of given type.
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_for_each_entry_reverse(pos, head, member) \
|
||||
for (pos = llist_entry((head)->prev, typeof(*pos), member), \
|
||||
prefetch(pos->member.prev); \
|
||||
&pos->member != (head); \
|
||||
pos = llist_entry(pos->member.prev, typeof(*pos), member), \
|
||||
prefetch(pos->member.prev))
|
||||
|
||||
/**
|
||||
* llist_for_each_entry_continue - iterate over llist of given type
|
||||
* continuing after existing point
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_for_each_entry_continue(pos, head, member) \
|
||||
for (pos = llist_entry(pos->member.next, typeof(*pos), member), \
|
||||
prefetch(pos->member.next); \
|
||||
&pos->member != (head); \
|
||||
pos = llist_entry(pos->member.next, typeof(*pos), member), \
|
||||
prefetch(pos->member.next))
|
||||
|
||||
/**
|
||||
* llist_for_each_entry_safe - iterate over llist of given type safe against removal of llist entry
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your llist.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = llist_entry((head)->next, typeof(*pos), member), \
|
||||
n = llist_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = llist_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* llist_for_each_rcu - iterate over an rcu-protected llist
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each_rcu(pos, head) \
|
||||
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
|
||||
pos = pos->next, ({ smp_read_barrier_depends(); 0;}), prefetch(pos->next))
|
||||
|
||||
#define __llist_for_each_rcu(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); \
|
||||
pos = pos->next, ({ smp_read_barrier_depends(); 0;}))
|
||||
|
||||
/**
|
||||
* llist_for_each_safe_rcu - iterate over an rcu-protected llist safe
|
||||
* against removal of llist entry
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @n: another &struct llist_head to use as temporary storage
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each_safe_rcu(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, ({ smp_read_barrier_depends(); 0;}), n = pos->next)
|
||||
|
||||
/**
|
||||
* llist_for_each_entry_rcu - iterate over rcu llist of given type
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
* @member: the name of the llist_struct within the struct.
|
||||
*/
|
||||
#define llist_for_each_entry_rcu(pos, head, member) \
|
||||
for (pos = llist_entry((head)->next, typeof(*pos), member), \
|
||||
prefetch(pos->member.next); \
|
||||
&pos->member != (head); \
|
||||
pos = llist_entry(pos->member.next, typeof(*pos), member), \
|
||||
({ smp_read_barrier_depends(); 0;}), \
|
||||
prefetch(pos->member.next))
|
||||
|
||||
|
||||
/**
|
||||
* llist_for_each_continue_rcu - iterate over an rcu-protected llist
|
||||
* continuing after existing point.
|
||||
* @pos: the &struct llist_head to use as a loop counter.
|
||||
* @head: the head for your llist.
|
||||
*/
|
||||
#define llist_for_each_continue_rcu(pos, head) \
|
||||
for ((pos) = (pos)->next, prefetch((pos)->next); (pos) != (head); \
|
||||
(pos) = (pos)->next, ({ smp_read_barrier_depends(); 0;}), prefetch((pos)->next))
|
||||
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@
|
||||
struct gsm_meas_rep_cell {
|
||||
u_int8_t rxlev;
|
||||
u_int8_t bsic;
|
||||
u_int8_t neigh_idx;
|
||||
u_int16_t arfcn;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
|
||||
|
||||
/*
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by on-waves.com
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,6 +21,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENBSC_MGCP_H
|
||||
#define OPENBSC_MGCP_H
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define RTP_PORT_DEFAULT 4000
|
||||
|
||||
/**
|
||||
* Calculate the RTP audio port for the given multiplex
|
||||
* and the direction. This allows a semi static endpoint
|
||||
@@ -40,7 +49,88 @@
|
||||
* network and BTS.
|
||||
*
|
||||
*/
|
||||
int rtp_calculate_port(int multiplex, int base)
|
||||
static inline int rtp_calculate_port(int multiplex, int base)
|
||||
{
|
||||
return base + (multiplex * 2);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handling of MGCP Endpoints and the MGCP Config
|
||||
*/
|
||||
struct mgcp_endpoint;
|
||||
struct mgcp_config;
|
||||
|
||||
#define MGCP_ENDP_CRCX 1
|
||||
#define MGCP_ENDP_DLCX 2
|
||||
#define MGCP_ENDP_MDCX 3
|
||||
|
||||
/*
|
||||
* what to do with the msg?
|
||||
* - continue as usual?
|
||||
* - reject and send a failure code?
|
||||
* - defer? do not send anything
|
||||
*/
|
||||
#define MGCP_POLICY_CONT 4
|
||||
#define MGCP_POLICY_REJECT 5
|
||||
#define MGCP_POLICY_DEFER 6
|
||||
|
||||
typedef int (*mgcp_change)(struct mgcp_config *cfg, int endpoint, int state, int local_rtp);
|
||||
typedef int (*mgcp_policy)(struct mgcp_config *cfg, int endpoint, int state, const char *transactio_id);
|
||||
typedef int (*mgcp_reset)(struct mgcp_config *cfg);
|
||||
|
||||
struct mgcp_config {
|
||||
int source_port;
|
||||
char *local_ip;
|
||||
char *source_addr;
|
||||
unsigned int number_endpoints;
|
||||
char *bts_ip;
|
||||
char *call_agent_addr;
|
||||
|
||||
struct in_addr bts_in;
|
||||
char *audio_name;
|
||||
int audio_payload;
|
||||
int audio_loop;
|
||||
int early_bind;
|
||||
int rtp_base_port;
|
||||
int endp_dscp;
|
||||
|
||||
char *forward_ip;
|
||||
int forward_port;
|
||||
|
||||
/* spec handling */
|
||||
int force_realloc;
|
||||
|
||||
mgcp_change change_cb;
|
||||
mgcp_policy policy_cb;
|
||||
mgcp_reset reset_cb;
|
||||
void *data;
|
||||
|
||||
struct mgcp_endpoint *endpoints;
|
||||
unsigned int last_call_id;
|
||||
};
|
||||
|
||||
/* config management */
|
||||
struct mgcp_config *mgcp_config_alloc(void);
|
||||
int mgcp_parse_config(const char *config_file, struct mgcp_config *cfg);
|
||||
int mgcp_vty_init(void);
|
||||
int mgcp_endpoints_allocate(struct mgcp_config *cfg);
|
||||
int mgcp_bind_rtp_port(struct mgcp_endpoint *endp, int rtp_port);
|
||||
void mgcp_free_endp(struct mgcp_endpoint *endp);
|
||||
|
||||
/*
|
||||
* format helper functions
|
||||
*/
|
||||
struct msgb *mgcp_handle_message(struct mgcp_config *cfg, struct msgb *msg);
|
||||
struct msgb *mgcp_create_response_with_data(int code, const char *msg, const char *trans, const char *data);
|
||||
|
||||
/* adc helper */
|
||||
static inline int mgcp_timeslot_to_endpoint(int multiplex, int timeslot)
|
||||
{
|
||||
if (timeslot == 0)
|
||||
timeslot = 1;
|
||||
return timeslot + (31 * multiplex);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
104
openbsc/include/openbsc/mgcp_internal.h
Normal file
104
openbsc/include/openbsc/mgcp_internal.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* MGCP Private Data */
|
||||
|
||||
/*
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENBSC_MGCP_DATA_H
|
||||
#define OPENBSC_MGCP_DATA_H
|
||||
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#define CI_UNUSED 0
|
||||
|
||||
enum mgcp_connection_mode {
|
||||
MGCP_CONN_NONE = 0,
|
||||
MGCP_CONN_RECV_ONLY = 1,
|
||||
MGCP_CONN_SEND_ONLY = 2,
|
||||
MGCP_CONN_RECV_SEND = MGCP_CONN_RECV_ONLY | MGCP_CONN_SEND_ONLY,
|
||||
MGCP_CONN_LOOPBACK = 4,
|
||||
};
|
||||
|
||||
struct mgcp_rtp_state {
|
||||
int initialized;
|
||||
int patch;
|
||||
|
||||
uint32_t orig_ssrc;
|
||||
uint32_t ssrc;
|
||||
uint16_t seq_no;
|
||||
int lost_no;
|
||||
int seq_offset;
|
||||
uint32_t last_timestamp;
|
||||
int32_t timestamp_offset;
|
||||
};
|
||||
|
||||
struct mgcp_endpoint {
|
||||
int ci;
|
||||
char *callid;
|
||||
char *local_options;
|
||||
int conn_mode;
|
||||
int orig_mode;
|
||||
|
||||
int bts_payload_type;
|
||||
int net_payload_type;
|
||||
|
||||
/* the local rtp port we are binding to */
|
||||
int rtp_port;
|
||||
|
||||
/*
|
||||
* RTP mangling:
|
||||
* - we get RTP and RTCP to us and need to forward to the BTS
|
||||
* - we get RTP and RTCP from the BTS and forward to the network
|
||||
*/
|
||||
struct bsc_fd local_rtp;
|
||||
struct bsc_fd local_rtcp;
|
||||
|
||||
struct in_addr remote;
|
||||
struct in_addr bts;
|
||||
|
||||
/* in network byte order */
|
||||
int net_rtp, net_rtcp;
|
||||
int bts_rtp, bts_rtcp;
|
||||
|
||||
/* backpointer */
|
||||
struct mgcp_config *cfg;
|
||||
|
||||
/* statistics */
|
||||
unsigned int in_bts;
|
||||
unsigned int in_remote;
|
||||
|
||||
/* sequence bits */
|
||||
struct mgcp_rtp_state net_state;
|
||||
struct mgcp_rtp_state bts_state;
|
||||
};
|
||||
|
||||
#define ENDPOINT_NUMBER(endp) abs(endp - endp->cfg->endpoints)
|
||||
|
||||
struct mgcp_msg_ptr {
|
||||
unsigned int start;
|
||||
unsigned int length;
|
||||
};
|
||||
|
||||
int mgcp_analyze_header(struct mgcp_config *cfg, struct msgb *msg,
|
||||
struct mgcp_msg_ptr *ptr, int size,
|
||||
const char **transaction_id, struct mgcp_endpoint **endp);
|
||||
int mgcp_send_dummy(struct mgcp_endpoint *endp);
|
||||
|
||||
#endif
|
||||
@@ -25,7 +25,8 @@
|
||||
#ifndef _MNCC_H
|
||||
#define _MNCC_H
|
||||
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/mncc.h>
|
||||
|
||||
/* One end of a call */
|
||||
struct gsm_call {
|
||||
@@ -109,69 +110,6 @@ struct gsm_call {
|
||||
#define MNCC_F_KEYPAD 0x1000
|
||||
#define MNCC_F_SIGNAL 0x2000
|
||||
|
||||
/* Expanded fields from GSM TS 04.08, Table 10.5.102 */
|
||||
struct gsm_mncc_bearer_cap {
|
||||
int transfer; /* Information Transfer Capability */
|
||||
int mode; /* Transfer Mode */
|
||||
int coding; /* Coding Standard */
|
||||
int radio; /* Radio Channel Requirement */
|
||||
int speech_ctm; /* CTM text telephony indication */
|
||||
int speech_ver[8]; /* Speech version indication */
|
||||
};
|
||||
|
||||
struct gsm_mncc_number {
|
||||
int type;
|
||||
int plan;
|
||||
int present;
|
||||
int screen;
|
||||
char number[33];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cause {
|
||||
int location;
|
||||
int coding;
|
||||
int rec;
|
||||
int rec_val;
|
||||
int value;
|
||||
int diag_len;
|
||||
char diag[32];
|
||||
};
|
||||
|
||||
struct gsm_mncc_useruser {
|
||||
int proto;
|
||||
char info[GSM_MAX_USERUSER + 1]; /* + termination char */
|
||||
};
|
||||
|
||||
struct gsm_mncc_progress {
|
||||
int coding;
|
||||
int location;
|
||||
int descr;
|
||||
};
|
||||
|
||||
struct gsm_mncc_facility {
|
||||
int len;
|
||||
char info[GSM_MAX_FACILITY];
|
||||
};
|
||||
|
||||
struct gsm_mncc_ssversion {
|
||||
int len;
|
||||
char info[GSM_MAX_SSVERSION];
|
||||
};
|
||||
|
||||
struct gsm_mncc_cccap {
|
||||
int dtmf;
|
||||
int pcp;
|
||||
};
|
||||
|
||||
enum {
|
||||
GSM_MNCC_BCAP_SPEECH = 0,
|
||||
GSM_MNCC_BCAP_UNR_DIG = 1,
|
||||
GSM_MNCC_BCAP_AUDIO = 2,
|
||||
GSM_MNCC_BCAP_FAX_G3 = 3,
|
||||
GSM_MNCC_BCAP_OTHER_ITC = 5,
|
||||
GSM_MNCC_BCAP_RESERVED = 7,
|
||||
};
|
||||
|
||||
struct gsm_mncc {
|
||||
/* context based information */
|
||||
u_int32_t msg_type;
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
#ifndef _MSGB_H
|
||||
#define _MSGB_H
|
||||
|
||||
/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
struct bts_link;
|
||||
|
||||
struct msgb {
|
||||
struct llist_head list;
|
||||
|
||||
/* ptr to the physical E1 link to the BTS(s) */
|
||||
struct gsm_bts_link *bts_link;
|
||||
|
||||
/* Part of which TRX logical channel we were received / transmitted */
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
unsigned char *l2h;
|
||||
unsigned char *l3h;
|
||||
unsigned char *smsh;
|
||||
unsigned char *l4h;
|
||||
|
||||
u_int16_t data_len;
|
||||
u_int16_t len;
|
||||
|
||||
unsigned char *head;
|
||||
unsigned char *tail;
|
||||
unsigned char *data;
|
||||
unsigned char _data[0];
|
||||
};
|
||||
|
||||
extern struct msgb *msgb_alloc(u_int16_t size, const char *name);
|
||||
extern void msgb_free(struct msgb *m);
|
||||
extern void msgb_enqueue(struct llist_head *queue, struct msgb *msg);
|
||||
extern struct msgb *msgb_dequeue(struct llist_head *queue);
|
||||
extern void msgb_reset(struct msgb *m);
|
||||
|
||||
#define msgb_l2(m) ((void *)(m->l2h))
|
||||
#define msgb_l3(m) ((void *)(m->l3h))
|
||||
#define msgb_l4(m) ((void *)(m->l4h))
|
||||
#define msgb_sms(m) ((void *)(m->smsh))
|
||||
|
||||
static inline unsigned int msgb_l2len(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->tail - (u_int8_t *)msgb_l2(msgb);
|
||||
}
|
||||
|
||||
static inline unsigned int msgb_l3len(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->tail - (u_int8_t *)msgb_l3(msgb);
|
||||
}
|
||||
|
||||
static inline unsigned int msgb_headlen(const struct msgb *msgb)
|
||||
{
|
||||
return msgb->len - msgb->data_len;
|
||||
}
|
||||
static inline unsigned char *msgb_put(struct msgb *msgb, unsigned int len)
|
||||
{
|
||||
unsigned char *tmp = msgb->tail;
|
||||
msgb->tail += len;
|
||||
msgb->len += len;
|
||||
return tmp;
|
||||
}
|
||||
static inline unsigned char *msgb_push(struct msgb *msgb, unsigned int len)
|
||||
{
|
||||
msgb->data -= len;
|
||||
msgb->len += len;
|
||||
return msgb->data;
|
||||
}
|
||||
static inline unsigned char *msgb_pull(struct msgb *msgb, unsigned int len)
|
||||
{
|
||||
msgb->len -= len;
|
||||
return msgb->data += len;
|
||||
}
|
||||
static inline int msgb_tailroom(const struct msgb *msgb)
|
||||
{
|
||||
return (msgb->data + msgb->data_len) - msgb->tail;
|
||||
}
|
||||
|
||||
/* increase the headroom of an empty msgb, reducing the tailroom */
|
||||
static inline void msgb_reserve(struct msgb *msg, int len)
|
||||
{
|
||||
msg->data += len;
|
||||
msg->tail += len;
|
||||
}
|
||||
|
||||
static inline struct msgb *msgb_alloc_headroom(int size, int headroom,
|
||||
const char *name)
|
||||
{
|
||||
struct msgb *msg = msgb_alloc(size, name);
|
||||
if (msg)
|
||||
msgb_reserve(msg, headroom);
|
||||
return msg;
|
||||
}
|
||||
|
||||
#endif /* _MSGB_H */
|
||||
16
openbsc/include/openbsc/network_listen.h
Normal file
16
openbsc/include/openbsc/network_listen.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _OPENBSC_NWL_H
|
||||
#define _OPENBSC_NWL_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
void ipac_nwl_init(void);
|
||||
|
||||
/* Start a NWL test. It will raise the S_IPAC_TEST_COMPLETE signal. */
|
||||
int ipac_nwl_test_start(struct gsm_bts_trx *trx, uint8_t testnr,
|
||||
const uint8_t *phys_conf, unsigned int phys_conf_len);
|
||||
|
||||
int ipac_rxlevstat2whitelist(uint16_t *buf, const struct rxlev_stats *st, uint8_t min_rxlev,
|
||||
uint16_t max_num_arfcns);
|
||||
|
||||
#endif /* _OPENBSC_NWL_H */
|
||||
10
openbsc/include/openbsc/osmo_bsc.h
Normal file
10
openbsc/include/openbsc/osmo_bsc.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* OpenBSC BSC code */
|
||||
|
||||
#ifndef OSMO_BSC_H
|
||||
#define OSMO_BSC_H
|
||||
|
||||
#include "bsc_api.h"
|
||||
|
||||
struct bsc_api *osmo_bsc_api();
|
||||
|
||||
#endif
|
||||
20
openbsc/include/openbsc/osmo_bsc_rf.h
Normal file
20
openbsc/include/openbsc/osmo_bsc_rf.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef OSMO_BSC_RF
|
||||
#define OSMO_BSC_RF
|
||||
|
||||
#include <osmocore/write_queue.h>
|
||||
|
||||
struct gsm_network;
|
||||
|
||||
struct osmo_bsc_rf {
|
||||
struct bsc_fd listen;
|
||||
struct gsm_network *gsm_network;
|
||||
};
|
||||
|
||||
struct osmo_bsc_rf_conn {
|
||||
struct write_queue queue;
|
||||
struct gsm_network *gsm_network;
|
||||
};
|
||||
|
||||
struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net);
|
||||
|
||||
#endif
|
||||
11
openbsc/include/openbsc/osmo_msc.h
Normal file
11
openbsc/include/openbsc/osmo_msc.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* Routines for the MSC handling */
|
||||
|
||||
#ifndef OSMO_MSC_H
|
||||
#define OSMO_MSC_H
|
||||
|
||||
#include "bsc_api.h"
|
||||
|
||||
struct bsc_api *msc_bsc_api();
|
||||
void msc_release_connection(struct gsm_subscriber_connection *conn);
|
||||
|
||||
#endif
|
||||
@@ -24,10 +24,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "linuxlist.h"
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include "gsm_data.h"
|
||||
#include "gsm_subscriber.h"
|
||||
#include "timer.h"
|
||||
#include <osmocore/timer.h>
|
||||
|
||||
/* call once for every gsm_bts... */
|
||||
void paging_init(struct gsm_bts *bts);
|
||||
@@ -38,7 +38,7 @@ int paging_request(struct gsm_network *network, struct gsm_subscriber *subscr,
|
||||
|
||||
/* stop paging requests */
|
||||
void paging_request_stop(struct gsm_bts *bts, struct gsm_subscriber *subscr,
|
||||
struct gsm_lchan *lchan);
|
||||
struct gsm_subscriber_connection *conn);
|
||||
|
||||
/* update paging load */
|
||||
void paging_update_buffer_space(struct gsm_bts *bts, u_int16_t);
|
||||
|
||||
@@ -71,6 +71,7 @@ enum gprs_nmo {
|
||||
GPRS_NMO_III = 2, /* no paging coordination */
|
||||
};
|
||||
|
||||
/* TS 04.60 12.24 */
|
||||
struct gprs_cell_options {
|
||||
enum gprs_nmo nmo;
|
||||
/* T3168: wait for packet uplink assignment message */
|
||||
@@ -79,6 +80,16 @@ struct gprs_cell_options {
|
||||
u_int32_t t3192; /* in milliseconds */
|
||||
u_int32_t drx_timer_max;/* in seconds */
|
||||
u_int32_t bs_cv_max;
|
||||
|
||||
u_int8_t ext_info_present;
|
||||
struct {
|
||||
u_int8_t egprs_supported;
|
||||
u_int8_t use_egprs_p_ch_req;
|
||||
u_int8_t bep_period;
|
||||
u_int8_t pfc_supported;
|
||||
u_int8_t dtm_supported;
|
||||
u_int8_t bss_paging_coordination;
|
||||
} ext_info;
|
||||
};
|
||||
|
||||
/* TS 04.60 Table 12.9.2 */
|
||||
|
||||
@@ -25,8 +25,14 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#define RTP_PT_GSM_FULL 3
|
||||
#define RTP_PT_GSM_HALF 96
|
||||
#define RTP_PT_GSM_EFR 97
|
||||
#define RTP_PT_AMR_FULL 98
|
||||
#define RTP_PT_AMR_HALF 99
|
||||
|
||||
enum rtp_rx_action {
|
||||
RTP_NONE,
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#ifndef _BSC_SELECT_H
|
||||
#define _BSC_SELECT_H
|
||||
|
||||
#include <openbsc/linuxlist.h>
|
||||
|
||||
#define BSC_FD_READ 0x0001
|
||||
#define BSC_FD_WRITE 0x0002
|
||||
#define BSC_FD_EXCEPT 0x0004
|
||||
|
||||
struct bsc_fd {
|
||||
struct llist_head list;
|
||||
int fd;
|
||||
unsigned int when;
|
||||
int (*cb)(struct bsc_fd *fd, unsigned int what);
|
||||
void *data;
|
||||
unsigned int priv_nr;
|
||||
};
|
||||
|
||||
int bsc_register_fd(struct bsc_fd *fd);
|
||||
void bsc_unregister_fd(struct bsc_fd *fd);
|
||||
int bsc_select_main(int polling);
|
||||
#endif /* _BSC_SELECT_H */
|
||||
65
openbsc/include/openbsc/sgsn.h
Normal file
65
openbsc/include/openbsc/sgsn.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef _SGSN_H
|
||||
#define _SGSN_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
#include <openbsc/gprs_ns.h>
|
||||
#include <openbsc/gprs_sgsn.h>
|
||||
|
||||
struct sgsn_config {
|
||||
/* parsed from config file */
|
||||
|
||||
char *gtp_statedir;
|
||||
struct sockaddr_in gtp_listenaddr;
|
||||
|
||||
/* misc */
|
||||
struct gprs_ns_inst *nsi;
|
||||
};
|
||||
|
||||
struct sgsn_instance {
|
||||
char *config_file;
|
||||
struct sgsn_config cfg;
|
||||
/* File descriptor wrappers for LibGTP */
|
||||
struct bsc_fd gtp_fd0;
|
||||
struct bsc_fd gtp_fd1c;
|
||||
struct bsc_fd gtp_fd1u;
|
||||
/* Timer for libGTP */
|
||||
struct timer_list gtp_timer;
|
||||
/* GSN instance for libgtp */
|
||||
struct gsn_t *gsn;
|
||||
};
|
||||
|
||||
extern struct sgsn_instance *sgsn;
|
||||
|
||||
/* sgsn_vty.c */
|
||||
|
||||
int sgsn_vty_init(void);
|
||||
int sgsn_parse_config(const char *config_file, struct sgsn_config *cfg);
|
||||
|
||||
/* sgsn.c */
|
||||
|
||||
/* Main input function for Gb proxy */
|
||||
int sgsn_rcvmsg(struct msgb *msg, struct gprs_nsvc *nsvc, uint16_t ns_bvci);
|
||||
|
||||
|
||||
struct sgsn_pdp_ctx *sgsn_create_pdp_ctx(struct sgsn_ggsn_ctx *ggsn,
|
||||
struct sgsn_mm_ctx *mmctx,
|
||||
uint16_t nsapi,
|
||||
struct tlv_parsed *tp);
|
||||
int sgsn_delete_pdp_ctx(struct sgsn_pdp_ctx *pctx);
|
||||
|
||||
/* gprs_sndcp.c */
|
||||
|
||||
/* Entry point for the SNSM-ACTIVATE.indication */
|
||||
int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi);
|
||||
/* Entry point for the SNSM-DEACTIVATE.indication */
|
||||
int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi);
|
||||
/* Called by SNDCP when it has received/re-assembled a N-PDU */
|
||||
int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi,
|
||||
struct msgb *msg, uint32_t npdu_len, uint8_t *npdu);
|
||||
int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi,
|
||||
void *mmcontext);
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Generic signalling/notification infrastructure */
|
||||
/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -26,8 +26,8 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
|
||||
#include <osmocore/signal.h>
|
||||
|
||||
/*
|
||||
* Signalling subsystems
|
||||
@@ -41,11 +41,16 @@ enum signal_subsystems {
|
||||
SS_SUBSCR,
|
||||
SS_SCALL,
|
||||
SS_GLOBAL,
|
||||
SS_CHALLOC,
|
||||
SS_NS,
|
||||
SS_IPAC_NWL,
|
||||
SS_RF,
|
||||
};
|
||||
|
||||
/* SS_PAGING signals */
|
||||
enum signal_paging {
|
||||
S_PAGING_COMPLETED,
|
||||
S_PAGING_SUCCEEDED,
|
||||
S_PAGING_EXPIRED,
|
||||
};
|
||||
|
||||
/* SS_SMS signals */
|
||||
@@ -69,6 +74,9 @@ enum signal_nm {
|
||||
S_NM_FAIL_REP, /* GSM 12.21 failure event report */
|
||||
S_NM_NACK, /* GSM 12.21 various NM_MT_*_NACK happened */
|
||||
S_NM_IPACC_NACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_NACK happened */
|
||||
S_NM_IPACC_ACK, /* GSM 12.21 nanoBTS extensions NM_MT_IPACC_*_*_ACK happened */
|
||||
S_NM_IPACC_RESTART_ACK, /* nanoBTS has send a restart ack */
|
||||
S_NM_IPACC_RESTART_NACK,/* nanoBTS has send a restart ack */
|
||||
S_NM_TEST_REP, /* GSM 12.21 Test Report */
|
||||
};
|
||||
|
||||
@@ -88,6 +96,12 @@ enum signal_lchan {
|
||||
S_LCHAN_MEAS_REP, /* 08.58 Measurement Report */
|
||||
};
|
||||
|
||||
/* SS_CHALLOC signals */
|
||||
enum signal_challoc {
|
||||
S_CHALLOC_ALLOC_FAIL, /* allocation of lchan has failed */
|
||||
S_CHALLOC_FREED, /* lchan has been successfully freed */
|
||||
};
|
||||
|
||||
/* SS_SUBSCR signals */
|
||||
enum signal_subscr {
|
||||
S_SUBSCR_ATTACHED,
|
||||
@@ -102,33 +116,68 @@ enum signal_scall {
|
||||
S_SCALL_DETACHED,
|
||||
};
|
||||
|
||||
/* SS_IPAC_NWL signals */
|
||||
enum signal_ipaccess {
|
||||
S_IPAC_NWL_COMPLETE,
|
||||
};
|
||||
|
||||
enum signal_global {
|
||||
S_GLOBAL_SHUTDOWN,
|
||||
};
|
||||
|
||||
typedef int signal_cbfn(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data);
|
||||
/* SS_RF signals */
|
||||
enum signal_rf {
|
||||
S_RF_OFF,
|
||||
S_RF_ON,
|
||||
S_RF_GRACE,
|
||||
};
|
||||
|
||||
struct gsm_subscriber;
|
||||
|
||||
struct paging_signal_data {
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_bts *bts;
|
||||
|
||||
/* NULL in case the paging didn't work */
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_subscriber_connection *conn;
|
||||
};
|
||||
|
||||
struct scall_signal_data {
|
||||
struct gsm_subscriber *subscr;
|
||||
struct gsm_lchan *lchan;
|
||||
struct gsm_subscriber_connection *conn;
|
||||
void *data;
|
||||
};
|
||||
|
||||
/* Management */
|
||||
int register_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
void unregister_signal_handler(unsigned int subsys, signal_cbfn *cbfn, void *data);
|
||||
struct ipacc_ack_signal_data {
|
||||
struct gsm_bts_trx *trx;
|
||||
u_int8_t msg_type;
|
||||
};
|
||||
|
||||
/* Dispatch */
|
||||
void dispatch_signal(unsigned int subsys, unsigned int signal, void *signal_data);
|
||||
struct nm_nack_signal_data {
|
||||
struct msgb *msg;
|
||||
uint8_t mt;
|
||||
};
|
||||
|
||||
struct challoc_signal_data {
|
||||
struct gsm_bts *bts;
|
||||
struct gsm_lchan *lchan;
|
||||
enum gsm_chan_t type;
|
||||
};
|
||||
|
||||
struct rf_signal_data {
|
||||
struct gsm_network *net;
|
||||
};
|
||||
|
||||
enum signal_ns {
|
||||
S_NS_RESET,
|
||||
S_NS_BLOCK,
|
||||
S_NS_UNBLOCK,
|
||||
S_NS_ALIVE_EXP, /* Tns-alive expired more than N times */
|
||||
};
|
||||
|
||||
struct ns_signal_data {
|
||||
struct gprs_nsvc *nsvc;
|
||||
uint8_t cause;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
#ifndef _SILENT_CALL_H
|
||||
#define _SILENT_CALL_H
|
||||
|
||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr, void *data);
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
extern int gsm_silent_call_start(struct gsm_subscriber *subscr,
|
||||
void *data, int type);
|
||||
extern int gsm_silent_call_stop(struct gsm_subscriber *subscr);
|
||||
extern int silent_call_rx(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
extern int silent_call_reroute(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
#endif /* _SILENT_CALL_H */
|
||||
|
||||
14
openbsc/include/openbsc/socket.h
Normal file
14
openbsc/include/openbsc/socket.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef _BSC_SOCKET_H
|
||||
#define _BSC_SOCKET_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <osmocore/select.h>
|
||||
|
||||
#ifndef IPPROTO_GRE
|
||||
#define IPPROTO_GRE 47
|
||||
#endif
|
||||
|
||||
int make_sock(struct bsc_fd *bfd, int proto, u_int32_t ip, u_int16_t port,
|
||||
int (*cb)(struct bsc_fd *fd, unsigned int what));
|
||||
|
||||
#endif /* _BSC_SOCKET_H */
|
||||
@@ -22,7 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
|
||||
#define NR_SUBCH 4
|
||||
#define TRAU_FRAME_SIZE 40
|
||||
|
||||
@@ -1,6 +1,42 @@
|
||||
#ifndef _SYSTEM_INFO_H
|
||||
#define _SYSTEM_INFO_H
|
||||
|
||||
int gsm_generate_si(u_int8_t *output, struct gsm_bts *bts, int type);
|
||||
#include <osmocore/utils.h>
|
||||
|
||||
#define GSM_MACBLOCK_LEN 23
|
||||
|
||||
enum osmo_sysinfo_type {
|
||||
SYSINFO_TYPE_NONE,
|
||||
SYSINFO_TYPE_1,
|
||||
SYSINFO_TYPE_2,
|
||||
SYSINFO_TYPE_3,
|
||||
SYSINFO_TYPE_4,
|
||||
SYSINFO_TYPE_5,
|
||||
SYSINFO_TYPE_6,
|
||||
SYSINFO_TYPE_7,
|
||||
SYSINFO_TYPE_8,
|
||||
SYSINFO_TYPE_9,
|
||||
SYSINFO_TYPE_10,
|
||||
SYSINFO_TYPE_13,
|
||||
SYSINFO_TYPE_16,
|
||||
SYSINFO_TYPE_17,
|
||||
SYSINFO_TYPE_18,
|
||||
SYSINFO_TYPE_19,
|
||||
SYSINFO_TYPE_20,
|
||||
SYSINFO_TYPE_2bis,
|
||||
SYSINFO_TYPE_2ter,
|
||||
SYSINFO_TYPE_2quater,
|
||||
SYSINFO_TYPE_5bis,
|
||||
SYSINFO_TYPE_5ter,
|
||||
/* FIXME all the various bis and ter */
|
||||
_MAX_SYSINFO_TYPE
|
||||
};
|
||||
|
||||
typedef u_int8_t sysinfo_buf_t[GSM_MACBLOCK_LEN];
|
||||
|
||||
const struct value_string osmo_sitype_strs[_MAX_SYSINFO_TYPE];
|
||||
uint8_t gsm_sitype2rsl(enum osmo_sysinfo_type si_type);
|
||||
const char *gsm_sitype_name(enum osmo_sysinfo_type si_type);
|
||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
#ifndef _TALLOC_H_
|
||||
#define _TALLOC_H_
|
||||
/*
|
||||
Unix SMB/CIFS implementation.
|
||||
Samba temporary memory allocation functions
|
||||
|
||||
Copyright (C) Andrew Tridgell 2004-2005
|
||||
Copyright (C) Stefan Metzmacher 2006
|
||||
|
||||
** NOTE! The following LGPL license applies to the talloc
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
** under the LGPL
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define HAVE_VA_COPY
|
||||
|
||||
/* this is only needed for compatibility with the old talloc */
|
||||
typedef void TALLOC_CTX;
|
||||
|
||||
/*
|
||||
this uses a little trick to allow __LINE__ to be stringified
|
||||
*/
|
||||
#ifndef __location__
|
||||
#define __TALLOC_STRING_LINE1__(s) #s
|
||||
#define __TALLOC_STRING_LINE2__(s) __TALLOC_STRING_LINE1__(s)
|
||||
#define __TALLOC_STRING_LINE3__ __TALLOC_STRING_LINE2__(__LINE__)
|
||||
#define __location__ __FILE__ ":" __TALLOC_STRING_LINE3__
|
||||
#endif
|
||||
|
||||
#ifndef TALLOC_DEPRECATED
|
||||
#define TALLOC_DEPRECATED 0
|
||||
#endif
|
||||
|
||||
#ifndef PRINTF_ATTRIBUTE
|
||||
#if (__GNUC__ >= 3)
|
||||
/** Use gcc attribute to check printf fns. a1 is the 1-based index of
|
||||
* the parameter containing the format, and a2 the index of the first
|
||||
* argument. Note that some gcc 2.x versions don't handle this
|
||||
* properly **/
|
||||
#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
|
||||
#else
|
||||
#define PRINTF_ATTRIBUTE(a1, a2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* try to make talloc_set_destructor() and talloc_steal() type safe,
|
||||
if we have a recent gcc */
|
||||
#if (__GNUC__ >= 3)
|
||||
#define _TALLOC_TYPEOF(ptr) __typeof__(ptr)
|
||||
#define talloc_set_destructor(ptr, function) \
|
||||
do { \
|
||||
int (*_talloc_destructor_fn)(_TALLOC_TYPEOF(ptr)) = (function); \
|
||||
_talloc_set_destructor((ptr), (int (*)(void *))_talloc_destructor_fn); \
|
||||
} while(0)
|
||||
/* this extremely strange macro is to avoid some braindamaged warning
|
||||
stupidity in gcc 4.1.x */
|
||||
#define talloc_steal(ctx, ptr) ({ _TALLOC_TYPEOF(ptr) __talloc_steal_ret = (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr)); __talloc_steal_ret; })
|
||||
#else
|
||||
#define talloc_set_destructor(ptr, function) \
|
||||
_talloc_set_destructor((ptr), (int (*)(void *))(function))
|
||||
#define _TALLOC_TYPEOF(ptr) void *
|
||||
#define talloc_steal(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_steal((ctx),(ptr))
|
||||
#endif
|
||||
|
||||
#define talloc_reference(ctx, ptr) (_TALLOC_TYPEOF(ptr))_talloc_reference((ctx),(ptr))
|
||||
#define talloc_move(ctx, ptr) (_TALLOC_TYPEOF(*(ptr)))_talloc_move((ctx),(void *)(ptr))
|
||||
|
||||
/* useful macros for creating type checked pointers */
|
||||
#define talloc(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
|
||||
#define talloc_size(ctx, size) talloc_named_const(ctx, size, __location__)
|
||||
#define talloc_ptrtype(ctx, ptr) (_TALLOC_TYPEOF(ptr))talloc_size(ctx, sizeof(*(ptr)))
|
||||
|
||||
#define talloc_new(ctx) talloc_named_const(ctx, 0, "talloc_new: " __location__)
|
||||
|
||||
#define talloc_zero(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
|
||||
#define talloc_zero_size(ctx, size) _talloc_zero(ctx, size, __location__)
|
||||
|
||||
#define talloc_zero_array(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
|
||||
#define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
|
||||
#define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__)
|
||||
#define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count)
|
||||
#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx))
|
||||
|
||||
#define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type)
|
||||
#define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__)
|
||||
|
||||
#define talloc_memdup(t, p, size) _talloc_memdup(t, p, size, __location__)
|
||||
|
||||
#define talloc_set_type(ptr, type) talloc_set_name_const(ptr, #type)
|
||||
#define talloc_get_type(ptr, type) (type *)talloc_check_name(ptr, #type)
|
||||
#define talloc_get_type_abort(ptr, type) (type *)_talloc_get_type_abort(ptr, #type, __location__)
|
||||
|
||||
#define talloc_find_parent_bytype(ptr, type) (type *)talloc_find_parent_byname(ptr, #type)
|
||||
|
||||
#if TALLOC_DEPRECATED
|
||||
#define talloc_zero_p(ctx, type) talloc_zero(ctx, type)
|
||||
#define talloc_p(ctx, type) talloc(ctx, type)
|
||||
#define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count)
|
||||
#define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count)
|
||||
#define talloc_destroy(ctx) talloc_free(ctx)
|
||||
#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a))
|
||||
#endif
|
||||
|
||||
#define TALLOC_FREE(ctx) do { talloc_free(ctx); ctx=NULL; } while(0)
|
||||
|
||||
/* The following definitions come from talloc.c */
|
||||
void *_talloc(const void *context, size_t size);
|
||||
void *talloc_pool(const void *context, size_t size);
|
||||
void _talloc_set_destructor(const void *ptr, int (*_destructor)(void *));
|
||||
int talloc_increase_ref_count(const void *ptr);
|
||||
size_t talloc_reference_count(const void *ptr);
|
||||
void *_talloc_reference(const void *context, const void *ptr);
|
||||
int talloc_unlink(const void *context, void *ptr);
|
||||
const char *talloc_set_name(const void *ptr, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
void talloc_set_name_const(const void *ptr, const char *name);
|
||||
void *talloc_named(const void *context, size_t size,
|
||||
const char *fmt, ...) PRINTF_ATTRIBUTE(3,4);
|
||||
void *talloc_named_const(const void *context, size_t size, const char *name);
|
||||
const char *talloc_get_name(const void *ptr);
|
||||
void *talloc_check_name(const void *ptr, const char *name);
|
||||
void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location);
|
||||
void *talloc_parent(const void *ptr);
|
||||
const char *talloc_parent_name(const void *ptr);
|
||||
void *talloc_init(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
|
||||
int talloc_free(void *ptr);
|
||||
void talloc_free_children(void *ptr);
|
||||
void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name);
|
||||
void *_talloc_steal(const void *new_ctx, const void *ptr);
|
||||
void *_talloc_move(const void *new_ctx, const void *pptr);
|
||||
size_t talloc_total_size(const void *ptr);
|
||||
size_t talloc_total_blocks(const void *ptr);
|
||||
void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
|
||||
void (*callback)(const void *ptr,
|
||||
int depth, int max_depth,
|
||||
int is_ref,
|
||||
void *private_data),
|
||||
void *private_data);
|
||||
void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f);
|
||||
void talloc_report_full(const void *ptr, FILE *f);
|
||||
void talloc_report(const void *ptr, FILE *f);
|
||||
void talloc_enable_null_tracking(void);
|
||||
void talloc_disable_null_tracking(void);
|
||||
void talloc_enable_leak_report(void);
|
||||
void talloc_enable_leak_report_full(void);
|
||||
void *_talloc_zero(const void *ctx, size_t size, const char *name);
|
||||
void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name);
|
||||
void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name);
|
||||
void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name);
|
||||
void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name);
|
||||
void *talloc_realloc_fn(const void *context, void *ptr, size_t size);
|
||||
void *talloc_autofree_context(void);
|
||||
size_t talloc_get_size(const void *ctx);
|
||||
void *talloc_find_parent_byname(const void *ctx, const char *name);
|
||||
void talloc_show_parents(const void *context, FILE *file);
|
||||
int talloc_is_parent(const void *context, const void *ptr);
|
||||
|
||||
char *talloc_strdup(const void *t, const char *p);
|
||||
char *talloc_strdup_append(char *s, const char *a);
|
||||
char *talloc_strdup_append_buffer(char *s, const char *a);
|
||||
|
||||
char *talloc_strndup(const void *t, const char *p, size_t n);
|
||||
char *talloc_strndup_append(char *s, const char *a, size_t n);
|
||||
char *talloc_strndup_append_buffer(char *s, const char *a, size_t n);
|
||||
|
||||
char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
|
||||
char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
|
||||
char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
|
||||
|
||||
char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3);
|
||||
|
||||
void talloc_set_abort_fn(void (*abort_fn)(const char *reason));
|
||||
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* (C) 2008, 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H
|
||||
#define TIMER_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "linuxlist.h"
|
||||
|
||||
/**
|
||||
* Timer management:
|
||||
* - Create a struct timer_list
|
||||
* - Fill out timeout and use add_timer or
|
||||
* use schedule_timer to schedule a timer in
|
||||
* x seconds and microseconds from now...
|
||||
* - Use del_timer to remove the timer
|
||||
*
|
||||
* Internally:
|
||||
* - We hook into select.c to give a timeval of the
|
||||
* nearest timer. On already passed timers we give
|
||||
* it a 0 to immediately fire after the select
|
||||
* - update_timers will call the callbacks and remove
|
||||
* the timers.
|
||||
*
|
||||
*/
|
||||
struct timer_list {
|
||||
struct llist_head entry;
|
||||
struct timeval timeout;
|
||||
unsigned int active : 1;
|
||||
unsigned int handled : 1;
|
||||
unsigned int in_list : 1;
|
||||
|
||||
void (*cb)(void*);
|
||||
void *data;
|
||||
};
|
||||
|
||||
/**
|
||||
* timer management
|
||||
*/
|
||||
void bsc_add_timer(struct timer_list *timer);
|
||||
void bsc_schedule_timer(struct timer_list *timer, int seconds, int microseconds);
|
||||
void bsc_del_timer(struct timer_list *timer);
|
||||
int bsc_timer_pending(struct timer_list *timer);
|
||||
|
||||
|
||||
/**
|
||||
* internal timer list management
|
||||
*/
|
||||
struct timeval *bsc_nearest_timer();
|
||||
void bsc_prepare_timers();
|
||||
int bsc_update_timers();
|
||||
int bsc_timer_check(void);
|
||||
|
||||
#endif
|
||||
@@ -1,221 +0,0 @@
|
||||
#ifndef _TLV_H
|
||||
#define _TLV_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
/* Terminology / wording
|
||||
tag length value (in bits)
|
||||
|
||||
V - - 8
|
||||
LV - 8 N * 8
|
||||
TLV 8 8 N * 8
|
||||
TL16V 8 16 N * 8
|
||||
TLV16 8 8 N * 16
|
||||
TvLV 8 8/16 N * 8
|
||||
|
||||
*/
|
||||
|
||||
#define LV_GROSS_LEN(x) (x+1)
|
||||
#define TLV_GROSS_LEN(x) (x+2)
|
||||
#define TLV16_GROSS_LEN(x) ((2*x)+2)
|
||||
#define TL16V_GROSS_LEN(x) (x+3)
|
||||
|
||||
#define TVLV_MAX_ONEBYTE 0x7f
|
||||
|
||||
static inline u_int16_t TVLV_GROSS_LEN(u_int16_t len)
|
||||
{
|
||||
if (len <= TVLV_MAX_ONEBYTE)
|
||||
return TLV_GROSS_LEN(len);
|
||||
else
|
||||
return TL16V_GROSS_LEN(len);
|
||||
}
|
||||
|
||||
/* TLV generation */
|
||||
|
||||
static inline u_int8_t *lv_put(u_int8_t *buf, u_int8_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tlv_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tlv16_put(u_int8_t *buf, u_int8_t tag, u_int8_t len,
|
||||
const u_int16_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len;
|
||||
memcpy(buf, val, len*2);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tl16v_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = len >> 8;
|
||||
*buf++ = len & 0xff;
|
||||
memcpy(buf, val, len);
|
||||
return buf + len*2;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tvlv_put(u_int8_t *buf, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *ret;
|
||||
|
||||
if (len <= TVLV_MAX_ONEBYTE) {
|
||||
ret = tlv_put(buf, tag, len, val);
|
||||
buf[1] |= 0x80;
|
||||
} else
|
||||
ret = tl16v_put(buf, tag, len, val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv16_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int16_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TLV16_GROSS_LEN(len));
|
||||
return tlv16_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tl16v_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TL16V_GROSS_LEN(len));
|
||||
return tl16v_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tvlv_put(struct msgb *msg, u_int8_t tag, u_int16_t len,
|
||||
const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TVLV_GROSS_LEN(len));
|
||||
return tvlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *v_put(u_int8_t *buf, u_int8_t val)
|
||||
{
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *tv_put(u_int8_t *buf, u_int8_t tag,
|
||||
u_int8_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val;
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* 'val' is still in host byte order! */
|
||||
static inline u_int8_t *tv16_put(u_int8_t *buf, u_int8_t tag,
|
||||
u_int16_t val)
|
||||
{
|
||||
*buf++ = tag;
|
||||
*buf++ = val >> 8;
|
||||
*buf++ = val & 0xff;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_lv_put(struct msgb *msg, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, LV_GROSS_LEN(len));
|
||||
return lv_put(buf, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_put(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv_put(struct msgb *msg, u_int8_t tag, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_v_put(struct msgb *msg, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 1);
|
||||
return v_put(buf, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_put(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_put(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tlv_push(struct msgb *msg, u_int8_t tag, u_int8_t len, const u_int8_t *val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, TLV_GROSS_LEN(len));
|
||||
return tlv_put(buf, tag, len, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv_push(struct msgb *msg, u_int8_t tag, u_int8_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, 2);
|
||||
return tv_put(buf, tag, val);
|
||||
}
|
||||
|
||||
static inline u_int8_t *msgb_tv16_push(struct msgb *msg, u_int8_t tag, u_int16_t val)
|
||||
{
|
||||
u_int8_t *buf = msgb_push(msg, 3);
|
||||
return tv16_put(buf, tag, val);
|
||||
}
|
||||
|
||||
/* TLV parsing */
|
||||
|
||||
struct tlv_p_entry {
|
||||
u_int16_t len;
|
||||
const u_int8_t *val;
|
||||
};
|
||||
|
||||
enum tlv_type {
|
||||
TLV_TYPE_FIXED,
|
||||
TLV_TYPE_T,
|
||||
TLV_TYPE_TV,
|
||||
TLV_TYPE_TLV,
|
||||
TLV_TYPE_TL16V,
|
||||
TLV_TYPE_TvLV,
|
||||
};
|
||||
|
||||
struct tlv_def {
|
||||
enum tlv_type type;
|
||||
u_int8_t fixed_len;
|
||||
};
|
||||
|
||||
struct tlv_definition {
|
||||
struct tlv_def def[0xff];
|
||||
};
|
||||
|
||||
struct tlv_parsed {
|
||||
struct tlv_p_entry lv[0xff];
|
||||
};
|
||||
|
||||
extern struct tlv_definition tvlv_att_def;
|
||||
|
||||
int tlv_parse_one(u_int8_t *o_tag, u_int16_t *o_len, const u_int8_t **o_val,
|
||||
const struct tlv_definition *def,
|
||||
const u_int8_t *buf, int buf_len);
|
||||
int tlv_parse(struct tlv_parsed *dec, const struct tlv_definition *def,
|
||||
const u_int8_t *buf, int buf_len, u_int8_t lv_tag, u_int8_t lv_tag2);
|
||||
|
||||
#define TLVP_PRESENT(x, y) ((x)->lv[y].val)
|
||||
#define TLVP_LEN(x, y) (x)->lv[y].len
|
||||
#define TLVP_VAL(x, y) (x)->lv[y].val
|
||||
|
||||
#endif /* _TLV_H */
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_subscriber.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/gsm_04_11.h>
|
||||
|
||||
/* One transaction */
|
||||
@@ -20,8 +20,8 @@ struct gsm_trans {
|
||||
/* To whom we belong, unique identifier of remote MM entity */
|
||||
struct gsm_subscriber *subscr;
|
||||
|
||||
/* The LCHAN that we're currently using to transmit messages */
|
||||
struct gsm_lchan *lchan;
|
||||
/* The associated connection we are using to transmit messages */
|
||||
struct gsm_subscriber_connection *conn;
|
||||
|
||||
/* reference from MNCC or other application */
|
||||
u_int32_t callref;
|
||||
@@ -69,8 +69,4 @@ void trans_free(struct gsm_trans *trans);
|
||||
int trans_assign_trans_id(struct gsm_subscriber *subscr,
|
||||
u_int8_t protocol, u_int8_t ti_flag);
|
||||
|
||||
/* update all transactions to use a different LCHAN, e.g.
|
||||
* after handover has succeeded */
|
||||
int trans_lchan_change(struct gsm_lchan *lchan_old,
|
||||
struct gsm_lchan *lchan_new);
|
||||
#endif
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
/* Handler function for mobile-originated USSD messages */
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
#include <osmocore/msgb.h>
|
||||
|
||||
int handle_rcv_ussd(struct msgb *msg);
|
||||
int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
#endif
|
||||
|
||||
37
openbsc/include/openbsc/vty.h
Normal file
37
openbsc/include/openbsc/vty.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef OPENBSC_VTY_H
|
||||
#define OPENBSC_VTY_H
|
||||
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/buffer.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
struct gsm_network;
|
||||
struct vty;
|
||||
|
||||
void logging_vty_add_cmds(void);
|
||||
void openbsc_vty_print_statistics(struct vty *vty, struct gsm_network *);
|
||||
|
||||
struct buffer *vty_argv_to_buffer(int argc, const char *argv[], int base);
|
||||
|
||||
extern struct cmd_element cfg_description_cmd;
|
||||
extern struct cmd_element cfg_no_description_cmd;
|
||||
extern struct cmd_element ournode_exit_cmd;
|
||||
extern struct cmd_element ournode_end_cmd;
|
||||
|
||||
enum bsc_vty_node {
|
||||
GSMNET_NODE = _LAST_OSMOVTY_NODE + 1,
|
||||
BTS_NODE,
|
||||
TRX_NODE,
|
||||
TS_NODE,
|
||||
SUBSCR_NODE,
|
||||
MGCP_NODE,
|
||||
GBPROXY_NODE,
|
||||
SGSN_NODE,
|
||||
NS_NODE,
|
||||
BSSGP_NODE,
|
||||
OML_NODE,
|
||||
NAT_NODE,
|
||||
NAT_BSC_NODE,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1 +0,0 @@
|
||||
noinst_HEADERS = sccp_types.h sccp.h
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* SCCP management code
|
||||
*
|
||||
* (C) 2009, 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCCP_H
|
||||
#define SCCP_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <openbsc/msgb.h>
|
||||
|
||||
#include "sccp_types.h"
|
||||
|
||||
struct sccp_system;
|
||||
|
||||
enum {
|
||||
SCCP_CONNECTION_STATE_NONE,
|
||||
SCCP_CONNECTION_STATE_REQUEST,
|
||||
SCCP_CONNECTION_STATE_CONFIRM,
|
||||
SCCP_CONNECTION_STATE_ESTABLISHED,
|
||||
SCCP_CONNECTION_STATE_RELEASE,
|
||||
SCCP_CONNECTION_STATE_RELEASE_COMPLETE,
|
||||
SCCP_CONNECTION_STATE_REFUSED,
|
||||
SCCP_CONNECTION_STATE_SETUP_ERROR,
|
||||
};
|
||||
|
||||
struct sockaddr_sccp {
|
||||
sa_family_t sccp_family; /* AF_SCCP in the future??? */
|
||||
u_int8_t sccp_ssn; /* subssystem number for routing */
|
||||
|
||||
/* TODO fill in address indicator... if that is ever needed */
|
||||
|
||||
/* not sure about these */
|
||||
/* u_int8_t sccp_class; */
|
||||
};
|
||||
|
||||
/*
|
||||
* parsed structure of an address
|
||||
*/
|
||||
struct sccp_address {
|
||||
struct sccp_called_party_address address;
|
||||
u_int8_t ssn;
|
||||
u_int8_t poi[2];
|
||||
};
|
||||
|
||||
struct sccp_optional_data {
|
||||
u_int8_t data_len;
|
||||
u_int8_t data_start;
|
||||
};
|
||||
|
||||
struct sccp_connection {
|
||||
/* public */
|
||||
void *data_ctx;
|
||||
void (*data_cb)(struct sccp_connection *conn, struct msgb *msg, unsigned int len);
|
||||
|
||||
void *state_ctx;
|
||||
void (*state_cb)(struct sccp_connection *, int old_state);
|
||||
|
||||
struct sccp_source_reference source_local_reference;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
|
||||
int connection_state;
|
||||
|
||||
/* private */
|
||||
/* list of active connections */
|
||||
struct llist_head list;
|
||||
struct sccp_system *system;
|
||||
int incoming;
|
||||
};
|
||||
|
||||
/**
|
||||
* system functionality to implement on top of any other transport layer:
|
||||
* call sccp_system_incoming for incoming data (from the network)
|
||||
* sccp will call outgoing whenever outgoing data exists
|
||||
*/
|
||||
int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *context);
|
||||
int sccp_system_incoming(struct msgb *data);
|
||||
|
||||
/**
|
||||
* Send data on an existing connection
|
||||
*/
|
||||
int sccp_connection_write(struct sccp_connection *connection, struct msgb *data);
|
||||
int sccp_connection_send_it(struct sccp_connection *connection);
|
||||
int sccp_connection_close(struct sccp_connection *connection, int cause);
|
||||
int sccp_connection_free(struct sccp_connection *connection);
|
||||
|
||||
/**
|
||||
* Create a new socket. Set your callbacks and then call bind to open
|
||||
* the connection.
|
||||
*/
|
||||
struct sccp_connection *sccp_connection_socket(void);
|
||||
|
||||
/**
|
||||
* Open the connection and send additional data
|
||||
*/
|
||||
int sccp_connection_connect(struct sccp_connection *conn,
|
||||
const struct sockaddr_sccp *sccp_called,
|
||||
struct msgb *data);
|
||||
|
||||
/**
|
||||
* mostly for testing purposes only. Set the accept callback.
|
||||
* TODO: add true routing information... in analogy to socket, bind, accept
|
||||
*/
|
||||
int sccp_connection_set_incoming(const struct sockaddr_sccp *sock,
|
||||
int (*accept_cb)(struct sccp_connection *connection, void *data),
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* Send data in terms of unit data. A fixed address indicator will be used.
|
||||
*/
|
||||
int sccp_write(struct msgb *data,
|
||||
const struct sockaddr_sccp *sock_sender,
|
||||
const struct sockaddr_sccp *sock_target, int class);
|
||||
int sccp_set_read(const struct sockaddr_sccp *sock,
|
||||
int (*read_cb)(struct msgb *msgb, unsigned int, void *user_data),
|
||||
void *user_data);
|
||||
|
||||
/* generic sock addresses */
|
||||
extern const struct sockaddr_sccp sccp_ssn_bssap;
|
||||
|
||||
/* helpers */
|
||||
u_int32_t sccp_src_ref_to_int(struct sccp_source_reference *ref);
|
||||
struct sccp_source_reference sccp_src_ref_from_int(u_int32_t);
|
||||
|
||||
/**
|
||||
* Below this are helper functions and structs for parsing SCCP messages
|
||||
*/
|
||||
struct sccp_parse_result {
|
||||
struct sccp_address called;
|
||||
struct sccp_address calling;
|
||||
|
||||
/* point to the msg packet */
|
||||
struct sccp_source_reference *source_local_reference;
|
||||
struct sccp_source_reference *destination_local_reference;
|
||||
|
||||
/* data pointer */
|
||||
int data_len;
|
||||
};
|
||||
|
||||
/*
|
||||
* helper functions for the nat code
|
||||
*/
|
||||
int sccp_determine_msg_type(struct msgb *msg);
|
||||
int sccp_parse_header(struct msgb *msg, struct sccp_parse_result *result);
|
||||
|
||||
#endif
|
||||
@@ -1,394 +0,0 @@
|
||||
/*
|
||||
* ITU Q.713 defined types for SCCP
|
||||
*
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SCCP_TYPES_H
|
||||
#define SCCP_TYPES_H
|
||||
|
||||
/* Table 1/Q.713 - SCCP message types */
|
||||
enum sccp_message_types {
|
||||
SCCP_MSG_TYPE_CR = 1,
|
||||
SCCP_MSG_TYPE_CC = 2,
|
||||
SCCP_MSG_TYPE_CREF = 3,
|
||||
SCCP_MSG_TYPE_RLSD = 4,
|
||||
SCCP_MSG_TYPE_RLC = 5,
|
||||
SCCP_MSG_TYPE_DT1 = 6,
|
||||
SCCP_MSG_TYPE_DT2 = 7,
|
||||
SCCP_MSG_TYPE_AK = 8,
|
||||
SCCP_MSG_TYPE_UDT = 9,
|
||||
SCCP_MSG_TYPE_UDTS = 10,
|
||||
SCCP_MSG_TYPE_ED = 11,
|
||||
SCCP_MSG_TYPE_EA = 12,
|
||||
SCCP_MSG_TYPE_RSR = 13,
|
||||
SCCP_MSG_TYPE_RSC = 14,
|
||||
SCCP_MSG_TYPE_ERR = 15,
|
||||
SCCP_MSG_TYPE_IT = 16,
|
||||
SCCP_MSG_TYPE_XUDT = 17,
|
||||
SCCP_MSG_TYPE_XUDTS = 18,
|
||||
SCCP_MSG_TYPE_LUDT = 19,
|
||||
SCCP_MSG_TYPE_LUDTS = 20
|
||||
};
|
||||
|
||||
/* Table 2/Q.713 - SCCP parameter name codes */
|
||||
enum sccp_parameter_name_codes {
|
||||
SCCP_PNC_END_OF_OPTIONAL = 0,
|
||||
SCCP_PNC_DESTINATION_LOCAL_REFERENCE = 1,
|
||||
SCCP_PNC_SOURCE_LOCAL_REFERENCE = 2,
|
||||
SCCP_PNC_CALLED_PARTY_ADDRESS = 3,
|
||||
SCCP_PNC_CALLING_PARTY_ADDRESS = 4,
|
||||
SCCP_PNC_PROTOCOL_CLASS = 5,
|
||||
SCCP_PNC_SEGMENTING = 6,
|
||||
SCCP_PNC_RECEIVE_SEQ_NUMBER = 7,
|
||||
SCCP_PNC_SEQUENCING = 8,
|
||||
SCCP_PNC_CREDIT = 9,
|
||||
SCCP_PNC_RELEASE_CAUSE = 10,
|
||||
SCCP_PNC_RETURN_CAUSE = 11,
|
||||
SCCP_PNC_RESET_CAUSE = 12,
|
||||
SCCP_PNC_ERROR_CAUSE = 13,
|
||||
SCCP_PNC_REFUSAL_CAUSE = 14,
|
||||
SCCP_PNC_DATA = 15,
|
||||
SCCP_PNC_SEGMENTATION = 16,
|
||||
SCCP_PNC_HOP_COUNTER = 17,
|
||||
SCCP_PNC_IMPORTANCE = 18,
|
||||
SCCP_PNC_LONG_DATA = 19,
|
||||
};
|
||||
|
||||
/* Figure 3/Q.713 Called/calling party address */
|
||||
enum {
|
||||
SCCP_TITLE_IND_NONE = 0,
|
||||
SCCP_TITLE_IND_NATURE_ONLY = 1,
|
||||
SCCP_TITLE_IND_TRANSLATION_ONLY = 2,
|
||||
SCCP_TITLE_IND_TRANS_NUM_ENC = 3,
|
||||
SCCP_TITLE_IND_TRANS_NUM_ENC_NATURE = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
SCCP_CALL_ROUTE_ON_SSN = 1,
|
||||
SCCP_CALL_ROUTE_ON_GT = 0,
|
||||
};
|
||||
|
||||
struct sccp_called_party_address {
|
||||
u_int8_t point_code_indicator : 1,
|
||||
ssn_indicator : 1,
|
||||
global_title_indicator : 4,
|
||||
routing_indicator : 1,
|
||||
reserved : 1;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* indicator indicates presence in the above order */
|
||||
|
||||
/* Figure 6/Q.713 */
|
||||
struct sccp_signalling_point_code {
|
||||
u_int8_t lsb;
|
||||
u_int8_t msb : 6,
|
||||
reserved : 2;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* SSN == subsystem number */
|
||||
enum sccp_subsystem_number {
|
||||
SCCP_SSN_NOT_KNOWN_OR_USED = 0,
|
||||
SCCP_SSN_MANAGEMENT = 1,
|
||||
SCCP_SSN_RESERVED_ITU = 2,
|
||||
SCCP_SSN_ISDN_USER_PART = 3,
|
||||
SCCP_SSN_OMAP = 4, /* operation, maint and administration part */
|
||||
SCCP_SSN_MAP = 5, /* mobile application part */
|
||||
SCCP_SSN_HLR = 6,
|
||||
SCCP_SSN_VLR = 7,
|
||||
SCCP_SSN_MSC = 8,
|
||||
SCCP_SSN_EIC = 9, /* equipent identifier centre */
|
||||
SCCP_SSN_AUC = 10, /* authentication centre */
|
||||
SCCP_SSN_ISDN_SUPPL_SERVICES = 11,
|
||||
SCCP_SSN_RESERVED_INTL = 12,
|
||||
SCCP_SSN_ISDN_EDGE_TO_EDGE = 13,
|
||||
SCCP_SSN_TC_TEST_RESPONDER = 14,
|
||||
|
||||
/* From GSM 03.03 8.2 */
|
||||
SCCP_SSN_BSSAP = 254,
|
||||
SCCP_SSN_BSSOM = 253,
|
||||
};
|
||||
|
||||
/* Q.713, 3.4.2.3 */
|
||||
enum {
|
||||
SCCP_NAI_UNKNOWN = 0,
|
||||
SCCP_NAI_SUBSCRIBER_NUMBER = 1,
|
||||
SCCP_NAI_RESERVED_NATIONAL = 2,
|
||||
SCCP_NAI_NATIONAL_SIGNIFICANT = 3,
|
||||
SCCP_NAI_INTERNATIONAL = 4,
|
||||
};
|
||||
|
||||
struct sccp_global_title {
|
||||
u_int8_t nature_of_addr_ind : 7,
|
||||
odd_even : 1;
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Q.713, 3.3 */
|
||||
struct sccp_source_reference {
|
||||
u_int8_t octet1;
|
||||
u_int8_t octet2;
|
||||
u_int8_t octet3;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Q.714, 3.6 */
|
||||
enum sccp_protocol_class {
|
||||
SCCP_PROTOCOL_CLASS_0 = 0,
|
||||
SCCP_PROTOCOL_CLASS_1 = 1,
|
||||
SCCP_PROTOCOL_CLASS_2 = 2,
|
||||
SCCP_PROTOCOL_CLASS_3 = 3,
|
||||
};
|
||||
|
||||
/* bits 5-8 when class0, class1 is used */
|
||||
enum sccp_protocol_options {
|
||||
SCCP_PROTOCOL_NO_SPECIAL = 0,
|
||||
SCCP_PROTOCOL_RETURN_MESSAGE = 8,
|
||||
};
|
||||
|
||||
enum sccp_release_cause {
|
||||
SCCP_RELEASE_CAUSE_END_USER_ORIGINATED = 0,
|
||||
SCCP_RELEASE_CAUSE_END_USER_CONGESTION = 1,
|
||||
SCCP_RELEASE_CAUSE_END_USER_FAILURE = 2,
|
||||
SCCP_RELEASE_CAUSE_SCCP_USER_ORIGINATED = 3,
|
||||
SCCP_RELEASE_CAUSE_REMOTE_PROCEDURE_ERROR = 4,
|
||||
SCCP_RELEASE_CAUSE_INCONSISTENT_CONN_DATA = 5,
|
||||
SCCP_RELEASE_CAUSE_ACCESS_FAILURE = 6,
|
||||
SCCP_RELEASE_CAUSE_ACCESS_CONGESTION = 7,
|
||||
SCCP_RELEASE_CAUSE_SUBSYSTEM_FAILURE = 8,
|
||||
SCCP_RELEASE_CAUSE_SUBSYSTEM_CONGESTION = 9,
|
||||
SCCP_RELEASE_CAUSE_MTP_FAILURE = 10,
|
||||
SCCP_RELEASE_CAUSE_NETWORK_CONGESTION = 11,
|
||||
SCCP_RELEASE_CAUSE_EXPIRATION_RESET = 12,
|
||||
SCCP_RELEASE_CAUSE_EXPIRATION_INACTIVE = 13,
|
||||
SCCP_RELEASE_CAUSE_RESERVED = 14,
|
||||
SCCP_RELEASE_CAUSE_UNQUALIFIED = 15,
|
||||
SCCP_RELEASE_CAUSE_SCCP_FAILURE = 16,
|
||||
};
|
||||
|
||||
enum sccp_return_cause {
|
||||
SCCP_RETURN_CAUSE_NO_TRANSLATION_NATURE = 0,
|
||||
SCCP_RETURN_CAUSE_NO_TRANSLATION = 1,
|
||||
SCCP_RETURN_CAUSE_SUBSYSTEM_CONGESTION = 2,
|
||||
SCCP_RETURN_CAUSE_SUBSYSTEM_FAILURE = 3,
|
||||
SCCP_RETURN_CAUSE_UNEQUIPPED_USER = 4,
|
||||
SCCP_RETURN_CAUSE_MTP_FAILURE = 5,
|
||||
SCCP_RETURN_CAUSE_NETWORK_CONGESTION = 6,
|
||||
SCCP_RETURN_CAUSE_UNQUALIFIED = 7,
|
||||
SCCP_RETURN_CAUSE_ERROR_IN_MSG_TRANSPORT = 8,
|
||||
SCCP_RETURN_CAUSE_ERROR_IN_LOCAL_PROCESSING = 9,
|
||||
SCCP_RETURN_CAUSE_DEST_CANNOT_PERFORM_REASSEMBLY = 10,
|
||||
SCCP_RETURN_CAUSE_SCCP_FAILURE = 11,
|
||||
SCCP_RETURN_CAUSE_HOP_COUNTER_VIOLATION = 12,
|
||||
SCCP_RETURN_CAUSE_SEGMENTATION_NOT_SUPPORTED= 13,
|
||||
SCCP_RETURN_CAUSE_SEGMENTATION_FAOLURE = 14
|
||||
};
|
||||
|
||||
enum sccp_reset_cause {
|
||||
SCCP_RESET_CAUSE_END_USER_ORIGINATED = 0,
|
||||
SCCP_RESET_CAUSE_SCCP_USER_ORIGINATED = 1,
|
||||
SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PS = 2,
|
||||
SCCP_RESET_CAUSE_MSG_OUT_OF_ORDER_PR = 3,
|
||||
SCCP_RESET_CAUSE_RPC_OUT_OF_WINDOW = 4,
|
||||
SCCP_RESET_CAUSE_RPC_INCORRECT_PS = 5,
|
||||
SCCP_RESET_CAUSE_RPC_GENERAL = 6,
|
||||
SCCP_RESET_CAUSE_REMOTE_END_USER_OPERATIONAL= 7,
|
||||
SCCP_RESET_CAUSE_NETWORK_OPERATIONAL = 8,
|
||||
SCCP_RESET_CAUSE_ACCESS_OPERATIONAL = 9,
|
||||
SCCP_RESET_CAUSE_NETWORK_CONGESTION = 10,
|
||||
SCCP_RESET_CAUSE_RESERVED = 11,
|
||||
};
|
||||
|
||||
enum sccp_error_cause {
|
||||
SCCP_ERROR_LRN_MISMATCH_UNASSIGNED = 0, /* local reference number */
|
||||
SCCP_ERROR_LRN_MISMATCH_INCONSISTENT = 1,
|
||||
SCCP_ERROR_POINT_CODE_MISMATCH = 2,
|
||||
SCCP_ERROR_SERVICE_CLASS_MISMATCH = 3,
|
||||
SCCP_ERROR_UNQUALIFIED = 4,
|
||||
};
|
||||
|
||||
enum sccp_refusal_cause {
|
||||
SCCP_REFUSAL_END_USER_ORIGINATED = 0,
|
||||
SCCP_REFUSAL_END_USER_CONGESTION = 1,
|
||||
SCCP_REFUSAL_END_USER_FAILURE = 2,
|
||||
SCCP_REFUSAL_SCCP_USER_ORIGINATED = 3,
|
||||
SCCP_REFUSAL_DESTINATION_ADDRESS_UKNOWN = 4,
|
||||
SCCP_REFUSAL_DESTINATION_INACCESSIBLE = 5,
|
||||
SCCP_REFUSAL_NET_QOS_NON_TRANSIENT = 6,
|
||||
SCCP_REFUSAL_NET_QOS_TRANSIENT = 7,
|
||||
SCCP_REFUSAL_ACCESS_FAILURE = 8,
|
||||
SCCP_REFUSAL_ACCESS_CONGESTION = 9,
|
||||
SCCP_REFUSAL_SUBSYSTEM_FAILURE = 10,
|
||||
SCCP_REFUSAL_SUBSYTEM_CONGESTION = 11,
|
||||
SCCP_REFUSAL_EXPIRATION = 12,
|
||||
SCCP_REFUSAL_INCOMPATIBLE_USER_DATA = 13,
|
||||
SCCP_REFUSAL_RESERVED = 14,
|
||||
SCCP_REFUSAL_UNQUALIFIED = 15,
|
||||
SCCP_REFUSAL_HOP_COUNTER_VIOLATION = 16,
|
||||
SCCP_REFUSAL_SCCP_FAILURE = 17,
|
||||
SCCP_REFUSAL_UNEQUIPPED_USER = 18,
|
||||
};
|
||||
|
||||
/*
|
||||
* messages... as of Q.713 Chapter 4
|
||||
*/
|
||||
struct sccp_connection_request {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference source_local_reference;
|
||||
u_int8_t proto_class;
|
||||
|
||||
|
||||
/* variable */
|
||||
u_int8_t variable_called;
|
||||
#if VARIABLE
|
||||
called_party_address
|
||||
#endif
|
||||
|
||||
/* optional */
|
||||
u_int8_t optional_start;
|
||||
|
||||
#if OPTIONAL
|
||||
credit 3
|
||||
callingparty var 4-n
|
||||
data 3-130
|
||||
hop_counter 3
|
||||
importance 3
|
||||
end_of_optional 1
|
||||
#endif
|
||||
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_connection_confirm {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
struct sccp_source_reference source_local_reference;
|
||||
u_int8_t proto_class;
|
||||
|
||||
/* optional */
|
||||
u_int8_t optional_start;
|
||||
|
||||
/* optional */
|
||||
#if OPTIONAL
|
||||
credit 3
|
||||
called party 4
|
||||
data 3-130
|
||||
importance 3
|
||||
end_of_optional 1
|
||||
#endif
|
||||
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_connection_refused {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
u_int8_t cause;
|
||||
|
||||
/* optional */
|
||||
u_int8_t optional_start;
|
||||
|
||||
/* optional */
|
||||
#if OPTIONAL
|
||||
called party 4
|
||||
data 3-130
|
||||
importance 3
|
||||
end_of_optional 1
|
||||
#endif
|
||||
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_connection_released {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
struct sccp_source_reference source_local_reference;
|
||||
u_int8_t release_cause;
|
||||
|
||||
|
||||
/* optional */
|
||||
u_int8_t optional_start;
|
||||
|
||||
#if OPTIONAL
|
||||
data 3-130
|
||||
importance 3
|
||||
end_of_optional 1
|
||||
#endif
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_connection_release_complete {
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
struct sccp_source_reference source_local_reference;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_data_form1 {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
u_int8_t segmenting;
|
||||
|
||||
/* variable */
|
||||
u_int8_t variable_start;
|
||||
|
||||
#if VARIABLE
|
||||
data 2-256;
|
||||
#endif
|
||||
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
|
||||
struct sccp_data_unitdata {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
u_int8_t proto_class;
|
||||
|
||||
|
||||
/* variable */
|
||||
u_int8_t variable_called;
|
||||
u_int8_t variable_calling;
|
||||
u_int8_t variable_data;
|
||||
|
||||
#if VARIABLE
|
||||
called party address
|
||||
calling party address
|
||||
#endif
|
||||
|
||||
u_int8_t data[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct sccp_data_it {
|
||||
/* mandantory */
|
||||
u_int8_t type;
|
||||
struct sccp_source_reference destination_local_reference;
|
||||
struct sccp_source_reference source_local_reference;
|
||||
u_int8_t proto_class;
|
||||
|
||||
u_int8_t sequencing[2];
|
||||
u_int8_t credit;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
||||
@@ -1 +0,0 @@
|
||||
noinst_HEADERS = buffer.h command.h vector.h vty.h
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Buffering to output and input.
|
||||
* Copyright (C) 1998 Kunihiro Ishiguro
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* GNU Zebra 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Zebra; see the file COPYING. If not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _ZEBRA_BUFFER_H
|
||||
#define _ZEBRA_BUFFER_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Create a new buffer. Memory will be allocated in chunks of the given
|
||||
size. If the argument is 0, the library will supply a reasonable
|
||||
default size suitable for buffering socket I/O. */
|
||||
struct buffer *buffer_new(size_t);
|
||||
|
||||
/* Free all data in the buffer. */
|
||||
void buffer_reset(struct buffer *);
|
||||
|
||||
/* This function first calls buffer_reset to release all buffered data.
|
||||
Then it frees the struct buffer itself. */
|
||||
void buffer_free(struct buffer *);
|
||||
|
||||
/* Add the given data to the end of the buffer. */
|
||||
extern void buffer_put(struct buffer *, const void *, size_t);
|
||||
/* Add a single character to the end of the buffer. */
|
||||
extern void buffer_putc(struct buffer *, u_char);
|
||||
/* Add a NUL-terminated string to the end of the buffer. */
|
||||
extern void buffer_putstr(struct buffer *, const char *);
|
||||
|
||||
/* Combine all accumulated (and unflushed) data inside the buffer into a
|
||||
single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
|
||||
that this function does not alter the state of the buffer, so the data
|
||||
is still inside waiting to be flushed. */
|
||||
char *buffer_getstr(struct buffer *);
|
||||
|
||||
/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
|
||||
int buffer_empty(struct buffer *);
|
||||
|
||||
typedef enum {
|
||||
/* An I/O error occurred. The buffer should be destroyed and the
|
||||
file descriptor should be closed. */
|
||||
BUFFER_ERROR = -1,
|
||||
|
||||
/* The data was written successfully, and the buffer is now empty
|
||||
(there is no pending data waiting to be flushed). */
|
||||
BUFFER_EMPTY = 0,
|
||||
|
||||
/* There is pending data in the buffer waiting to be flushed. Please
|
||||
try flushing the buffer when select indicates that the file descriptor
|
||||
is writeable. */
|
||||
BUFFER_PENDING = 1
|
||||
} buffer_status_t;
|
||||
|
||||
/* Try to write this data to the file descriptor. Any data that cannot
|
||||
be written immediately is added to the buffer queue. */
|
||||
extern buffer_status_t buffer_write(struct buffer *, int fd,
|
||||
const void *, size_t);
|
||||
|
||||
/* This function attempts to flush some (but perhaps not all) of
|
||||
the queued data to the given file descriptor. */
|
||||
extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
|
||||
|
||||
/* The following 2 functions (buffer_flush_all and buffer_flush_window)
|
||||
are for use in lib/vty.c only. They should not be used elsewhere. */
|
||||
|
||||
/* Call buffer_flush_available repeatedly until either all data has been
|
||||
flushed, or an I/O error has been encountered, or the operation would
|
||||
block. */
|
||||
extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
|
||||
|
||||
/* Attempt to write enough data to the given fd to fill a window of the
|
||||
given width and height (and remove the data written from the buffer).
|
||||
|
||||
If !no_more, then a message saying " --More-- " is appended.
|
||||
If erase is true, then first overwrite the previous " --More-- " message
|
||||
with spaces.
|
||||
|
||||
Any write error (including EAGAIN or EINTR) will cause this function
|
||||
to return -1 (because the logic for handling the erase and more features
|
||||
is too complicated to retry the write later).
|
||||
*/
|
||||
extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
|
||||
int height, int erase, int no_more);
|
||||
|
||||
#endif /* _ZEBRA_BUFFER_H */
|
||||
@@ -1,359 +0,0 @@
|
||||
/*
|
||||
* Zebra configuration command interface routine
|
||||
* Copyright (C) 1997, 98 Kunihiro Ishiguro
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* GNU Zebra 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Zebra; see the file COPYING. If not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _ZEBRA_COMMAND_H
|
||||
#define _ZEBRA_COMMAND_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "vector.h"
|
||||
#include "vty.h"
|
||||
|
||||
/* Host configuration variable */
|
||||
struct host {
|
||||
/* Host name of this router. */
|
||||
char *name;
|
||||
|
||||
/* Password for vty interface. */
|
||||
char *password;
|
||||
char *password_encrypt;
|
||||
|
||||
/* Enable password */
|
||||
char *enable;
|
||||
char *enable_encrypt;
|
||||
|
||||
/* System wide terminal lines. */
|
||||
int lines;
|
||||
|
||||
/* Log filename. */
|
||||
char *logfile;
|
||||
|
||||
/* config file name of this host */
|
||||
char *config;
|
||||
|
||||
/* Flags for services */
|
||||
int advanced;
|
||||
int encrypt;
|
||||
|
||||
/* Banner configuration. */
|
||||
const char *motd;
|
||||
char *motdfile;
|
||||
};
|
||||
|
||||
/* There are some command levels which called from command node. */
|
||||
enum node_type {
|
||||
AUTH_NODE, /* Authentication mode of vty interface. */
|
||||
VIEW_NODE, /* View node. Default mode of vty interface. */
|
||||
AUTH_ENABLE_NODE, /* Authentication mode for change enable. */
|
||||
ENABLE_NODE, /* Enable node. */
|
||||
CONFIG_NODE, /* Config node. Default mode of config file. */
|
||||
SERVICE_NODE, /* Service node. */
|
||||
DEBUG_NODE, /* Debug node. */
|
||||
#if 0
|
||||
AAA_NODE, /* AAA node. */
|
||||
KEYCHAIN_NODE, /* Key-chain node. */
|
||||
KEYCHAIN_KEY_NODE, /* Key-chain key node. */
|
||||
INTERFACE_NODE, /* Interface mode node. */
|
||||
ZEBRA_NODE, /* zebra connection node. */
|
||||
TABLE_NODE, /* rtm_table selection node. */
|
||||
RIP_NODE, /* RIP protocol mode node. */
|
||||
RIPNG_NODE, /* RIPng protocol mode node. */
|
||||
BGP_NODE, /* BGP protocol mode which includes BGP4+ */
|
||||
BGP_VPNV4_NODE, /* BGP MPLS-VPN PE exchange. */
|
||||
BGP_IPV4_NODE, /* BGP IPv4 unicast address family. */
|
||||
BGP_IPV4M_NODE, /* BGP IPv4 multicast address family. */
|
||||
BGP_IPV6_NODE, /* BGP IPv6 address family */
|
||||
OSPF_NODE, /* OSPF protocol mode */
|
||||
OSPF6_NODE, /* OSPF protocol for IPv6 mode */
|
||||
ISIS_NODE, /* ISIS protocol mode */
|
||||
MASC_NODE, /* MASC for multicast. */
|
||||
IRDP_NODE, /* ICMP Router Discovery Protocol mode. */
|
||||
IP_NODE, /* Static ip route node. */
|
||||
ACCESS_NODE, /* Access list node. */
|
||||
PREFIX_NODE, /* Prefix list node. */
|
||||
ACCESS_IPV6_NODE, /* Access list node. */
|
||||
PREFIX_IPV6_NODE, /* Prefix list node. */
|
||||
AS_LIST_NODE, /* AS list node. */
|
||||
COMMUNITY_LIST_NODE, /* Community list node. */
|
||||
RMAP_NODE, /* Route map node. */
|
||||
SMUX_NODE, /* SNMP configuration node. */
|
||||
DUMP_NODE, /* Packet dump node. */
|
||||
FORWARDING_NODE, /* IP forwarding node. */
|
||||
#endif
|
||||
VTY_NODE, /* Vty node. */
|
||||
|
||||
GSMNET_NODE,
|
||||
BTS_NODE,
|
||||
TRX_NODE,
|
||||
TS_NODE,
|
||||
SUBSCR_NODE,
|
||||
MGCP_NODE,
|
||||
};
|
||||
|
||||
/* Node which has some commands and prompt string and configuration
|
||||
function pointer . */
|
||||
struct cmd_node {
|
||||
/* Node index. */
|
||||
enum node_type node;
|
||||
|
||||
/* Prompt character at vty interface. */
|
||||
const char *prompt;
|
||||
|
||||
/* Is this node's configuration goes to vtysh ? */
|
||||
int vtysh;
|
||||
|
||||
/* Node's configuration write function */
|
||||
int (*func) (struct vty *);
|
||||
|
||||
/* Vector of this node's command list. */
|
||||
vector cmd_vector;
|
||||
};
|
||||
|
||||
enum {
|
||||
CMD_ATTR_DEPRECATED = 1,
|
||||
CMD_ATTR_HIDDEN,
|
||||
};
|
||||
|
||||
/* Structure of command element. */
|
||||
struct cmd_element {
|
||||
const char *string; /* Command specification by string. */
|
||||
int (*func) (struct cmd_element *, struct vty *, int, const char *[]);
|
||||
const char *doc; /* Documentation of this command. */
|
||||
int daemon; /* Daemon to which this command belong. */
|
||||
vector strvec; /* Pointing out each description vector. */
|
||||
unsigned int cmdsize; /* Command index count. */
|
||||
char *config; /* Configuration string */
|
||||
vector subconfig; /* Sub configuration string */
|
||||
u_char attr; /* Command attributes */
|
||||
};
|
||||
|
||||
/* Command description structure. */
|
||||
struct desc {
|
||||
const char *cmd; /* Command string. */
|
||||
const char *str; /* Command's description. */
|
||||
};
|
||||
|
||||
/* Return value of the commands. */
|
||||
#define CMD_SUCCESS 0
|
||||
#define CMD_WARNING 1
|
||||
#define CMD_ERR_NO_MATCH 2
|
||||
#define CMD_ERR_AMBIGUOUS 3
|
||||
#define CMD_ERR_INCOMPLETE 4
|
||||
#define CMD_ERR_EXEED_ARGC_MAX 5
|
||||
#define CMD_ERR_NOTHING_TODO 6
|
||||
#define CMD_COMPLETE_FULL_MATCH 7
|
||||
#define CMD_COMPLETE_MATCH 8
|
||||
#define CMD_COMPLETE_LIST_MATCH 9
|
||||
#define CMD_SUCCESS_DAEMON 10
|
||||
|
||||
/* Argc max counts. */
|
||||
#define CMD_ARGC_MAX 25
|
||||
|
||||
/* Turn off these macros when uisng cpp with extract.pl */
|
||||
#ifndef VTYSH_EXTRACT_PL
|
||||
|
||||
/* helper defines for end-user DEFUN* macros */
|
||||
#define DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attrs, dnum) \
|
||||
struct cmd_element cmdname = \
|
||||
{ \
|
||||
.string = cmdstr, \
|
||||
.func = funcname, \
|
||||
.doc = helpstr, \
|
||||
.attr = attrs, \
|
||||
.daemon = dnum, \
|
||||
};
|
||||
|
||||
#define DEFUN_CMD_FUNC_DECL(funcname) \
|
||||
static int funcname (struct cmd_element *, struct vty *, int, const char *[]); \
|
||||
|
||||
#define DEFUN_CMD_FUNC_TEXT(funcname) \
|
||||
static int funcname \
|
||||
(struct cmd_element *self, struct vty *vty, int argc, const char *argv[])
|
||||
|
||||
/* DEFUN for vty command interafce. Little bit hacky ;-). */
|
||||
#define DEFUN(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_FUNC_DECL(funcname) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0) \
|
||||
DEFUN_CMD_FUNC_TEXT(funcname)
|
||||
|
||||
#define DEFUN_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
|
||||
DEFUN_CMD_FUNC_DECL(funcname) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0) \
|
||||
DEFUN_CMD_FUNC_TEXT(funcname)
|
||||
|
||||
#define DEFUN_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
|
||||
|
||||
#define DEFUN_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_ATTR (funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED) \
|
||||
|
||||
/* DEFUN_NOSH for commands that vtysh should ignore */
|
||||
#define DEFUN_NOSH(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN(funcname, cmdname, cmdstr, helpstr)
|
||||
|
||||
/* DEFSH for vtysh. */
|
||||
#define DEFSH(daemon, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(NULL, cmdname, cmdstr, helpstr, 0, daemon) \
|
||||
|
||||
/* DEFUN + DEFSH */
|
||||
#define DEFUNSH(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_FUNC_DECL(funcname) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon) \
|
||||
DEFUN_CMD_FUNC_TEXT(funcname)
|
||||
|
||||
/* DEFUN + DEFSH with attributes */
|
||||
#define DEFUNSH_ATTR(daemon, funcname, cmdname, cmdstr, helpstr, attr) \
|
||||
DEFUN_CMD_FUNC_DECL(funcname) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, daemon) \
|
||||
DEFUN_CMD_FUNC_TEXT(funcname)
|
||||
|
||||
#define DEFUNSH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN)
|
||||
|
||||
#define DEFUNSH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUNSH_ATTR (daemon, funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED)
|
||||
|
||||
/* ALIAS macro which define existing command's alias. */
|
||||
#define ALIAS(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, 0)
|
||||
|
||||
#define ALIAS_ATTR(funcname, cmdname, cmdstr, helpstr, attr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, attr, 0)
|
||||
|
||||
#define ALIAS_HIDDEN(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, 0)
|
||||
|
||||
#define ALIAS_DEPRECATED(funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, 0)
|
||||
|
||||
#define ALIAS_SH(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, 0, daemon)
|
||||
|
||||
#define ALIAS_SH_HIDDEN(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_HIDDEN, daemon)
|
||||
|
||||
#define ALIAS_SH_DEPRECATED(daemon, funcname, cmdname, cmdstr, helpstr) \
|
||||
DEFUN_CMD_ELEMENT(funcname, cmdname, cmdstr, helpstr, CMD_ATTR_DEPRECATED, daemon)
|
||||
|
||||
#endif /* VTYSH_EXTRACT_PL */
|
||||
|
||||
/* Some macroes */
|
||||
#define CMD_OPTION(S) ((S[0]) == '[')
|
||||
#define CMD_VARIABLE(S) (((S[0]) >= 'A' && (S[0]) <= 'Z') || ((S[0]) == '<'))
|
||||
#define CMD_VARARG(S) ((S[0]) == '.')
|
||||
#define CMD_RANGE(S) ((S[0] == '<'))
|
||||
|
||||
#define CMD_IPV4(S) ((strcmp ((S), "A.B.C.D") == 0))
|
||||
#define CMD_IPV4_PREFIX(S) ((strcmp ((S), "A.B.C.D/M") == 0))
|
||||
#define CMD_IPV6(S) ((strcmp ((S), "X:X::X:X") == 0))
|
||||
#define CMD_IPV6_PREFIX(S) ((strcmp ((S), "X:X::X:X/M") == 0))
|
||||
|
||||
/* Common descriptions. */
|
||||
#define SHOW_STR "Show running system information\n"
|
||||
#define IP_STR "IP information\n"
|
||||
#define IPV6_STR "IPv6 information\n"
|
||||
#define NO_STR "Negate a command or set its defaults\n"
|
||||
#define CLEAR_STR "Reset functions\n"
|
||||
#define RIP_STR "RIP information\n"
|
||||
#define BGP_STR "BGP information\n"
|
||||
#define OSPF_STR "OSPF information\n"
|
||||
#define NEIGHBOR_STR "Specify neighbor router\n"
|
||||
#define DEBUG_STR "Debugging functions (see also 'undebug')\n"
|
||||
#define UNDEBUG_STR "Disable debugging functions (see also 'debug')\n"
|
||||
#define ROUTER_STR "Enable a routing process\n"
|
||||
#define AS_STR "AS number\n"
|
||||
#define MBGP_STR "MBGP information\n"
|
||||
#define MATCH_STR "Match values from routing table\n"
|
||||
#define SET_STR "Set values in destination routing protocol\n"
|
||||
#define OUT_STR "Filter outgoing routing updates\n"
|
||||
#define IN_STR "Filter incoming routing updates\n"
|
||||
#define V4NOTATION_STR "specify by IPv4 address notation(e.g. 0.0.0.0)\n"
|
||||
#define OSPF6_NUMBER_STR "Specify by number\n"
|
||||
#define INTERFACE_STR "Interface infomation\n"
|
||||
#define IFNAME_STR "Interface name(e.g. ep0)\n"
|
||||
#define IP6_STR "IPv6 Information\n"
|
||||
#define OSPF6_STR "Open Shortest Path First (OSPF) for IPv6\n"
|
||||
#define OSPF6_ROUTER_STR "Enable a routing process\n"
|
||||
#define OSPF6_INSTANCE_STR "<1-65535> Instance ID\n"
|
||||
#define SECONDS_STR "<1-65535> Seconds\n"
|
||||
#define ROUTE_STR "Routing Table\n"
|
||||
#define PREFIX_LIST_STR "Build a prefix list\n"
|
||||
#define OSPF6_DUMP_TYPE_LIST \
|
||||
"(neighbor|interface|area|lsa|zebra|config|dbex|spf|route|lsdb|redistribute|hook|asbr|prefix|abr)"
|
||||
#define ISIS_STR "IS-IS information\n"
|
||||
#define AREA_TAG_STR "[area tag]\n"
|
||||
|
||||
#define CONF_BACKUP_EXT ".sav"
|
||||
|
||||
/* IPv4 only machine should not accept IPv6 address for peer's IP
|
||||
address. So we replace VTY command string like below. */
|
||||
#ifdef HAVE_IPV6
|
||||
#define NEIGHBOR_CMD "neighbor (A.B.C.D|X:X::X:X) "
|
||||
#define NO_NEIGHBOR_CMD "no neighbor (A.B.C.D|X:X::X:X) "
|
||||
#define NEIGHBOR_ADDR_STR "Neighbor address\nIPv6 address\n"
|
||||
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|X:X::X:X|WORD) "
|
||||
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|X:X::X:X|WORD) "
|
||||
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor IPv6 address\nNeighbor tag\n"
|
||||
#else
|
||||
#define NEIGHBOR_CMD "neighbor A.B.C.D "
|
||||
#define NO_NEIGHBOR_CMD "no neighbor A.B.C.D "
|
||||
#define NEIGHBOR_ADDR_STR "Neighbor address\n"
|
||||
#define NEIGHBOR_CMD2 "neighbor (A.B.C.D|WORD) "
|
||||
#define NO_NEIGHBOR_CMD2 "no neighbor (A.B.C.D|WORD) "
|
||||
#define NEIGHBOR_ADDR_STR2 "Neighbor address\nNeighbor tag\n"
|
||||
#endif /* HAVE_IPV6 */
|
||||
|
||||
/* Prototypes. */
|
||||
void install_node(struct cmd_node *, int (*)(struct vty *));
|
||||
void install_default(enum node_type);
|
||||
void install_element(enum node_type, struct cmd_element *);
|
||||
void sort_node();
|
||||
|
||||
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
|
||||
string with a space between each element (allocated using
|
||||
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
|
||||
char *argv_concat(const char **argv, int argc, int shift);
|
||||
|
||||
vector cmd_make_strvec(const char *);
|
||||
void cmd_free_strvec(vector);
|
||||
vector cmd_describe_command();
|
||||
char **cmd_complete_command();
|
||||
const char *cmd_prompt(enum node_type);
|
||||
int config_from_file(struct vty *, FILE *);
|
||||
enum node_type node_parent(enum node_type);
|
||||
int cmd_execute_command(vector, struct vty *, struct cmd_element **, int);
|
||||
int cmd_execute_command_strict(vector, struct vty *, struct cmd_element **);
|
||||
void config_replace_string(struct cmd_element *, char *, ...);
|
||||
void cmd_init(int);
|
||||
|
||||
/* Export typical functions. */
|
||||
extern struct cmd_element config_end_cmd;
|
||||
extern struct cmd_element config_exit_cmd;
|
||||
extern struct cmd_element config_quit_cmd;
|
||||
extern struct cmd_element config_help_cmd;
|
||||
extern struct cmd_element config_list_cmd;
|
||||
char *host_config_file();
|
||||
void host_config_set(const char *);
|
||||
|
||||
void print_version(const char *);
|
||||
|
||||
#endif /* _ZEBRA_COMMAND_H */
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Generic vector interface header.
|
||||
* Copyright (C) 1997, 98 Kunihiro Ishiguro
|
||||
*
|
||||
* This file is part of GNU Zebra.
|
||||
*
|
||||
* GNU Zebra is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2, or (at your option) any
|
||||
* later version.
|
||||
*
|
||||
* GNU Zebra 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
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Zebra; see the file COPYING. If not, write to the Free
|
||||
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _ZEBRA_VECTOR_H
|
||||
#define _ZEBRA_VECTOR_H
|
||||
|
||||
/* struct for vector */
|
||||
struct _vector {
|
||||
unsigned int active; /* number of active slots */
|
||||
unsigned int alloced; /* number of allocated slot */
|
||||
void **index; /* index to data */
|
||||
};
|
||||
typedef struct _vector *vector;
|
||||
|
||||
#define VECTOR_MIN_SIZE 1
|
||||
|
||||
/* (Sometimes) usefull macros. This macro convert index expression to
|
||||
array expression. */
|
||||
/* Reference slot at given index, caller must ensure slot is active */
|
||||
#define vector_slot(V,I) ((V)->index[(I)])
|
||||
/* Number of active slots.
|
||||
* Note that this differs from vector_count() as it the count returned
|
||||
* will include any empty slots
|
||||
*/
|
||||
#define vector_active(V) ((V)->active)
|
||||
|
||||
/* Prototypes. */
|
||||
vector vector_init(unsigned int size);
|
||||
void vector_ensure(vector v, unsigned int num);
|
||||
int vector_empty_slot(vector v);
|
||||
int vector_set(vector v, void *val);
|
||||
int vector_set_index(vector v, unsigned int i, void *val);
|
||||
void vector_unset(vector v, unsigned int i);
|
||||
unsigned int vector_count(vector v);
|
||||
void vector_only_wrapper_free(vector v);
|
||||
void vector_only_index_free(void *index);
|
||||
void vector_free(vector v);
|
||||
vector vector_copy(vector v);
|
||||
|
||||
void *vector_lookup(vector, unsigned int);
|
||||
void *vector_lookup_ensure(vector, unsigned int);
|
||||
|
||||
#endif /* _ZEBRA_VECTOR_H */
|
||||
@@ -1,151 +0,0 @@
|
||||
#ifndef _VTY_H
|
||||
#define _VTY_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* GCC have printf type attribute check. */
|
||||
#ifdef __GNUC__
|
||||
#define VTY_PRINTF_ATTRIBUTE(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
#else
|
||||
#define VTY_PRINTF_ATTRIBUTE(a,b)
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
/* Does the I/O error indicate that the operation should be retried later? */
|
||||
#define ERRNO_IO_RETRY(EN) \
|
||||
(((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))
|
||||
|
||||
/* Vty read buffer size. */
|
||||
#define VTY_READ_BUFSIZ 512
|
||||
|
||||
#define VTY_BUFSIZ 512
|
||||
#define VTY_MAXHIST 20
|
||||
|
||||
/* Vty events */
|
||||
enum event {
|
||||
VTY_SERV,
|
||||
VTY_READ,
|
||||
VTY_WRITE,
|
||||
VTY_CLOSED,
|
||||
VTY_TIMEOUT_RESET,
|
||||
#ifdef VTYSH
|
||||
VTYSH_SERV,
|
||||
VTYSH_READ,
|
||||
VTYSH_WRITE
|
||||
#endif /* VTYSH */
|
||||
};
|
||||
|
||||
struct vty {
|
||||
FILE *file;
|
||||
|
||||
/* private data, specified by creator */
|
||||
void *priv;
|
||||
|
||||
/* File descripter of this vty. */
|
||||
int fd;
|
||||
|
||||
/* Is this vty connect to file or not */
|
||||
enum { VTY_TERM, VTY_FILE, VTY_SHELL, VTY_SHELL_SERV } type;
|
||||
|
||||
/* Node status of this vty */
|
||||
int node;
|
||||
|
||||
/* Failure count */
|
||||
int fail;
|
||||
|
||||
/* Output buffer. */
|
||||
struct buffer *obuf;
|
||||
|
||||
/* Command input buffer */
|
||||
char *buf;
|
||||
|
||||
/* Command cursor point */
|
||||
int cp;
|
||||
|
||||
/* Command length */
|
||||
int length;
|
||||
|
||||
/* Command max length. */
|
||||
int max;
|
||||
|
||||
/* Histry of command */
|
||||
char *hist[VTY_MAXHIST];
|
||||
|
||||
/* History lookup current point */
|
||||
int hp;
|
||||
|
||||
/* History insert end point */
|
||||
int hindex;
|
||||
|
||||
/* For current referencing point of interface, route-map,
|
||||
access-list etc... */
|
||||
void *index;
|
||||
|
||||
/* For multiple level index treatment such as key chain and key. */
|
||||
void *index_sub;
|
||||
|
||||
/* For escape character. */
|
||||
unsigned char escape;
|
||||
|
||||
/* Current vty status. */
|
||||
enum { VTY_NORMAL, VTY_CLOSE, VTY_MORE, VTY_MORELINE } status;
|
||||
|
||||
/* IAC handling: was the last character received the IAC
|
||||
* (interpret-as-command) escape character (and therefore the next
|
||||
* character will be the command code)? Refer to Telnet RFC 854. */
|
||||
unsigned char iac;
|
||||
|
||||
/* IAC SB (option subnegotiation) handling */
|
||||
unsigned char iac_sb_in_progress;
|
||||
/* At the moment, we care only about the NAWS (window size) negotiation,
|
||||
* and that requires just a 5-character buffer (RFC 1073):
|
||||
* <NAWS char> <16-bit width> <16-bit height> */
|
||||
#define TELNET_NAWS_SB_LEN 5
|
||||
unsigned char sb_buf[TELNET_NAWS_SB_LEN];
|
||||
/* How many subnegotiation characters have we received? We just drop
|
||||
* those that do not fit in the buffer. */
|
||||
size_t sb_len;
|
||||
|
||||
/* Window width/height. */
|
||||
int width;
|
||||
int height;
|
||||
|
||||
/* Configure lines. */
|
||||
int lines;
|
||||
|
||||
int monitor;
|
||||
|
||||
/* In configure mode. */
|
||||
int config;
|
||||
};
|
||||
|
||||
/* Small macro to determine newline is newline only or linefeed needed. */
|
||||
#define VTY_NEWLINE ((vty->type == VTY_TERM) ? "\r\n" : "\n")
|
||||
|
||||
static inline char *vty_newline(struct vty *vty)
|
||||
{
|
||||
return VTY_NEWLINE;
|
||||
}
|
||||
|
||||
/* Prototypes. */
|
||||
void vty_init (void);
|
||||
int vty_read_config_file(const char *file_name);
|
||||
void vty_init_vtysh (void);
|
||||
void vty_reset (void);
|
||||
struct vty *vty_new (void);
|
||||
struct vty *vty_create (int vty_sock, void *priv);
|
||||
int vty_out (struct vty *, const char *, ...) VTY_PRINTF_ATTRIBUTE(2, 3);
|
||||
int vty_out_newline(struct vty *);
|
||||
int vty_read(struct vty *vty);
|
||||
//void vty_time_print (struct vty *, int);
|
||||
void vty_close (struct vty *);
|
||||
char *vty_get_cwd (void);
|
||||
void vty_log (const char *level, const char *proto, const char *fmt, va_list);
|
||||
int vty_config_lock (struct vty *);
|
||||
int vty_config_unlock (struct vty *);
|
||||
int vty_shell (struct vty *);
|
||||
int vty_shell_serv (struct vty *);
|
||||
void vty_hello (struct vty *);
|
||||
|
||||
void *tall_vty_ctx;
|
||||
#endif
|
||||
@@ -1,7 +1,7 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@/openbsc-1.0
|
||||
includedir=@includedir@/
|
||||
|
||||
Name: OpenBSC
|
||||
Description: OpenBSC base station controller
|
||||
|
||||
@@ -1,47 +1,48 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include
|
||||
AM_CFLAGS=-Wall
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS)
|
||||
|
||||
sbin_PROGRAMS = bsc_hack bs11_config ipaccess-find ipaccess-config \
|
||||
isdnsync bsc_mgcp bsc_msc_ip bsc_nat
|
||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libsccp.a
|
||||
noinst_HEADERS = vty/cardshell.h
|
||||
# build current directory before building gprs
|
||||
SUBDIRS = . ipaccess gprs
|
||||
|
||||
# Conditional modules
|
||||
if BUILD_NAT
|
||||
SUBDIRS += nat
|
||||
endif
|
||||
if BUILD_BSC
|
||||
SUBDIRS += bsc
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = bsc_hack bs11_config isdnsync bsc_mgcp
|
||||
noinst_LIBRARIES = libbsc.a libmsc.a libvty.a libmgcp.a
|
||||
|
||||
libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \
|
||||
msgb.c select.c chan_alloc.c timer.c debug.c \
|
||||
chan_alloc.c debug.c socket.c abis_nm_vty.c \
|
||||
gsm_subscriber_base.c subchan_demux.c bsc_rll.c transaction.c \
|
||||
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c tlv_parser.c \
|
||||
input/misdn.c input/ipaccess.c signal.c gsm_utils.c talloc.c \
|
||||
talloc_ctx.c system_information.c bitvec.c rest_octets.c \
|
||||
rtp_proxy.c telnet_interface.c
|
||||
trau_frame.c trau_mux.c paging.c e1_config.c e1_input.c \
|
||||
input/misdn.c input/ipaccess.c handover_logic.c \
|
||||
talloc_ctx.c system_information.c rest_octets.c \
|
||||
rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \
|
||||
bts_unknown.c bsc_version.c bsc_api.c bsc_vty.c meas_rep.c
|
||||
|
||||
libmsc_a_SOURCES = gsm_subscriber.c db.c \
|
||||
mncc.c gsm_04_08.c gsm_04_11.c transaction.c \
|
||||
token_auth.c rrlp.c gsm_04_80.c ussd.c silent_call.c \
|
||||
handover_logic.c handover_decision.c meas_rep.c
|
||||
handover_decision.c auth.c \
|
||||
osmo_msc.c
|
||||
|
||||
libvty_a_SOURCES = vty/buffer.c vty/command.c vty/vector.c vty/vty.c
|
||||
libvty_a_SOURCES = common_vty.c
|
||||
|
||||
libsccp_a_SOURCES = sccp/sccp.c
|
||||
libmgcp_a_SOURCES = mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c
|
||||
|
||||
bsc_hack_SOURCES = bsc_hack.c bsc_init.c vty_interface.c vty_interface_layer3.c
|
||||
bsc_hack_LDADD = libmsc.a libbsc.a libmsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
|
||||
bsc_hack_SOURCES = bsc_hack.c bsc_init.c bsc_vty.c vty_interface_layer3.c
|
||||
bsc_hack_LDADD = libmsc.a libbsc.a libvty.a libmsc.a \
|
||||
-ldl -ldbi $(LIBCRYPT) $(LIBOSMOVTY_LIBS)
|
||||
|
||||
bsc_msc_ip_SOURCES = bssap.c bsc_msc_ip.c bsc_init.c vty_interface.c vty_interface_bsc.c \
|
||||
bsc_msc.c
|
||||
bsc_msc_ip_LDADD = libbsc.a libvty.a libsccp.a
|
||||
|
||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c msgb.c debug.c \
|
||||
select.c timer.c rs232.c tlv_parser.c signal.c talloc.c
|
||||
|
||||
ipaccess_find_SOURCES = ipaccess-find.c select.c timer.c
|
||||
|
||||
ipaccess_config_SOURCES = ipaccess-config.c
|
||||
ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYPT)
|
||||
bs11_config_SOURCES = bs11_config.c abis_nm.c gsm_data.c debug.c \
|
||||
rs232.c bts_siemens_bs11.c
|
||||
|
||||
isdnsync_SOURCES = isdnsync.c
|
||||
|
||||
bsc_mgcp_SOURCES = bsc_mgcp.c msgb.c talloc.c debug.c select.c timer.c telnet_interface.c
|
||||
bsc_mgcp_LDADD = libvty.a
|
||||
|
||||
bsc_nat_SOURCES = nat/bsc_nat.c nat/bsc_filter.c bsc_msc.c
|
||||
bsc_nat_LDADD = libbsc.a libsccp.a
|
||||
bsc_mgcp_SOURCES = mgcp/mgcp_main.c debug.c
|
||||
bsc_mgcp_LDADD = libvty.a libmgcp.a $(LIBOSMOVTY_LIBS)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
198
openbsc/src/abis_nm_vty.c
Normal file
198
openbsc/src/abis_nm_vty.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/* VTY interface for A-bis OML (Netowrk Management) */
|
||||
|
||||
/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/vty.h>
|
||||
|
||||
#include <osmocom/vty/vty.h>
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/logging.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
|
||||
extern struct gsm_network *bsc_gsmnet;
|
||||
|
||||
static struct cmd_node oml_node = {
|
||||
OML_NODE,
|
||||
"%s(oml)# ",
|
||||
1,
|
||||
};
|
||||
|
||||
struct oml_node_state {
|
||||
struct gsm_bts *bts;
|
||||
uint8_t obj_class;
|
||||
uint8_t obj_inst[3];
|
||||
};
|
||||
|
||||
static int dummy_config_write(struct vty *v)
|
||||
{
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* FIXME: auto-generate those strings from the value_string lists */
|
||||
#define NM_OBJCLASS_VTY "(site-manager|bts|radio-carrier|baseband-transceiver|channel|adjc|handover|power-contorl|btse|rack|test|envabtse|bport|gprs-nse|gprs-cell|gprs-nsvc|siemenshw)"
|
||||
#define NM_OBJCLASS_VTY_HELP "FIXME"
|
||||
|
||||
DEFUN(oml_class_inst, oml_class_inst_cmd,
|
||||
"bts <0-255> oml class " NM_OBJCLASS_VTY
|
||||
" instance <0-255> <0-255> <0-255>",
|
||||
"BTS related commands\n" "BTS Number\n"
|
||||
"Manipulate the OML managed objects\n"
|
||||
"Object Class\n" NM_OBJCLASS_VTY_HELP
|
||||
"Object Instance\n" "BTS Number\n" "TRX Number\n" "TS Number\n")
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
struct oml_node_state *oms;
|
||||
int bts_nr = atoi(argv[0]);
|
||||
|
||||
bts = gsm_bts_num(bsc_gsmnet, bts_nr);
|
||||
if (!bts) {
|
||||
vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
|
||||
if (!oms)
|
||||
return CMD_WARNING;
|
||||
|
||||
oms->bts = bts;
|
||||
oms->obj_class = get_string_value(abis_nm_obj_class_names, argv[1]);
|
||||
oms->obj_inst[0] = atoi(argv[2]);
|
||||
oms->obj_inst[1] = atoi(argv[3]);
|
||||
oms->obj_inst[2] = atoi(argv[4]);
|
||||
|
||||
vty->index = oms;
|
||||
vty->node = OML_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
DEFUN(oml_classnum_inst, oml_classnum_inst_cmd,
|
||||
"bts <0-255> oml class <0-255> instance <0-255> <0-255> <0-255>",
|
||||
"BTS related commands\n" "BTS Number\n"
|
||||
"Manipulate the OML managed objects\n"
|
||||
"Object Class\n" "Object Class\n"
|
||||
"Object Instance\n" "BTS Number\n" "TRX Number\n" "TS Number\n")
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
struct oml_node_state *oms;
|
||||
int bts_nr = atoi(argv[0]);
|
||||
|
||||
bts = gsm_bts_num(bsc_gsmnet, bts_nr);
|
||||
if (!bts) {
|
||||
vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
oms = talloc_zero(tall_bsc_ctx, struct oml_node_state);
|
||||
if (!oms)
|
||||
return CMD_WARNING;
|
||||
|
||||
oms->bts = bts;
|
||||
oms->obj_class = atoi(argv[1]);
|
||||
oms->obj_inst[0] = atoi(argv[2]);
|
||||
oms->obj_inst[1] = atoi(argv[3]);
|
||||
oms->obj_inst[2] = atoi(argv[4]);
|
||||
|
||||
vty->index = oms;
|
||||
vty->node = OML_NODE;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(oml_attrib_get, oml_attrib_get_cmd,
|
||||
"attribute get <0-255>",
|
||||
"OML Attribute Actions\n" "Get a single OML Attribute\n"
|
||||
"OML Attribute Number\n")
|
||||
{
|
||||
struct oml_node_state *oms = vty->index;
|
||||
|
||||
/* FIXME */
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(oml_attrib_set, oml_attrib_set_cmd,
|
||||
"attribute set <0-255> .HEX",
|
||||
"OML Attribute Actions\n" "Set a single OML Attribute\n"
|
||||
"OML Attribute Number\n")
|
||||
{
|
||||
struct oml_node_state *oms = vty->index;
|
||||
|
||||
/* FIXME */
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(oml_chg_adm_state, oml_chg_adm_state_cmd,
|
||||
"change-adm-state (locked|unlocked|shutdown|null)",
|
||||
"Change the Administrative State\n"
|
||||
"Locked\n" "Unlocked\n" "Shutdown\n" "NULL\n")
|
||||
{
|
||||
struct oml_node_state *oms = vty->index;
|
||||
enum abis_nm_adm_state state;
|
||||
|
||||
state = get_string_value(abis_nm_adm_state_names, argv[0]);
|
||||
|
||||
abis_nm_chg_adm_state(oms->bts, oms->obj_class, oms->obj_inst[0],
|
||||
oms->obj_inst[1], oms->obj_inst[2], state);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(oml_opstart, oml_opstart_cmd,
|
||||
"opstart", "Send an OPSTART message to the object")
|
||||
{
|
||||
struct oml_node_state *oms = vty->index;
|
||||
|
||||
abis_nm_opstart(oms->bts, oms->obj_class, oms->obj_inst[0],
|
||||
oms->obj_inst[1], oms->obj_inst[2]);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
int abis_nm_vty_init(void)
|
||||
{
|
||||
install_element(ENABLE_NODE, &oml_class_inst_cmd);
|
||||
install_element(ENABLE_NODE, &oml_classnum_inst_cmd);
|
||||
install_node(&oml_node, dummy_config_write);
|
||||
|
||||
install_default(OML_NODE);
|
||||
install_element(OML_NODE, &ournode_exit_cmd);
|
||||
install_element(OML_NODE, &oml_attrib_get_cmd);
|
||||
install_element(OML_NODE, &oml_attrib_set_cmd);
|
||||
install_element(OML_NODE, &oml_chg_adm_state_cmd);
|
||||
install_element(OML_NODE, &oml_opstart_cmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
128
openbsc/src/auth.c
Normal file
128
openbsc/src/auth.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/* Authentication related functions */
|
||||
|
||||
/*
|
||||
* (C) 2010 by Sylvain Munaut <tnt@246tNt.com>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/db.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
|
||||
#include <osmocore/comp128.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static int
|
||||
_use_xor(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple)
|
||||
{
|
||||
int i, l = ainfo->a3a8_ki_len;
|
||||
|
||||
if ((l > A38_XOR_MAX_KEY_LEN) || (l < A38_XOR_MIN_KEY_LEN)) {
|
||||
DEBUGP(DMM, "Invalid XOR key (len=%d) %s",
|
||||
ainfo->a3a8_ki_len,
|
||||
hexdump(ainfo->a3a8_ki, ainfo->a3a8_ki_len));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
atuple->sres[i] = atuple->rand[i] ^ ainfo->a3a8_ki[i];
|
||||
for (i=8; i<12; i++)
|
||||
atuple->kc[i-4] = atuple->rand[i] ^ ainfo->a3a8_ki[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_use_comp128_v1(struct gsm_auth_info *ainfo, struct gsm_auth_tuple *atuple)
|
||||
{
|
||||
if (ainfo->a3a8_ki_len != A38_COMP128_KEY_LEN) {
|
||||
DEBUGP(DMM, "Invalid COMP128v1 key (len=%d) %s",
|
||||
ainfo->a3a8_ki_len,
|
||||
hexdump(ainfo->a3a8_ki, ainfo->a3a8_ki_len));
|
||||
return -1;
|
||||
}
|
||||
|
||||
comp128(ainfo->a3a8_ki, atuple->rand, atuple->sres, atuple->kc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return values
|
||||
* -1 -> Internal error
|
||||
* 0 -> Not available
|
||||
* 1 -> Tuple returned, need to do auth, then enable cipher
|
||||
* 2 -> Tuple returned, need to enable cipher
|
||||
*/
|
||||
int auth_get_tuple_for_subscr(struct gsm_auth_tuple *atuple,
|
||||
struct gsm_subscriber *subscr, int key_seq)
|
||||
{
|
||||
struct gsm_auth_info ainfo;
|
||||
int i, rc;
|
||||
|
||||
/* Get subscriber info (if any) */
|
||||
rc = db_get_authinfo_for_subscr(&ainfo, subscr);
|
||||
if (rc < 0) {
|
||||
DEBUGP(DMM, "No retrievable Ki for subscriber, skipping auth");
|
||||
return rc == -ENOENT ? 0 : -1;
|
||||
}
|
||||
|
||||
/* If possible, re-use the last tuple and skip auth */
|
||||
rc = db_get_lastauthtuple_for_subscr(atuple, subscr);
|
||||
if ((rc == 0) &&
|
||||
(atuple->key_seq != GSM_KEY_SEQ_INVAL) &&
|
||||
(atuple->use_count < 3))
|
||||
{
|
||||
atuple->use_count++;
|
||||
db_sync_lastauthtuple_for_subscr(atuple, subscr);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Generate a new one */
|
||||
atuple->use_count = 1;
|
||||
atuple->key_seq = (atuple->key_seq + 1) % 7;
|
||||
for (i=0; i<sizeof(atuple->rand); i++)
|
||||
atuple->rand[i] = random() & 0xff;
|
||||
|
||||
switch (ainfo.auth_algo) {
|
||||
case AUTH_ALGO_NONE:
|
||||
return 0;
|
||||
|
||||
case AUTH_ALGO_XOR:
|
||||
if (_use_xor(&ainfo, atuple))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case AUTH_ALGO_COMP128v1:
|
||||
if (_use_comp128_v1(&ainfo, atuple))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUGP(DMM, "Unsupported auth type algo_id=%d\n",
|
||||
ainfo.auth_algo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
db_sync_lastauthtuple_for_subscr(atuple, subscr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,170 +0,0 @@
|
||||
/* bit vector utility routines */
|
||||
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <openbsc/bitvec.h>
|
||||
|
||||
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
|
||||
|
||||
static inline unsigned int bytenum_from_bitnum(unsigned int bitnum)
|
||||
{
|
||||
unsigned int bytenum = bitnum / 8;
|
||||
|
||||
return bytenum;
|
||||
}
|
||||
|
||||
/* convert ZERO/ONE/L/H to a bitmask at given pos in a byte */
|
||||
static u_int8_t bitval2mask(enum bit_value bit, u_int8_t bitnum)
|
||||
{
|
||||
int bitval;
|
||||
|
||||
switch (bit) {
|
||||
case ZERO:
|
||||
bitval = (0 << bitnum);
|
||||
break;
|
||||
case ONE:
|
||||
bitval = (1 << bitnum);
|
||||
break;
|
||||
case L:
|
||||
bitval = ((0x2b ^ (0 << bitnum)) & (1 << bitnum));
|
||||
break;
|
||||
case H:
|
||||
bitval = ((0x2b ^ (1 << bitnum)) & (1 << bitnum));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return bitval;
|
||||
}
|
||||
|
||||
/* check if the bit is 0 or 1 for a given position inside a bitvec */
|
||||
enum bit_value bitvec_get_bit_pos(struct bitvec *bv, unsigned int bitnr)
|
||||
{
|
||||
unsigned int bytenum = bytenum_from_bitnum(bitnr);
|
||||
unsigned int bitnum = 7 - (bitnr % 8);
|
||||
u_int8_t bitval;
|
||||
|
||||
if (bytenum >= bv->data_len)
|
||||
return -EINVAL;
|
||||
|
||||
bitval = bitval2mask(ONE, bitnum);
|
||||
|
||||
if (bv->data[bytenum] & bitval)
|
||||
return ONE;
|
||||
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/* get the Nth set bit inside the bit vector */
|
||||
unsigned int bitvec_get_nth_set_bit(struct bitvec *bv, unsigned int n)
|
||||
{
|
||||
unsigned int i, k = 0;
|
||||
|
||||
for (i = 0; i < bv->data_len*8; i++) {
|
||||
if (bitvec_get_bit_pos(bv, i) == ONE) {
|
||||
k++;
|
||||
if (k == n)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set the bit at a given position inside a bitvec */
|
||||
int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnr,
|
||||
enum bit_value bit)
|
||||
{
|
||||
unsigned int bytenum = bytenum_from_bitnum(bitnr);
|
||||
unsigned int bitnum = 7 - (bitnr % 8);
|
||||
u_int8_t bitval;
|
||||
|
||||
if (bytenum >= bv->data_len)
|
||||
return -EINVAL;
|
||||
|
||||
/* first clear the bit */
|
||||
bitval = bitval2mask(ONE, bitnum);
|
||||
bv->data[bytenum] &= ~bitval;
|
||||
|
||||
/* then set it to desired value */
|
||||
bitval = bitval2mask(bit, bitnum);
|
||||
bv->data[bytenum] |= bitval;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set the next bit inside a bitvec */
|
||||
int bitvec_set_bit(struct bitvec *bv, enum bit_value bit)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = bitvec_set_bit_pos(bv, bv->cur_bit, bit);
|
||||
if (!rc)
|
||||
bv->cur_bit++;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* set multiple bits (based on array of bitvals) at current pos */
|
||||
int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
rc = bitvec_set_bit(bv, bits[i]);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set multiple bits (based on numeric value) at current pos */
|
||||
int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits)
|
||||
{
|
||||
int i, rc;
|
||||
|
||||
for (i = 0; i < num_bits; i++) {
|
||||
int bit = 0;
|
||||
if (ui & (1 << (num_bits - i - 1)))
|
||||
bit = 1;
|
||||
rc = bitvec_set_bit(bv, bit);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* pad all remaining bits up to num_bits */
|
||||
int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = bv->cur_bit; i <= up_to_bit; i++)
|
||||
bitvec_set_bit(bv, L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
/* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This software is based on ideas (but not code) of BS11Config
|
||||
* This software is based on ideas (but not code) of BS11Config
|
||||
* (C) 2009 by Dieter Spaar <spaar@mirider.augusta.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -36,10 +36,10 @@
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/msgb.h>
|
||||
#include <openbsc/tlv.h>
|
||||
#include <osmocore/msgb.h>
|
||||
#include <osmocore/tlv.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/rs232.h>
|
||||
|
||||
/* state of our bs11_config application */
|
||||
@@ -51,12 +51,12 @@ enum bs11cfg_state {
|
||||
STATE_QUERY,
|
||||
};
|
||||
static enum bs11cfg_state bs11cfg_state = STATE_NONE;
|
||||
static char *command;
|
||||
static char *command, *value;
|
||||
struct timer_list status_timer;
|
||||
|
||||
static const u_int8_t obj_li_attr[] = {
|
||||
static const u_int8_t obj_li_attr[] = {
|
||||
NM_ATT_BS11_BIT_ERR_THESH, 0x09, 0x00,
|
||||
NM_ATT_BS11_L1_PROT_TYPE, 0x00,
|
||||
NM_ATT_BS11_L1_PROT_TYPE, 0x00,
|
||||
NM_ATT_BS11_LINE_CFG, 0x00,
|
||||
};
|
||||
static const u_int8_t obj_bbsig0_attr[] = {
|
||||
@@ -71,6 +71,13 @@ static const char *trx1_password = "1111111111";
|
||||
|
||||
static const u_int8_t too_fast[] = { 0x12, 0x80, 0x00, 0x00, 0x02, 0x02 };
|
||||
|
||||
static struct log_target *stderr_target;
|
||||
|
||||
/* dummy function to keep gsm_data.c happy */
|
||||
struct counter *counter_alloc(const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int handle_serial_msg(struct msgb *rx_msg);
|
||||
|
||||
@@ -474,7 +481,7 @@ static int handle_state_resp(enum abis_bs11_phase state)
|
||||
* argument, so our swload_cbfn can distinguish
|
||||
* a safety load from a regular software */
|
||||
if (file_is_readable(fname_safety))
|
||||
rc = abis_nm_software_load(g_bts, fname_safety,
|
||||
rc = abis_nm_software_load(g_bts, 0xff, fname_safety,
|
||||
win_size, param_forced,
|
||||
swload_cbfn, g_bts);
|
||||
else
|
||||
@@ -533,6 +540,21 @@ static int handle_state_resp(enum abis_bs11_phase state)
|
||||
sleep(1);
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "pll-setvalue")) {
|
||||
abis_nm_bs11_set_pll(g_bts, atoi(value));
|
||||
sleep(1);
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "pll-workvalue")) {
|
||||
/* To set the work value we need to login as FIELD */
|
||||
abis_nm_bs11_factory_logon(g_bts, 0);
|
||||
sleep(1);
|
||||
abis_nm_bs11_infield_logon(g_bts, 1);
|
||||
sleep(1);
|
||||
abis_nm_bs11_set_pll(g_bts, atoi(value));
|
||||
sleep(1);
|
||||
abis_nm_bs11_infield_logon(g_bts, 0);
|
||||
command = NULL;
|
||||
} else if (!strcmp(command, "oml-tei")) {
|
||||
abis_nm_bs11_conn_oml_tei(g_bts, 0, 1, 0xff, TEI_OML);
|
||||
command = NULL;
|
||||
@@ -627,7 +649,7 @@ int handle_serial_msg(struct msgb *rx_msg)
|
||||
exit(0);
|
||||
break;
|
||||
case NM_MT_BS11_GET_STATE_ACK:
|
||||
rc = abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
rc = abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
|
||||
print_state(&tp);
|
||||
if (TLVP_PRESENT(&tp, NM_ATT_BS11_BTS_STATE) &&
|
||||
TLVP_LEN(&tp, NM_ATT_BS11_BTS_STATE) >= 1)
|
||||
@@ -635,7 +657,7 @@ int handle_serial_msg(struct msgb *rx_msg)
|
||||
break;
|
||||
case NM_MT_GET_ATTR_RESP:
|
||||
printf("\n%sATTRIBUTES:\n", obj_name(foh));
|
||||
abis_nm_tlv_parse(&tp, foh->data, oh->length-sizeof(*foh));
|
||||
abis_nm_tlv_parse(&tp, g_bts, foh->data, oh->length-sizeof(*foh));
|
||||
rc = print_attr(&tp);
|
||||
//hexdump(foh->data, oh->length-sizeof(*foh));
|
||||
break;
|
||||
@@ -675,7 +697,8 @@ int handle_serial_msg(struct msgb *rx_msg)
|
||||
}
|
||||
|
||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
|
||||
struct abis_om_obj_inst *obj_ins)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -699,25 +722,27 @@ static void print_help(void)
|
||||
printf("\t-p --port </dev/ttyXXX>\t\tSpecify serial port\n");
|
||||
printf("\t-s --software <file>\t\tSpecify Software file\n");
|
||||
printf("\t-S --safety <file>\t\tSpecify Safety Load file\n");
|
||||
printf("\t-d --delay <ms>\t\tSpecify delay in milliseconds\n");
|
||||
printf("\t-d --delay <ms>\t\t\tSpecify delay in milliseconds\n");
|
||||
printf("\t-D --disconnect\t\t\tDisconnect BTS from BSC\n");
|
||||
printf("\t-w --win-size <num>\t\tSpecify Window Size\n");
|
||||
printf("\t-f --forced\t\t\tForce Software Load\n");
|
||||
printf("\nSupported commands:\n");
|
||||
printf("\tquery\t\tQuery the BS-11 about serial number and configuration\n");
|
||||
printf("\tdisconnect\tDisconnect A-bis link (go into administrative state)\n");
|
||||
printf("\tresconnect\tReconnect A-bis link (go into normal state)\n");
|
||||
printf("\trestart\t\tRestart the BTS\n");
|
||||
printf("\tsoftware\tDownload Software (only in administrative state)\n");
|
||||
printf("\tcreate-trx1\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
|
||||
printf("\tdelete-trx1\tDelete objects for TRX1\n");
|
||||
printf("\tpll-e1-locked\tSet the PLL to be locked to E1 clock\n");
|
||||
printf("\tpll-standalone\tSet the PLL to be in standalone mode\n");
|
||||
printf("\toml-tei\tSet OML E1 TS and TEI\n");
|
||||
printf("\tbport0-star\tSet BPORT0 line config to star\n");
|
||||
printf("\tquery\t\t\tQuery the BS-11 about serial number and configuration\n");
|
||||
printf("\tdisconnect\t\tDisconnect A-bis link (go into administrative state)\n");
|
||||
printf("\tresconnect\t\tReconnect A-bis link (go into normal state)\n");
|
||||
printf("\trestart\t\t\tRestart the BTS\n");
|
||||
printf("\tsoftware\t\tDownload Software (only in administrative state)\n");
|
||||
printf("\tcreate-trx1\t\tCreate objects for TRX1 (Danger: Your BS-11 might overheat)\n");
|
||||
printf("\tdelete-trx1\t\tDelete objects for TRX1\n");
|
||||
printf("\tpll-e1-locked\t\tSet the PLL to be locked to E1 clock\n");
|
||||
printf("\tpll-standalone\t\tSet the PLL to be in standalone mode\n");
|
||||
printf("\tpll-setvalue <value>\tSet the PLL set value\n");
|
||||
printf("\tpll-workvalue <value>\tSet the PLL work value\n");
|
||||
printf("\toml-tei\t\t\tSet OML E1 TS and TEI\n");
|
||||
printf("\tbport0-star\t\tSet BPORT0 line config to star\n");
|
||||
printf("\tbport0-multiport\tSet BPORT0 line config to multiport\n");
|
||||
printf("\tcreate-bport1\tCreate BPORT1 object\n");
|
||||
printf("\tdelete-bport1\tDelete BPORT1 object\n");
|
||||
printf("\tcreate-bport1\t\tCreate BPORT1 object\n");
|
||||
printf("\tdelete-bport1\t\tDelete BPORT1 object\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char **argv)
|
||||
@@ -754,7 +779,7 @@ static void handle_options(int argc, char **argv)
|
||||
serial_port = optarg;
|
||||
break;
|
||||
case 'b':
|
||||
debug_parse_category_mask(optarg);
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 's':
|
||||
fname_software = optarg;
|
||||
@@ -784,6 +809,9 @@ static void handle_options(int argc, char **argv)
|
||||
}
|
||||
if (optind < argc)
|
||||
command = argv[optind];
|
||||
if (optind+1 < argc)
|
||||
value = argv[optind+1];
|
||||
|
||||
}
|
||||
|
||||
static int num_sigint;
|
||||
@@ -802,12 +830,18 @@ static void signal_handler(int signal)
|
||||
}
|
||||
}
|
||||
|
||||
extern int bts_model_bs11_init(void);
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct gsm_network *gsmnet;
|
||||
int rc;
|
||||
|
||||
log_init(&log_info);
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
handle_options(argc, argv);
|
||||
bts_model_bs11_init();
|
||||
|
||||
gsmnet = gsm_network_init(1, 1, NULL);
|
||||
if (!gsmnet) {
|
||||
|
||||
13
openbsc/src/bsc/Makefile.am
Normal file
13
openbsc/src/bsc/Makefile.am
Normal file
@@ -0,0 +1,13 @@
|
||||
INCLUDES = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
|
||||
AM_CFLAGS=-Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOSCCP_CFLAGS)
|
||||
AM_LDFLAGS = $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS)
|
||||
|
||||
bin_PROGRAMS = osmo-bsc
|
||||
|
||||
|
||||
osmo_bsc_SOURCES = osmo_bsc_main.c osmo_bsc_rf.c osmo_bsc_vty.c osmo_bsc_api.c \
|
||||
$(top_srcdir)/src/debug.c $(top_srcdir)/src/bsc_msc.c \
|
||||
$(top_srcdir)/src/bsc_init.c
|
||||
osmo_bsc_LDADD = $(top_builddir)/src/libvty.a \
|
||||
$(top_builddir)/src/libmgcp.a $(top_builddir)/src/libbsc.a \
|
||||
$(LIBOSMOSCCP_LIBS)
|
||||
@@ -1,9 +1,5 @@
|
||||
/* GSM utility functions, e.g. coding and decoding */
|
||||
/*
|
||||
* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
/* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -22,20 +18,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GSM_UTILS_H
|
||||
#define GSM_UTILS_H
|
||||
#include <openbsc/osmo_bsc.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int gsm_7bit_decode(char *decoded, const u_int8_t *user_data, u_int8_t length);
|
||||
int gsm_7bit_encode(u_int8_t *result, const char *data);
|
||||
|
||||
int ms_pwr_ctl_lvl(enum gsm_band band, unsigned int dbm);
|
||||
int ms_pwr_dbm(enum gsm_band band, u_int8_t lvl);
|
||||
|
||||
/* According to TS 08.05 Chapter 8.1.4 */
|
||||
int rxlev2dbm(u_int8_t rxlev);
|
||||
u_int8_t dbm2rxlev(int dbm);
|
||||
|
||||
void generate_backtrace();
|
||||
#endif
|
||||
struct bsc_api *osmo_bsc_api()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
188
openbsc/src/bsc/osmo_bsc_main.c
Normal file
188
openbsc/src/bsc/osmo_bsc_main.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009-2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009-2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/osmo_bsc_rf.h>
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
#include <osmocom/sccp/sccp.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "bscconfig.h"
|
||||
|
||||
static struct log_target *stderr_target;
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
static const char *rf_ctl = NULL;
|
||||
|
||||
extern void bsc_vty_init(void);
|
||||
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: bsc_msc_ip\n");
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -T --timestamp. Print a timestamp in the debug output.\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -l --local=IP. The local address of the MGCP.\n");
|
||||
printf(" -e --log-level number. Set a global loglevel.\n");
|
||||
printf(" -r --rf-ctl NAME. A unix domain socket to listen for cmds.\n");
|
||||
printf(" -t --testmode. A special mode to provoke failures at the MSC.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char** argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"msc", 1, 0, 'm'},
|
||||
{"local", 1, 0, 'l'},
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{"rf-ctl", 1, 0, 'r'},
|
||||
{"testmode", 0, 0, 't'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:sTc:e:r:t",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
log_set_use_color(stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 'c':
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
break;
|
||||
case 'r':
|
||||
rf_ctl = optarg;
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern int bts_model_unknown_init(void);
|
||||
extern int bts_model_bs11_init(void);
|
||||
extern int bts_model_nanobts_init(void);
|
||||
|
||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
|
||||
|
||||
static struct vty_app_info vty_info = {
|
||||
.name = "OpenBSC Osmo BSC",
|
||||
.version = PACKAGE_VERSION,
|
||||
.go_parent_cb = bsc_vty_go_parent,
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *msc;
|
||||
int rc;
|
||||
|
||||
log_init(&log_info);
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
|
||||
bts_model_unknown_init();
|
||||
bts_model_bs11_init();
|
||||
bts_model_nanobts_init();
|
||||
|
||||
/* enable filters */
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
/* This needs to precede handle_options() */
|
||||
vty_init(&vty_info);
|
||||
bsc_vty_init();
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
/* initialize SCCP */
|
||||
sccp_set_log_area(DSCCP);
|
||||
|
||||
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (rf_ctl) {
|
||||
struct osmo_bsc_rf *rf;
|
||||
rf = osmo_bsc_rf_create(rf_ctl, bsc_gsmnet);
|
||||
if (!rf) {
|
||||
fprintf(stderr, "Failed to create the RF service.\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
bsc_select_main(0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
264
openbsc/src/bsc/osmo_bsc_rf.c
Normal file
264
openbsc/src/bsc/osmo_bsc_rf.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/* RF Ctl handling socket */
|
||||
|
||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/osmo_bsc_rf.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/protocol/gsm_12_21.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define RF_CMD_QUERY '?'
|
||||
#define RF_CMD_OFF '0'
|
||||
#define RF_CMD_ON '1'
|
||||
#define RF_CMD_GRACE 'g'
|
||||
|
||||
static int lock_each_trx(struct gsm_network *net, int lock)
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
|
||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||
struct gsm_bts_trx *trx;
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
gsm_trx_lock_rf(trx, lock);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a '1' when one TRX is online, otherwise send 0
|
||||
*/
|
||||
static void handle_query(struct osmo_bsc_rf_conn *conn)
|
||||
{
|
||||
struct msgb *msg;
|
||||
struct gsm_bts *bts;
|
||||
char send = RF_CMD_OFF;
|
||||
|
||||
llist_for_each_entry(bts, &conn->gsm_network->bts_list, list) {
|
||||
struct gsm_bts_trx *trx;
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
if (trx->nm_state.availability == NM_AVSTATE_OK &&
|
||||
trx->nm_state.operational != NM_STATE_LOCKED) {
|
||||
send = RF_CMD_ON;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg = msgb_alloc(10, "RF Query");
|
||||
if (!msg) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to allocate response msg.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
msg->l2h = msgb_put(msg, 1);
|
||||
msg->l2h[0] = send;
|
||||
|
||||
if (write_queue_enqueue(&conn->queue, msg) != 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to enqueue the answer.\n");
|
||||
msgb_free(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void send_signal(struct osmo_bsc_rf_conn *conn, int val)
|
||||
{
|
||||
struct rf_signal_data sig;
|
||||
sig.net = conn->gsm_network;
|
||||
|
||||
dispatch_signal(SS_RF, val, &sig);
|
||||
}
|
||||
|
||||
static int rf_read_cmd(struct bsc_fd *fd)
|
||||
{
|
||||
struct osmo_bsc_rf_conn *conn = fd->data;
|
||||
char buf[1];
|
||||
int rc;
|
||||
|
||||
rc = read(fd->fd, buf, sizeof(buf));
|
||||
if (rc != sizeof(buf)) {
|
||||
LOGP(DINP, LOGL_ERROR, "Short read %d/%s\n", errno, strerror(errno));
|
||||
bsc_unregister_fd(fd);
|
||||
close(fd->fd);
|
||||
write_queue_clear(&conn->queue);
|
||||
talloc_free(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (buf[0]) {
|
||||
case RF_CMD_QUERY:
|
||||
handle_query(conn);
|
||||
break;
|
||||
case RF_CMD_OFF:
|
||||
lock_each_trx(conn->gsm_network, 1);
|
||||
send_signal(conn, S_RF_OFF);
|
||||
break;
|
||||
case RF_CMD_ON:
|
||||
lock_each_trx(conn->gsm_network, 0);
|
||||
send_signal(conn, S_RF_ON);
|
||||
break;
|
||||
case RF_CMD_GRACE:
|
||||
send_signal(conn, S_RF_GRACE);
|
||||
break;
|
||||
default:
|
||||
LOGP(DINP, LOGL_ERROR, "Unknown command %d\n", buf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rf_write_cmd(struct bsc_fd *fd, struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = write(fd->fd, msg->data, msg->len);
|
||||
if (rc != msg->len) {
|
||||
LOGP(DINP, LOGL_ERROR, "Short write %d/%s\n", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rf_ctl_accept(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
struct osmo_bsc_rf_conn *conn;
|
||||
struct osmo_bsc_rf *rf = bfd->data;
|
||||
struct sockaddr_un addr;
|
||||
socklen_t len = sizeof(addr);
|
||||
int fd;
|
||||
|
||||
fd = accept(bfd->fd, (struct sockaddr *) &addr, &len);
|
||||
if (fd < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to accept. errno: %d/%s\n",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
conn = talloc_zero(rf, struct osmo_bsc_rf_conn);
|
||||
if (!conn) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to allocate mem.\n");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
write_queue_init(&conn->queue, 10);
|
||||
conn->queue.bfd.data = conn;
|
||||
conn->queue.bfd.fd = fd;
|
||||
conn->queue.bfd.when = BSC_FD_READ | BSC_FD_WRITE;
|
||||
conn->queue.read_cb = rf_read_cmd;
|
||||
conn->queue.write_cb = rf_write_cmd;
|
||||
conn->gsm_network = rf->gsm_network;
|
||||
|
||||
if (bsc_register_fd(&conn->queue.bfd) != 0) {
|
||||
close(fd);
|
||||
talloc_free(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct osmo_bsc_rf *osmo_bsc_rf_create(const char *path, struct gsm_network *net)
|
||||
{
|
||||
unsigned int namelen;
|
||||
struct sockaddr_un local;
|
||||
struct bsc_fd *bfd;
|
||||
struct osmo_bsc_rf *rf;
|
||||
int rc;
|
||||
|
||||
rf = talloc_zero(NULL, struct osmo_bsc_rf);
|
||||
if (!rf) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to create osmo_bsc_rf.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bfd = &rf->listen;
|
||||
bfd->fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (bfd->fd < 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Can not create socket. %d/%s\n",
|
||||
errno, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
local.sun_family = AF_UNIX;
|
||||
strncpy(local.sun_path, path, sizeof(local.sun_path));
|
||||
local.sun_path[sizeof(local.sun_path) - 1] = '\0';
|
||||
unlink(local.sun_path);
|
||||
|
||||
/* we use the same magic that X11 uses in Xtranssock.c for
|
||||
* calculating the proper length of the sockaddr */
|
||||
#if defined(BSD44SOCKETS) || defined(__UNIXWARE__)
|
||||
local.sun_len = strlen(local.sun_path);
|
||||
#endif
|
||||
#if defined(BSD44SOCKETS) || defined(SUN_LEN)
|
||||
namelen = SUN_LEN(&local);
|
||||
#else
|
||||
namelen = strlen(local.sun_path) +
|
||||
offsetof(struct sockaddr_un, sun_path);
|
||||
#endif
|
||||
|
||||
rc = bind(bfd->fd, (struct sockaddr *) &local, namelen);
|
||||
if (rc != 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to bind '%s' errno: %d/%s\n",
|
||||
local.sun_path, errno, strerror(errno));
|
||||
close(bfd->fd);
|
||||
talloc_free(rf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (listen(bfd->fd, 0) != 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to listen: %d/%s\n", errno, strerror(errno));
|
||||
close(bfd->fd);
|
||||
talloc_free(rf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bfd->when = BSC_FD_READ;
|
||||
bfd->cb = rf_ctl_accept;
|
||||
bfd->data = rf;
|
||||
|
||||
if (bsc_register_fd(bfd) != 0) {
|
||||
LOGP(DINP, LOGL_ERROR, "Failed to register bfd.\n");
|
||||
close(bfd->fd);
|
||||
talloc_free(rf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rf->gsm_network = net;
|
||||
|
||||
return rf;
|
||||
}
|
||||
|
||||
27
openbsc/src/bsc/osmo_bsc_vty.c
Normal file
27
openbsc/src/bsc/osmo_bsc_vty.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* Osmo BSC VTY Configuration */
|
||||
/* (C) 2009-2010 by Holger Hans Peter Freyther
|
||||
* (C) 2009-2010 by On Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/vty/vty.h>
|
||||
|
||||
int bsc_vty_init_extra(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
209
openbsc/src/bsc_api.c
Normal file
209
openbsc/src/bsc_api.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/* GSM 08.08 like API for OpenBSC. The bridge from MSC to BSC */
|
||||
|
||||
/* (C) 2010 by Holger Hans Peter Freyther
|
||||
* (C) 2010 by On Waves
|
||||
* (C) 2009 by Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openbsc/bsc_api.h>
|
||||
#include <openbsc/bsc_rll.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/handover.h>
|
||||
#include <openbsc/debug.h>
|
||||
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
static void rll_ind_cb(struct gsm_lchan *, uint8_t, void *, enum bsc_rllr_ind);
|
||||
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id);
|
||||
|
||||
int bsc_api_init(struct gsm_network *network, struct bsc_api *api)
|
||||
{
|
||||
network->bsc_api = api;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gsm0808_submit_dtap(struct gsm_subscriber_connection *conn,
|
||||
struct msgb *msg, int link_id)
|
||||
{
|
||||
uint8_t sapi = link_id & 0x7;
|
||||
msg->lchan = conn->lchan;
|
||||
msg->trx = msg->lchan->ts->trx;
|
||||
|
||||
msg->l3h = msg->data;
|
||||
if (conn->lchan->sapis[sapi] == LCHAN_SAPI_UNUSED) {
|
||||
OBSC_LINKID_CB(msg) = link_id;
|
||||
if (rll_establish(msg->lchan, sapi, rll_ind_cb, msg) != 0) {
|
||||
msgb_free(msg);
|
||||
send_sapi_reject(conn, link_id);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return rsl_data_request(msg, link_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a GSM08.08 Assignment Request. Right now this does not contain the
|
||||
* audio codec type or the allowed rates for the config.
|
||||
*/
|
||||
int gsm0808_assign_req(struct gsm_subscriber_connection *conn, int chan_type, int audio)
|
||||
{
|
||||
struct bsc_api *api;
|
||||
api = conn->bts->network->bsc_api;
|
||||
|
||||
api->assign_fail(conn, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gsm0808_page(struct gsm_bts *bts, unsigned int page_group, unsigned int mi_len,
|
||||
uint8_t *mi, int chan_type)
|
||||
{
|
||||
return rsl_paging_cmd(bts, page_group, mi_len, mi, chan_type);
|
||||
}
|
||||
|
||||
/* dequeue messages to layer 4 */
|
||||
int bsc_upqueue(struct gsm_network *net)
|
||||
{
|
||||
struct gsm_mncc *mncc;
|
||||
struct msgb *msg;
|
||||
int work = 0;
|
||||
|
||||
if (net)
|
||||
while ((msg = msgb_dequeue(&net->upqueue))) {
|
||||
mncc = (struct gsm_mncc *)msg->data;
|
||||
if (net->mncc_recv)
|
||||
net->mncc_recv(net, mncc->msg_type, mncc);
|
||||
work = 1; /* work done */
|
||||
talloc_free(msg);
|
||||
}
|
||||
|
||||
return work;
|
||||
}
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, uint8_t link_id)
|
||||
{
|
||||
int rc;
|
||||
struct bsc_api *api = msg->lchan->ts->trx->bts->network->bsc_api;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
lchan = msg->lchan;
|
||||
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||
LOGP(DRSL, LOGL_ERROR, "Got data in non active state. discarding.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (lchan->conn) {
|
||||
api->dtap(lchan->conn, msg);
|
||||
} else {
|
||||
rc = BSC_API_CONN_POL_REJECT;
|
||||
lchan->conn = subscr_con_allocate(msg->lchan);
|
||||
|
||||
if (lchan->conn)
|
||||
rc = api->compl_l3(lchan->conn, msg, 0);
|
||||
|
||||
if (rc != BSC_API_CONN_POL_ACCEPT) {
|
||||
subscr_con_free(lchan->conn);
|
||||
lchan_release(lchan, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gsm0808_cipher_mode(struct gsm_subscriber_connection *conn, int cipher,
|
||||
uint8_t *key, int len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int gsm0808_clear(struct gsm_subscriber_connection* conn)
|
||||
{
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
bsc_clear_handover(conn);
|
||||
|
||||
lchan = conn->lchan;
|
||||
subscr_con_free(conn);
|
||||
lchan_release(lchan, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_sapi_reject(struct gsm_subscriber_connection *conn, int link_id)
|
||||
{
|
||||
struct bsc_api *api;
|
||||
|
||||
if (!conn)
|
||||
return;
|
||||
|
||||
api = conn->bts->network->bsc_api;
|
||||
if (!api || !api->sapi_n_reject)
|
||||
return;
|
||||
|
||||
api->sapi_n_reject(conn, link_id);
|
||||
}
|
||||
|
||||
static void rll_ind_cb(struct gsm_lchan *lchan, uint8_t link_id, void *_data, enum bsc_rllr_ind rllr_ind)
|
||||
{
|
||||
struct msgb *msg = _data;
|
||||
|
||||
switch (rllr_ind) {
|
||||
case BSC_RLLR_IND_EST_CONF:
|
||||
rsl_data_request(msg, OBSC_LINKID_CB(msg));
|
||||
break;
|
||||
case BSC_RLLR_IND_REL_IND:
|
||||
case BSC_RLLR_IND_ERR_IND:
|
||||
case BSC_RLLR_IND_TIMEOUT:
|
||||
send_sapi_reject(lchan->conn, OBSC_LINKID_CB(msg));
|
||||
msgb_free(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int bsc_handle_lchan_signal(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct bsc_api *bsc;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
if (subsys != SS_LCHAN || signal != S_LCHAN_UNEXPECTED_RELEASE)
|
||||
return 0;
|
||||
|
||||
lchan = (struct gsm_lchan *)signal_data;
|
||||
if (!lchan || !lchan->conn)
|
||||
return 0;
|
||||
|
||||
bsc = lchan->ts->trx->bts->network->bsc_api;
|
||||
if (!bsc || !bsc->clear_request)
|
||||
return 0;
|
||||
|
||||
bsc->clear_request(lchan->conn, 0);
|
||||
subscr_con_free(lchan->conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_bsc(void)
|
||||
{
|
||||
register_signal_handler(SS_LCHAN, bsc_handle_lchan_signal, NULL);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -31,16 +31,27 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include <openbsc/db.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <osmocore/select.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/osmo_msc.h>
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
|
||||
#include "../bscconfig.h"
|
||||
|
||||
/* MCC and MNC for the Location Area Identifier */
|
||||
static struct log_target *stderr_target;
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *database_name = "hlr.sqlite3";
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
extern const char *openbsc_copyright;
|
||||
|
||||
/* timer to store statistics */
|
||||
#define DB_SYNC_INTERVAL 60, 0
|
||||
static struct timer_list db_sync_timer;
|
||||
|
||||
extern int bsc_bootstrap_network(int (*mmc_rev)(struct gsm_network *, int, void *),
|
||||
const char *cfg_file);
|
||||
@@ -69,12 +80,15 @@ static void print_help()
|
||||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -l --database db-name The database to use\n");
|
||||
printf(" -a --authorize-everyone. Authorize every new subscriber. Dangerous!.\n");
|
||||
printf(" -p --pcap file The filename of the pcap file\n");
|
||||
printf(" -T --timestamp Prefix every log line with a timestamp\n");
|
||||
printf(" -V --version. Print the version of OpenBSC.\n");
|
||||
printf(" -P --rtp-proxy Enable the RTP Proxy code inside OpenBSC\n");
|
||||
printf(" -e --log-level number. Set a global loglevel.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char** argv)
|
||||
@@ -90,11 +104,13 @@ static void handle_options(int argc, char** argv)
|
||||
{"authorize-everyone", 0, 0, 'a'},
|
||||
{"pcap", 1, 0, 'p'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"version", 0, 0, 'V' },
|
||||
{"rtp-proxy", 0, 0, 'P'},
|
||||
{"log-level", 1, 0, 'e'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:sl:ar:p:TPc:",
|
||||
c = getopt_long(argc, argv, "hd:sl:ar:p:TPVc:e:",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
@@ -105,10 +121,10 @@ static void handle_options(int argc, char** argv)
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
debug_use_color(0);
|
||||
log_set_use_color(stderr_target, 0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_parse_category_mask(optarg);
|
||||
log_parse_category_mask(stderr_target, optarg);
|
||||
break;
|
||||
case 'l':
|
||||
database_name = strdup(optarg);
|
||||
@@ -120,11 +136,18 @@ static void handle_options(int argc, char** argv)
|
||||
create_pcap_file(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
debug_timestamp(1);
|
||||
log_set_print_timestamp(stderr_target, 1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'e':
|
||||
log_set_log_level(stderr_target, atoi(optarg));
|
||||
break;
|
||||
case 'V':
|
||||
print_version(1);
|
||||
exit(0);
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
@@ -132,6 +155,7 @@ static void handle_options(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
extern void *tall_vty_ctx;
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
@@ -147,26 +171,76 @@ static void signal_handler(int signal)
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
case SIGUSR1:
|
||||
talloc_report(tall_vty_ctx, stderr);
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
break;
|
||||
case SIGUSR2:
|
||||
talloc_report_full(tall_vty_ctx, stderr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* timer handling */
|
||||
static int _db_store_counter(struct counter *counter, void *data)
|
||||
{
|
||||
return db_store_counter(counter);
|
||||
}
|
||||
|
||||
static void db_sync_timer_cb(void *data)
|
||||
{
|
||||
/* store counters to database and re-schedule */
|
||||
counters_for_each(_db_store_counter, NULL);
|
||||
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
|
||||
}
|
||||
|
||||
extern int bts_model_unknown_init(void);
|
||||
extern int bts_model_bs11_init(void);
|
||||
extern int bts_model_nanobts_init(void);
|
||||
|
||||
extern enum node_type bsc_vty_go_parent(struct vty *vty);
|
||||
|
||||
static struct vty_app_info vty_info = {
|
||||
.name = "OpenBSC",
|
||||
.version = PACKAGE_VERSION,
|
||||
.go_parent_cb = bsc_vty_go_parent,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
vty_info.copyright = openbsc_copyright;
|
||||
|
||||
log_init(&log_info);
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
talloc_ctx_init();
|
||||
on_dso_load_token();
|
||||
on_dso_load_rrlp();
|
||||
on_dso_load_ho_dec();
|
||||
stderr_target = log_target_create_stderr();
|
||||
log_add_target(stderr_target);
|
||||
|
||||
bts_model_unknown_init();
|
||||
bts_model_bs11_init();
|
||||
bts_model_nanobts_init();
|
||||
|
||||
/* enable filters */
|
||||
log_set_all_filter(stderr_target, 1);
|
||||
|
||||
/* This needs to precede handle_options() */
|
||||
vty_init(&vty_info);
|
||||
bsc_vty_init();
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
rc = bsc_bootstrap_network(mncc_recv, config_file);
|
||||
if (rc < 0)
|
||||
exit(1);
|
||||
bsc_api_init(bsc_gsmnet, msc_bsc_api());
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
@@ -182,17 +256,20 @@ int main(int argc, char **argv)
|
||||
}
|
||||
printf("DB: Database prepared.\n");
|
||||
|
||||
rc = bsc_bootstrap_network(mncc_recv, config_file);
|
||||
if (rc < 0)
|
||||
exit(1);
|
||||
/* setup the timer */
|
||||
db_sync_timer.cb = db_sync_timer_cb;
|
||||
db_sync_timer.data = NULL;
|
||||
bsc_schedule_timer(&db_sync_timer, DB_SYNC_INTERVAL);
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGUSR2, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
while (1) {
|
||||
bsc_upqueue(bsc_gsmnet);
|
||||
log_reset_context();
|
||||
bsc_select_main(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
@@ -21,17 +21,18 @@
|
||||
*/
|
||||
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/gsm_utils.h>
|
||||
#include <osmocore/gsm_utils.h>
|
||||
#include <openbsc/gsm_04_08.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/abis_nm.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/misdn.h>
|
||||
#include <openbsc/telnet_interface.h>
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
#include <openbsc/system_information.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
/* global pointer to the gsm network data structure */
|
||||
extern struct gsm_network *bsc_gsmnet;
|
||||
@@ -330,6 +331,7 @@ static unsigned char nanobts_attr_bts[] = {
|
||||
NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
|
||||
NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
|
||||
NM_ATT_BSIC, HARDCODED_BSIC,
|
||||
NM_ATT_IPACC_CGI, 0, 7, 0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_radio[] = {
|
||||
@@ -337,13 +339,75 @@ static unsigned char nanobts_attr_radio[] = {
|
||||
NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_nse[] = {
|
||||
NM_ATT_IPACC_NSEI, 0, 2, 0x03, 0x9d, /* NSEI 925 */
|
||||
NM_ATT_IPACC_NS_CFG, 0, 7, 3, /* (un)blocking timer (Tns-block) */
|
||||
3, /* (un)blocking retries */
|
||||
3, /* reset timer (Tns-reset) */
|
||||
3, /* reset retries */
|
||||
30, /* test timer (Tns-test) */
|
||||
3, /* alive timer (Tns-alive) */
|
||||
10, /* alive retrires */
|
||||
NM_ATT_IPACC_BSSGP_CFG, 0, 11,
|
||||
3, /* blockimg timer (T1) */
|
||||
3, /* blocking retries */
|
||||
3, /* unblocking retries */
|
||||
3, /* reset timer */
|
||||
3, /* reset retries */
|
||||
10, /* suspend timer (T3) in 100ms */
|
||||
3, /* suspend retries */
|
||||
10, /* resume timer (T4) in 100ms */
|
||||
3, /* resume retries */
|
||||
10, /* capability update timer (T5) */
|
||||
3, /* capability update retries */
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_cell[] = {
|
||||
NM_ATT_IPACC_RAC, 0, 1, 1, /* routing area code */
|
||||
NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
|
||||
5, /* repeat time (50ms) */
|
||||
3, /* repeat count */
|
||||
NM_ATT_IPACC_BVCI, 0, 2, 0x03, 0x9d, /* BVCI 925 */
|
||||
NM_ATT_IPACC_RLC_CFG, 0, 9,
|
||||
20, /* T3142 */
|
||||
5, /* T3169 */
|
||||
5, /* T3191 */
|
||||
200, /* T3193 */
|
||||
5, /* T3195 */
|
||||
10, /* N3101 */
|
||||
4, /* N3103 */
|
||||
8, /* N3105 */
|
||||
15, /* RLC CV countdown */
|
||||
NM_ATT_IPACC_CODING_SCHEMES, 0, 2, 0x0f, 0x00, /* CS1..CS4 */
|
||||
NM_ATT_IPACC_RLC_CFG_2, 0, 5,
|
||||
0x00, 250, /* T downlink TBF extension (0..500) */
|
||||
0x00, 250, /* T uplink TBF extension (0..500) */
|
||||
2, /* CS2 */
|
||||
#if 0
|
||||
/* EDGE model only, breaks older models.
|
||||
* Should inquire the BTS capabilities */
|
||||
NM_ATT_IPACC_RLC_CFG_3, 0, 1,
|
||||
2, /* MCS2 */
|
||||
#endif
|
||||
};
|
||||
|
||||
static unsigned char nanobts_attr_nsvc0[] = {
|
||||
NM_ATT_IPACC_NSVCI, 0, 2, 0x03, 0x9d, /* 925 */
|
||||
NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
|
||||
0x59, 0xd8, /* remote udp port (23000) */
|
||||
192, 168, 100, 11, /* remote ip address */
|
||||
0x59, 0xd8, /* local udp port (23000) */
|
||||
};
|
||||
|
||||
/* Callback function to be called whenever we get a GSM 12.21 state change event */
|
||||
int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state)
|
||||
struct gsm_nm_state *old_state, struct gsm_nm_state *new_state,
|
||||
struct abis_om_obj_inst *obj_inst)
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
struct gsm_bts_gprs_nsvc *nsvc;
|
||||
|
||||
/* This event-driven BTS setup is currently only required on nanoBTS */
|
||||
|
||||
@@ -355,16 +419,15 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
switch (obj_class) {
|
||||
case NM_OC_SITE_MANAGER:
|
||||
bts = container_of(obj, struct gsm_bts, site_mgr);
|
||||
if (new_state->operational == 2 &&
|
||||
new_state->availability == NM_AVSTATE_OK) {
|
||||
printf("STARTING SITE MANAGER\n");
|
||||
if ((new_state->operational == NM_OPSTATE_ENABLED &&
|
||||
new_state->availability == NM_AVSTATE_OK) ||
|
||||
(new_state->operational == NM_OPSTATE_DISABLED &&
|
||||
new_state->availability == NM_AVSTATE_OFF_LINE))
|
||||
abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
|
||||
}
|
||||
break;
|
||||
case NM_OC_BTS:
|
||||
bts = obj;
|
||||
if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
printf("STARTING BTS...\n");
|
||||
patch_nm_tables(bts);
|
||||
abis_nm_set_bts_attr(bts, nanobts_attr_bts,
|
||||
sizeof(nanobts_attr_bts));
|
||||
@@ -378,9 +441,8 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
case NM_OC_CHANNEL:
|
||||
ts = obj;
|
||||
trx = ts->trx;
|
||||
if (new_state->operational == 1 &&
|
||||
if (new_state->operational == NM_OPSTATE_DISABLED &&
|
||||
new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
printf("STARTING OC Channel...\n");
|
||||
patch_nm_tables(trx->bts);
|
||||
enum abis_nm_chan_comb ccomb =
|
||||
abis_nm_chcomb4pchan(ts->pchan);
|
||||
@@ -394,11 +456,58 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj,
|
||||
break;
|
||||
case NM_OC_RADIO_CARRIER:
|
||||
trx = obj;
|
||||
if (new_state->operational == 1 &&
|
||||
if (new_state->operational == NM_OPSTATE_DISABLED &&
|
||||
new_state->availability == NM_AVSTATE_OK)
|
||||
abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
|
||||
trx->nr, 0xff);
|
||||
break;
|
||||
case NM_OC_GPRS_NSE:
|
||||
bts = container_of(obj, struct gsm_bts, gprs.nse);
|
||||
if (bts->gprs.mode == BTS_GPRS_NONE)
|
||||
break;
|
||||
if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff, nanobts_attr_nse,
|
||||
sizeof(nanobts_attr_nse));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
0xff, 0xff, NM_STATE_UNLOCKED);
|
||||
}
|
||||
break;
|
||||
case NM_OC_GPRS_CELL:
|
||||
bts = container_of(obj, struct gsm_bts, gprs.cell);
|
||||
if (bts->gprs.mode == BTS_GPRS_NONE)
|
||||
break;
|
||||
if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff, nanobts_attr_cell,
|
||||
sizeof(nanobts_attr_cell));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
0, 0xff, NM_STATE_UNLOCKED);
|
||||
}
|
||||
break;
|
||||
case NM_OC_GPRS_NSVC:
|
||||
nsvc = obj;
|
||||
bts = nsvc->bts;
|
||||
if (bts->gprs.mode == BTS_GPRS_NONE)
|
||||
break;
|
||||
/* We skip NSVC1 since we only use NSVC0 */
|
||||
if (nsvc->id == 1)
|
||||
break;
|
||||
if (new_state->availability == NM_AVSTATE_OFF_LINE) {
|
||||
abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff,
|
||||
nanobts_attr_nsvc0,
|
||||
sizeof(nanobts_attr_nsvc0));
|
||||
abis_nm_opstart(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff);
|
||||
abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
|
||||
nsvc->id, 0xff,
|
||||
NM_STATE_UNLOCKED);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -412,6 +521,8 @@ static int sw_activ_rep(struct msgb *mb)
|
||||
struct gsm_bts *bts = mb->trx->bts;
|
||||
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
|
||||
|
||||
if (!trx)
|
||||
return -EINVAL;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
@@ -433,8 +544,7 @@ static int sw_activ_rep(struct msgb *mb)
|
||||
* This code is here to make sure that on start
|
||||
* a TRX remains locked.
|
||||
*/
|
||||
int rc_state = trx->rf_locked ?
|
||||
NM_STATE_LOCKED : NM_STATE_UNLOCKED;
|
||||
int rc_state = trx->nm_state.administrative;
|
||||
/* Patch ARFCN into radio attribute */
|
||||
nanobts_attr_radio[5] &= 0xf0;
|
||||
nanobts_attr_radio[5] |= trx->arfcn >> 8;
|
||||
@@ -453,9 +563,9 @@ static int sw_activ_rep(struct msgb *mb)
|
||||
}
|
||||
|
||||
/* Callback function for NACK on the OML NM */
|
||||
static int oml_msg_nack(u_int8_t mt)
|
||||
static int oml_msg_nack(struct nm_nack_signal_data *nack)
|
||||
{
|
||||
if (mt == NM_MT_SET_BTS_ATTR_NACK) {
|
||||
if (nack->mt == NM_MT_SET_BTS_ATTR_NACK) {
|
||||
LOGP(DNM, LOGL_FATAL, "Failed to set BTS attributes. That is fatal. "
|
||||
"Was the bts type and frequency properly specified?\n");
|
||||
exit(-1);
|
||||
@@ -468,14 +578,15 @@ static int oml_msg_nack(u_int8_t mt)
|
||||
static int nm_sig_cb(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct nm_nack_signal_data *nack;
|
||||
u_int8_t *msg_type;
|
||||
|
||||
switch (signal) {
|
||||
case S_NM_SW_ACTIV_REP:
|
||||
return sw_activ_rep(signal_data);
|
||||
case S_NM_NACK:
|
||||
msg_type = signal_data;
|
||||
return oml_msg_nack(*msg_type);
|
||||
nack = signal_data;
|
||||
return oml_msg_nack(nack);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -671,57 +782,92 @@ int bsc_shutdown_net(struct gsm_network *net)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generate_and_rsl_si(struct gsm_bts_trx *trx, enum osmo_sysinfo_type i)
|
||||
{
|
||||
struct gsm_bts *bts = trx->bts;
|
||||
int rc;
|
||||
|
||||
/* Only generate SI if this SI is not in "static" (user-defined) mode */
|
||||
if (!(bts->si_mode_static & (1 << i))) {
|
||||
rc = gsm_generate_si(bts, i);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
DEBUGP(DRR, "SI%s: %s\n", gsm_sitype_name(i),
|
||||
hexdump(GSM_BTS_SI(bts, i), GSM_MACBLOCK_LEN));
|
||||
|
||||
switch (i) {
|
||||
case SYSINFO_TYPE_5:
|
||||
case SYSINFO_TYPE_5bis:
|
||||
case SYSINFO_TYPE_5ter:
|
||||
case SYSINFO_TYPE_6:
|
||||
rc = rsl_sacch_filling(trx, gsm_sitype2rsl(i),
|
||||
GSM_BTS_SI(bts, i), rc);
|
||||
break;
|
||||
default:
|
||||
rc = rsl_bcch_info(trx, gsm_sitype2rsl(i),
|
||||
GSM_BTS_SI(bts, i), rc);
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* set all system information types */
|
||||
static int set_system_infos(struct gsm_bts_trx *trx)
|
||||
{
|
||||
int i, rc;
|
||||
u_int8_t si_tmp[23];
|
||||
struct gsm_bts *bts = trx->bts;
|
||||
|
||||
bts->si_common.cell_sel_par.ms_txpwr_max_ccch =
|
||||
ms_pwr_ctl_lvl(bts->band, bts->ms_max_power);
|
||||
bts->si_common.cell_sel_par.neci = bts->network->neci;
|
||||
|
||||
if (trx == trx->bts->c0) {
|
||||
for (i = 1; i <= 4; i++) {
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, i);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_bcch_info(trx, i, si_tmp, sizeof(si_tmp));
|
||||
}
|
||||
#ifdef GPRS
|
||||
i = 13
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_13);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_bcch_info(trx, RSL_SYSTEM_INFO_13, si_tmp, rc);
|
||||
#endif
|
||||
/* First, we determine which of the SI messages we actually need */
|
||||
|
||||
if (trx == bts->c0) {
|
||||
/* 1...4 are always present on a C0 TRX */
|
||||
for (i = SYSINFO_TYPE_1; i <= SYSINFO_TYPE_4; i++)
|
||||
bts->si_valid |= (1 << i);
|
||||
|
||||
/* 13 is always present on a C0 TRX of a GPRS BTS */
|
||||
if (bts->gprs.mode != BTS_GPRS_NONE)
|
||||
bts->si_valid |= (1 << SYSINFO_TYPE_13);
|
||||
}
|
||||
|
||||
i = 5;
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_5);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_5, si_tmp, rc);
|
||||
/* 5 and 6 are always present on every TRX */
|
||||
bts->si_valid |= (1 << SYSINFO_TYPE_5);
|
||||
bts->si_valid |= (1 << SYSINFO_TYPE_6);
|
||||
|
||||
i = 6;
|
||||
rc = gsm_generate_si(si_tmp, trx->bts, RSL_SYSTEM_INFO_6);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
DEBUGP(DRR, "SI%2u: %s\n", i, hexdump(si_tmp, rc));
|
||||
rsl_sacch_filling(trx, RSL_SYSTEM_INFO_6, si_tmp, rc);
|
||||
/* Second, we generate and send the selected SI via RSL */
|
||||
for (i = SYSINFO_TYPE_1; i < _MAX_SYSINFO_TYPE; i++) {
|
||||
if (!(bts->si_valid & (1 << i)))
|
||||
continue;
|
||||
|
||||
rc = generate_and_rsl_si(trx, i);
|
||||
if (rc < 0)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err_out:
|
||||
LOGP(DRR, LOGL_ERROR, "Cannot generate SI %u for BTS %u, most likely "
|
||||
"a problem with neighbor cell list generation\n",
|
||||
i, trx->bts->nr);
|
||||
i, bts->nr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void patch_16(uint8_t *data, const uint16_t val)
|
||||
{
|
||||
memcpy(data, &val, sizeof(val));
|
||||
}
|
||||
|
||||
static void patch_32(uint8_t *data, const uint32_t val)
|
||||
{
|
||||
memcpy(data, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Patch the various SYSTEM INFORMATION tables to update
|
||||
* the LAI
|
||||
@@ -744,26 +890,143 @@ static void patch_nm_tables(struct gsm_bts *bts)
|
||||
bs11_attr_radio[2] |= arfcn_high;
|
||||
bs11_attr_radio[3] = arfcn_low;
|
||||
|
||||
/* patch the RACH attributes */
|
||||
if (bts->rach_b_thresh != -1) {
|
||||
nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
|
||||
bs11_attr_bts[33] = bts->rach_b_thresh & 0xff;
|
||||
}
|
||||
|
||||
if (bts->rach_ldavg_slots != -1) {
|
||||
u_int8_t avg_high = bts->rach_ldavg_slots & 0xff;
|
||||
u_int8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;
|
||||
|
||||
nanobts_attr_bts[35] = avg_high;
|
||||
nanobts_attr_bts[36] = avg_low;
|
||||
bs11_attr_bts[35] = avg_high;
|
||||
bs11_attr_bts[36] = avg_low;
|
||||
}
|
||||
|
||||
/* patch BSIC */
|
||||
bs11_attr_bts[1] = bts->bsic;
|
||||
nanobts_attr_bts[sizeof(nanobts_attr_bts)-1] = bts->bsic;
|
||||
nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;
|
||||
|
||||
/* patch CGI */
|
||||
abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);
|
||||
|
||||
/* patch the power reduction */
|
||||
bs11_attr_radio[5] = bts->c0->max_power_red / 2;
|
||||
nanobts_attr_radio[1] = bts->c0->max_power_red / 2;
|
||||
|
||||
/* patch NSEI */
|
||||
nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
|
||||
nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
|
||||
memcpy(nanobts_attr_nse+8, bts->gprs.nse.timer,
|
||||
ARRAY_SIZE(bts->gprs.nse.timer));
|
||||
memcpy(nanobts_attr_nse+18, bts->gprs.cell.timer,
|
||||
ARRAY_SIZE(bts->gprs.cell.timer));
|
||||
|
||||
/* patch NSVCI */
|
||||
nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
|
||||
nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;
|
||||
|
||||
/* patch IP address as SGSN IP */
|
||||
patch_16(nanobts_attr_nsvc0 + 8,
|
||||
htons(bts->gprs.nsvc[0].remote_port));
|
||||
patch_32(nanobts_attr_nsvc0 + 10,
|
||||
htonl(bts->gprs.nsvc[0].remote_ip));
|
||||
patch_16(nanobts_attr_nsvc0 + 14,
|
||||
htons(bts->gprs.nsvc[0].local_port));
|
||||
|
||||
/* patch BVCI */
|
||||
nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
|
||||
nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
|
||||
/* patch RAC */
|
||||
nanobts_attr_cell[3] = bts->gprs.rac;
|
||||
|
||||
if (bts->gprs.mode == BTS_GPRS_EGPRS) {
|
||||
/* patch EGPRS coding schemes MCS 1..9 */
|
||||
nanobts_attr_cell[29] = 0x8f;
|
||||
nanobts_attr_cell[30] = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Produce a MA as specified in 10.5.2.21 */
|
||||
static int generate_ma_for_ts(struct gsm_bts_trx_ts *ts)
|
||||
{
|
||||
/* we have three bitvecs: the per-timeslot ARFCNs, the cell chan ARFCNs
|
||||
* and the MA */
|
||||
struct bitvec *cell_chan = &ts->trx->bts->si_common.cell_alloc;
|
||||
struct bitvec *ts_arfcn = &ts->hopping.arfcns;
|
||||
struct bitvec *ma = &ts->hopping.ma;
|
||||
unsigned int num_cell_arfcns, bitnum, n_chan;
|
||||
int i;
|
||||
|
||||
/* re-set the MA to all-zero */
|
||||
ma->cur_bit = 0;
|
||||
ts->hopping.ma_len = 0;
|
||||
memset(ma->data, 0, ma->data_len);
|
||||
|
||||
if (!ts->hopping.enabled)
|
||||
return 0;
|
||||
|
||||
/* count the number of ARFCNs in the cell channel allocation */
|
||||
num_cell_arfcns = 0;
|
||||
for (i = 1; i < 1024; i++) {
|
||||
if (bitvec_get_bit_pos(cell_chan, i))
|
||||
num_cell_arfcns++;
|
||||
}
|
||||
|
||||
/* pad it to octet-aligned number of bits */
|
||||
ts->hopping.ma_len = num_cell_arfcns / 8;
|
||||
if (num_cell_arfcns % 8)
|
||||
ts->hopping.ma_len++;
|
||||
|
||||
n_chan = 0;
|
||||
for (i = 1; i < 1024; i++) {
|
||||
if (!bitvec_get_bit_pos(cell_chan, i))
|
||||
continue;
|
||||
/* set the corresponding bit in the MA */
|
||||
bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
|
||||
if (bitvec_get_bit_pos(ts_arfcn, i))
|
||||
bitvec_set_bit_pos(ma, bitnum, 1);
|
||||
else
|
||||
bitvec_set_bit_pos(ma, bitnum, 0);
|
||||
n_chan++;
|
||||
}
|
||||
|
||||
/* ARFCN 0 is special: It is coded last in the bitmask */
|
||||
if (bitvec_get_bit_pos(cell_chan, 0)) {
|
||||
n_chan++;
|
||||
/* set the corresponding bit in the MA */
|
||||
bitnum = (ts->hopping.ma_len * 8) - 1 - n_chan;
|
||||
if (bitvec_get_bit_pos(ts_arfcn, 0))
|
||||
bitvec_set_bit_pos(ma, bitnum, 1);
|
||||
else
|
||||
bitvec_set_bit_pos(ma, bitnum, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bootstrap_rsl(struct gsm_bts_trx *trx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
LOGP(DRSL, LOGL_NOTICE, "bootstrapping RSL for BTS/TRX (%u/%u) "
|
||||
"using MCC=%u MNC=%u BSIC=%u TSC=%u\n",
|
||||
trx->bts->nr, trx->nr, bsc_gsmnet->country_code,
|
||||
bsc_gsmnet->network_code, trx->bts->bsic, trx->bts->tsc);
|
||||
"on ARFCN %u using MCC=%u MNC=%u LAC=%u CID=%u BSIC=%u TSC=%u\n",
|
||||
trx->bts->nr, trx->nr, trx->arfcn, bsc_gsmnet->country_code,
|
||||
bsc_gsmnet->network_code, trx->bts->location_area_code,
|
||||
trx->bts->cell_identity, trx->bts->bsic, trx->bts->tsc);
|
||||
set_system_infos(trx);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
|
||||
generate_ma_for_ts(&trx->ts[i]);
|
||||
}
|
||||
|
||||
void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
|
||||
{
|
||||
int ts_no, lchan_no;
|
||||
|
||||
switch (event) {
|
||||
case EVT_E1_TEI_UP:
|
||||
switch (type) {
|
||||
@@ -778,8 +1041,35 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
|
||||
}
|
||||
break;
|
||||
case EVT_E1_TEI_DN:
|
||||
LOGP(DMI, LOGL_NOTICE, "Lost some E1 TEI link\n");
|
||||
/* FIXME: deal with TEI or L1 link loss */
|
||||
LOGP(DMI, LOGL_ERROR, "Lost some E1 TEI link: %d %p\n", type, trx);
|
||||
|
||||
if (type == E1INP_SIGN_OML)
|
||||
counter_inc(trx->bts->network->stats.bts.oml_fail);
|
||||
else if (type == E1INP_SIGN_RSL)
|
||||
counter_inc(trx->bts->network->stats.bts.rsl_fail);
|
||||
|
||||
/*
|
||||
* free all allocated channels. change the nm_state so the
|
||||
* trx and trx_ts becomes unusable and chan_alloc.c can not
|
||||
* allocate from it.
|
||||
*/
|
||||
for (ts_no = 0; ts_no < ARRAY_SIZE(trx->ts); ++ts_no) {
|
||||
struct gsm_bts_trx_ts *ts = &trx->ts[ts_no];
|
||||
|
||||
for (lchan_no = 0; lchan_no < ARRAY_SIZE(ts->lchan); ++lchan_no) {
|
||||
if (ts->lchan[lchan_no].state != GSM_LCHAN_NONE)
|
||||
lchan_free(&ts->lchan[lchan_no]);
|
||||
lchan_reset(&ts->lchan[lchan_no]);
|
||||
}
|
||||
|
||||
ts->nm_state.operational = 0;
|
||||
ts->nm_state.availability = 0;
|
||||
}
|
||||
|
||||
trx->nm_state.operational = 0;
|
||||
trx->nm_state.availability = 0;
|
||||
trx->bb_transc.nm_state.operational = 0;
|
||||
trx->bb_transc.nm_state.availability = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -788,6 +1078,10 @@ void input_event(int event, enum e1inp_sign_type type, struct gsm_bts_trx *trx)
|
||||
|
||||
static int bootstrap_bts(struct gsm_bts *bts)
|
||||
{
|
||||
int i, n;
|
||||
|
||||
/* FIXME: What about secondary TRX of a BTS? What about a BTS that has TRX
|
||||
* in different bands? Why is 'band' a parameter of the BTS and not of the TRX? */
|
||||
switch (bts->band) {
|
||||
case GSM_BAND_1800:
|
||||
if (bts->c0->arfcn < 512 || bts->c0->arfcn > 885) {
|
||||
@@ -802,8 +1096,16 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
}
|
||||
break;
|
||||
case GSM_BAND_900:
|
||||
if (bts->c0->arfcn < 1 || bts->c0->arfcn > 124) {
|
||||
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124.\n");
|
||||
if (bts->c0->arfcn < 1 ||
|
||||
(bts->c0->arfcn > 124 && bts->c0->arfcn < 955) ||
|
||||
bts->c0->arfcn > 1023) {
|
||||
LOGP(DNM, LOGL_ERROR, "GSM900 channel must be between 1-124, 955-1023.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case GSM_BAND_850:
|
||||
if (bts->c0->arfcn < 128 || bts->c0->arfcn > 251) {
|
||||
LOGP(DNM, LOGL_ERROR, "GSM850 channel must be between 128-251.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
@@ -822,16 +1124,35 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
|
||||
/* Control Channel Description */
|
||||
bts->si_common.chan_desc.att = 1;
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
|
||||
bts->si_common.chan_desc.bs_pa_mfrms = RSL_BS_PA_MFRMS_5;
|
||||
/* T3212 is set from vty/config */
|
||||
|
||||
/* some defaults for our system information */
|
||||
bts->si_common.rach_control.re = 1; /* no re-establishment */
|
||||
bts->si_common.rach_control.tx_integer = 5; /* 8 slots spread */
|
||||
bts->si_common.rach_control.max_trans = 3; /* 7 retransmissions */
|
||||
bts->si_common.rach_control.t2 = 4; /* no emergency calls */
|
||||
/* Set ccch config by looking at ts config */
|
||||
for (n=0, i=0; i<8; i++)
|
||||
n += bts->c0->ts[i].pchan == GSM_PCHAN_CCCH ? 1 : 0;
|
||||
|
||||
switch (n) {
|
||||
case 0:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_C;
|
||||
break;
|
||||
case 1:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_1_NC;
|
||||
break;
|
||||
case 2:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_2_NC;
|
||||
break;
|
||||
case 3:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_3_NC;
|
||||
break;
|
||||
case 4:
|
||||
bts->si_common.chan_desc.ccch_conf = RSL_BCCH_CCCH_CONF_4_NC;
|
||||
break;
|
||||
default:
|
||||
LOGP(DNM, LOGL_ERROR, "Unsupported CCCH timeslot configuration\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* some defaults for our system information */
|
||||
bts->si_common.cell_options.radio_link_timeout = 2; /* 12 */
|
||||
bts->si_common.cell_options.dtx = 2; /* MS shall not use upplink DTX */
|
||||
bts->si_common.cell_options.pwrc = 0; /* PWRC not set */
|
||||
@@ -848,6 +1169,7 @@ static int bootstrap_bts(struct gsm_bts *bts)
|
||||
int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
|
||||
const char *config_file)
|
||||
{
|
||||
struct telnet_connection dummy_conn;
|
||||
struct gsm_bts *bts;
|
||||
int rc;
|
||||
|
||||
@@ -859,13 +1181,18 @@ int bsc_bootstrap_network(int (*mncc_recv)(struct gsm_network *, int, void *),
|
||||
bsc_gsmnet->name_long = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
||||
bsc_gsmnet->name_short = talloc_strdup(bsc_gsmnet, "OpenBSC");
|
||||
|
||||
telnet_init(bsc_gsmnet, 4242);
|
||||
rc = vty_read_config_file(config_file);
|
||||
/* our vty command code expects vty->priv to point to a telnet_connection */
|
||||
dummy_conn.priv = bsc_gsmnet;
|
||||
rc = vty_read_config_file(config_file, &dummy_conn);
|
||||
if (rc < 0) {
|
||||
LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = telnet_init(tall_bsc_ctx, bsc_gsmnet, 4242);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
register_signal_handler(SS_NM, nm_sig_cb, NULL);
|
||||
|
||||
llist_for_each_entry(bts, &bsc_gsmnet->bts_list, list) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/* Routines to talk to the MSC using the IPA Protocol */
|
||||
/*
|
||||
* (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2010 by on-waves.com
|
||||
* (C) 2010 by On-Waves
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -21,23 +21,138 @@
|
||||
*/
|
||||
|
||||
#include <openbsc/bsc_msc.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
|
||||
#include <osmocore/write_queue.h>
|
||||
#include <osmocore/talloc.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
|
||||
static void connection_loss(struct bsc_msc_connection *con)
|
||||
{
|
||||
struct bsc_fd *fd;
|
||||
|
||||
fd = &con->write_queue.bfd;
|
||||
|
||||
close(fd->fd);
|
||||
fd->fd = -1;
|
||||
fd->cb = write_queue_bfd_cb;
|
||||
fd->when = 0;
|
||||
|
||||
con->is_connected = 0;
|
||||
con->first_contact = 0;
|
||||
con->connection_loss(con);
|
||||
}
|
||||
|
||||
static void msc_con_timeout(void *_con)
|
||||
{
|
||||
struct bsc_msc_connection *con = _con;
|
||||
|
||||
LOGP(DMSC, LOGL_ERROR, "MSC Connection timeout.\n");
|
||||
bsc_msc_lost(con);
|
||||
}
|
||||
|
||||
static int bsc_msc_except(struct bsc_fd *bfd)
|
||||
{
|
||||
struct write_queue *wrt;
|
||||
struct bsc_msc_connection *con;
|
||||
|
||||
LOGP(DMSC, LOGL_ERROR, "Exception on the BFD. Closing down.\n");
|
||||
|
||||
wrt = container_of(bfd, struct write_queue, bfd);
|
||||
con = container_of(wrt, struct bsc_msc_connection, write_queue);
|
||||
|
||||
connection_loss(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called in the case of a non blocking connect */
|
||||
static int msc_connection_connect(struct bsc_fd *fd, unsigned int what)
|
||||
{
|
||||
int rc;
|
||||
int val;
|
||||
struct bsc_msc_connection *con;
|
||||
struct write_queue *queue;
|
||||
|
||||
socklen_t len = sizeof(val);
|
||||
|
||||
if ((what & BSC_FD_WRITE) == 0) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Callback but not readable.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
queue = container_of(fd, struct write_queue, bfd);
|
||||
con = container_of(queue, struct bsc_msc_connection, write_queue);
|
||||
|
||||
/* check the socket state */
|
||||
rc = getsockopt(fd->fd, SOL_SOCKET, SO_ERROR, &val, &len);
|
||||
if (rc != 0) {
|
||||
LOGP(DMSC, LOGL_ERROR, "getsockopt for the MSC socket failed.\n");
|
||||
goto error;
|
||||
}
|
||||
if (val != 0) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Not connected to the MSC: %d\n", val);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
/* go to full operation */
|
||||
fd->cb = write_queue_bfd_cb;
|
||||
fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
|
||||
|
||||
con->is_connected = 1;
|
||||
bsc_del_timer(&con->timeout_timer);
|
||||
LOGP(DMSC, LOGL_NOTICE, "(Re)Connected to the MSC.\n");
|
||||
if (con->connected)
|
||||
con->connected(con);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
bsc_unregister_fd(fd);
|
||||
connection_loss(con);
|
||||
return -1;
|
||||
}
|
||||
static void setnonblocking(struct bsc_fd *fd)
|
||||
{
|
||||
int flags;
|
||||
|
||||
flags = fcntl(fd->fd, F_GETFL);
|
||||
if (flags < 0) {
|
||||
perror("fcntl get failed");
|
||||
close(fd->fd);
|
||||
fd->fd = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
flags |= O_NONBLOCK;
|
||||
flags = fcntl(fd->fd, F_SETFL, flags);
|
||||
if (flags < 0) {
|
||||
perror("fcntl get failed");
|
||||
close(fd->fd);
|
||||
fd->fd = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int bsc_msc_connect(struct bsc_msc_connection *con)
|
||||
{
|
||||
struct bsc_fd *fd;
|
||||
struct sockaddr_in sin;
|
||||
int on = 1, ret;
|
||||
|
||||
printf("Attempting to connect MSC at %s:%d\n", ip, port);
|
||||
LOGP(DMSC, LOGL_NOTICE, "Attempting to connect MSC at %s:%d\n", con->ip, con->port);
|
||||
|
||||
con->is_connected = 0;
|
||||
|
||||
fd = &con->write_queue.bfd;
|
||||
fd->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
fd->when = BSC_FD_READ;
|
||||
fd->data = NULL;
|
||||
fd->priv_nr = 1;
|
||||
|
||||
if (fd->fd < 0) {
|
||||
@@ -45,18 +160,41 @@ int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
|
||||
return fd->fd;
|
||||
}
|
||||
|
||||
/* make it non blocking */
|
||||
setnonblocking(fd);
|
||||
|
||||
/* set the socket priority */
|
||||
ret = setsockopt(fd->fd, IPPROTO_IP, IP_TOS,
|
||||
&con->prio, sizeof(con->prio));
|
||||
if (ret != 0)
|
||||
LOGP(DMSC, LOGL_ERROR, "Failed to set prio to %d. %s\n",
|
||||
con->prio, strerror(errno));
|
||||
|
||||
memset(&sin, 0, sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons(port);
|
||||
inet_aton(ip, &sin.sin_addr);
|
||||
sin.sin_port = htons(con->port);
|
||||
inet_aton(con->ip, &sin.sin_addr);
|
||||
|
||||
setsockopt(fd->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
|
||||
ret = connect(fd->fd, (struct sockaddr *) &sin, sizeof(sin));
|
||||
|
||||
if (ret < 0) {
|
||||
if (ret == -1 && errno == EINPROGRESS) {
|
||||
LOGP(DMSC, LOGL_ERROR, "MSC Connection in progress\n");
|
||||
fd->when = BSC_FD_WRITE;
|
||||
fd->cb = msc_connection_connect;
|
||||
con->timeout_timer.cb = msc_con_timeout;
|
||||
con->timeout_timer.data = con;
|
||||
bsc_schedule_timer(&con->timeout_timer, 20, 0);
|
||||
} else if (ret < 0) {
|
||||
perror("Connection failed");
|
||||
connection_loss(con);
|
||||
return ret;
|
||||
} else {
|
||||
fd->when = BSC_FD_READ | BSC_FD_EXCEPT;
|
||||
fd->cb = write_queue_bfd_cb;
|
||||
con->is_connected = 1;
|
||||
if (con->connected)
|
||||
con->connected(con);
|
||||
}
|
||||
|
||||
ret = bsc_register_fd(fd);
|
||||
@@ -69,4 +207,64 @@ int connect_to_msc(struct bsc_fd *fd, const char *ip, int port)
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct bsc_msc_connection *bsc_msc_create(const char *ip, int port, int prio)
|
||||
{
|
||||
struct bsc_msc_connection *con;
|
||||
|
||||
con = talloc_zero(NULL, struct bsc_msc_connection);
|
||||
if (!con) {
|
||||
LOGP(DMSC, LOGL_FATAL, "Failed to create the MSC connection.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
con->ip = ip;
|
||||
con->port = port;
|
||||
con->prio = prio;
|
||||
write_queue_init(&con->write_queue, 100);
|
||||
con->write_queue.except_cb = bsc_msc_except;
|
||||
return con;
|
||||
}
|
||||
|
||||
void bsc_msc_lost(struct bsc_msc_connection *con)
|
||||
{
|
||||
write_queue_clear(&con->write_queue);
|
||||
bsc_unregister_fd(&con->write_queue.bfd);
|
||||
connection_loss(con);
|
||||
}
|
||||
|
||||
static void reconnect_msc(void *_msc)
|
||||
{
|
||||
struct bsc_msc_connection *con = _msc;
|
||||
|
||||
LOGP(DMSC, LOGL_NOTICE, "Attempting to reconnect to the MSC.\n");
|
||||
bsc_msc_connect(con);
|
||||
}
|
||||
|
||||
void bsc_msc_schedule_connect(struct bsc_msc_connection *con)
|
||||
{
|
||||
LOGP(DMSC, LOGL_NOTICE, "Attempting to reconnect to the MSC.\n");
|
||||
con->reconnect_timer.cb = reconnect_msc;
|
||||
con->reconnect_timer.data = con;
|
||||
bsc_schedule_timer(&con->reconnect_timer, 5, 0);
|
||||
}
|
||||
|
||||
struct msgb *bsc_msc_id_get_resp(const char *token)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
||||
if (!token) {
|
||||
LOGP(DMSC, LOGL_ERROR, "No token specified.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg = msgb_alloc_headroom(4096, 128, "id resp");
|
||||
if (!msg) {
|
||||
LOGP(DMSC, LOGL_ERROR, "Failed to create the message.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg->l2h = msgb_v_put(msg, IPAC_MSGT_ID_RESP);
|
||||
msgb_l16tv_put(msg, strlen(token) + 1,
|
||||
IPAC_IDTAG_UNITNAME, (u_int8_t *) token);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -1,809 +0,0 @@
|
||||
/* A hackish minimal BSC (+MSC +HLR) implementation */
|
||||
|
||||
/* (C) 2008-2009 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
* (C) 2009 by on-waves.com
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/e1_input.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/select.h>
|
||||
#include <openbsc/ipaccess.h>
|
||||
#include <openbsc/bssap.h>
|
||||
#include <openbsc/paging.h>
|
||||
#include <openbsc/signal.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/bsc_msc.h>
|
||||
|
||||
#include <sccp/sccp.h>
|
||||
|
||||
/* SCCP helper */
|
||||
#define SCCP_IT_TIMER 60
|
||||
|
||||
/* MCC and MNC for the Location Area Identifier */
|
||||
struct gsm_network *bsc_gsmnet = 0;
|
||||
static const char *config_file = "openbsc.cfg";
|
||||
static char *msc_address = "127.0.0.1";
|
||||
static struct bsc_fd msc_connection;
|
||||
static struct in_addr local_addr;
|
||||
extern int ipacc_rtp_direct;
|
||||
|
||||
extern int bsc_bootstrap_network(int (*layer4)(struct gsm_network *, int, void *), const char *cfg_file);
|
||||
extern int bsc_shutdown_net(struct gsm_network *net);
|
||||
|
||||
struct bss_sccp_connection_data *bss_sccp_create_data()
|
||||
{
|
||||
struct bss_sccp_connection_data *data;
|
||||
|
||||
data = _talloc_zero(tall_bsc_ctx,
|
||||
sizeof(struct bss_sccp_connection_data),
|
||||
"bsc<->msc");
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
INIT_LLIST_HEAD(&data->sccp_queue);
|
||||
INIT_LLIST_HEAD(&data->gsm_queue);
|
||||
return data;
|
||||
}
|
||||
|
||||
void bss_sccp_free_data(struct bss_sccp_connection_data *data)
|
||||
{
|
||||
bsc_del_timer(&data->T10);
|
||||
bsc_del_timer(&data->sccp_it);
|
||||
bsc_free_queued(data->sccp);
|
||||
bts_free_queued(data);
|
||||
talloc_free(data);
|
||||
}
|
||||
|
||||
static void sccp_it_fired(void *_data)
|
||||
{
|
||||
struct bss_sccp_connection_data *data =
|
||||
(struct bss_sccp_connection_data *) _data;
|
||||
|
||||
sccp_connection_send_it(data->sccp);
|
||||
bsc_schedule_timer(&data->sccp_it, SCCP_IT_TIMER, 0);
|
||||
}
|
||||
|
||||
|
||||
/* GSM subscriber drop-ins */
|
||||
extern struct llist_head *subscr_bsc_active_subscriber(void);
|
||||
struct gsm_subscriber *find_subscriber(u_int8_t type, const char *mi_string)
|
||||
{
|
||||
struct gsm_subscriber *subscr;
|
||||
u_int32_t tmsi = GSM_RESERVED_TMSI;
|
||||
if (type == GSM_MI_TYPE_TMSI) {
|
||||
tmsi = tmsi_from_string(mi_string);
|
||||
if (tmsi == GSM_RESERVED_TMSI) {
|
||||
DEBUGP(DMSC, "The TMSI is the reserved one.\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
llist_for_each_entry(subscr, subscr_bsc_active_subscriber(), entry) {
|
||||
if (type == GSM_MI_TYPE_TMSI && tmsi == subscr->tmsi) {
|
||||
return subscr_get(subscr);
|
||||
} else if (type == GSM_MI_TYPE_IMSI && strcmp(mi_string, subscr->imsi) == 0) {
|
||||
return subscr_get(subscr);
|
||||
}
|
||||
}
|
||||
|
||||
DEBUGP(DMSC, "No subscriber has been found.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* SCCP handling */
|
||||
void msc_outgoing_sccp_data(struct sccp_connection *conn, struct msgb *msg, unsigned int len)
|
||||
{
|
||||
struct bssmap_header *bs;
|
||||
|
||||
if (len < 1) {
|
||||
DEBUGP(DMSC, "The header is too short.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (msg->l3h[0]) {
|
||||
case BSSAP_MSG_BSS_MANAGEMENT:
|
||||
msg->l4h = &msg->l3h[sizeof(*bs)];
|
||||
msg->lchan = sccp_get_lchan(conn->data_ctx);
|
||||
bssmap_rcvmsg_dt1(conn, msg, len - sizeof(*bs));
|
||||
break;
|
||||
case BSSAP_MSG_DTAP:
|
||||
dtap_rcvmsg(sccp_get_lchan(conn->data_ctx), msg, len);
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", msg->l3h[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void msc_outgoing_sccp_state(struct sccp_connection *conn, int old_state)
|
||||
{
|
||||
if (conn->connection_state >= SCCP_CONNECTION_STATE_RELEASE_COMPLETE) {
|
||||
DEBUGP(DMSC, "Freeing sccp conn: %p state: %d\n", conn, conn->connection_state);
|
||||
if (sccp_get_lchan(conn->data_ctx) != NULL) {
|
||||
struct gsm_lchan *lchan = sccp_get_lchan(conn->data_ctx);
|
||||
|
||||
DEBUGP(DMSC, "ERROR: The lchan is still associated\n.");
|
||||
|
||||
lchan->msc_data = NULL;
|
||||
put_lchan(lchan);
|
||||
}
|
||||
|
||||
bss_sccp_free_data((struct bss_sccp_connection_data *)conn->data_ctx);
|
||||
sccp_connection_free(conn);
|
||||
return;
|
||||
} else if (conn->connection_state == SCCP_CONNECTION_STATE_ESTABLISHED) {
|
||||
struct bss_sccp_connection_data *con_data;
|
||||
|
||||
DEBUGP(DMSC, "Connection established: %p\n", conn);
|
||||
|
||||
/* start the inactivity test timer */
|
||||
con_data = (struct bss_sccp_connection_data *) conn->data_ctx;
|
||||
con_data->sccp_it.cb = sccp_it_fired;
|
||||
con_data->sccp_it.data = con_data;
|
||||
bsc_schedule_timer(&con_data->sccp_it, SCCP_IT_TIMER, 0);
|
||||
|
||||
bsc_send_queued(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* General COMPLETE LAYER3 INFORMATION handling for
|
||||
* PAGING RESPONSE, LOCATION UPDATING REQUEST, CM REESTABLISHMENT REQUEST,
|
||||
* CM SERVICE REQUEST, IMSI DETACH, IMMEDIATE SETUP.
|
||||
*
|
||||
* IMMEDIATE SETUP is coming from GROUP CC that is not yet
|
||||
* supported...
|
||||
*/
|
||||
int open_sccp_connection(struct msgb *layer3)
|
||||
{
|
||||
struct bss_sccp_connection_data *con_data;
|
||||
struct sccp_connection *sccp_connection;
|
||||
struct msgb *data;
|
||||
|
||||
DEBUGP(DMSC, "Opening new layer3 connection\n");
|
||||
sccp_connection = sccp_connection_socket();
|
||||
if (!sccp_connection) {
|
||||
DEBUGP(DMSC, "Failed to allocate memory.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
data = bssmap_create_layer3(layer3);
|
||||
if (!data) {
|
||||
DEBUGP(DMSC, "Failed to allocate complete layer3.\n");
|
||||
sccp_connection_free(sccp_connection);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
con_data = bss_sccp_create_data();
|
||||
if (!con_data) {
|
||||
DEBUGP(DMSC, "Failed to allocate bss<->msc data.\n");
|
||||
sccp_connection_free(sccp_connection);
|
||||
msgb_free(data);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* initialize the bridge */
|
||||
con_data->lchan = layer3->lchan;
|
||||
con_data->sccp = sccp_connection;
|
||||
|
||||
sccp_connection->state_cb = msc_outgoing_sccp_state;
|
||||
sccp_connection->data_cb = msc_outgoing_sccp_data;
|
||||
sccp_connection->data_ctx = con_data;
|
||||
layer3->lchan->msc_data = con_data;
|
||||
|
||||
/* FIXME: Use transaction for this */
|
||||
use_lchan(layer3->lchan);
|
||||
sccp_connection_connect(sccp_connection, &sccp_ssn_bssap, data);
|
||||
msgb_free(data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* figure out if this is the inial layer3 message */
|
||||
static int send_dtap_or_open_connection(struct msgb *msg)
|
||||
{
|
||||
if (msg->lchan->msc_data) {
|
||||
struct msgb *dtap = dtap_create_msg(msg, 0);
|
||||
if (!dtap) {
|
||||
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
|
||||
return 1;
|
||||
} else {
|
||||
return open_sccp_connection(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Receive a PAGING RESPONSE message from the MS */
|
||||
static int handle_paging_response(struct msgb *msg)
|
||||
{
|
||||
struct gsm_subscriber *subscr;
|
||||
char mi_string[GSM48_MI_SIZE];
|
||||
u_int8_t mi_type;
|
||||
|
||||
gsm48_paging_extract_mi(msg, mi_string, &mi_type);
|
||||
DEBUGP(DMSC, "PAGING RESPONSE: mi_type=0x%02x MI(%s)\n",
|
||||
mi_type, mi_string);
|
||||
|
||||
subscr = find_subscriber(mi_type, mi_string);
|
||||
if (!subscr)
|
||||
return -EINVAL;
|
||||
|
||||
/* force the paging to stop at every bts */
|
||||
subscr->lac = GSM_LAC_RESERVED_ALL_BTS;
|
||||
if (gsm48_handle_paging_resp(msg, subscr) != 0) {
|
||||
DEBUGP(DMSC, "Paging failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open a new transaction and SCCP connection */
|
||||
return send_dtap_or_open_connection(msg);
|
||||
}
|
||||
|
||||
/* Receive a CIPHER MODE COMPLETE from the MS */
|
||||
static int handle_cipher_m_complete(struct msgb *msg)
|
||||
{
|
||||
struct msgb *resp;
|
||||
|
||||
DEBUGP(DMSC, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
|
||||
resp = bssmap_create_cipher_complete(msg);
|
||||
if (!resp) {
|
||||
DEBUGP(DMSC, "Creating MSC response failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* handled this message */
|
||||
bts_unblock_queue(msg->lchan->msc_data);
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), resp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Receive a ASSIGNMENT COMPLETE */
|
||||
static int handle_ass_compl(struct msgb *msg)
|
||||
{
|
||||
struct gsm_lchan *old_chan;
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
||||
DEBUGP(DMSC, "ASSIGNMENT COMPLETE from MS, forwarding to MSC\n");
|
||||
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* swap the channels and release the old */
|
||||
old_chan = msg->lchan->msc_data->lchan;
|
||||
msg->lchan->msc_data->lchan = msg->lchan;
|
||||
msg->lchan->msc_data->secondary_lchan = NULL;
|
||||
old_chan->msc_data = NULL;
|
||||
|
||||
/* give up the old channel to not do a SACCH deactivate */
|
||||
subscr_put(old_chan->subscr);
|
||||
old_chan->subscr = NULL;
|
||||
put_lchan(old_chan);
|
||||
|
||||
/* activate audio on it... */
|
||||
if (is_ipaccess_bts(msg->lchan->ts->trx->bts) && msg->lchan->tch_mode != GSM48_CMODE_SIGN)
|
||||
rsl_ipacc_crcx(msg->lchan);
|
||||
|
||||
gsm0808_send_assignment_compl(msg->lchan, gh->data[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a ASSIGNMENT FAILURE. If the message is failed
|
||||
* to be parsed the T10 timer will send the failure.
|
||||
*/
|
||||
static int handle_ass_fail(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
|
||||
DEBUGP(DMSC, "ASSIGNMENT FAILURE from MS, forwarding to MSC\n");
|
||||
if (!msg->lchan->msc_data) {
|
||||
DEBUGP(DMSC, "No MSC data\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msg->lchan->msc_data->secondary_lchan != msg->lchan) {
|
||||
LOGP(DMSC, LOGL_NOTICE, "Wrong assignment complete.\n");
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (msgb_l3len(msg) - sizeof(*gh) != 1) {
|
||||
DEBUGP(DMSC, "assignment failure invalid: %d\n",
|
||||
msgb_l3len(msg) - sizeof(*gh));
|
||||
put_lchan(msg->lchan);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gsm0808_send_assignment_failure(msg->lchan,
|
||||
GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, &gh->data[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a GSM04.08 MODIFY ACK. Actually we have to check
|
||||
* the content to see if this was a success or not.
|
||||
*/
|
||||
static int handle_modify_ack(struct msgb *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* modify RSL */
|
||||
rc = gsm48_rx_rr_modif_ack(msg);
|
||||
if (rc < 0)
|
||||
gsm0808_send_assignment_failure(msg->lchan,
|
||||
GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE, NULL);
|
||||
else
|
||||
gsm0808_send_assignment_compl(msg->lchan, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Receive a GSM 04.08 Radio Resource (RR) message */
|
||||
static int gsm0408_rcv_rr(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
int rc = 0;
|
||||
|
||||
switch (gh->msg_type) {
|
||||
case GSM48_MT_RR_PAG_RESP:
|
||||
rc = handle_paging_response(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_MEAS_REP:
|
||||
/* ignore measurement for now */
|
||||
rc = -1;
|
||||
break;
|
||||
case GSM48_MT_RR_CIPH_M_COMPL:
|
||||
rc = handle_cipher_m_complete(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_ASS_COMPL:
|
||||
rc = handle_ass_compl(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_ASS_FAIL:
|
||||
rc = handle_ass_fail(msg);
|
||||
break;
|
||||
case GSM48_MT_RR_CHAN_MODE_MODIF_ACK:
|
||||
rc = handle_modify_ack(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Receive a GSM 04.08 Mobility Management (MM) message */
|
||||
static int gsm0408_rcv_mm(struct msgb *msg)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
int rc = 0;
|
||||
|
||||
switch (gh->msg_type & 0xbf) {
|
||||
case GSM48_MT_MM_LOC_UPD_REQUEST:
|
||||
case GSM48_MT_MM_CM_REEST_REQ:
|
||||
case GSM48_MT_MM_CM_SERV_REQ:
|
||||
case GSM48_MT_MM_IMSI_DETACH_IND:
|
||||
rc = send_dtap_or_open_connection(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int gsm0408_rcvmsg(struct msgb *msg, u_int8_t link_id)
|
||||
{
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
u_int8_t pdisc = gh->proto_discr & 0x0f;
|
||||
int rc = 0;
|
||||
|
||||
switch (pdisc) {
|
||||
case GSM48_PDISC_RR:
|
||||
rc = gsm0408_rcv_rr(msg);
|
||||
break;
|
||||
case GSM48_PDISC_MM:
|
||||
rc = gsm0408_rcv_mm(msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we have a sccp connection and didn't handle the message
|
||||
* forward it to the MSC using DTAP
|
||||
*/
|
||||
if (rc == 0 && msg->lchan->msc_data && lchan_get_sccp(msg->lchan)) {
|
||||
struct msgb *dtap = dtap_create_msg(msg, link_id);
|
||||
if (!dtap) {
|
||||
DEBUGP(DMSC, "Creating a DTAP message failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bsc_queue_connection_write(lchan_get_sccp(msg->lchan), dtap);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* handle ipaccess signals */
|
||||
static int handle_abisip_signal(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct gsm_lchan *lchan = signal_data;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
int rc;
|
||||
|
||||
if (subsys != SS_ABISIP)
|
||||
return 0;
|
||||
|
||||
ts = lchan->ts;
|
||||
|
||||
switch (signal) {
|
||||
case S_ABISIP_CRCX_ACK:
|
||||
/* we can ask it to connect now */
|
||||
if (lchan->msc_data) {
|
||||
DEBUGP(DMSC, "Connecting BTS to port: %d conn: %d\n",
|
||||
lchan->msc_data->rtp_port, lchan->abis_ip.conn_id);
|
||||
|
||||
int rtp_payload = ts->trx->bts->network->rtp_payload;
|
||||
if (rtp_payload == 0)
|
||||
rtp_payload = lchan->abis_ip.rtp_payload2;
|
||||
|
||||
rc = rsl_ipacc_mdcx(lchan, ntohl(local_addr.s_addr),
|
||||
lchan->msc_data->rtp_port,
|
||||
rtp_payload);
|
||||
if (rc < 0) {
|
||||
DEBUGP(DMSC, "Failed to send connect: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case S_ABISIP_DLCX_IND:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: bsc_hack\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* SCCP handling
|
||||
*/
|
||||
static int msc_sccp_write_ipa(struct msgb *msg, void *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DEBUGP(DMSC, "Sending SCCP to MSC: %u\n", msgb_l2len(msg));
|
||||
ipaccess_prepend_header(msg, IPAC_PROTO_SCCP);
|
||||
|
||||
|
||||
DEBUGP(DMI, "MSC TX %s\n", hexdump(msg->l2h, msgb_l2len(msg)));
|
||||
ret = write(msc_connection.fd, msg->data, msg->len);
|
||||
|
||||
if (ret <= 0) {
|
||||
perror("MSC: Failed to send SCCP");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msc_sccp_accept(struct sccp_connection *connection, void *data)
|
||||
{
|
||||
DEBUGP(DMSC, "Rejecting incoming SCCP connection.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int msc_sccp_read(struct msgb *msgb, unsigned int length, void *data)
|
||||
{
|
||||
struct bssmap_header *bs;
|
||||
|
||||
DEBUGP(DMSC, "Incoming SCCP message ftom MSC: %s\n", hexdump(msgb->l3h, length));
|
||||
|
||||
if (length < sizeof(*bs)) {
|
||||
DEBUGP(DMSC, "The header is too short.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
bs = (struct bssmap_header *) msgb->l3h;
|
||||
if (bs->length < length - sizeof(*bs))
|
||||
return -1;
|
||||
|
||||
switch (bs->type) {
|
||||
case BSSAP_MSG_BSS_MANAGEMENT:
|
||||
msgb->l4h = &msgb->l3h[sizeof(*bs)];
|
||||
bssmap_rcvmsg_udt(bsc_gsmnet, msgb, length - sizeof(*bs));
|
||||
break;
|
||||
default:
|
||||
DEBUGPC(DMSC, "Unimplemented msg type: %d\n", bs->type);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* network initialisation
|
||||
*/
|
||||
static void initialize_if_needed(void)
|
||||
{
|
||||
if (!bsc_gsmnet) {
|
||||
int rc;
|
||||
struct msgb *msg;
|
||||
|
||||
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* send a gsm 08.08 reset message from here */
|
||||
msg = bssmap_create_reset();
|
||||
if (!msg) {
|
||||
DEBUGP(DMSC, "Failed to create the reset message.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sccp_write(msg, &sccp_ssn_bssap, &sccp_ssn_bssap, 0);
|
||||
msgb_free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* callback with IP access data
|
||||
*/
|
||||
static int ipaccess_a_fd_cb(struct bsc_fd *bfd, unsigned int what)
|
||||
{
|
||||
int error;
|
||||
struct msgb *msg = ipaccess_read_msg(bfd, &error);
|
||||
struct ipaccess_head *hh;
|
||||
|
||||
if (!msg) {
|
||||
if (error == 0) {
|
||||
fprintf(stderr, "The connection to the MSC was lost, exiting\n");
|
||||
exit(-2);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to parse ip access message: %d\n", error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUGP(DMSC, "From MSC: %s proto: %d\n", hexdump(msg->data, msg->len), msg->l2h[0]);
|
||||
|
||||
/* handle base message handling */
|
||||
hh = (struct ipaccess_head *) msg->data;
|
||||
ipaccess_rcvmsg_base(msg, bfd);
|
||||
|
||||
/* initialize the networking. This includes sending a GSM08.08 message */
|
||||
if (hh->proto == IPAC_PROTO_IPACCESS && msg->l2h[0] == IPAC_MSGT_ID_ACK)
|
||||
initialize_if_needed();
|
||||
else if (hh->proto == IPAC_PROTO_SCCP)
|
||||
sccp_system_incoming(msg);
|
||||
|
||||
msgb_free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
printf(" Some useful help...\n");
|
||||
printf(" -h --help this text\n");
|
||||
printf(" -d option --debug=DRLL:DCC:DMM:DRR:DRSL:DNM enable debugging\n");
|
||||
printf(" -s --disable-color\n");
|
||||
printf(" -c --config-file filename The config file to use.\n");
|
||||
printf(" -m --msc=IP. The address of the MSC.\n");
|
||||
printf(" -l --local=IP. The local address of the MGCP.\n");
|
||||
}
|
||||
|
||||
static void handle_options(int argc, char** argv)
|
||||
{
|
||||
while (1) {
|
||||
int option_index = 0, c;
|
||||
static struct option long_options[] = {
|
||||
{"help", 0, 0, 'h'},
|
||||
{"debug", 1, 0, 'd'},
|
||||
{"config-file", 1, 0, 'c'},
|
||||
{"disable-color", 0, 0, 's'},
|
||||
{"timestamp", 0, 0, 'T'},
|
||||
{"rtp-proxy", 0, 0, 'P'},
|
||||
{"msc", 1, 0, 'm'},
|
||||
{"local", 1, 0, 'l'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hd:sTPc:m:l:",
|
||||
long_options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'h':
|
||||
print_usage();
|
||||
print_help();
|
||||
exit(0);
|
||||
case 's':
|
||||
debug_use_color(0);
|
||||
break;
|
||||
case 'd':
|
||||
debug_parse_category_mask(optarg);
|
||||
break;
|
||||
case 'c':
|
||||
config_file = strdup(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
debug_timestamp(1);
|
||||
break;
|
||||
case 'P':
|
||||
ipacc_rtp_direct = 0;
|
||||
break;
|
||||
case 'm':
|
||||
msc_address = strdup(optarg);
|
||||
break;
|
||||
case 'l':
|
||||
inet_aton(optarg, &local_addr);
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_handler(int signal)
|
||||
{
|
||||
fprintf(stdout, "signal %u received\n", signal);
|
||||
|
||||
switch (signal) {
|
||||
case SIGINT:
|
||||
bsc_shutdown_net(bsc_gsmnet);
|
||||
sleep(3);
|
||||
exit(0);
|
||||
break;
|
||||
case SIGABRT:
|
||||
/* in case of abort, we want to obtain a talloc report
|
||||
* and then return to the caller, who will abort the process */
|
||||
case SIGUSR1:
|
||||
talloc_report_full(tall_bsc_ctx, stderr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_mode()
|
||||
{
|
||||
static const u_int8_t assignment_req[] = { 0x01, 0x0b, 0x03, 0x01, 0x0b, 0x25, 0x01, 0x00, 0x01 };
|
||||
struct gsm_lchan lchan;
|
||||
struct sccp_connection conn;
|
||||
struct bss_sccp_connection_data data;
|
||||
|
||||
struct gsm_bts_trx_ts trx_ts;
|
||||
struct gsm_bts_trx trx;
|
||||
struct gsm_bts bts;
|
||||
int rc;
|
||||
|
||||
/* initialize */
|
||||
fprintf(stderr, "Bootstraping the network. Sending GSM08.08 reset.\n");
|
||||
rc = bsc_bootstrap_network(NULL, config_file);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Bootstrapping the network failed. exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bts.network = bsc_gsmnet;
|
||||
trx.bts = &bts;
|
||||
trx_ts.trx = &trx;
|
||||
lchan.ts = &trx_ts;
|
||||
|
||||
/* create fake data connection */
|
||||
data.lchan = &lchan;
|
||||
data.sccp = &conn;
|
||||
lchan.msc_data = &data;
|
||||
conn.data_ctx = &data;
|
||||
|
||||
|
||||
struct msgb *msg = msgb_alloc(400, "test-msg");
|
||||
msg->lchan = &lchan;
|
||||
|
||||
msg->l4h = msgb_put(msg, ARRAY_SIZE(assignment_req));
|
||||
memcpy(msg->l4h, assignment_req, ARRAY_SIZE(assignment_req));
|
||||
bssmap_rcvmsg_dt1(&conn, msg, ARRAY_SIZE(assignment_req));
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc;
|
||||
|
||||
tall_bsc_ctx = talloc_named_const(NULL, 1, "openbsc");
|
||||
|
||||
/* parse options */
|
||||
handle_options(argc, argv);
|
||||
|
||||
/* seed the PRNG */
|
||||
srand(time(NULL));
|
||||
|
||||
/* initialize sccp */
|
||||
sccp_system_init(msc_sccp_write_ipa, NULL);
|
||||
sccp_connection_set_incoming(&sccp_ssn_bssap, msc_sccp_accept, NULL);
|
||||
sccp_set_read(&sccp_ssn_bssap, msc_sccp_read, NULL);
|
||||
|
||||
/* initialize ipaccess handling */
|
||||
register_signal_handler(SS_ABISIP, handle_abisip_signal, NULL);
|
||||
|
||||
msc_connection.cb = ipaccess_a_fd_cb;
|
||||
rc = connect_to_msc(&msc_connection, msc_address, 5000);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Opening the MSC connection failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
signal(SIGINT, &signal_handler);
|
||||
signal(SIGABRT, &signal_handler);
|
||||
signal(SIGUSR1, &signal_handler);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
while (1) {
|
||||
bsc_select_main(0);
|
||||
}
|
||||
}
|
||||
@@ -24,13 +24,14 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <openbsc/debug.h>
|
||||
#include <openbsc/talloc.h>
|
||||
#include <openbsc/timer.h>
|
||||
#include <openbsc/linuxlist.h>
|
||||
#include <osmocore/talloc.h>
|
||||
#include <osmocore/timer.h>
|
||||
#include <osmocore/linuxlist.h>
|
||||
#include <openbsc/bsc_rll.h>
|
||||
#include <openbsc/gsm_data.h>
|
||||
#include <openbsc/chan_alloc.h>
|
||||
#include <openbsc/abis_rsl.h>
|
||||
#include <openbsc/signal.h>
|
||||
|
||||
struct bsc_rll_req {
|
||||
struct llist_head list;
|
||||
@@ -52,7 +53,6 @@ static LLIST_HEAD(bsc_rll_reqs);
|
||||
static void complete_rllr(struct bsc_rll_req *rllr, enum bsc_rllr_ind type)
|
||||
{
|
||||
llist_del(&rllr->list);
|
||||
put_lchan(rllr->lchan);
|
||||
rllr->cb(rllr->lchan, rllr->link_id, rllr->data, type);
|
||||
talloc_free(rllr);
|
||||
}
|
||||
@@ -80,11 +80,9 @@ int rll_establish(struct gsm_lchan *lchan, u_int8_t sapi,
|
||||
/* If we are a TCH and not in signalling mode, we need to
|
||||
* indicate that the new RLL connection is to be made on the SACCH */
|
||||
if ((lchan->type == GSM_LCHAN_TCH_F ||
|
||||
lchan->type == GSM_LCHAN_TCH_H) &&
|
||||
lchan->rsl_cmode != RSL_CMOD_SPD_SIGN)
|
||||
lchan->type == GSM_LCHAN_TCH_H) && sapi != 0)
|
||||
link_id |= 0x40;
|
||||
|
||||
use_lchan(lchan);
|
||||
rllr->lchan = lchan;
|
||||
rllr->link_id = link_id;
|
||||
rllr->cb = cb;
|
||||
@@ -116,3 +114,29 @@ void rll_indication(struct gsm_lchan *lchan, u_int8_t link_id, u_int8_t type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int rll_lchan_signal(unsigned int subsys, unsigned int signal,
|
||||
void *handler_data, void *signal_data)
|
||||
{
|
||||
struct challoc_signal_data *challoc;
|
||||
struct bsc_rll_req *rllr, *rllr2;
|
||||
|
||||
if (subsys != SS_CHALLOC || signal != S_CHALLOC_FREED)
|
||||
return 0;
|
||||
|
||||
challoc = (struct challoc_signal_data *) signal_data;
|
||||
|
||||
llist_for_each_entry_safe(rllr, rllr2, &bsc_rll_reqs, list) {
|
||||
if (rllr->lchan == challoc->lchan) {
|
||||
bsc_del_timer(&rllr->timer);
|
||||
complete_rllr(rllr, BSC_RLLR_IND_ERR_IND);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void on_dso_load_rll(void)
|
||||
{
|
||||
register_signal_handler(SS_CHALLOC, rll_lchan_signal, NULL);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* minimalistic telnet/network interface it might turn into a wire interface */
|
||||
/* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
/* Hold the copyright and version string */
|
||||
/* (C) 2010 by Harald Welte <laforge@gnumonks.org>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,28 +18,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TELNET_INTERFACE_H
|
||||
#define TELNET_INTERFACE_H
|
||||
#include "bscconfig.h"
|
||||
|
||||
#include "gsm_data.h"
|
||||
#include "linuxlist.h"
|
||||
#include "select.h"
|
||||
|
||||
#include <vty/vty.h>
|
||||
|
||||
#define TELNET_COMMAND_48 1
|
||||
#define TELNET_COMMAND_11 2
|
||||
|
||||
struct telnet_connection {
|
||||
struct llist_head entry;
|
||||
struct gsm_network *network;
|
||||
struct bsc_fd fd;
|
||||
struct vty *vty;
|
||||
};
|
||||
const char *openbsc_copyright =
|
||||
"Copyright (C) 2008-2010 Harald Welte, Holger Freyther\n"
|
||||
"Contributions by Daniel Willmann, Jan Lübbe,Stefan Schmidt\n"
|
||||
"Dieter Spaar, Andreas Eversberg\n\n"
|
||||
"License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>\n"
|
||||
"This is free software: you are free to change and redistribute it.\n"
|
||||
"There is NO WARRANTY, to the extent permitted by law.\n";
|
||||
|
||||
|
||||
void telnet_init(struct gsm_network *network, int port);
|
||||
|
||||
int bsc_vty_init(struct gsm_network *net);
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user