mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-16 03:41:35 +00:00
Compare commits
923 Commits
keith/lc15
...
daniel/abi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08f337abec | ||
|
|
c8e2b021a9 | ||
|
|
300b72b44c | ||
|
|
c96d34f828 | ||
|
|
c2261bb62e | ||
|
|
82d92f703a | ||
|
|
ffe2b28c9b | ||
|
|
5b9a5f569a | ||
|
|
035080e4f4 | ||
|
|
a590b1a15a | ||
|
|
eba8816d51 | ||
|
|
8ec66a7f58 | ||
|
|
c33ff98d39 | ||
|
|
aa8779b824 | ||
|
|
764820e742 | ||
|
|
77fd0a589c | ||
|
|
ea35b26b35 | ||
|
|
59e147e7ad | ||
|
|
0087a1137e | ||
|
|
2950c0363d | ||
|
|
493ff0000b | ||
|
|
8396471638 | ||
|
|
0db38d6521 | ||
|
|
943ef9665e | ||
|
|
65f63a55c7 | ||
|
|
b73c46ae97 | ||
|
|
3fd60a5784 | ||
|
|
53e566247d | ||
|
|
fd356bdcd2 | ||
|
|
ae6ae89a19 | ||
|
|
8cfb8bcc6c | ||
|
|
ff5c8787dd | ||
|
|
bbec5df6c7 | ||
|
|
9108eed3e4 | ||
|
|
cd3d71b318 | ||
|
|
e826d78399 | ||
|
|
9b7a48421c | ||
|
|
2201900f94 | ||
|
|
0908c7da22 | ||
|
|
d48d4beb56 | ||
|
|
1176d1a626 | ||
|
|
0ccd8781b1 | ||
|
|
e9bdd73fdc | ||
|
|
a2dc808acc | ||
|
|
ebecff4a5a | ||
|
|
52da5b6f64 | ||
|
|
755546028e | ||
|
|
fff806bc92 | ||
|
|
7593cc743d | ||
|
|
9ea93c7e20 | ||
|
|
5a1b14fa4f | ||
|
|
d9f2cf2df6 | ||
|
|
311f9ffcf8 | ||
|
|
db8a676844 | ||
|
|
541b7525ae | ||
|
|
a5a150c7ee | ||
|
|
7243cada6a | ||
|
|
b8ae49d0ca | ||
|
|
b90e1ef2d0 | ||
|
|
2baf54dd46 | ||
|
|
1f9fbd8816 | ||
|
|
284f16e7d7 | ||
|
|
991f3f64d9 | ||
|
|
0ad31d8956 | ||
|
|
7bf970ede4 | ||
|
|
d399f49261 | ||
|
|
523b6de593 | ||
|
|
cf09b0cb50 | ||
|
|
8aab8d484b | ||
|
|
4cbc2acde8 | ||
|
|
e178269890 | ||
|
|
d99e20f97a | ||
|
|
162ca199e0 | ||
|
|
8630f898b2 | ||
|
|
0f075a1e2d | ||
|
|
7d2193b467 | ||
|
|
11fb108221 | ||
|
|
0fb9517fed | ||
|
|
1422a80cae | ||
|
|
5a9eaf7088 | ||
|
|
fbbc019f7d | ||
|
|
0f3d7ea35b | ||
|
|
8b83a4a70f | ||
|
|
b1d5b8639c | ||
|
|
64192c26e6 | ||
|
|
95f2201148 | ||
|
|
44cb0113cf | ||
|
|
cfabf6275e | ||
|
|
5c95312487 | ||
|
|
fe21e88630 | ||
|
|
c350b9a9f6 | ||
|
|
56585bb351 | ||
|
|
4765a5d195 | ||
|
|
f576e673a3 | ||
|
|
cf3d314501 | ||
|
|
c02876eae2 | ||
|
|
bab872cc0d | ||
|
|
7af62e2d0f | ||
|
|
9ae443d368 | ||
|
|
468c9e0a90 | ||
|
|
128039a163 | ||
|
|
851047b759 | ||
|
|
ab4ab48178 | ||
|
|
e3ff3bc4e0 | ||
|
|
9b0c60ea63 | ||
|
|
7bb3024764 | ||
|
|
9ab2472851 | ||
|
|
5cbd18cfce | ||
|
|
3ed84cc26b | ||
|
|
3ac0cf8c39 | ||
|
|
93e3a220b1 | ||
|
|
14b00bb8b2 | ||
|
|
94f7b4753a | ||
|
|
dd7bed3415 | ||
|
|
94806cee7b | ||
|
|
c4368ce3ab | ||
|
|
f5b756e484 | ||
|
|
5ce5c7db9b | ||
|
|
5a8413166f | ||
|
|
12b3921a4a | ||
|
|
333e35439d | ||
|
|
6d04bd95ee | ||
|
|
b8b6066450 | ||
|
|
da433bba7b | ||
|
|
bd7ef4101b | ||
|
|
7a2f307246 | ||
|
|
5bb7031366 | ||
|
|
b147878f9e | ||
|
|
35e601a322 | ||
|
|
523598e655 | ||
|
|
2de4d9baa8 | ||
|
|
4e9affee0b | ||
|
|
eb8059b615 | ||
|
|
d32cf22fbc | ||
|
|
79aaec8f01 | ||
|
|
dc17d1036b | ||
|
|
8ec3f28fad | ||
|
|
d84567779c | ||
|
|
ff30ca63a9 | ||
|
|
577de3a5a2 | ||
|
|
ad8426e40c | ||
|
|
a3dca762dd | ||
|
|
a6a0c6ad1e | ||
|
|
bd02811e7e | ||
|
|
df505a503f | ||
|
|
41d9e2c093 | ||
|
|
d4ebb1f6c4 | ||
|
|
374939f8cc | ||
|
|
7ce4fa4325 | ||
|
|
487feeb0ff | ||
|
|
4b3fe16200 | ||
|
|
1475a45492 | ||
|
|
1d9106d768 | ||
|
|
4275bf7232 | ||
|
|
a271ca7fc7 | ||
|
|
127c419d08 | ||
|
|
cf12cee46c | ||
|
|
79f21c4ed1 | ||
|
|
40e97f3d02 | ||
|
|
02532bafb8 | ||
|
|
77524ea511 | ||
|
|
f422873087 | ||
|
|
efc0d5bf57 | ||
|
|
b9fcb85a29 | ||
|
|
bc7a490dbc | ||
|
|
8104922d81 | ||
|
|
5dcafedc33 | ||
|
|
333d8787ff | ||
|
|
9833a4e198 | ||
|
|
fbd9aaca66 | ||
|
|
e714406632 | ||
|
|
81a4b3c090 | ||
|
|
110ec15fe9 | ||
|
|
c13b325877 | ||
|
|
5c705a676d | ||
|
|
84dceb5245 | ||
|
|
3ca3243e57 | ||
|
|
5826136a9d | ||
|
|
c64d7ae4a1 | ||
|
|
7bb7889012 | ||
|
|
98a47e8c9d | ||
|
|
5c93b8b671 | ||
|
|
36062825de | ||
|
|
7001816773 | ||
|
|
a1377d9080 | ||
|
|
03cf6042fb | ||
|
|
b71d2f5a4b | ||
|
|
887fa01977 | ||
|
|
c2ae1df890 | ||
|
|
fb905b8d23 | ||
|
|
5c5982067d | ||
|
|
8a85b71167 | ||
|
|
991b4f6283 | ||
|
|
2e8332d650 | ||
|
|
e50223074e | ||
|
|
c5f75f0bcf | ||
|
|
430954630b | ||
|
|
778aaedb95 | ||
|
|
991020c049 | ||
|
|
184fcb8010 | ||
|
|
5f3d01eed4 | ||
|
|
df6e4533dd | ||
|
|
de8e202d83 | ||
|
|
e0154aa09b | ||
|
|
ea0247e26c | ||
|
|
dffb6fac25 | ||
|
|
45094096b1 | ||
|
|
31637b4673 | ||
|
|
e3818832b0 | ||
|
|
26417d4574 | ||
|
|
ae606d69a4 | ||
|
|
d9079b192b | ||
|
|
3b02b9ad53 | ||
|
|
3cd4745efe | ||
|
|
d3e730c61d | ||
|
|
07232521a9 | ||
|
|
ac81d2789a | ||
|
|
578b540711 | ||
|
|
fd051b0f5c | ||
|
|
03cb50f809 | ||
|
|
72d9981cd0 | ||
|
|
0e2a20bfb4 | ||
|
|
7643be1d55 | ||
|
|
3e2b7faed6 | ||
|
|
074672b604 | ||
|
|
33b4b15f75 | ||
|
|
8e7d00f1ce | ||
|
|
0eb6891259 | ||
|
|
be688f1603 | ||
|
|
9419319ab5 | ||
|
|
556a966952 | ||
|
|
ee5eb61694 | ||
|
|
605cb85afd | ||
|
|
187e099c3b | ||
|
|
e73516ed00 | ||
|
|
7726d23327 | ||
|
|
2e62159c8d | ||
|
|
715ff2900a | ||
|
|
15c23179dc | ||
|
|
b1409015fa | ||
|
|
db5bf829cd | ||
|
|
36bbf1c328 | ||
|
|
e525584f3a | ||
|
|
e4d60ff8ff | ||
|
|
3c32cce087 | ||
|
|
77e014f061 | ||
|
|
c97a7f51e1 | ||
|
|
93fbcdfb39 | ||
|
|
0d8f51f1a5 | ||
|
|
582d9cf0d5 | ||
|
|
3440104723 | ||
|
|
fa9dd74d83 | ||
|
|
61349d6f14 | ||
|
|
66f5fb0577 | ||
|
|
87f48a1d38 | ||
|
|
5fa08dee72 | ||
|
|
1c3431db95 | ||
|
|
d17beeacde | ||
|
|
134c999103 | ||
|
|
304de2e115 | ||
|
|
27f42205ea | ||
|
|
414bc76ea5 | ||
|
|
1f213a2402 | ||
|
|
d680a62975 | ||
|
|
0468376c53 | ||
|
|
3871c1ff0c | ||
|
|
5f4e729122 | ||
|
|
d6ef2bf12f | ||
|
|
056a3632dc | ||
|
|
4034e61d03 | ||
|
|
7b80dde7b5 | ||
|
|
e51fb333ae | ||
|
|
9e2262b667 | ||
|
|
9be6b56033 | ||
|
|
72d81b978a | ||
|
|
e12f911bbb | ||
|
|
9a3a5cbc9c | ||
|
|
0c44a92197 | ||
|
|
bc6d35f52d | ||
|
|
127e8fc416 | ||
|
|
2e90e0f756 | ||
|
|
130e2e59c6 | ||
|
|
49979bb794 | ||
|
|
37f63f12f7 | ||
|
|
4ddc37ce71 | ||
|
|
dfedf2cb76 | ||
|
|
192390c797 | ||
|
|
ce9ec4963c | ||
|
|
ddd357f3e3 | ||
|
|
300e31ed13 | ||
|
|
2f3cd4b697 | ||
|
|
137166fd5f | ||
|
|
7c466d8cc7 | ||
|
|
32b51eca7d | ||
|
|
eab7068d58 | ||
|
|
4444262a6a | ||
|
|
3bf40e4f3a | ||
|
|
03c74baa83 | ||
|
|
3c56335094 | ||
|
|
68a39a8617 | ||
|
|
5a2d8716ef | ||
|
|
92186c672d | ||
|
|
c56d120b29 | ||
|
|
43a4a1d5e7 | ||
|
|
ea53ad454e | ||
|
|
729aff7938 | ||
|
|
82275d5eb2 | ||
|
|
8dd699e545 | ||
|
|
3f7bd192a6 | ||
|
|
65c0341f3d | ||
|
|
79a92cfc50 | ||
|
|
5831512c2c | ||
|
|
a09c9a8c32 | ||
|
|
4a1e34c077 | ||
|
|
41fe4089a8 | ||
|
|
3f51571a2f | ||
|
|
daadbc33aa | ||
|
|
a17043f2b4 | ||
|
|
bc7c8a42f3 | ||
|
|
c2ba34d9c1 | ||
|
|
e1dbc616b0 | ||
|
|
c81b41c62e | ||
|
|
c85027a510 | ||
|
|
132b67a7a0 | ||
|
|
c80abd109b | ||
|
|
8d21891959 | ||
|
|
22a160bd24 | ||
|
|
f54a7462dd | ||
|
|
f21b9231dd | ||
|
|
494b251109 | ||
|
|
da7c56ab8e | ||
|
|
314a0db113 | ||
|
|
746d0a7500 | ||
|
|
5ed69d0fd5 | ||
|
|
e0febb700a | ||
|
|
aac12bfd67 | ||
|
|
e2f9abee58 | ||
|
|
dd97023388 | ||
|
|
cd11905f64 | ||
|
|
160da8ea2b | ||
|
|
085a4cb91e | ||
|
|
0617afdb5f | ||
|
|
7c23017806 | ||
|
|
a65cf63619 | ||
|
|
ca41f091fc | ||
|
|
8f37660fd6 | ||
|
|
298a259b7c | ||
|
|
6aa959ecf4 | ||
|
|
294fa4e061 | ||
|
|
c485901d3d | ||
|
|
f616294d8c | ||
|
|
bb840eceb9 | ||
|
|
9eb8c9f0d7 | ||
|
|
f1312f9818 | ||
|
|
30c838fdfa | ||
|
|
6611e7f305 | ||
|
|
ace4e500ed | ||
|
|
dda5cf4bb7 | ||
|
|
a5602d593c | ||
|
|
454a2516f2 | ||
|
|
471df615e2 | ||
|
|
ae783bcb0e | ||
|
|
a4b9073989 | ||
|
|
30aea88c2c | ||
|
|
0e8d68437a | ||
|
|
f50b684594 | ||
|
|
c3b3ca358a | ||
|
|
8bf5cbea49 | ||
|
|
80ce85295b | ||
|
|
1fe9a89308 | ||
|
|
b53a84ac75 | ||
|
|
4d845ccbb6 | ||
|
|
f1bdf605b5 | ||
|
|
a6af31cd44 | ||
|
|
f47fa70b9f | ||
|
|
54d0931330 | ||
|
|
c126870c5f | ||
|
|
8a1a74e6ca | ||
|
|
dded16c4c9 | ||
|
|
6fd4f77243 | ||
|
|
a484742793 | ||
|
|
d4efc3f9c5 | ||
|
|
64e1c1222e | ||
|
|
4e8d4d5bb8 | ||
|
|
a556c49114 | ||
|
|
b04ffc11fb | ||
|
|
ef4a6a0f43 | ||
|
|
4590b099bf | ||
|
|
52f6fc5aab | ||
|
|
5acd0102e4 | ||
|
|
85c2d641d5 | ||
|
|
bd49fd2492 | ||
|
|
43adbe200c | ||
|
|
fc8c9880d9 | ||
|
|
628853de74 | ||
|
|
177799fe7e | ||
|
|
68671291f3 | ||
|
|
6d20a49806 | ||
|
|
0686ae6128 | ||
|
|
d9daa3fd9e | ||
|
|
b99db695a7 | ||
|
|
28cd8a318f | ||
|
|
5b8080208a | ||
|
|
f6716bf846 | ||
|
|
510fb2e2b8 | ||
|
|
8cb5a25874 | ||
|
|
c5844779e8 | ||
|
|
069796bcd8 | ||
|
|
a02d9e57b0 | ||
|
|
bcdbb6c556 | ||
|
|
5d888e5064 | ||
|
|
0704b29d6d | ||
|
|
24e5f72f83 | ||
|
|
dd3b7d469e | ||
|
|
d8598005ce | ||
|
|
60fc1d3763 | ||
|
|
3c1151f945 | ||
|
|
207d56afe5 | ||
|
|
163ff40dd5 | ||
|
|
91054e78ef | ||
|
|
ef5c364bba | ||
|
|
bdef33d527 | ||
|
|
c70196240c | ||
|
|
e02612d863 | ||
|
|
13d595a9ef | ||
|
|
ec1045a01b | ||
|
|
272d474ccb | ||
|
|
d89938afa7 | ||
|
|
a179a9434a | ||
|
|
949874433f | ||
|
|
1cad2f51c6 | ||
|
|
518ada9414 | ||
|
|
97193ced54 | ||
|
|
bdc5095368 | ||
|
|
d4abdd80fe | ||
|
|
a344db979f | ||
|
|
d7323d6f1f | ||
|
|
e24279508d | ||
|
|
6ad89f2f58 | ||
|
|
dd9a6f16bc | ||
|
|
462bf0952a | ||
|
|
b4c0e43c60 | ||
|
|
98aeaf6fa7 | ||
|
|
e728f22136 | ||
|
|
641ffaaef3 | ||
|
|
0277cddab2 | ||
|
|
4733b099f5 | ||
|
|
05493ca810 | ||
|
|
c74f25bdcc | ||
|
|
b6d3e2c360 | ||
|
|
2dda5d835a | ||
|
|
0dcaf34927 | ||
|
|
57ebf04171 | ||
|
|
9e09441814 | ||
|
|
c9635b0ad1 | ||
|
|
38cdafd656 | ||
|
|
d2eafadc25 | ||
|
|
f3e3a3ac99 | ||
|
|
67b141c567 | ||
|
|
7651b078b1 | ||
|
|
010841644b | ||
|
|
1896c8f03e | ||
|
|
75f56805e0 | ||
|
|
134062e335 | ||
|
|
b1b100ce59 | ||
|
|
9c321b8486 | ||
|
|
dd8439f889 | ||
|
|
8a99365281 | ||
|
|
ac55dcb5d0 | ||
|
|
17350e2fd6 | ||
|
|
974bf725a4 | ||
|
|
16c2998069 | ||
|
|
b619da5e72 | ||
|
|
61fcfa6ae7 | ||
|
|
708fca343e | ||
|
|
823cd52964 | ||
|
|
7177e666bb | ||
|
|
6072be9be4 | ||
|
|
93b04aa4c3 | ||
|
|
b03ff89876 | ||
|
|
b11012c1f5 | ||
|
|
ab5cc5e6c5 | ||
|
|
32ef94cac0 | ||
|
|
0b33ab8ac2 | ||
|
|
8de227fd13 | ||
|
|
aee336eaac | ||
|
|
5ac4456173 | ||
|
|
9cf65a7af5 | ||
|
|
078682d7b5 | ||
|
|
976e7e51e6 | ||
|
|
479ff386ff | ||
|
|
cabfbf470f | ||
|
|
1334316844 | ||
|
|
f88f539c77 | ||
|
|
2915bbf4c5 | ||
|
|
1adcc27eb9 | ||
|
|
180ddb0da3 | ||
|
|
9dd7e3c907 | ||
|
|
fd5151668c | ||
|
|
ca1628fb7a | ||
|
|
29c4f3173f | ||
|
|
8593b38616 | ||
|
|
7a7beb9b35 | ||
|
|
166b10059b | ||
|
|
6a1a5f988b | ||
|
|
ffce0e45a5 | ||
|
|
9fa152a981 | ||
|
|
3f3cdff773 | ||
|
|
6940d34ee5 | ||
|
|
0436fe7fca | ||
|
|
8777b63ef8 | ||
|
|
b1571af864 | ||
|
|
3abbb67ded | ||
|
|
da084794a6 | ||
|
|
f8f806ff2a | ||
|
|
db403a4e3e | ||
|
|
b89632cc67 | ||
|
|
d37041b1ea | ||
|
|
7d29ff9345 | ||
|
|
3215344300 | ||
|
|
6b93f0f366 | ||
|
|
9eb37bc3cb | ||
|
|
58952ac2b4 | ||
|
|
82aeeacd52 | ||
|
|
6664f47ad7 | ||
|
|
76308ab3fb | ||
|
|
2b3aa67a7b | ||
|
|
dabe5d0327 | ||
|
|
522a33fe82 | ||
|
|
b1485cd590 | ||
|
|
6b36cce2ea | ||
|
|
bb04495251 | ||
|
|
187effa00d | ||
|
|
fe45b4eb1f | ||
|
|
a2da0e96e1 | ||
|
|
f7afeb1fa9 | ||
|
|
5ca7707e85 | ||
|
|
ed7bca6b33 | ||
|
|
f7c7d2baf6 | ||
|
|
df80385f26 | ||
|
|
ac38cf8e90 | ||
|
|
6eb98ab25c | ||
|
|
98c7b44f8d | ||
|
|
23ff5f8861 | ||
|
|
10272f7702 | ||
|
|
a666f713ec | ||
|
|
f7cf5e2612 | ||
|
|
a81dfdb096 | ||
|
|
3992249c64 | ||
|
|
af48e77f23 | ||
|
|
dc61d6032b | ||
|
|
f416e5a01c | ||
|
|
510a47818a | ||
|
|
66637c68ae | ||
|
|
2627c28188 | ||
|
|
66f76223c4 | ||
|
|
3e1dad2a37 | ||
|
|
bb6765a93c | ||
|
|
6351974464 | ||
|
|
cd30a40be1 | ||
|
|
25b11f473a | ||
|
|
b327c9598c | ||
|
|
ef53ffe8bb | ||
|
|
ef99e36626 | ||
|
|
e920902e25 | ||
|
|
834ba05cd2 | ||
|
|
e8f857453d | ||
|
|
4a0a6fd014 | ||
|
|
9238c3549d | ||
|
|
f0089a8495 | ||
|
|
7a8c9dbad7 | ||
|
|
22646cb122 | ||
|
|
e0b9570cde | ||
|
|
9b6c149e42 | ||
|
|
e476629bcf | ||
|
|
763ce0627a | ||
|
|
5f909b45c5 | ||
|
|
20cbf7bc67 | ||
|
|
ecf4879403 | ||
|
|
129cb51597 | ||
|
|
f158bb614c | ||
|
|
538c56ef34 | ||
|
|
7233fa8623 | ||
|
|
6904d7dd5d | ||
|
|
675618b4f8 | ||
|
|
2b416d6d2b | ||
|
|
75162427ad | ||
|
|
36743255cd | ||
|
|
237ec6194b | ||
|
|
63c1838c7a | ||
|
|
0698c58ebe | ||
|
|
0ced8dd03e | ||
|
|
2f53fae01f | ||
|
|
567ea2a079 | ||
|
|
2b59a625e8 | ||
|
|
08f3eafd02 | ||
|
|
f15c44df52 | ||
|
|
0e24ace2f1 | ||
|
|
9381576e18 | ||
|
|
fb03b43e24 | ||
|
|
3b1e66af9e | ||
|
|
369c852022 | ||
|
|
e9b6648761 | ||
|
|
ca9ab523e1 | ||
|
|
af4eec056e | ||
|
|
5b25e8e7de | ||
|
|
7c87612b42 | ||
|
|
a36d6832a1 | ||
|
|
7e38cf4e66 | ||
|
|
ff96c5d16c | ||
|
|
33dfe2bcec | ||
|
|
def24f0d9a | ||
|
|
4ee4d6be2a | ||
|
|
6158525433 | ||
|
|
1c05ef15ec | ||
|
|
f733cf8263 | ||
|
|
da680071a6 | ||
|
|
090f1cebe8 | ||
|
|
44d72333ad | ||
|
|
28d0a1db79 | ||
|
|
48ffeb8139 | ||
|
|
251fc3c06c | ||
|
|
2edf5cf47f | ||
|
|
70d78f21f2 | ||
|
|
5e92f628ab | ||
|
|
ace1ca46a7 | ||
|
|
a75b402f55 | ||
|
|
ef1671c6ed | ||
|
|
44d25af9cd | ||
|
|
ffbe63f408 | ||
|
|
5c7b709027 | ||
|
|
484952a3e5 | ||
|
|
90e01e47cb | ||
|
|
9076b3947b | ||
|
|
fa3e22bc17 | ||
|
|
a72a0765a4 | ||
|
|
850607295c | ||
|
|
07aa8927e1 | ||
|
|
79294134dd | ||
|
|
44fc252381 | ||
|
|
1325443dc3 | ||
|
|
91652c8dbe | ||
|
|
0b6e568d05 | ||
|
|
c3a293fde1 | ||
|
|
5f95a16ec1 | ||
|
|
4d7c6ad860 | ||
|
|
26cc8580f6 | ||
|
|
6e27523d11 | ||
|
|
22f59cd63a | ||
|
|
7810a91733 | ||
|
|
ae6e3e8f8b | ||
|
|
88fe4b079d | ||
|
|
6d117891c9 | ||
|
|
cf7a7fcebf | ||
|
|
629824ac14 | ||
|
|
1b5b629624 | ||
|
|
debfbb6965 | ||
|
|
4cc38b8a72 | ||
|
|
2e28b3859d | ||
|
|
fc1976e1a0 | ||
|
|
66be4b6785 | ||
|
|
46aa8465be | ||
|
|
68323527e7 | ||
|
|
bdea34165b | ||
|
|
284e4c4437 | ||
|
|
00da6dcb88 | ||
|
|
17fd344249 | ||
|
|
79eab9689f | ||
|
|
e20baa31bf | ||
|
|
cf2226093f | ||
|
|
52aa451ae2 | ||
|
|
ae09c8acb4 | ||
|
|
967bca7b9e | ||
|
|
9a7acc1744 | ||
|
|
8d62d66ed5 | ||
|
|
52d6e43d0e | ||
|
|
8d56806c65 | ||
|
|
43f211a77d | ||
|
|
7b239f40cb | ||
|
|
1ab6412610 | ||
|
|
ca5d1e6ba6 | ||
|
|
e1de96088d | ||
|
|
2db8da22d6 | ||
|
|
a73c6d6785 | ||
|
|
6710438899 | ||
|
|
74750fe2b0 | ||
|
|
912b4df76c | ||
|
|
c0b544f103 | ||
|
|
8be3fa6f36 | ||
|
|
a2690a8921 | ||
|
|
403a37ec34 | ||
|
|
81ca3206ad | ||
|
|
132f72e76a | ||
|
|
05549ae252 | ||
|
|
9096461507 | ||
|
|
d6b82e57a3 | ||
|
|
650a0c31a7 | ||
|
|
90e0c205b5 | ||
|
|
17de4e708f | ||
|
|
7dd865badd | ||
|
|
c41b94e93b | ||
|
|
b62612fbde | ||
|
|
64bd96b3f8 | ||
|
|
4785fe7622 | ||
|
|
6e725279ca | ||
|
|
0c7e9354fe | ||
|
|
7a95af61fe | ||
|
|
4ded469b0f | ||
|
|
27c5fd9369 | ||
|
|
2302cb162c | ||
|
|
ee92f6980f | ||
|
|
0cd8df2184 | ||
|
|
9b6000c6fa | ||
|
|
86c8d2f81c | ||
|
|
f3161349cf | ||
|
|
df17af689f | ||
|
|
03e9972695 | ||
|
|
c9079d9106 | ||
|
|
666adf6a97 | ||
|
|
f1222fc724 | ||
|
|
9ad00d1c28 | ||
|
|
df93a448b7 | ||
|
|
2ff4592ffc | ||
|
|
3d085dc6a7 | ||
|
|
81251bdbe8 | ||
|
|
c84b007efb | ||
|
|
af4015cb91 | ||
|
|
359ca18374 | ||
|
|
5a2262da64 | ||
|
|
6f4db8c620 | ||
|
|
1ac4243a13 | ||
|
|
a12c0b16f4 | ||
|
|
f68fa09376 | ||
|
|
49ad9f9375 | ||
|
|
eecb97146e | ||
|
|
063eaa80a4 | ||
|
|
8f1974ba1e | ||
|
|
345a857e14 | ||
|
|
67e5a72a51 | ||
|
|
1565d16a0a | ||
|
|
624b5cdc22 | ||
|
|
d6daf726a2 | ||
|
|
c131ce45ba | ||
|
|
30458c83e5 | ||
|
|
4fa40f5913 | ||
|
|
089e4baef3 | ||
|
|
dc27771205 | ||
|
|
017f85ab1c | ||
|
|
cf3635fbaa | ||
|
|
dc232c137b | ||
|
|
bebf458385 | ||
|
|
dcfec2d993 | ||
|
|
2c331ee908 | ||
|
|
4d61c67392 | ||
|
|
48ff5313cd | ||
|
|
10e64630ce | ||
|
|
9d5e955ea1 | ||
|
|
fc3909a0b1 | ||
|
|
60e2919ff4 | ||
|
|
c14f1641c6 | ||
|
|
3d5cf0b341 | ||
|
|
57fc9fa782 | ||
|
|
eef420d1ca | ||
|
|
f30440553c | ||
|
|
be15a12c87 | ||
|
|
912ff0d759 | ||
|
|
4134bdf009 | ||
|
|
742590b5df | ||
|
|
82a35a1dbf | ||
|
|
4479c94fd1 | ||
|
|
2ee6de20e2 | ||
|
|
5c22fa33f7 | ||
|
|
3f4588273d | ||
|
|
7bda77928c | ||
|
|
1272af4529 | ||
|
|
414d649e01 | ||
|
|
22a949f38e | ||
|
|
5432f69f16 | ||
|
|
122ff83dd0 | ||
|
|
d5107c0583 | ||
|
|
9b2641ff3d | ||
|
|
3daccb151f | ||
|
|
9b47b27d4f | ||
|
|
23fd316dea | ||
|
|
8ca8a26ce9 | ||
|
|
221ee92551 | ||
|
|
a470d016b1 | ||
|
|
0a6bdb024f | ||
|
|
aba8354ed3 | ||
|
|
4dfd43bb51 | ||
|
|
b505ac38e7 | ||
|
|
842e4fab44 | ||
|
|
f23d835831 | ||
|
|
f3f0638066 | ||
|
|
2931fc337f | ||
|
|
cdc5c6f5c5 | ||
|
|
f28dc5197e | ||
|
|
2f18578dcc | ||
|
|
7a7168f0a8 | ||
|
|
3612920ce7 | ||
|
|
a08685a576 | ||
|
|
bbfc6e44ce | ||
|
|
504eca9d39 | ||
|
|
ab7f409bff | ||
|
|
a6386ea64d | ||
|
|
8090df2a81 | ||
|
|
ceb80fc6b6 | ||
|
|
0211bd6e79 | ||
|
|
69299114f8 | ||
|
|
fee04adc75 | ||
|
|
580a27e97c | ||
|
|
7afdccdff2 | ||
|
|
c08d927085 | ||
|
|
4e01d8e709 | ||
|
|
34940bdb2a | ||
|
|
f5e22703e7 | ||
|
|
d819a57c60 | ||
|
|
cec19e6324 | ||
|
|
492c7c50aa | ||
|
|
8712e1c827 | ||
|
|
10695a7512 | ||
|
|
1212df69b8 | ||
|
|
7a58aa9bc4 | ||
|
|
1240ea8b83 | ||
|
|
871f624f40 | ||
|
|
600ab79e7d | ||
|
|
44d91846f0 | ||
|
|
b56161f4e6 | ||
|
|
1e63317e29 | ||
|
|
2772cabbd0 | ||
|
|
5f71aab35f | ||
|
|
6f71a959b9 | ||
|
|
c3fdee43dd | ||
|
|
df26770d41 | ||
|
|
906a9b5e71 | ||
|
|
b828b32f31 | ||
|
|
ae781bc5cd | ||
|
|
36c5ec4881 | ||
|
|
0b92bcc37c | ||
|
|
c8086c317e | ||
|
|
0bf87ccc3e | ||
|
|
8c6bc4dbb4 | ||
|
|
26cecfdea4 | ||
|
|
0a81cfefea | ||
|
|
c854ca14d5 | ||
|
|
adf5d3aed2 | ||
|
|
c579e674c7 | ||
|
|
f896d64e22 | ||
|
|
578156b815 | ||
|
|
ba0e5c7d50 | ||
|
|
f1c2d40b2c | ||
|
|
46aa972411 | ||
|
|
8f8d3a7e07 | ||
|
|
66564ed696 | ||
|
|
5969988754 | ||
|
|
a003fec7cd | ||
|
|
fe8f13ace3 | ||
|
|
79aec05c23 | ||
|
|
4977e135c8 | ||
|
|
b8200203d8 | ||
|
|
897aa786c2 | ||
|
|
aa5e46dc9a | ||
|
|
031f925ccd | ||
|
|
5a877b37c2 | ||
|
|
9a413231d6 | ||
|
|
ffe5a8d8b8 | ||
|
|
301b218509 | ||
|
|
759a12e8aa | ||
|
|
fccd944bd7 | ||
|
|
b8bdefc33b | ||
|
|
24454fc2f8 | ||
|
|
0d25f9c94c | ||
|
|
79ad26cabf | ||
|
|
d7fa003686 | ||
|
|
1851781d99 | ||
|
|
c966253aad | ||
|
|
a44a8f469e | ||
|
|
f106db2e37 | ||
|
|
936ed22bd9 | ||
|
|
308d252795 | ||
|
|
4fa3598639 | ||
|
|
36e2b55a9e | ||
|
|
f53e4aafc7 | ||
|
|
5ad8db2a19 | ||
|
|
f5f614b86d | ||
|
|
5de50a598b | ||
|
|
53a9c98737 | ||
|
|
14819d8053 | ||
|
|
0a8642ab5c | ||
|
|
633de1fb88 | ||
|
|
dbc8372064 | ||
|
|
9daa67d0e7 | ||
|
|
94dee95120 | ||
|
|
01342bce4a | ||
|
|
ed4ed9e5d0 | ||
|
|
f938e91bd0 | ||
|
|
e82c8436cb | ||
|
|
f0171a9974 | ||
|
|
de2ef31f4c | ||
|
|
d211c490ca | ||
|
|
98e235b732 | ||
|
|
d4a53017e1 | ||
|
|
b1eb6c2fa2 | ||
|
|
59e7773055 | ||
|
|
7726eaa477 | ||
|
|
71fd083c16 | ||
|
|
63920cefa6 | ||
|
|
ee320d5b36 | ||
|
|
40fb4b7614 | ||
|
|
78a1d3a31a | ||
|
|
58b9f11898 | ||
|
|
557ca0f468 | ||
|
|
fd6584b179 | ||
|
|
5a618186a1 | ||
|
|
321d69f4fd | ||
|
|
4f3e3db8d1 | ||
|
|
7b0da0650d | ||
|
|
187f7c8713 | ||
|
|
731683cd62 | ||
|
|
9974eb739a | ||
|
|
7f1800832f | ||
|
|
085872fe85 | ||
|
|
c4744ac24c |
17
.gitignore
vendored
17
.gitignore
vendored
@@ -35,10 +35,10 @@ src/osmo-bts-sysmo/osmo-bts-sysmo-remote
|
|||||||
src/osmo-bts-sysmo/sysmobts-mgr
|
src/osmo-bts-sysmo/sysmobts-mgr
|
||||||
src/osmo-bts-sysmo/sysmobts-util
|
src/osmo-bts-sysmo/sysmobts-util
|
||||||
|
|
||||||
src/osmo-bts-litecell15/lc15bts-mgr
|
src/osmo-bts-lc15/lc15bts-mgr
|
||||||
src/osmo-bts-litecell15/lc15bts-util
|
src/osmo-bts-lc15/lc15bts-util
|
||||||
src/osmo-bts-litecell15/misc/.dirstamp
|
src/osmo-bts-lc15/misc/.dirstamp
|
||||||
src/osmo-bts-litecell15/osmo-bts-lc15
|
src/osmo-bts-lc15/osmo-bts-lc15
|
||||||
|
|
||||||
src/osmo-bts-trx/osmo-bts-trx
|
src/osmo-bts-trx/osmo-bts-trx
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ src/osmo-bts-oc2g/misc/.dirstamp
|
|||||||
|
|
||||||
tests/atconfig
|
tests/atconfig
|
||||||
tests/package.m4
|
tests/package.m4
|
||||||
|
tests/amr/amr_test
|
||||||
tests/agch/agch_test
|
tests/agch/agch_test
|
||||||
tests/paging/paging_test
|
tests/paging/paging_test
|
||||||
tests/cipher/cipher_test
|
tests/cipher/cipher_test
|
||||||
@@ -63,6 +64,8 @@ tests/misc/misc_test
|
|||||||
tests/handover/handover_test
|
tests/handover/handover_test
|
||||||
tests/tx_power/tx_power_test
|
tests/tx_power/tx_power_test
|
||||||
tests/ta_control/ta_control_test
|
tests/ta_control/ta_control_test
|
||||||
|
tests/power/ms_power_loop_test
|
||||||
|
tests/power/bs_power_loop_test
|
||||||
tests/testsuite
|
tests/testsuite
|
||||||
tests/testsuite.log
|
tests/testsuite.log
|
||||||
|
|
||||||
@@ -85,7 +88,6 @@ debian/*.substvars
|
|||||||
debian/osmo-bts-trx-dbg/
|
debian/osmo-bts-trx-dbg/
|
||||||
debian/osmo-bts-trx/
|
debian/osmo-bts-trx/
|
||||||
debian/tmp/
|
debian/tmp/
|
||||||
/tests/power/power_test
|
|
||||||
|
|
||||||
# manuals
|
# manuals
|
||||||
doc/manuals/*.html
|
doc/manuals/*.html
|
||||||
@@ -94,6 +96,11 @@ doc/manuals/*.pdf
|
|||||||
doc/manuals/*__*.png
|
doc/manuals/*__*.png
|
||||||
doc/manuals/*.check
|
doc/manuals/*.check
|
||||||
doc/manuals/generated/
|
doc/manuals/generated/
|
||||||
|
doc/manuals/vty/osmobts-*-vty-reference.xml
|
||||||
|
doc/manuals/vty/osmobts-*-vty-reference.xml.inc.gen
|
||||||
|
doc/manuals/vty/osmobts-*-vty-reference.xml.inc.merged
|
||||||
doc/manuals/osmomsc-usermanual.xml
|
doc/manuals/osmomsc-usermanual.xml
|
||||||
doc/manuals/common
|
doc/manuals/common
|
||||||
doc/manuals/build
|
doc/manuals/build
|
||||||
|
|
||||||
|
contrib/osmo-bts.spec
|
||||||
|
|||||||
@@ -5,9 +5,13 @@ SUBDIRS = include src tests doc contrib
|
|||||||
|
|
||||||
# package the contrib and doc
|
# package the contrib and doc
|
||||||
EXTRA_DIST = \
|
EXTRA_DIST = \
|
||||||
|
.version \
|
||||||
|
README.md \
|
||||||
contrib/dump_docs.py \
|
contrib/dump_docs.py \
|
||||||
git-version-gen .version \
|
contrib/osmo-bts.spec.in \
|
||||||
README.md
|
debian \
|
||||||
|
git-version-gen \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
AM_DISTCHECK_CONFIGURE_FLAGS = \
|
||||||
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
--with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
|
||||||
|
|||||||
33
README.md
33
README.md
@@ -20,32 +20,41 @@ Several kinds of BTS hardware are supported:
|
|||||||
* sysmocom sysmoBTS
|
* sysmocom sysmoBTS
|
||||||
* Octasic octphy
|
* Octasic octphy
|
||||||
* Nutaq litecell 1.5
|
* Nutaq litecell 1.5
|
||||||
|
* OpenCellular 2G (OC-2G)
|
||||||
* software-defined radio based osmo-bts-trx (e.g. USRP B210, UmTRX, LimeSDR)
|
* software-defined radio based osmo-bts-trx (e.g. USRP B210, UmTRX, LimeSDR)
|
||||||
|
|
||||||
Homepage
|
Homepage
|
||||||
--------
|
--------
|
||||||
|
|
||||||
The official homepage of the project is
|
The official homepage of the project is
|
||||||
https://osmocom.org/projects/osmobts/wiki
|
<https://osmocom.org/projects/osmobts/wiki>
|
||||||
|
|
||||||
GIT Repository
|
GIT Repository
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
You can clone from the official osmo-bts.git repository using
|
You can clone from the official osmo-bts.git repository using
|
||||||
|
|
||||||
git clone git://git.osmocom.org/osmo-bts.git
|
git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
|
|
||||||
There is a cgit interface at http://git.osmocom.org/osmo-bts/
|
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-bts>
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
We provide a
|
User Manuals and VTY reference manuals are [optionally] built in PDF form
|
||||||
[User Manual](http://ftp.osmocom.org/docs/latest/osmobts-usermanual.pdf)
|
as part of the build process.
|
||||||
as well as a
|
|
||||||
[VTY Reference Manual](http://ftp.osmocom.org/docs/latest/osmobsc-vty-reference.pdf)
|
Pre-rendered PDF version of the current "master" can be found at
|
||||||
and a
|
[User Manual](https://ftp.osmocom.org/docs/latest/osmobts-usermanual.pdf)
|
||||||
[Abis reference MAnual](http://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
|
as well as the VTY reference manuals
|
||||||
|
* [VTY Reference Manual for osmo-bts-sysmo](https://ftp.osmocom.org/docs/latest/osmobts-sysmo-vty-reference.pdf)
|
||||||
|
* [VTY Reference Manual for osmo-bts-trx](https://ftp.osmocom.org/docs/latest/osmobts-trx-vty-reference.pdf)
|
||||||
|
* [VTY Reference Manual for osmo-bts-lc15](https://ftp.osmocom.org/docs/latest/osmobts-lc15-vty-reference.pdf)
|
||||||
|
* [VTY Reference Manual for osmo-bts-oc2g](https://ftp.osmocom.org/docs/latest/osmobts-oc2g-vty-reference.pdf)
|
||||||
|
* [VTY Reference Manual for osmo-bts-octphy](https://ftp.osmocom.org/docs/latest/osmobts-octphy-vty-reference.pdf)
|
||||||
|
|
||||||
|
There also is an
|
||||||
|
[Abis reference Manual](https://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
|
||||||
describing the OsmoBTS specific A-bis dialect.
|
describing the OsmoBTS specific A-bis dialect.
|
||||||
|
|
||||||
Mailing List
|
Mailing List
|
||||||
@@ -77,7 +86,7 @@ https://gerrit.osmocom.org/#/q/project:osmo-bts+status:open
|
|||||||
Known Limitations
|
Known Limitations
|
||||||
=================
|
=================
|
||||||
|
|
||||||
As of March 17, 2017, the following known limitations exist in this
|
As of January 2021, the following known limitations exist in this
|
||||||
implementation:
|
implementation:
|
||||||
|
|
||||||
Common Core
|
Common Core
|
||||||
@@ -87,10 +96,6 @@ Common Core
|
|||||||
* System Information limited to 1,2,2bis,2ter,2quater,3,4,5,6,9,13
|
* System Information limited to 1,2,2bis,2ter,2quater,3,4,5,6,9,13
|
||||||
* No RATSCCH in AMR
|
* No RATSCCH in AMR
|
||||||
* Will reject TS 12.21 STARTING TIME in SET BTS ATTR / SET CHAN ATTR
|
* Will reject TS 12.21 STARTING TIME in SET BTS ATTR / SET CHAN ATTR
|
||||||
* No support for frequency hopping
|
|
||||||
* No reporting of interference levels as part of TS 08.58 RF RES IND
|
|
||||||
* No error reporting in case PAGING COMMAND fails due to queue overflow
|
|
||||||
* No use of TS 08.58 BS Power and MS Power parameters
|
|
||||||
* No support of TS 08.58 MultiRate Control
|
* No support of TS 08.58 MultiRate Control
|
||||||
* No support of TS 08.58 Supported Codec Types
|
* No support of TS 08.58 Supported Codec Types
|
||||||
* No support of Bter frame / ENHANCED MEASUREMENT REPORT
|
* No support of Bter frame / ENHANCED MEASUREMENT REPORT
|
||||||
|
|||||||
12
TODO-RELEASE
Normal file
12
TODO-RELEASE
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
|
||||||
|
# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||||
|
# In short:
|
||||||
|
# LIBVERSION=c:r:a
|
||||||
|
# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a.
|
||||||
|
# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0.
|
||||||
|
# If any interfaces have been added since the last public release: c:r:a + 1.
|
||||||
|
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||||
|
#library what description / commit summary line
|
||||||
|
libosmocore >1.7.0 BTS_FEAT_OSMUX, RSL_IE_OSMO_OSMUX_CID
|
||||||
|
libosmo-netif >1.2.0 OSMUX_DEFAULT_PORT, new osmux APIs
|
||||||
|
libosmo-abis >1.3.0 e1inp_ipa_bts_rsl_close_n()
|
||||||
79
configure.ac
79
configure.ac
@@ -9,6 +9,8 @@ AC_CONFIG_AUX_DIR([.])
|
|||||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||||
AC_CONFIG_TESTDIR(tests)
|
AC_CONFIG_TESTDIR(tests)
|
||||||
|
|
||||||
|
CFLAGS="$CFLAGS -std=gnu11"
|
||||||
|
|
||||||
dnl kernel style compile messages
|
dnl kernel style compile messages
|
||||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||||
|
|
||||||
@@ -22,6 +24,11 @@ AC_PROG_CC
|
|||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
|
dnl patching ${archive_cmds} to affect generation of file "libtool" to fix linking with clang
|
||||||
|
AS_CASE(["$LD"],[*clang*],
|
||||||
|
[AS_CASE(["${host_os}"],
|
||||||
|
[*linux*],[archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'])])
|
||||||
|
|
||||||
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
dnl check for pkg-config (explained in detail in libosmocore/configure.ac)
|
||||||
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
AC_PATH_PROG(PKG_CONFIG_INSTALLED, pkg-config, no)
|
||||||
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
||||||
@@ -62,14 +69,16 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl checks for libraries
|
dnl checks for libraries
|
||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.7.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 0.6.0)
|
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 0.6.0)
|
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.3.0)
|
||||||
|
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.2.0)
|
||||||
|
#FIXME: ^ it actually needs > 1.2.0
|
||||||
|
|
||||||
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
|
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
|
||||||
AC_ARG_ENABLE(sysmobts-calib,
|
AC_ARG_ENABLE(sysmobts-calib,
|
||||||
@@ -342,6 +351,56 @@ then
|
|||||||
AC_SUBST([OSMO_GSM_MANUALS_DIR])
|
AC_SUBST([OSMO_GSM_MANUALS_DIR])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([external_tests],
|
||||||
|
AC_HELP_STRING([--enable-external-tests],
|
||||||
|
[Include the VTY/CTRL tests in make check [default=no]]),
|
||||||
|
[enable_ext_tests="$enableval"],[enable_ext_tests="no"])
|
||||||
|
if test "x$enable_ext_tests" = "xyes" ; then
|
||||||
|
AC_CHECK_PROG(PYTHON3_AVAIL,python3,yes)
|
||||||
|
if test "x$PYTHON3_AVAIL" != "xyes" ; then
|
||||||
|
AC_MSG_ERROR([Please install python3 to run the VTY/CTRL tests.])
|
||||||
|
fi
|
||||||
|
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
||||||
|
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
||||||
|
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||||
|
AC_MSG_RESULT([$enable_ext_tests])
|
||||||
|
AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes")
|
||||||
|
|
||||||
|
#
|
||||||
|
# SystemTap support
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([whether to include systemtap tracing support])
|
||||||
|
AC_ARG_ENABLE([systemtap],
|
||||||
|
[AS_HELP_STRING([--enable-systemtap],
|
||||||
|
[Enable inclusion of systemtap trace support])],
|
||||||
|
[ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP='no'])
|
||||||
|
AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$ENABLE_SYSTEMTAP = xyes])
|
||||||
|
AC_MSG_RESULT(${ENABLE_SYSTEMTAP})
|
||||||
|
|
||||||
|
if test "x${ENABLE_SYSTEMTAP}" = xyes; then
|
||||||
|
# Additional configuration for --enable-systemtap is HERE
|
||||||
|
AC_CHECK_PROGS(DTRACE, dtrace)
|
||||||
|
if test -z "$DTRACE"; then
|
||||||
|
AC_MSG_ERROR([dtrace not found])
|
||||||
|
fi
|
||||||
|
AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='yes'],
|
||||||
|
[SDT_H_FOUND='no';
|
||||||
|
AC_MSG_ERROR([systemtap support needs sys/sdt.h header])])
|
||||||
|
AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using SystemTap probes.])
|
||||||
|
AC_ARG_WITH([tapset-install-dir],
|
||||||
|
[AS_HELP_STRING([--with-tapset-install-dir],
|
||||||
|
[The absolute path where the tapset dir will be installed])],
|
||||||
|
[if test "x${withval}" = x; then
|
||||||
|
ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"
|
||||||
|
else
|
||||||
|
ABS_TAPSET_DIR="${withval}"
|
||||||
|
fi], [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"])
|
||||||
|
AC_SUBST(ABS_TAPSET_DIR)
|
||||||
|
fi
|
||||||
|
|
||||||
# https://www.freedesktop.org/software/systemd/man/daemon.html
|
# https://www.freedesktop.org/software/systemd/man/daemon.html
|
||||||
AC_ARG_WITH([systemdsystemunitdir],
|
AC_ARG_WITH([systemdsystemunitdir],
|
||||||
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
|
[AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],,
|
||||||
@@ -369,7 +428,7 @@ AC_OUTPUT(
|
|||||||
src/osmo-bts-virtual/Makefile
|
src/osmo-bts-virtual/Makefile
|
||||||
src/osmo-bts-omldummy/Makefile
|
src/osmo-bts-omldummy/Makefile
|
||||||
src/osmo-bts-sysmo/Makefile
|
src/osmo-bts-sysmo/Makefile
|
||||||
src/osmo-bts-litecell15/Makefile
|
src/osmo-bts-lc15/Makefile
|
||||||
src/osmo-bts-oc2g/Makefile
|
src/osmo-bts-oc2g/Makefile
|
||||||
src/osmo-bts-trx/Makefile
|
src/osmo-bts-trx/Makefile
|
||||||
src/osmo-bts-octphy/Makefile
|
src/osmo-bts-octphy/Makefile
|
||||||
@@ -386,9 +445,11 @@ AC_OUTPUT(
|
|||||||
tests/tx_power/Makefile
|
tests/tx_power/Makefile
|
||||||
tests/power/Makefile
|
tests/power/Makefile
|
||||||
tests/meas/Makefile
|
tests/meas/Makefile
|
||||||
|
tests/amr/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/examples/Makefile
|
doc/examples/Makefile
|
||||||
doc/manuals/Makefile
|
doc/manuals/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
contrib/systemd/Makefile
|
contrib/systemd/Makefile
|
||||||
|
contrib/osmo-bts.spec
|
||||||
Makefile)
|
Makefile)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
|||||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ configure_flags="\
|
|||||||
--enable-sanitize \
|
--enable-sanitize \
|
||||||
--enable-werror \
|
--enable-werror \
|
||||||
--enable-trx \
|
--enable-trx \
|
||||||
|
--enable-external-tests \
|
||||||
"
|
"
|
||||||
|
|
||||||
build_bts "osmo-bts-trx" "$configure_flags"
|
build_bts "osmo-bts-trx" "$configure_flags"
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ build_bts() {
|
|||||||
conf_flags="$*"
|
conf_flags="$*"
|
||||||
if [ "$WITH_MANUALS" = "1" ]; then
|
if [ "$WITH_MANUALS" = "1" ]; then
|
||||||
conf_flags="$conf_flags --enable-manuals"
|
conf_flags="$conf_flags --enable-manuals"
|
||||||
osmo-build-dep.sh osmo-gsm-manuals
|
|
||||||
export PATH="$inst/bin:$PATH"
|
export PATH="$inst/bin:$PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -51,12 +50,12 @@ build_bts() {
|
|||||||
./configure $conf_flags
|
./configure $conf_flags
|
||||||
$MAKE $PARALLEL_MAKE
|
$MAKE $PARALLEL_MAKE
|
||||||
$MAKE check || cat-testlogs.sh
|
$MAKE check || cat-testlogs.sh
|
||||||
DISTCHECK_CONFIGURE_FLAGS="$conf_flags" $MAKE distcheck || cat-testlogs.sh
|
DISTCHECK_CONFIGURE_FLAGS="$conf_flags" $MAKE $PARALLEL_MAKE distcheck || cat-testlogs.sh
|
||||||
|
|
||||||
# Manuals: publish
|
# Manuals: publish
|
||||||
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||||
$MAKE -C "$base/doc/manuals" publish
|
$MAKE -C "$base/doc/manuals" publish
|
||||||
fi
|
fi
|
||||||
|
|
||||||
$MAKE maintainer-clean
|
$MAKE $PARALLEL_MAKE maintainer-clean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
|||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
|||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
|||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
|||||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
@@ -20,6 +21,7 @@ configure_flags="\
|
|||||||
--with-octsdr-2g=$deps/layer1-headers/ \
|
--with-octsdr-2g=$deps/layer1-headers/ \
|
||||||
--enable-octphy \
|
--enable-octphy \
|
||||||
--enable-trx \
|
--enable-trx \
|
||||||
|
--enable-external-tests \
|
||||||
"
|
"
|
||||||
|
|
||||||
build_bts "osmo-bts-octphy+trx" "$configure_flags"
|
build_bts "osmo-bts-octphy+trx" "$configure_flags"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
|||||||
export LD_LIBRARY_PATH="$inst/lib"
|
export LD_LIBRARY_PATH="$inst/lib"
|
||||||
|
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION"
|
||||||
@@ -21,6 +22,7 @@ configure_flags="\
|
|||||||
--enable-werror \
|
--enable-werror \
|
||||||
--enable-sysmocom-bts \
|
--enable-sysmocom-bts \
|
||||||
--with-sysmobts=$inst/include/ \
|
--with-sysmobts=$inst/include/ \
|
||||||
|
--enable-external-tests \
|
||||||
"
|
"
|
||||||
|
|
||||||
# This will not work for the femtobts
|
# This will not work for the femtobts
|
||||||
|
|||||||
118
contrib/osmo-bts.spec.in
Normal file
118
contrib/osmo-bts.spec.in
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#
|
||||||
|
# spec file for package osmo-bts
|
||||||
|
#
|
||||||
|
# Copyright (c) 2017, Martin Hauke <mardnh@gmx.de>
|
||||||
|
#
|
||||||
|
# All modifications and additions to the file contributed by third parties
|
||||||
|
# remain the property of their copyright owners, unless otherwise agreed
|
||||||
|
# upon. The license for this file, and modifications and additions to the
|
||||||
|
# file, is the same license as for the pristine package itself (unless the
|
||||||
|
# license for the pristine package is not an Open Source License, in which
|
||||||
|
# case the license is the MIT License). An "Open Source License" is a
|
||||||
|
# license that conforms to the Open Source Definition (Version 1.9)
|
||||||
|
# published by the Open Source Initiative.
|
||||||
|
|
||||||
|
Name: osmo-bts
|
||||||
|
Version: @VERSION@
|
||||||
|
Release: 0
|
||||||
|
Summary: Osmocom BTS-Side code (Abis, scheduling)
|
||||||
|
License: AGPL-3.0-or-later AND GPL-2.0-only
|
||||||
|
Group: Productivity/Telephony/Servers
|
||||||
|
URL: https://osmocom.org/projects/osmobts
|
||||||
|
Source: %{name}-%{version}.tar.xz
|
||||||
|
BuildRequires: autoconf
|
||||||
|
BuildRequires: automake
|
||||||
|
BuildRequires: libtool
|
||||||
|
BuildRequires: pkgconfig >= 0.20
|
||||||
|
%if 0%{?suse_version}
|
||||||
|
BuildRequires: systemd-rpm-macros
|
||||||
|
%endif
|
||||||
|
BuildRequires: pkgconfig(libosmocodec) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmocoding) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
||||||
|
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
||||||
|
BuildRequires: pkgconfig(libosmotrau) >= 1.3.0
|
||||||
|
BuildRequires: pkgconfig(libosmo-netif) >= 1.2.0
|
||||||
|
### FIXME: DependencyHACK to include osmocom/gprs/protocol/gsm_04_60.h
|
||||||
|
BuildRequires: pkgconfig(libosmogb)
|
||||||
|
%{?systemd_requires}
|
||||||
|
|
||||||
|
%description
|
||||||
|
Osmocom BTS-Side code (A-bis, scheduling).
|
||||||
|
|
||||||
|
%package -n osmo-bts-virtual
|
||||||
|
Summary: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
|
||||||
|
License: GPL-2.0-or-later
|
||||||
|
Group: Productivity/Telephony/Utilities
|
||||||
|
|
||||||
|
%description -n osmo-bts-virtual
|
||||||
|
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but
|
||||||
|
utilizes GSMTAP-over-UDP frames for the Um interface. This is useful
|
||||||
|
in fully virtualized setups e.g. in combination with OsmocomBB virt_phy.
|
||||||
|
|
||||||
|
%package -n osmo-bts-omldummy
|
||||||
|
Summary: Osmocom CI: Bring up only OML without RSL
|
||||||
|
License: GPL-2.0-or-later
|
||||||
|
Group: Productivity/Telephony/Utilities
|
||||||
|
|
||||||
|
%description -n osmo-bts-omldummy
|
||||||
|
This is used only in integration testing, where in the TTCN-3 testsuite
|
||||||
|
we currently have no A-bis OML implementation, but only a RSL one.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q
|
||||||
|
|
||||||
|
%build
|
||||||
|
echo "%{version}" >.tarball-version
|
||||||
|
autoreconf -fi
|
||||||
|
%configure \
|
||||||
|
--docdir="%{_docdir}/%{name}" \
|
||||||
|
--with-systemdsystemunitdir=%{_unitdir} \
|
||||||
|
--enable-trx
|
||||||
|
make V=1 %{?_smp_mflags}
|
||||||
|
|
||||||
|
%install
|
||||||
|
%make_install
|
||||||
|
|
||||||
|
%if 0%{?suse_version}
|
||||||
|
%pre %service_add_pre osmo-bts-trx.service
|
||||||
|
%post %service_add_post osmo-bts-trx.service
|
||||||
|
%preun %service_del_preun osmo-bts-trx.service
|
||||||
|
%postun %service_del_postun osmo-bts-trx.service
|
||||||
|
%pre virtual %service_add_pre osmo-bts-virtual.service
|
||||||
|
%post virtual %service_add_post osmo-bts-virtual.service
|
||||||
|
%preun virtual %service_del_preun osmo-bts-virtual.service
|
||||||
|
%postun virtual %service_del_postun osmo-bts-virtual.service
|
||||||
|
%endif
|
||||||
|
|
||||||
|
%check
|
||||||
|
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||||
|
|
||||||
|
%files
|
||||||
|
%license COPYING
|
||||||
|
%doc README.md
|
||||||
|
%dir %{_docdir}/%{name}
|
||||||
|
%dir %{_docdir}/%{name}/examples
|
||||||
|
%dir %{_docdir}/%{name}/examples/osmo-bts-trx
|
||||||
|
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx-calypso.cfg
|
||||||
|
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx.cfg
|
||||||
|
%dir %{_docdir}/%{name}/examples/osmo-bts-virtual
|
||||||
|
%{_docdir}/%{name}/examples/osmo-bts-virtual/osmo-bts-virtual.cfg
|
||||||
|
%{_bindir}/osmo-bts-trx
|
||||||
|
%dir %{_sysconfdir}/osmocom
|
||||||
|
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-trx.cfg
|
||||||
|
%{_unitdir}/osmo-bts-trx.service
|
||||||
|
|
||||||
|
%files -n osmo-bts-virtual
|
||||||
|
%{_bindir}/osmo-bts-virtual
|
||||||
|
%dir %{_sysconfdir}/osmocom
|
||||||
|
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-virtual.cfg
|
||||||
|
%{_unitdir}/osmo-bts-virtual.service
|
||||||
|
|
||||||
|
%files -n osmo-bts-omldummy
|
||||||
|
%{_bindir}/osmo-bts-omldummy
|
||||||
|
|
||||||
|
%changelog
|
||||||
@@ -7,6 +7,8 @@ Wants=lc15-sysdev-remap.service
|
|||||||
Type=simple
|
Type=simple
|
||||||
NotifyAccess=all
|
NotifyAccess=all
|
||||||
WatchdogSec=21780s
|
WatchdogSec=21780s
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ Wants=oc2g-sysdev-remap.service
|
|||||||
Type=simple
|
Type=simple
|
||||||
NotifyAccess=all
|
NotifyAccess=all
|
||||||
WatchdogSec=21780s
|
WatchdogSec=21780s
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,18 @@ Description=osmo-bts for LC15 / sysmoBTS 2100
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/osmo-bts-lc15 -t 2 -s -c /etc/osmocom/osmo-bts-lc15.cfg -M
|
ExecStart=/usr/bin/osmo-bts-lc15 -t 2 -s -c /etc/osmocom/osmo-bts-lc15.cfg -M
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
RuntimeDirectory=osmo-bts
|
RuntimeDirectory=osmo-bts
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
RestartPreventExitStatus=1
|
RestartPreventExitStatus=1
|
||||||
|
|
||||||
# The msg queues must be read fast enough
|
# CPU scheduling policy:
|
||||||
CPUSchedulingPolicy=rr
|
CPUSchedulingPolicy=rr
|
||||||
CPUSchedulingPriority=1
|
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||||
|
CPUSchedulingPriority=11
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -4,14 +4,18 @@ Description=osmo-bts for OC-2G
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/osmo-bts-oc2g -s -c /etc/osmocom/osmo-bts-oc2g.cfg -M
|
ExecStart=/usr/bin/osmo-bts-oc2g -s -c /etc/osmocom/osmo-bts-oc2g.cfg -M
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
RuntimeDirectory=osmo-bts
|
RuntimeDirectory=osmo-bts
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
RestartPreventExitStatus=1
|
RestartPreventExitStatus=1
|
||||||
|
|
||||||
# The msg queues must be read fast enough
|
# CPU scheduling policy:
|
||||||
CPUSchedulingPolicy=rr
|
CPUSchedulingPolicy=rr
|
||||||
CPUSchedulingPriority=1
|
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||||
|
CPUSchedulingPriority=11
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -7,13 +7,17 @@ ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
|
|||||||
ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts-sysmo.cfg -M
|
ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts-sysmo.cfg -M
|
||||||
ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
|
ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness'
|
||||||
ExecStopPost=/bin/sh -c 'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s'
|
ExecStopPost=/bin/sh -c 'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s'
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
RestartPreventExitStatus=1
|
RestartPreventExitStatus=1
|
||||||
|
|
||||||
# The msg queues must be read fast enough
|
# CPU scheduling policy:
|
||||||
CPUSchedulingPolicy=rr
|
CPUSchedulingPolicy=rr
|
||||||
CPUSchedulingPriority=1
|
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||||
|
CPUSchedulingPriority=11
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ Description=Osmocom osmo-bts for osmo-trx
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts-trx.cfg
|
ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts-trx.cfg
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
# Let it process messages quickly enough
|
# CPU scheduling policy:
|
||||||
CPUSchedulingPolicy=rr
|
CPUSchedulingPolicy=rr
|
||||||
CPUSchedulingPriority=1
|
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||||
|
CPUSchedulingPriority=11
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/osmo-bts-virtual -s -c /etc/osmocom/osmo-bts-virtual.cfg
|
ExecStart=/usr/bin/osmo-bts-virtual -s -c /etc/osmocom/osmo-bts-virtual.cfg
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
# Let it process messages quickly enough
|
# CPU scheduling policy:
|
||||||
CPUSchedulingPolicy=rr
|
CPUSchedulingPolicy=rr
|
||||||
CPUSchedulingPriority=1
|
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||||
|
CPUSchedulingPriority=11
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ Description=osmo-bts manager for sysmoBTS
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg
|
ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg
|
||||||
|
StateDirectory=osmocom
|
||||||
|
WorkingDirectory=%S/osmocom
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=2
|
RestartSec=2
|
||||||
|
|
||||||
|
|||||||
959
debian/changelog
vendored
959
debian/changelog
vendored
@@ -1,3 +1,962 @@
|
|||||||
|
osmo-bts (1.5.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* bts_shutdown_fsm.h: Remove wrong comment describing enum
|
||||||
|
* bts: Properly free bts->shutdown_fi when struct gsm_bts is freed
|
||||||
|
* bts-trx: amr: Fix return code of osmo_amr_rtp_dec() checked too late
|
||||||
|
* Change some log levels NOTICE->INFO
|
||||||
|
* rsl: Conditionally decrease log level if cause is normal event
|
||||||
|
* bts-trx: Log lchan if avaialble in Meas Avg
|
||||||
|
* doc: rsl: Fix description of 'IP Connection Statistics' IE
|
||||||
|
* bts-trx: sched_lchan_tchh.c: Workaround gcc false positive error
|
||||||
|
* bts-sysmo: Replace use of deprecated ipa_client_conn_create API
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* cbch: Fix bts_smscb_state_reset() to avoid double-free
|
||||||
|
* cbch: Fix dangling cur_msg leading to double-free in bts_cbch_reset()
|
||||||
|
* [lc15,oc2g,octphy] Fix memory leak on write queue overflow
|
||||||
|
* update git URLs (git -> https; gitea)
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* debian/control: add osmo-bts meta-package
|
||||||
|
* treewide: remove FSF address
|
||||||
|
* model_init: order features alphabetically
|
||||||
|
* model_init: set BTS_FEAT_PAGINATION_COORDINATION
|
||||||
|
* model_init: order features alphabetically, part 2
|
||||||
|
* src/common/bts.c: set BTS_FEAT_PAGING_COORDINATION
|
||||||
|
* src/common/bts.c: set BTS_FEAT_CCN
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* oml: use proper talloc context in oml_rx_set_radio_attr()
|
||||||
|
* oml: use ts->trx as talloc-context in oml_rx_set_chan_attr()
|
||||||
|
* oml: fix copy-pasted comments in oml_rx_set_*_attr()
|
||||||
|
* oml: assign unique names to 'struct tlv_parsed' chunks
|
||||||
|
* osmo-bts-trx: use l1ts as talloc context for burst buffers
|
||||||
|
* osmo-bts-trx: fix a memleak in trx_sched_set_lchan()
|
||||||
|
* cbch: cosmetic: use talloc_zero() in bts_process_smscb_cmd()
|
||||||
|
* phy_instance_destroy(): fix NULL pointer dereference
|
||||||
|
* logging: get rid of logging category DSUM
|
||||||
|
* osmo-bts-trx: make use of OSMO_UNLIKELY() when handling TRXD PDUs
|
||||||
|
* osmo-bts-trx: cosmetic: use rate_ctr_inc2() instead of rate_ctr_inc()
|
||||||
|
* osmo-bts-trx: new rate counter 'trx_sched:dl_fh_cache_miss'
|
||||||
|
* VTY: fix ambiguity in BTS specific command definitions
|
||||||
|
* osmo-bts-trx: do not run osmo_{fr,hr}_check_sid() on FACCH/U frames
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): do not calculate BER10k for FACCH twice
|
||||||
|
* rsl: fix wrong IE being checked in rsl_rx_chan_activ()
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): fix HR SID detection (wrong offset)
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): mark valid SID frames as such
|
||||||
|
* osmo-bts-trx: use consistent naming for 'enum sched_meas_avg_mode'
|
||||||
|
* osmo-bts-trx: use a lookup table in trx_sched_meas_avg()
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): use proper meas averaging mode
|
||||||
|
* trx_sched_ul_burst(): get rid of the 'switch' statement
|
||||||
|
* fix gsm_bts_get_cbch(): CBCH can be allocated on Cn
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): indicate BER10k=0 for FACCH BFIs
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): get rid of chan_state->meas_avg_facch
|
||||||
|
* osmo-bts-trx: rx_{tchf,tchh}_fn(): also use meas_avg for BFI
|
||||||
|
* osmo-bts-trx: rx_{tchf,tchh}_fn(): shift Rx burst buffer on bid=0
|
||||||
|
* osmo-bts-trx: rx_{tchf,tchh}_fn(): ensure complete set of bursts
|
||||||
|
* osmo-bts-trx: rx_{tchf,tchh}_fn(): get TDMA FN from meas history
|
||||||
|
* osmo-bts-trx: rx_{tchh,tchf}_fn(): use AMR CMI lookup tables
|
||||||
|
* osmo-bts-trx: rx_{tchh,tchf}_fn(): use tch_mode directly
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): fix meas reporting in signalling mode
|
||||||
|
* osmo-bts-trx: move AMR CMI lookup tables to the respective files
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): fix indexes in the AMR CMI lookup table
|
||||||
|
* osmo-bts-trx: rx_tchf_fn(): clarify indexes in the AMR CMI lookup table
|
||||||
|
* power_ctrl_params_def_reset(): set .ctrl_interval for both UL/DL
|
||||||
|
* scheduler: remove redundant OSMO_ASSERT() statements
|
||||||
|
* scheduler: rts_tchh_fn(): use a lookup table for FACCH/H
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): use a lookup table for FACCH/H
|
||||||
|
* osmo-bts-{trx,virtual}: tx_tchh_fn(): remove FACCH/H alignment check
|
||||||
|
* osmo-bts-trx: rename 'loops.[ch]' to 'amr_loop.[ch]'
|
||||||
|
* osmo-bts-trx: use '#pragma once' in amr_loop.h
|
||||||
|
* osmo-bts-trx: amr_loop: remove unneeded #includes
|
||||||
|
* rsl: de-duplicate parsing of MultiRate configuration IE
|
||||||
|
* rsl: rsl_rx_chan_{activ,modif}: do not sent an Error Report
|
||||||
|
* rsl: parse_multirate_config(): check if AMR codec is used
|
||||||
|
* logging: use a different color tone for DLOOP
|
||||||
|
* rsl: always check return value of rsl_tlv_parse()
|
||||||
|
* rsl: misc / cosmetic fixes for tx_ipac_XXcx_nack()
|
||||||
|
* osmo-bts-virtual: remove unused 'codec_mode_request' argument
|
||||||
|
* l1sap: l1sap_chan_act(): alloc DTX FSM only for TCH
|
||||||
|
* l1sap: l1sap_chan_act(): remove unused *tp argument
|
||||||
|
* osmo-bts-trx: bts_report_interf_meas(): remove unused fn param
|
||||||
|
* rsl: use hard-coded defaults if the MultiRate conf IE is absent
|
||||||
|
* tests/amr/Makefile.am: use proper binary name prefix 'amr_test_'
|
||||||
|
* tests/amr: add a unit test for amr_parse_mr_conf()
|
||||||
|
* amr: fix parsing of threshold and hysteresis in amr_parse_mr_conf()
|
||||||
|
* tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS'
|
||||||
|
* struct amr_multirate_conf: remove ms_mode[], raname bts_mode[]
|
||||||
|
* common: fix coding style: if is not a function
|
||||||
|
* osmo-bts-trx: amr_loop: simplify trx_loop_amr_set()
|
||||||
|
* osmo-bts-trx: use C/I in the AMR link adaptation loop
|
||||||
|
* osmo-bts-trx: amr_loop: improve logging in trx_loop_amr_input()
|
||||||
|
* osmo-bts-trx: amr_loop: allow upgrading codec mode > 0
|
||||||
|
* osmo-bts-trx: amr_loop: log if AMR mode remains unchanged
|
||||||
|
* osmo-bts-trx: amr_loop: do not miss C/I samples
|
||||||
|
* osmo-bts-trx: prioritize FACCH in s/tx_tch_common()/tch_dl_dequeue()/s
|
||||||
|
* osmo-bts-trx: tx_tchh_fn(): make handling of FACCH/H cleaner
|
||||||
|
* osmo-bts-trx: fix scheduling of dummy FACCH/H and FACCH/F
|
||||||
|
* VTY: fix NULL-pointer dereference in 'show transceiver'
|
||||||
|
* osmo-bts-trx: check if scheduling of [dummy] FACCH/H is allowed
|
||||||
|
* osmo-bts-trx: rx_{tchh,tchf}_fn(): improve logging of AMR DTX frames
|
||||||
|
* pcu_sock: comment out {dl,ul}_tbf_ext related warnings
|
||||||
|
* osmo-bts-trx: drop Uplink loss detection from Downlink path
|
||||||
|
* scheduler: trx_sched_is_sacch_fn(): make ts pointer const
|
||||||
|
* struct bts_ul_meas: reflect C/I units in field name s/c_i/ci_cb/
|
||||||
|
* tests/meas: improve logging in test_ts45008_83_is_sub_single()
|
||||||
|
* tests/meas: improve test_ts45008_83_is_sub_is_sub()
|
||||||
|
* measurement: log SUB/FULL as text in lchan_new_ul_meas()
|
||||||
|
* measurement: move SACCH detection to process_l1sap_meas_data()
|
||||||
|
* measurement: fix matching of SUB frames by TDMA FN
|
||||||
|
* osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame
|
||||||
|
* Revert "osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame"
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 29 Jun 2022 09:41:38 +0200
|
||||||
|
|
||||||
|
osmo-bts (1.4.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* l1sap: Store status of SRR in an lchan struct memeber
|
||||||
|
* l1sap: add logging and VTY introspection for ACCH repetition
|
||||||
|
* sched_lchan_tchh: fix frame number and fill FACCH gap
|
||||||
|
* main,abis: change model name from sysmoBTS to osmo-bts
|
||||||
|
* paging: prioritize CS related paging over PS related pagings.
|
||||||
|
* allow to configure multiple oml remote-ip addresses
|
||||||
|
* sched_lchan_tch_x: do not use cmr as ft
|
||||||
|
* sched_lchan_tch_x: use functions to determine AMR tranmssion phase
|
||||||
|
* sched_lchan_tch_x: use ul_cmr and ul_ft when generating RTP bad frame
|
||||||
|
* rsl: simplfy parse_repeated_acch_capability
|
||||||
|
* rsl: parse temporary overpower value RSL CHAN ACT / MODIFY
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* doc/examples: remove obsolete power control parameters
|
||||||
|
* doc/examples: enable stderr logging for osmo-bts-virtual.cfg
|
||||||
|
* osmo-bts-trx: fix: do not call trx_if_close() two times
|
||||||
|
* osmo-bts-trx: fix segfault on trx_phy_inst_open() failure
|
||||||
|
* l1sap: use the passed 'trx' pointer in l1sap_chan_act()
|
||||||
|
* l1sap: use TLVP_PRES_LEN() macro in l1sap_chan_act()
|
||||||
|
* l1sap: check BTS_FEAT_MULTI_TSC in l1sap_chan_act()
|
||||||
|
* l1sap: fix wrong IEI and parsing in l1sap_chan_act()
|
||||||
|
* manuals: fix wrong VTY node for 'gsmtap-sapi' command
|
||||||
|
* manuals: document GSMTAP 'enable-all' / 'disable-all'
|
||||||
|
* osmo-bts-trx: correct definition of 'osmotrx rx-gain' command
|
||||||
|
* rsl: do not blindly ignore unhandled/unknown Channel Mode
|
||||||
|
* manuals: remove deprecated command line parameters
|
||||||
|
* manuals: document new 'gsmtap-remote-host' command
|
||||||
|
* l1sap: fix incorrect pointer cast in l1sap_chan_act()
|
||||||
|
* rsl: rename, fix and refactor lchan_tchmode_from_cmode()
|
||||||
|
* rsl: add missing Channel Mode values to rsl_handle_chan_mod_ie()
|
||||||
|
* lchan2lch_par(): fix missing default branch in switch
|
||||||
|
* osmo-bts-trx: cosmetic: TRXD 'header version' -> 'PDU version'
|
||||||
|
* osmo-bts-trx: remove outdated TRXD protocol documentation
|
||||||
|
* osmo-bts-trx: cosmetic: use '#pragma once' in trx_if.h
|
||||||
|
* osmo-bts-trx: define TRXC/TRXD message buffer size
|
||||||
|
* osmo-bts-trx: 'burst type' is actually modulation type
|
||||||
|
* osmo-bts-trx: move MTS parser into trx_data_parse_mts()
|
||||||
|
* osmo-bts-trx: discard TRXD PDUs with unexpected version
|
||||||
|
* osmo-bts-trx: move TDMA frame number check to trx_data_read_cb()
|
||||||
|
* osmo-bts-trx: cosmetic: get rid of TRX_CHDR_LEN macro
|
||||||
|
* osmo-bts-trx: generalize checking of TRXD header length
|
||||||
|
* osmo-bts-trx: pass 'struct phy_instance' to TRXD dissectors
|
||||||
|
* osmo-bts-trx: refactor handling of version specific TRXD parts
|
||||||
|
* osmo-bts-trx: enlarge and share TRXD message buffer
|
||||||
|
* osmo-bts-trx: assert PDU version in trx_if_send_burst()
|
||||||
|
* osmo-bts-trx: reduce code nasting in trx_if_send_burst()
|
||||||
|
* vty: fix the use of deprecated osmo_bts_feature_name()
|
||||||
|
* common/abis: fix the use of deprecated e1inp_line_get() API
|
||||||
|
* osmo-bts-trx: refactor parse_rsp(), fix compilation warnings
|
||||||
|
* rsl: fix wrong value printed in rsl_handle_chan_mod_ie()
|
||||||
|
* struct gsm_bts_trx: remove unused leftovers from openbsc
|
||||||
|
* common/sysinfo: make struct gsm_bts_trx const in num_agch()
|
||||||
|
* osmo-bts-{lc15,oc2g}: drop redundant checks in VTY commands
|
||||||
|
* [VAMOS] struct gsm_bts_trx: fix the PHY instance pointer
|
||||||
|
* [VAMOS] Merge bts_trx_init() into gsm_bts_trx_alloc()
|
||||||
|
* [VAMOS] osmo-bts-trx: move {chan,bid} to trx_{dl,ul}_burst_{req,ind}
|
||||||
|
* osmo-bts-trx: implement TRXDv2 protocol support
|
||||||
|
* scheduler.h: cosmetic: use #pragma once
|
||||||
|
* osmo-bts-trx: cosmetic: s/trx_sched_fn/bts_sched_fn/g
|
||||||
|
* osmo-bts-trx: remove redundant assert() in bts_sched_fn()
|
||||||
|
* osmo-bts-trx: fix hopping pointer bug in bts_sched_fn()
|
||||||
|
* [VAMOS] Re-organize osmo-bts-trx specific structures
|
||||||
|
* osmo-bts-trx: clarify logging messages in trx_if_{open,close}()
|
||||||
|
* osmo-bts-{trx,virtual}: fix: pinst->trx may be NULL
|
||||||
|
* common: make the arguments of phy_{link,instance}_name() const
|
||||||
|
* [VAMOS] common: make 'struct gsm_bts_trx_ts' pointers const
|
||||||
|
* [VAMOS] gsm_data.h: fix wrong bit-mask in BSIC2BCC macro
|
||||||
|
* [VAMOS] gsm_data.h: introduce and use BTS_TSC macro
|
||||||
|
* common: phy_links_open(): warn about dangling PHY instances
|
||||||
|
* [VAMOS] osmo-bts-trx: rework and split up bts_sched_fn()
|
||||||
|
* Fix regression in 'osmo-bts-trx: rework and split up bts_sched_fn()'
|
||||||
|
* [VAMOS] osmo-bts-trx: implement and enable PDU batching for TRXDv2
|
||||||
|
* [VAMOS] osmo-bts-trx: indicate MTS in Downlink TRXDv2 PDUs
|
||||||
|
* [VAMOS] rsl_rx_mode_modif(): handle Channel Identification IE
|
||||||
|
* [VAMOS] rsl: call bts_supports_cm() from rsl_handle_chan_mod_ie()
|
||||||
|
* [VAMOS] bts_supports_cm(): handle RSL_CMOD_CRT_OSMO_TCH_VAMOS_{Bm,Lm}
|
||||||
|
* [VAMOS] common/scheduler: unify symbol names for training sequences
|
||||||
|
* [VAMOS] osmo-bts-trx: rework handling of Training Sequence
|
||||||
|
* [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values
|
||||||
|
* [VAMOS] scheduler: add new GMSK training sequences from 3GPP 45.002
|
||||||
|
* [VAMOS] l1sap_chan_act(): handle Osmocom specific TSC IE
|
||||||
|
* [VAMOS] common/oml: generalize checking BTS_FEAT_MULTI_TSC
|
||||||
|
* [VAMOS] gsm_pchan2chan_nr(): use ABIS_RSL_CHAN_NR_CBITS_* macros
|
||||||
|
* [VAMOS] rsl_lchan_lookup(): use ABIS_RSL_CHAN_NR_CBITS_* macros
|
||||||
|
* [VAMOS] rsl_lchan_lookup(): make it more readable
|
||||||
|
* [VAMOS] gsm_data: rework and rename gsm_lchan_name_compute()
|
||||||
|
* [VAMOS] l1sap: get_lchan_by_chan_nr() may return NULL
|
||||||
|
* [VAMOS] oml_rx_set_chan_attr(): clarify NM_ATT_CHAN_COMB handling
|
||||||
|
* manuals/abis/rsl.adoc: s/TS 08.58/TS 48.058/
|
||||||
|
* manuals/abis/rsl.adoc: rework Channel Number description
|
||||||
|
* manuals/abis/rsl.adoc: add missing CBCH Channel Number values
|
||||||
|
* manuals/abis/rsl.adoc: add VAMOS specific Channel Number values
|
||||||
|
* osmo-bts-trx: fix NULL pointer dereference in trx_if_send_burst()
|
||||||
|
* trx_sched_is_sacch_fn(): fix handling of dynamic timeslots
|
||||||
|
* [VAMOS] scheduler: drop meaningless channel number checks
|
||||||
|
* [VAMOS] conf_lchans_as_pchan(): improve readability
|
||||||
|
* [VAMOS] Implement the concept of 'shadow' timeslots
|
||||||
|
* [VAMOS] osmo-bts-trx: schedule bursts on 'shadow' timeslots
|
||||||
|
* l1sap: fix TDMA frame number wrap in l1sap_info_time_ind()
|
||||||
|
* conf_lchans_as_pchan(): fix GSM_LCHAN_{CCCH->CBCH} regression
|
||||||
|
* conf_lchans_as_pchan(): initialize all lchans with GSM_LCHAN_NONE
|
||||||
|
* measurement: remove over-defensive checks in is_meas_complete()
|
||||||
|
* [VAMOS] trx_sched_init_ts(): assign names to per-timeslot counters
|
||||||
|
* common/vty: facilitate finding duplicate PHY/TRX associations
|
||||||
|
* vty: ensure all warning messages are prefixed with '%%'
|
||||||
|
* osmo-bts-octphy: drop talloc_replace(), use osmo_talloc_replace_string()
|
||||||
|
* l1sap: fix TDMA frame number arithmetic in fn_ms_adj()
|
||||||
|
* osmo-bts-trx: fix typo: s/bisc/bsic/ in 'show transceiver'
|
||||||
|
* osmo-bts-trx: fix copy-pasted comment: s/sysmoBTS/osmo-bts-trx/
|
||||||
|
* oml: fix handling of NM_ATT_INTERF_BOUND attribute
|
||||||
|
* Report interference levels in RSL RF RESource INDication
|
||||||
|
* scheduler: reorder enum trx_chan_type, add TRX_CHAN_IS_DEDIC()
|
||||||
|
* osmo-bts-trx: report interference levels to the upper layers
|
||||||
|
* osmo-bts-{trx,virtual}: get rid of dummy tx_idle_fn()
|
||||||
|
* scheduler: unset TRX_CHAN_FLAG_AUTO_ACTIVE for TRXC_IDLE
|
||||||
|
* osmo-bts-trx: print timeslot brief info in 'show transceiver'
|
||||||
|
* osmo-bts-trx: measure interference levels on TRXC_IDLE
|
||||||
|
* osmo-bts-trx: report PDCH interference levels to the PCU
|
||||||
|
* scheduler: fix wrong union field in trx_sched_tch_req()
|
||||||
|
* scheduler: fix: use ts_pchan() in trx_sched_set_cipher()
|
||||||
|
* Revert "power_control: BS power shall not be reduced on C0"
|
||||||
|
* osmo-bts-omldummy: indicate BTS_FEAT_BCCH_POWER_RED as supported
|
||||||
|
* osmo-bts-trx: implement BCCH carrier power reduction mode
|
||||||
|
* power_control: constrain BS power reduction on BCCH carrier
|
||||||
|
* manuals/abis/rsl.adoc: clarify RF Resource Indication conformance
|
||||||
|
* rsl: use tlvp_val16be() in rsl_rx_ipac_XXcx()
|
||||||
|
* gsm_lchan_interf_meas_calc_band(): also print number of AVG samples
|
||||||
|
* osmo-bts-trx: send dummy FACCH in the absense of RTP frames
|
||||||
|
* osmo-bts-trx: return -ENODEV if 'bursts_p' is NULL
|
||||||
|
* l1sap: unify channel (de)activation/modification messages
|
||||||
|
* gsm_lchan2chan_nr(): separate RSL specific variant of this API
|
||||||
|
* osmo-bts-trx: bts_model_l1sap_down(): remove chan_nr patching
|
||||||
|
* trx_sched_set_lchan(): use LOGL_INFO for logging messages
|
||||||
|
* osmo-bts-trx: remove an 'else' branch in _sched_dl_burst()
|
||||||
|
* osmo-bts-trx: implement Temporary Overpower for SACCH/FACCH
|
||||||
|
* scheduler: fix comments explaining the interleaving of TCH/H
|
||||||
|
* fix handle_ms_meas_report(): properly count measurement reports
|
||||||
|
* abis: fix memory leak in abis_oml_sendmsg()
|
||||||
|
* rsl: remove redundant logging in rsl_rx_chan_activ()
|
||||||
|
* .gitignore: add tests/amr/amr_test
|
||||||
|
* rsl: prevent race condition during timeslot re-configuration
|
||||||
|
* rsl_tx_rf_res(): separate interference AVG / band calculation
|
||||||
|
* rsl_tx_rf_res(): also report noise levels for PDTCH
|
||||||
|
* osmo-bts-trx: report PDCH interference levels to L1SAP
|
||||||
|
* l1sap: check if BTS model supports interference reporting
|
||||||
|
* vty: show interference level / band in 'show lchan'
|
||||||
|
* trx_sched_clean_ts(): also free() the associated 'struct l1sched_ts'
|
||||||
|
* trx_sched_clean(): also free() the shadow timeslot
|
||||||
|
* osmo-bts-trx: refactor 'maxdly' / 'maxdlynb' commands
|
||||||
|
* rsl: rsl_tx_meas_res() does not change l3, make it const
|
||||||
|
* rsl: send NACK if BTS_FEAT_ACCH_REP is not supported
|
||||||
|
* measurement: handle_ms_meas_report() accepts const gh
|
||||||
|
* measurement: move repeated_dl_facch_active_decision() here
|
||||||
|
* measurement: make sure that DL measurements are valid
|
||||||
|
* cosmetic: s/repeated_acch_capability/rep_acch_cap/g
|
||||||
|
* struct gsm_lchan: group ACCH repetition state fields
|
||||||
|
* struct gsm_lchan: move tch.rep_facch to rep_acch.dl_facch
|
||||||
|
* measurement: fix wrong operator used in handle_ms_meas_report()
|
||||||
|
* osmo-bts-trx: fix potential NULL pointer dereference
|
||||||
|
* lchan_set_state(): also free pending messages if any
|
||||||
|
* lchan: introduce and use lchan_is_tch() helper
|
||||||
|
* [overpower] rsl: store full content of RSL_IE_OSMO_TEMP_OVP_ACCH_CAP
|
||||||
|
* [overpower] lchan_dump_full_vty(): print overpower state
|
||||||
|
* [overpower] scheduler: handle {sacch,facch}_enabled flags
|
||||||
|
* l1sap: fix handling of lchan->pending_rel_ind_msg
|
||||||
|
* l1sap: move false PTCCH/U detection into PDCH branch
|
||||||
|
* l1sap: use designated initializers in process_l1sap_meas_data()
|
||||||
|
* l1sap: process_l1sap_meas_data() accepts pointer to lchan
|
||||||
|
* l1sap: make 'l1sap' argument of process_l1sap_meas_data() const
|
||||||
|
* rsl: fix a memory leak in handle_gprs_susp_req()
|
||||||
|
* l1sap: rework handling of DATA.ind on SACCH
|
||||||
|
* lchan_meas_handle_sacch(): check if Measurement Result is valid
|
||||||
|
* measurement: get rid of *le in lchan_meas_handle_sacch()
|
||||||
|
* measurement: pass *mr to repeated_dl_facch_active_decision()
|
||||||
|
* measurement: pass *mr to lchan_bs_pwr_ctrl()
|
||||||
|
* [overpower] Turn it on and off depending on DL RxQual
|
||||||
|
* measurement: make use of gsm48_meas_res_is_valid()
|
||||||
|
* common/Makefile.am: reformat {AM_CPPFLAGS,AM_CFLAGS,LDADD}
|
||||||
|
* rsl: exclude disabled timeslots from interference reports
|
||||||
|
* oml: use ARRAY_SIZE() in oml_rx_set_bts_attr()
|
||||||
|
* gsm_lchan_interf_meas_calc_avg(): fix band calculation
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* l1sap: Transmit pdtch invalid MAC blocks to PCU
|
||||||
|
* bts-trx: Always submit rx PDTCH DATA.ind to l1sap
|
||||||
|
* bts-trx: Avoid submitting first data_ind with FN=0 to upper layers
|
||||||
|
* bts-trx: Drop duplicate set of last_clk_ind
|
||||||
|
* bts-trx: reorder first timerfd schedule to decrease first timeout skew
|
||||||
|
* sysmo,oc2g,lc15: Make RadioChannel MO depend on RadioCarrier MO
|
||||||
|
* bts: Clean up TS selection in sign_link_up
|
||||||
|
* Fix regression in 'bts: Clean up TS selection in sign_link_up'
|
||||||
|
* Add missing value_string for NM_EV_* introduced recently
|
||||||
|
* pcuif: Set missing bsic field during Tx of info_ind
|
||||||
|
* Use new stat item/ctr getter APIs
|
||||||
|
* rsl: Use switch statement in rsl_rx_bcch_info()
|
||||||
|
* pcu_sock: Transmit SI2
|
||||||
|
* doc: rsl.adoc: Fix trailing whitespace
|
||||||
|
* gsm_data: Drop unused function gsm_pchan_parse()
|
||||||
|
* pcuif_proto.h: Add new container messages
|
||||||
|
* Support forwarding proto IPAC_PROTO_EXT_PCU BSC<->PCU
|
||||||
|
* Rename osmo dyn ts enums to contain SDCCH8
|
||||||
|
* Support SDCCH8 in osmo dyn ts
|
||||||
|
* Make gcc 11.1.0 false positivies happy
|
||||||
|
* rsl: Fix rx of multiple RSL_IPAC_EIE_MEAS_AVG_CFG IEs
|
||||||
|
* rsl: Support parsing up to 3 RSL_IPAC_EIE_MEAS_AVG_CFG IEs
|
||||||
|
* MS Power Control Loop: Take C/I into account
|
||||||
|
* MS Power Control Loop: Support EWMA algorithm for C/I measurements
|
||||||
|
* MS Power Control Loop: Improve logging
|
||||||
|
* BS Power Control Loop: refactor lchan_bs_pwr_ctrl() to look similar to lchan_ms_pwr_ctrl()
|
||||||
|
* BS Power Control Loop: Support EWMA average algo for RxQual meas
|
||||||
|
* BS Power Control Loop: Increase attenuation if RxQual is better than upper threshold
|
||||||
|
* MS/BS Power Control Loop: Do RxLEV meas avg & delta calculations directly on RxLevels
|
||||||
|
* MS/BS Power Control Loop: Fix downscaling averaging bug
|
||||||
|
* Power Control Loop: Move skip loop logic to function helper
|
||||||
|
* comsetic: measurement.c: fix typo in comment
|
||||||
|
* l1sap: Take L1SACCH MS_PWR from bitfield instead of manual parsing
|
||||||
|
* TA loop: Take into account UL SACCH 'Actual Timing advance' field
|
||||||
|
* ta_control: Allow switching TA quicker
|
||||||
|
* lchan: Move TA CTRL param to its own substruct
|
||||||
|
* MS Power Control Loop: Feed UL RSSI from correct measurement period
|
||||||
|
* MS Power Control Loop: Feed UL C/I from correct measurement period
|
||||||
|
* TA Control Loop: Change toa256 switch threshold to 75% of a symbol
|
||||||
|
* Power Control Loop: Set P_CON_INTERVAL to 1 by default
|
||||||
|
* Support configuring TA loop SACCH block rate
|
||||||
|
* MS Power Control Loop: Fix sub vs full being passed to algo
|
||||||
|
* abis: Clear code and drop code not executed
|
||||||
|
* abis.h: Drop unused state
|
||||||
|
* cosmetic: fix typo in comment
|
||||||
|
* abis.c: Rearrange code to follow logic state order
|
||||||
|
* abis.c: Convert early return to assert()
|
||||||
|
* power_control: Drop unused param in function
|
||||||
|
* tests: MS Power Control Loop: Show oscillation among good power levels
|
||||||
|
* cosmetic: Fix formatting of conditional operator
|
||||||
|
* abis: Move FSM registration to constructor function
|
||||||
|
* abis: Shorten string names of events
|
||||||
|
* abis.c: Transition to CONNECTED state only when OML link is up
|
||||||
|
* abis.c: Fix mess with priv->bsc_oml_host
|
||||||
|
* abis.c: Loop over list of BSCs until connection succeeds
|
||||||
|
* trx_provision_fsm: Add missing state transition OPEN_WAIT_POWEROFF_CNF => OPEN_POWEROFF
|
||||||
|
* nm_*_fsm: Add missing item in event mask list for state ENABLED
|
||||||
|
* Allow setting administrative state through oml_mo_state_chg()
|
||||||
|
* nm_*_fsm: Set adminsitrative state 'shutting down' when shutdown procedure starts
|
||||||
|
* MS Power Control Loop: Fix oscillations within good MS Power Levels
|
||||||
|
* nm_*_fsm: Move to state Disabled NotInstalled Locked when shtudown proc ends
|
||||||
|
* abis: Drop internal OML msg queue
|
||||||
|
* nm_*fsm: Make FSMs aware of object being properly configured or not
|
||||||
|
* bts_shutdown_fsm: Fix event name
|
||||||
|
* trx_if: Set pointer to null after freeing it
|
||||||
|
* trx_if: Allow calling trx_if_flush/close from within TRXC callback
|
||||||
|
* trx_if: delete retrans timer when flushing the Tx queue
|
||||||
|
* trx_provision_fsm: Properly reset FSM state upon starting listening for events
|
||||||
|
* bts-trx: Submit TRX_PROV_EV_CFG_ARFCN for C0 during SetBtsAttr
|
||||||
|
* bts-trx: Get rid of check_transceiver_availability_trx()
|
||||||
|
* MS Power Control Loop: Disable threshold comparison on {LOWER,UPPER}_CMP_N=0
|
||||||
|
* l1sap: Support rx of empty rlcmac blocks from PCU
|
||||||
|
* bts-trx: Avoid race condition configuring TS-specific TSC values
|
||||||
|
* bts-trx: Submit TRX SW_ACT when PHY becomes connected
|
||||||
|
* trx_sched_clean_ts: Clean VAMOS shadow TS too
|
||||||
|
* phy_link: Introduce bts_model_phy_link_close() and use it in bts-trx
|
||||||
|
* nm_bts_fsm: Make sure PHYs are opened when SW_ACTivating it
|
||||||
|
* bts_shutdown_fsm: Allow configuring FSM to shutdown without exiting process
|
||||||
|
* abis: Call bts_model_abis_close() when Abis link goes down
|
||||||
|
* bts_trx: Drop non-executed path in trx_link_estab()
|
||||||
|
* Avoid sending Load Indications when BTS is not RSL-connected
|
||||||
|
* abis: Fix memory leak of bts->osmo_link upon link going down
|
||||||
|
* abis: Fix line leaked & recreated upon every reconnect
|
||||||
|
* bts-trx: Keep the process ongoing trying to reconnect on Abis link down
|
||||||
|
* Revert "bts-trx: Keep the process ongoing trying to reconnect on Abis link down"
|
||||||
|
* Revert "abis: Fix line leaked & recreated upon every reconnect"
|
||||||
|
* osmo-bts-omldummy: Fix crash accessing null phy
|
||||||
|
* bts-trx: Fix rxgain & maxdly VTY values being reset
|
||||||
|
* Decouple handling of Measurement Report from lapdm
|
||||||
|
* Move TA & Power Loops further up the stack, take DTXu flag into account
|
||||||
|
* scheduler: Fix lqual_cb not populated for TCH.ind
|
||||||
|
* abis: Fix line leaked & recreated upon every reconnect
|
||||||
|
* trx_provision_fsm: Fix TRX!=0 never going back to CLOSED state
|
||||||
|
* trx_provision_fsm: Support OPEN_POWEROFF->CLOSED transition
|
||||||
|
* bts-trx: Delay power ramp up until RCARRIER is ENABLED
|
||||||
|
* Delay abis reconnect while bts is shutting down
|
||||||
|
* bts-trx: Keep the process ongoing trying to reconnect on Abis link down
|
||||||
|
* trx_provision_fsm: Drop unneeded reset of fields
|
||||||
|
* trx_provision_fsm: Drop impossible paths
|
||||||
|
* trx_provision_fsm: poweronoff_sent flag: track POWERON and POWEROFF separately
|
||||||
|
* trx_provision_fsm: Fix shutdown while POWERON in transit
|
||||||
|
* rsl: NACK Chan Activation for lchans on disabled TS
|
||||||
|
* Introduce gsm_lchan_init() function helper
|
||||||
|
* MS Power Control Loop: Use P_CON_INTERVAL=2 by default
|
||||||
|
* load_indication.c: Avoid sending if CCCH is still not operational
|
||||||
|
* Move lchan,power_ctrl specific code from gsm_data.h to their own files
|
||||||
|
* Move lchan,power_control related code from gsm_data.c to their own files
|
||||||
|
* lchan.h: Add related ticket info to FIXME comment
|
||||||
|
* Introduce gsm_lchan_release function helper
|
||||||
|
* nm_channel_fsm: Release lchans after BTS shutdown
|
||||||
|
* nm_bts_fsm: Reset si_valid bitmask when BTS is shut down
|
||||||
|
* nm_*_fsm: Move reset state code to st_op_disabled_notinstalled_on_enter
|
||||||
|
* nm_*_fsm: reset mo.nm_attr from previous runs when entering state NOT_INSTALLED
|
||||||
|
* Add new gsm_bts_trx_free_shadow_ts() function
|
||||||
|
* Make sure lchan allocated memory from shadow_ts is properly freed
|
||||||
|
* rsl: Fix all shadow TS being Chan Act NACKed
|
||||||
|
* bts-trx: Guard call to trx_sched_clean with NULL trx ptr
|
||||||
|
* lchan: Setup early_rr_ia timer only once during init
|
||||||
|
* Move lchan related code to lchan.{c,h}
|
||||||
|
* lchan: Update log line level to use macro and level INFO
|
||||||
|
* lchan: Avoid applying transition changes if state new==old
|
||||||
|
* Move lchan_deactivate() to lchan.c
|
||||||
|
* Move lchan_init_lapdm inside lchan_set_state(LCHAN_S_ACTIVE)
|
||||||
|
* lchan: Call lapdm_channel_exit() when state changes to NONE
|
||||||
|
* bts_shutdown_fsm: Make sure pending power ramping are aborted before closing TRX
|
||||||
|
* gsm_pchan2chan_nr(): Properly assert if unexpected pchan is passed
|
||||||
|
* Reset CBCH state after BTS shutdown
|
||||||
|
* bts-trx: sched_lchan_pdtch: Refactor tx_pdtch_fn to get rid of goto tag
|
||||||
|
* bts-trx: sched: tx_pdtch_fn: Handle PCU idle blocks properly
|
||||||
|
* Revert "bts-trx: sched: tx_pdtch_fn: Handle PCU idle blocks properly"
|
||||||
|
* scheduler: Fix check against empty PDCH blocks
|
||||||
|
* bts-trx: sched: tx_pdtch_fn: Drop log line clogging logs
|
||||||
|
* l1sap: Avoid re-(de)activating already (de)active lchans
|
||||||
|
* scheduler: Avoid crash upon call to trx_sched_set_lchan if l1ts is uninitialized
|
||||||
|
* bts-trx: sched_lchan_tchf: Drop impossible code path
|
||||||
|
* scheduler: Fix FACCH msg with l2len==0 going to lower layers and logging errors
|
||||||
|
* bts-trx: sched_lchan_tchf: Change log level to debug for line informing about missing dl prim
|
||||||
|
* abis: Drop unneded if condition in else clause
|
||||||
|
* abis: Try one reconnect to previously connected BSC before trying next one
|
||||||
|
* gsm_ts_release(): Make sure pchan{,is_want} is reset to NONE
|
||||||
|
|
||||||
|
[ Neels Hofmeyr ]
|
||||||
|
* osmobts-abis.adoc: add missing bibliography
|
||||||
|
* Abis manual: s/TS 12.21/TS 52.021
|
||||||
|
* Abis manual: add Get Attributes, add BTS features
|
||||||
|
* Abis manual: add VAMOS to BTS features
|
||||||
|
* Abis manual: add RSL_IE_OSMO_TRAINING_SEQUENCE
|
||||||
|
* omldummy: introduce using getopt_long
|
||||||
|
* omldummy: add cmdline arg --features
|
||||||
|
* [VAMOS] osmo-bts-omldummy: allocate shadow timeslots
|
||||||
|
* remove unused LCHAN_S_INACTIVE
|
||||||
|
* enable Early Immediate Assignment
|
||||||
|
* add VTY transcript testing
|
||||||
|
* jenkins: enable new flag --enable-external-tests
|
||||||
|
* add osmo_tdef groups, exposing T timers on VTY config
|
||||||
|
* early IMM ASS: add configurable delay for RR IMM ASS
|
||||||
|
* early IA: change default X15 timer to 0 ms
|
||||||
|
* gsm_lchan_interf_meas_calc_avg(): adapt to the order of boundaries
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* Introduce ability to set socket priority of RTP sockets
|
||||||
|
* manual: Include QoS chapter and add osmo-bts specific example
|
||||||
|
* manual: Remove manual revision history; we don't use it anywawy
|
||||||
|
* manuals: Update copyright years
|
||||||
|
* l1sap/gsmtap: Don't log UI fill frames [zero information field]
|
||||||
|
* rsl: fix handling of REL IND in lapdm_rll_tx_cb()
|
||||||
|
* initial support for static userspace probes via systemtap
|
||||||
|
|
||||||
|
[ Keith ]
|
||||||
|
* sysmobts-mgr: Fix path to hwmon in /sys
|
||||||
|
|
||||||
|
[ Eric Wild ]
|
||||||
|
* osmo-bts-trx: indicate A5/4 support, handle Kc128
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* debian/control: remove dh-systemd build-depend
|
||||||
|
|
||||||
|
[ Eric ]
|
||||||
|
* lc15, oc2g, sysmo: fix show dsp-trace-flags
|
||||||
|
* osmo-trx: fix maxdly
|
||||||
|
|
||||||
|
[ Martin Hauke ]
|
||||||
|
* osmo-bts-trx-calypso.cfg: Adjust settings to work with current osmo-bts versions
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 16:40:05 +0100
|
||||||
|
|
||||||
|
osmo-bts (1.3.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Michael McTernan ]
|
||||||
|
* measurement: use signed integer for division of ta256b_sum
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* common/vty.c: get rid of generic exit / end commands
|
||||||
|
* common/abis.c: make use of RSL TEI from OML IPA RSL Connect
|
||||||
|
* L1SAP: use LOGL_DEBUG for logging from rach_pass_filter()
|
||||||
|
* osmo-bts-sysmo/Makefile.am: fix: do not overwrite bin_PROGRAMS
|
||||||
|
* vty: fix left shift by 31 cannot be represented in type 'int'
|
||||||
|
* common/sysinfo: reduce criticality of a logging message
|
||||||
|
* osmo-bts-virtual: fix wrong endianness in gsmtap_hdr_stringify()
|
||||||
|
* osmo-bts-virtual: do not print redundant info in tx_to_virt_um()
|
||||||
|
* osmo-bts-virtual: do not log GSMTAP message sending failure twice
|
||||||
|
* l1sap: fix gsmtap_ph_rach(): properly pack 8-bit and 11-bit RA
|
||||||
|
* osmo-bts-{sysmo,oc2g,lc15}: fix segfault on 'dsp-trace-flag'
|
||||||
|
* osmo-bts-trx/scheduler: remove a left-over from UL TCH handlers
|
||||||
|
* oml: fix oml_mo_tx_sw_act_rep(): do not allocate FOM header twice
|
||||||
|
* fix typo in osmo_bts_variant_names: s/omso/osmo/g
|
||||||
|
* doc/manuals: fix typo in interfaces.adoc: s/Omsocom/Osmocom/g
|
||||||
|
* osmo-bts-omldummy: print a brief usage statement if argc < 3
|
||||||
|
* osmo-bts-omldummy: make number of transceivers configurable
|
||||||
|
* vty: get rid of unused ournode_{exit,end}_cmd declarations
|
||||||
|
* vty: cosmetic: make an error message more informative
|
||||||
|
* vty: use gsm48_chan_mode_name() from libosmocore
|
||||||
|
* gsm_data_shared: drop unused supports_egprs_11bit_rach
|
||||||
|
* gsm_data_shared: drop unused enum bts_gprs_mode
|
||||||
|
* gsm_data_shared: drop unused channel request reason definitions
|
||||||
|
* gsm_data_shared: get rid of unused HARDCODED_{ARFCN,BSIC}
|
||||||
|
* gsm_data_shared: get rid of unused HARDCODED_BTS{0,1,2}_TS
|
||||||
|
* gsm_data_shared: get rid of unused enum gsm_hooks
|
||||||
|
* gsm_data_shared: drop declaration of non-existing gsm_parse_reg()
|
||||||
|
* gsm_data_shared: drop unused A38_XOR_{MIN,MAX,COMP128}_KEY_LEN
|
||||||
|
* gsm_data_shared: drop unused MAX_EARFCN_LIST
|
||||||
|
* gsm_data_shared: drop unused LCHAN_SAPI_{UNUSED,MS,NET,REL}
|
||||||
|
* gsm_data_shared: drop unused struct bts_codec_conf
|
||||||
|
* gsm_data_shared: drop meaningless comments
|
||||||
|
* gsm_data_shared: drop unused sacch_deact from struct gsm_lchan
|
||||||
|
* gsm_data_shared: drop forward declaration of struct vty
|
||||||
|
* gsm_data_shared: drop unused *nmh from struct gsm_bts
|
||||||
|
* gsm_data_shared: drop unused dtxu from struct gsm_bts
|
||||||
|
* gsm_data_shared: drop unused ctrl_ack_type_use_block & net_ctrl_ord
|
||||||
|
* gsm_data_shared: drop unused rach_b_thresh & rach_ldavg_slots
|
||||||
|
* gsm_data_shared: drop force_combined_si & bcch_change_mark
|
||||||
|
* scheduler: drop non-existing extern declarations
|
||||||
|
* vty: fix bts_dump_vty(): properly print OML stream ID (TEI)
|
||||||
|
* rsl: refactor handling of RSL_IE_MR_CONFIG
|
||||||
|
* osmo-bts-trx: prettify Makefile.am: make it git friendly
|
||||||
|
* osmo-bts-trx: fix: use noinst_HEADERS instead of EXTRA_DIST
|
||||||
|
* osmo-bts-virtual: cosmetic: use LID_{SACCH,DEDIC} macros
|
||||||
|
* doc/examples: remove virtual/openbsc-virtual.cfg
|
||||||
|
* common/scheduler: fix unreachable code in trx_sched_set_lchan()
|
||||||
|
* common/scheduler: use boolean for channel activation state
|
||||||
|
* osmo-bts-trx/trx_if: fix memleak in trx_ctrl_cmd_cb()
|
||||||
|
* osmo-bts-trx/trx_if: cosmetic: s/ocommand/command/
|
||||||
|
* oml: fix TL16V length calculation in add_bts_feat()
|
||||||
|
* osmo-bts-trx: indicate BTS_FEAT_EGPRS support to BSC
|
||||||
|
* gsm_data_shared: use bitvec API to allocate the feature vector
|
||||||
|
* Do not mix public and private BTS features, use libosmocore's API
|
||||||
|
* osmo-bts-trx/scheduler: properly handle NOPE.ind during handover
|
||||||
|
* osmo-bts-trx: use osmo_store32be() in trx_if_send_burst()
|
||||||
|
* osmo-bts-trx: move logical channel handlers to separate files
|
||||||
|
* osmo-bts-trx: introduce and use struct trx_dl_burst_req
|
||||||
|
* osmo-bts-trx: store pointer to gsm_lchan in l1sched_chan_state
|
||||||
|
* osmo-bts-trx: include BS Power reduction in Downlink bursts
|
||||||
|
* A-bis/RSL: refactor handling of BS Power IE (power reduction)
|
||||||
|
* A-bis/OML: fix logging: do not print A-bis MO name twice
|
||||||
|
* Use libosmocore's TDMA frame number API (constatns & arithmetic)
|
||||||
|
* osmo-bts-trx: fix trx_sched_fn(): properly advance frame number
|
||||||
|
* osmo-bts-trx/scheduler: make mark trx_sched_fn() return void
|
||||||
|
* vty: fix missing separator in help for power ramp commands
|
||||||
|
* osmo-bts-trx/scheduler: get rid of _sched_fcch_burst
|
||||||
|
* A-bis/OML: handle hopping params in Set Channel Attributes
|
||||||
|
* osmo-bts-trx/scheduler: cosmetic: move trx_if_powered() check
|
||||||
|
* osmo-bts-trx/scheduler: get rid of unused 'meas' in l1sched_chan_state
|
||||||
|
* l1sap: do not print redundant info in l1sap_chan_act()
|
||||||
|
* Constify the 'trx' argument of trx_get_hlayer1() everywhere
|
||||||
|
* common: constify the argument of trx_ms_pwr_ctrl_is_osmo()
|
||||||
|
* pcu_sock: constify the argument of ts_should_be_pdch()
|
||||||
|
* osmo-bts-trx/scheduler: fix CLCK.ind handling during ramping down
|
||||||
|
* osmo-bts-trx/scheduler: refactor dummy burst scheduling
|
||||||
|
* oml: fix ARFCN range check in oml_rx_set_radio_attr()
|
||||||
|
* oml: fix ARFCN range check in oml_rx_set_bts_attr()
|
||||||
|
* pcu_sock: use a 'switch' statement in ts_should_be_pdch()
|
||||||
|
* pcu_sock: warn about maximum transceiver number constraints
|
||||||
|
* pcu_sock: separate trx / ts filling from pcu_tx_info_ind()
|
||||||
|
* pcu_sock: use LOGPTRX() in info_ind_fill_trx()
|
||||||
|
* osmo-bts-trx/scheduler: implement baseband frequency hopping
|
||||||
|
* osmo-bts-trx: indicate support of BTS_FEAT_HOPPING
|
||||||
|
* l1sap: radio_link_timeout(): clarify logging messages
|
||||||
|
* l1sap: radio_link_timeout(): use LOGPLCHAN() macro
|
||||||
|
* l1sap: radio_link_timeout(): bad_frame is a boolean
|
||||||
|
* rsl: constify the 'lchan' argument of rsl_tx_conn_fail()
|
||||||
|
* debian/control: change maintainer to the Osmocom team / mailing list
|
||||||
|
* osmo-bts-omldummy: enable BTS_FEAT_{CBCH,HOPPING} support
|
||||||
|
* vty: clarify documentation of '[no] gsmtap-sapi' command
|
||||||
|
* vty: add 'gsmtap-sapi (enable-all|disable-all)' command
|
||||||
|
* osmo-bts-trx/trx_provision_fsm: fix misleading comment in header
|
||||||
|
* osmo-bts-trx/trx_provision_fsm: cosmetic: switch is not a function
|
||||||
|
* osmo-bts-trx/l1_if: drop redundant logging message
|
||||||
|
* osmo-bts-trx: fix trx_init(): do not send OPSTART ACK blindly
|
||||||
|
* osmo-bts-trx/trx_provision_fsm: add missing default labels
|
||||||
|
* osmo-bts-trx: also print 'txtune-ack' in st_open_poweroff()
|
||||||
|
* struct gsm_bts_trx: remove unused per-TRX OML Link pointer
|
||||||
|
* struct gsm_bts_trx[_ts]: remove unused parsed NM attribute list
|
||||||
|
* gsm_data: rename hopping.{ma,ma_len} to hopping.arfcn_{list,num}
|
||||||
|
* pcuif_proto: version 10: add frequency hopping parameters
|
||||||
|
* osmo-bts-trx/scheduler: refactor UL burst measurement processing
|
||||||
|
* vty: fix bts_dump_vty_features(): properly check BTS model flags
|
||||||
|
* bts: cosmetic: make param 'net' of gsm_bts_num() const
|
||||||
|
* vty: cosmetic: use osmo_talloc_replace_string()
|
||||||
|
* tx_power: make trx/lchan struct pointers const where possible
|
||||||
|
* vty: make most struct pointers const in show/write commands
|
||||||
|
* osmo-bts-omldummy: fix: do not crash on OML connection drop/failure
|
||||||
|
* osmo-bts-omldummy: suppress 'Unimplemented bts_model_trx_deact_rf'
|
||||||
|
* vty: fix 'show bts' command: print proper BTS variant
|
||||||
|
* vty: fix 'show bts' command: BTS number is optional
|
||||||
|
* pcu_sock: cosmetic: use ARRAY_SIZE() in pcu_tx_info_ind()
|
||||||
|
* pcu_sock: cosmetic: make *nsvc a scoped and const variable
|
||||||
|
* pcu_sock: use llist_for_each_entry() in pcu_sock_close()
|
||||||
|
* pcu_sock: fix pcu_sock_close(): deactivate dynamic timeslots too
|
||||||
|
* oml: fix handling of NSVC local port in oml_ipa_mo_set_attr_nsvc()
|
||||||
|
* pcu_sock: fix {local,remote}_port byte ordering in pcu_tx_info_ind()
|
||||||
|
* pcu_sock: support handling multiple BTS instances in pcu_rx()
|
||||||
|
* gsm_data: check in and use enum lchan_rel_act_kind
|
||||||
|
* tests/power_test: also match stderr, not only stdout
|
||||||
|
* tests/power_test: move bts/trx/ts/lchan init to init_test()
|
||||||
|
* tests/power_test: do not assert in apply_power_test()
|
||||||
|
* power_control: clarify argument names of lchan_ms_pwr_ctrl()
|
||||||
|
* power_control: implement EWMA based Uplink power filtering
|
||||||
|
* fix pcu_if_signal_cb(): do not send INFO.ind if PCU is not connected
|
||||||
|
* scheduler: ensure PRIM_OP_REQUEST when adding to the queue
|
||||||
|
* scheduler: _sched_dequeue_prim(): make 'l1sap' a scoped pointer
|
||||||
|
* scheduler: use RSL_CHAN_NR_MASK in trx_sched_set_lchan()
|
||||||
|
* measurement: remove redundant 'break' statements in modulus_by_lchan()
|
||||||
|
* measurement: use LOGPLCHAN() macro in lchan_meas_check_compute()
|
||||||
|
* power_test: fix incorrect line termination in init_test()
|
||||||
|
* power_control: do nothing if 'rx-current' equals 'rx-target'
|
||||||
|
* power_control: tolerate small deviations from 'rx-target'
|
||||||
|
* scheduler: use RSL_CHAN_NR_MASK in trx_sched_set_cipher()
|
||||||
|
* scheduler: drop meaningless check in trx_sched_set_lchan()
|
||||||
|
* scheduler: drop redundant check in trx_sched_set_cipher()
|
||||||
|
* scheduler: get rid of useless TRX_CHAN_FLAG_PDCH
|
||||||
|
* scheduler: reduce nesting in trx_sched_set_lchan()
|
||||||
|
* scheduler: treat subsequent lchan (de)activation as error
|
||||||
|
* scheduler: join conditions in trx_sched_set_lchan()
|
||||||
|
* scheduler: remove pending Tx prims on lchan deactivation
|
||||||
|
* power_control: fix default EWMA smoothing coefficient (80% -> 50%)
|
||||||
|
* main: do not print deprecated '-r' / '--realtime' in help
|
||||||
|
* main: increase spacing between commands and description
|
||||||
|
* main: separate model-specific arguments in help
|
||||||
|
* main: add --vty-ref-mode, use vty_dump_xml_ref_mode()
|
||||||
|
* osmo-bts-trx/scheduler: fix comments related to FACCH/H and BFI
|
||||||
|
* main: register VTY commands before handle_options()
|
||||||
|
* main: move general options from bts_vty_init()
|
||||||
|
* vty: fix double '%' in description of some commands
|
||||||
|
* vty: fix missing / wrong documentation for some commands
|
||||||
|
* vty: call bts_model_vty_init() from bts_vty_init()
|
||||||
|
* fixup: vty: call bts_model_vty_init() from bts_vty_init()
|
||||||
|
* main: do not print asciiart to stdout, use stderr instead
|
||||||
|
* osmo-bts-lc15: use consistent name for containing directory
|
||||||
|
* doc/manuals: generate XML VTY reference at build-time
|
||||||
|
* doc/manuals: also generate VTY reference for osmo-bts-virtual
|
||||||
|
* doc/manuals: move osmobts-vty-reference.xml to vty/
|
||||||
|
* osmo-bts-trx/scheduler: ensure no DL power attenuation on C0
|
||||||
|
* struct gsm_bts: move ul_power_{target,hysteresis} to ul_power_ctrl
|
||||||
|
* bts: rename MS_UL_PF_ALGO_{NONE,EWMA} to BTS_PF_ALGO_{NONE,EWMA}
|
||||||
|
* bts: generalize a struct for UL/DL power control parameters
|
||||||
|
* bts: add Downlink power control parameters
|
||||||
|
* l1sap: make sure that UL SACCH is always 23 octets long
|
||||||
|
* tests/power: rename s/power_test/ms_power_loop_test/
|
||||||
|
* power_control: generalize power control state structure
|
||||||
|
* power_control: lchan_ul_pf_ewma(): do not use lchan->meas.res_nr
|
||||||
|
* power_control: lchan_ms_pwr_ctrl(): use existing 'trx' pointer
|
||||||
|
* power_control: generalize and rename lchan_ul_pf_ewma()
|
||||||
|
* power_control: lchan_ms_pwr_ctrl(): make use of params/state pointers
|
||||||
|
* power_control: remove a logging statement and early return
|
||||||
|
* power_control: do not log averaged RSSI values as 'rx-current'
|
||||||
|
* power_control: derive calc_delta() from lchan_ms_pwr_ctrl()
|
||||||
|
* power_control: implement BS (Downlink) Power Control
|
||||||
|
* power_control: cosmetic: fix weird spacing
|
||||||
|
* power_control: clarify units in 'struct bts_power_ctrl_params'
|
||||||
|
* power_control: clarify units in 'struct lchan_power_ctrl_state'
|
||||||
|
* rsl: properly initialize MS/BS Power Control state
|
||||||
|
* power_control: make raise/lower step limitation configurable
|
||||||
|
* vty: resurrect per-lchan BS/MS Power Control information
|
||||||
|
* vty: fix dump_lchan_trx_ts(): dump dedicated channels only
|
||||||
|
* rsl: remove redundant boolean flag in rsl_rx_chan_activ()
|
||||||
|
* power_control: check-in new parameters and default values
|
||||||
|
* power_control: add VTY introspection commands for MS/BS params
|
||||||
|
* l1sap: fix: enable UL SACCH repetition if RxQual threshold is 0
|
||||||
|
* sysinfo: fix less-than-zero comparison of an unsigned value
|
||||||
|
* osmo-bts-trx: vty: clarify and improve some deprecation messages
|
||||||
|
* power_control: vty: re-use cfg_bts_ul_power_target()
|
||||||
|
* power_control: vty: deprecate 'uplink-power-control' commands
|
||||||
|
* power_control: handle MS/BS Power control params on A-bis/RSL
|
||||||
|
* vty: add a command to show GPRS related info
|
||||||
|
* power_control: migrate MS/BS control loops to the new params
|
||||||
|
* power_control: generalize measurement pre-processing state
|
||||||
|
* power_control: properly track the first initial state
|
||||||
|
* power_control: use more reasonable reduce step size
|
||||||
|
* power_control: rework handling of DL RxQual measurements
|
||||||
|
* power_control: BS power shall not be reduced on C0
|
||||||
|
* paging: refactor and optimize fill_paging_type_1()
|
||||||
|
* power_control: print current RxLev and lower/upper thresholds
|
||||||
|
* power_control: fix: properly print 'delta' applied to attenuation
|
||||||
|
* vty: fix error messages in lchan specific commands
|
||||||
|
* vty: add macro for 'bts <0-0> trx <0-0> ts <0-7> lchan <0-1>'
|
||||||
|
* vty: extend trx / lchan number range in BTS_T_T_L_CMD
|
||||||
|
* vty: make commands related to the loopback mode hidden
|
||||||
|
* vty: add expert commands for MS/BS power control
|
||||||
|
* power_control: add test for inc / red step size limitations
|
||||||
|
* l1sap: fix gsmtap_ph_{data,pdch,rach}(): use 'const'
|
||||||
|
* l1sap: include Uplink RSSI in GSMTAP packets
|
||||||
|
* power_control: clarify the meaning of 'delta' in logging messages
|
||||||
|
* pcu_sock: pcu_tx_si_all(): make 'si_types' const
|
||||||
|
* pcu_sock: pcu_tx_si_all(): cosmetic coding style change
|
||||||
|
* pcu_sock: pcu_tx_si_all(): fix returning ununitialized rc
|
||||||
|
* osmo-bts-trx/scheduler: use DMEAS in trx_sched_meas_avg()
|
||||||
|
* oml: cosmetic code style changes in rx_oml_ipa_rsl_connect()
|
||||||
|
* vty: register libosmocore's FSM introspection commands
|
||||||
|
* oml: avoid redundant ntohl() / htonl() conversion
|
||||||
|
* oml: make 'struct tlv_parsed' pointer const where possible
|
||||||
|
* oml: use regular TLVP_PRES() in rx_oml_ipa_rsl_connect()
|
||||||
|
* power_control: cosmetic: fix swapped {L,U}_RXQUAL_XX_P comments
|
||||||
|
* power_control: implement handling of P_Con_INTERVAL parameter
|
||||||
|
* oml: reuse the given msgb in oml_fom_ack_nack()
|
||||||
|
* oml: ensure that IPA RSL Connect ACK/NACK contains all IEs
|
||||||
|
* main: cosmetic: tweak deprecation warning messages
|
||||||
|
* GSMTAP: move 'gsmtap_sapi_names' from l1sap.c to vty.c
|
||||||
|
* GSMTAP: fix wrong naming of per-BTS SAPI commands
|
||||||
|
* GSMTAP: move 'struct gsmtap_inst' and masks to 'struct gsm_bts'
|
||||||
|
* ta_control: cosmetic: use correct naming for MIN/MAX constraints
|
||||||
|
* ta_control: make 'struct bts_ul_meas' parameters const
|
||||||
|
* ta_control: fix Timing Advance control for SDCCH channels
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* rsl.c: Fix compiler error on gcc-9.2.1
|
||||||
|
* virtual: Fix VTY commands to specify GSMTAP multicast groups
|
||||||
|
* l1sap: Use msgb_pull_l2() and unify l1sap_tch_ind + l1sap_ph_data_ind
|
||||||
|
* osmo-bts-virtual: implement GSMTAP_CHANNEL_VOICE
|
||||||
|
* osmo-bts-virtual: Add "virtual-um ttl <0-255>" VTY option
|
||||||
|
* osmo-bts-virtual: Fix "virtual-um net-device NETDEV"
|
||||||
|
* cosmetic: remove dead code from logging.c
|
||||||
|
* fix compilation with gcc-10
|
||||||
|
* osmo-bts-virtual: Avoid rejecting AMR in uplink
|
||||||
|
* virtual/scheduler: log unknown GSMTAP chan
|
||||||
|
* Ensure we include lchan name in all LAPDm log lines
|
||||||
|
* osmo-bts.spec.in: Use %config(noreplace) to retain current config file
|
||||||
|
* bts: Add VTY command to manually override Radio Link Timeout
|
||||||
|
* sysinfo: Only send SI13 if PCU is connected
|
||||||
|
* sysinfo: Don't broadcast SI4 GPRS INDICATOR if PCU is disconnected
|
||||||
|
* use osmo_fd_setup() everywhere
|
||||||
|
* remove dead oml_router code
|
||||||
|
* sysinfo.c: Fix SI4 GPRS patching which overwrote CBCH IE
|
||||||
|
* fix-up missed review comment in CBCH SI4 patching fix
|
||||||
|
* major README uppdate
|
||||||
|
* Use osmo_fd_*_{disable,enable}
|
||||||
|
* add support for sysmoBTS 1003 aka "1002 with GPS and PoE"
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* ta_control: move timing advance code from osmo-bts-trx to common
|
||||||
|
* measurment: write irssi_full_sum variable correctly
|
||||||
|
* l1sap: merge MEAS IND into PRIM PH DATA / PRIM TCH
|
||||||
|
* Do not depend on pcu_direct flag when populating ph_data_ind
|
||||||
|
* osmo-bts-sysmo: merge measurement data and payload
|
||||||
|
* osmo-bts-trx: do not set rx-gain to 1 by default
|
||||||
|
* scheduler: always call Uplink burst handler on NOPE.ind
|
||||||
|
* logging: use only LOGL_NOTICE as defualt loglevel
|
||||||
|
* dtx: add detection of AMR DTX frames for osmo-bts-trx
|
||||||
|
* measurement: remove unecessary is_amr_sid_update parameter
|
||||||
|
* measurement: make measurements more debugable
|
||||||
|
* measurement: expect at least 1 SUB frame for AMR
|
||||||
|
* osmo-bts-trx/scheduler: fix measurement handling for SUB frames
|
||||||
|
* vty: add attributes to VTY commands indicating when they apply
|
||||||
|
* sched_lchan_tchh: initialize meas_avg with zeros
|
||||||
|
* main: add commandline option --vty-ref-xml
|
||||||
|
* cosmetic: add missing semicolon after OSMO_ASSERT()
|
||||||
|
* sched_lchan_tchf: count measurements for FACCH/F only once
|
||||||
|
* measurement: count all blocks as SUB for TCH/F in signalling mode
|
||||||
|
* measurement: fix expected number of measurements
|
||||||
|
* measurement.c: fix integer overflow problem
|
||||||
|
* rsl.adoc: add info about RSL_IE_OSMO_REP_ACCH_CAP
|
||||||
|
* l1sap: pre-initalize pointer with NULL to avoid gcc warning
|
||||||
|
* l1sap: add repeated downlink FACCH
|
||||||
|
* rsl.adoc: update documentation for RSL_IE_OSMO_REP_ACCH_CAP
|
||||||
|
* l1sap: also include SRR bit in RSL l1 info field.
|
||||||
|
* l1sap: add repeated downlink SACCH
|
||||||
|
* l1sap: add repeated uplink SACCH
|
||||||
|
* l1sap: acch_repetition fix hysthereis threshold table
|
||||||
|
* l1sap: use rxlev_full when no DTX was used
|
||||||
|
* pcu_sock: send SI1, SI3 and SI13 via PCUIF
|
||||||
|
* pcu_sock: fix uninitalized returncode value
|
||||||
|
* l1sap: fix repeated_dl_facch_active_decision()
|
||||||
|
* l1sap.c: be sure that FACCH repetition is turned off
|
||||||
|
* l1sap: be sure that UL-SACCH repetition is turned off
|
||||||
|
* l1sap: fix comment: sapi number is missing
|
||||||
|
* vty: dont put a colon after vty_out in cfg_out macro
|
||||||
|
* gsm_data: handle l1_info with structs
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* l1_if: Fix strange formatting of Meas info logging
|
||||||
|
* l1sap: Change loglevel of Rx TCH.ind INFO->DEBUG
|
||||||
|
* bts-trx: trx_if.c: Fix some printf formats
|
||||||
|
* cosmetic: Fix some typos with codespell
|
||||||
|
* lc15: Fix returning values on void function
|
||||||
|
* lc15: Fix mismatching signature in callback provided
|
||||||
|
* oc2g: Fix returning values on void function
|
||||||
|
* oc2g: Fix mismatching signature in callback provided
|
||||||
|
* Use OSMO_FD_* instead of deprecated BSC_FD_*
|
||||||
|
* l1_utils.h: Avoid redefinition of global vars defined in l1_utils.c
|
||||||
|
* vty: Fix misleading define name
|
||||||
|
* tests/tx_power: Speed up test
|
||||||
|
* doc: Update vty reference xml file
|
||||||
|
* bts-trx: vty: Add 'nominal-tx-power' cmd
|
||||||
|
* bts-trx: phy_link: Improve logging fmt in phy_link_state_set()
|
||||||
|
* oml.c: Fix whitespace in log line
|
||||||
|
* oml.c: Log ADM STATE change locked/unlocked
|
||||||
|
* scheduler.c: Fix trailing whitespace
|
||||||
|
* pcu_sock: Change log about tx PCH confirm INFO->DEBUG
|
||||||
|
* bts-trx: Implement power ramping during BTS bring up
|
||||||
|
* bts-trx: Rename setpower TRXC functions to describe they use power attenuation
|
||||||
|
* bts-trx: Introduce helper func l1if_trx_set_nominal_power
|
||||||
|
* bts-trx: Use TRXC cmd NOMTXPOWER to retrieve nominal tx power from osmo-trx
|
||||||
|
* bts-trx: Re-apply tx power if nominal power is received after POWERON
|
||||||
|
* scheduler: Fix reading out of buffer during tx of dummy burst on PDCH TS with EGPRS enabled
|
||||||
|
* abis.c: Grab reference to e1inp_line_get if already created
|
||||||
|
* doc: Fix typos in bts-models.adoc
|
||||||
|
* scheduler: Improve logging about prim being out of range
|
||||||
|
* scheduler: Early return in _sched_dequeue_prim() and clarify FN cases
|
||||||
|
* scheduler: _sched_dequeue_prim(): Refactor goto paths
|
||||||
|
* scheduler: _sched_dequeue_prim(): Refactor found_msg goto path
|
||||||
|
* cosmetic: common/Makefile.am: split each source file in one line
|
||||||
|
* cosmetic: include/osmo-bts/Makefile.am: split each header file in one line
|
||||||
|
* Merge gsm_data_shared.h into gsm_data.h
|
||||||
|
* scheduler: Add rate_ctr informing about too low rts-advance
|
||||||
|
* scheduler: Add rate_ctr informing about Dl block not found
|
||||||
|
* handover_tests: Avoid redefining all bts_model stubs
|
||||||
|
* meas_tests: Avoid redefining all bts_model stubs
|
||||||
|
* tests/stubs.c: Add missing stub for bts_model_change_power
|
||||||
|
* cosmetic: {oc2g,lc15}bts_bty.c: Fix trailing whitespace
|
||||||
|
* Fix missing bts_model implementations in stubs.c and bts_model.c
|
||||||
|
* Introduce LOGPTRX macro and use it in tx_power.c
|
||||||
|
* power_ramp: Add support to get callback when ramping process completes
|
||||||
|
* bts-trx: Instruct user to set manually nominal-tx-power if NOMTXPOWER not supported
|
||||||
|
* tx_power: Log bypass param in power_ramp_start
|
||||||
|
* phy_link.h: Drop unimplemented function definition
|
||||||
|
* bts.c: Fix typo in log line and improve it
|
||||||
|
* abis.c: Use LOGPIL when logging signalling link down
|
||||||
|
* Introduce bts_shutdown FSM
|
||||||
|
* Implement tx power ramp down during BTS shutdown
|
||||||
|
* bts-trx: Split part of bts_model_trx_close() steps into bts_model_deact_rf
|
||||||
|
* bts_shutdown: First deact RF on all TRX, finally close them
|
||||||
|
* bts_model: Convert bts_model_trx_close() to return asynchronously
|
||||||
|
* bts_shutdown: Wait until all TRX are closed
|
||||||
|
* bts-virtual: Implement bts_model_trx_close
|
||||||
|
* bts-trx: Mark 'osmotrx power' VTY cmd as deprecated
|
||||||
|
* Fix shutdown in osmo-bts-{omldummy,virtual}
|
||||||
|
* bts-omldummy: Implement bts_model_trx_close
|
||||||
|
* bts-omldummy: Speed up shutdown (instantaneous ramp)
|
||||||
|
* tx_power: Support controlling BTS with nominal tx pwr < 0dBm
|
||||||
|
* bts-trx: Introduce rate counter for scheduler timerfd missed FNs
|
||||||
|
* bts_shutdown: Speed up shutdown if no TRX is operational
|
||||||
|
* pcu_sock: Avoid presenting TS from disabled TRX as available to PCU
|
||||||
|
* bts-trx: Implement ramp up/down during ADM state change
|
||||||
|
* gsm_data.h: Use enum type for NM state fields
|
||||||
|
* Move nm_state and Mo related code gsm_data.* => oml.*
|
||||||
|
* Move gsm_bts code gsm-data.* => bts.*
|
||||||
|
* bts-virt: Don't rely on gsmtap_makemsg() returning NULL for GSMTAP_CHANNEL_UNKNOWN
|
||||||
|
* Move struct gsm_bts_trx: gsm_data.* & bts.* => bts_trx.*
|
||||||
|
* bts-trx: Don't set OPSTATE enabled during trx_init
|
||||||
|
* common: Avoid changing OPSTATE to Enabled upon RSL up
|
||||||
|
* bts-trx: Remove unused function l1if_provision_transceiver()
|
||||||
|
* bts-trx: introduce TRX provisioning FSM
|
||||||
|
* tx_power_test: Disable using color in log output
|
||||||
|
* bts-trx: Use bool type for on/off state variables
|
||||||
|
* bts-trx: Integrate TRX provisioning logic more tightly into the FSM
|
||||||
|
* bts-trx: Delay TRXC POWERON cmd until all TRXs are provisioned
|
||||||
|
* rsl: Fix wrong param passed to gsm_pchan_name() in log line
|
||||||
|
* bts-trx: Fix osmocom dyn ts assert hit during Adm State Unlock
|
||||||
|
* bts-trx: prov_fsm: Fix mess with 1 event having 2 names
|
||||||
|
* bts_shutdown_fsm: Fix switching too quickly to state WAIT_TRX_CLOSED
|
||||||
|
* common: Avoid call to bts_model_chg_adm_state() if there's no ADM state change
|
||||||
|
* bts-trx: Fix handling ADM state change while previous one WIP
|
||||||
|
* vty: Allow setting power-ramp max-initial to negative values
|
||||||
|
* bts-trx: Fix assert hit when rf_locked in .cfg and TS TCH/F_PDCH
|
||||||
|
* tx_power: Take into account max-initial when ramping up bigger power lvl intervals
|
||||||
|
* doc: configuration.adoc: Document ramping down feature
|
||||||
|
* common: Support setting rt prio through new libosmovty sched VTY cmds
|
||||||
|
* tests: tx_power: Extend and add extra power_ramp buggy case
|
||||||
|
* common: tx_power: Fix bug in power ramp up below max-initial value
|
||||||
|
* Update dependency on libosmocore 1.4.0
|
||||||
|
* configure.ac: Fix trailing whitespace
|
||||||
|
* pcu_sock: Fix typo in log message
|
||||||
|
* bts-trx: Use TRXC RFMUTE instead of resetting the scheduler
|
||||||
|
* bts-trx: Ensure RFMUTE state is set properly at startup
|
||||||
|
* scheduler: Drop unused function trx_sched_reset()
|
||||||
|
* Fix RadioCarrier OML Operative State Change report not sent on some scenarios
|
||||||
|
* Improve logging around failing to (de)activate chan_nr
|
||||||
|
* Improve error handling and logging in gsm_pchan2chan_nr()
|
||||||
|
* Improve logging and error handling receiving act_req for dyn TS not yet configured
|
||||||
|
* pcu_sock: Only announce dyn TS already configured by lower layers
|
||||||
|
* Avoid sending RSL RF REL ACK if PDCH chan is disabled by administrative lock
|
||||||
|
* oml: Set RadioChannel operational state to Enabled only during OPSTART
|
||||||
|
* gsm_data.h: Drop unused struct field
|
||||||
|
* contrib/jenkins: Enable parallel make in make distcheck
|
||||||
|
* Drop unused param in oml_init()
|
||||||
|
* Change NM Channel availability Dependency->Offline when RadioCarrier becomes enabled
|
||||||
|
* Introduce NM BTS Site Manager FSM
|
||||||
|
* Introduce NM BTS FSM
|
||||||
|
* Introduce NM Radio Carrier and Baseband Transceiver FSMs
|
||||||
|
* Introduce NM Channel FSM
|
||||||
|
* bts_trx.c: Dispatch missing NM_EV_RSL_UP/DOWN to the bb_transc object
|
||||||
|
* oml: Set NM_OPSTATE_DISABLED by default
|
||||||
|
* common: Enable SIGABRT signal handler
|
||||||
|
* common: generate coredump and exit upon SIGABRT received
|
||||||
|
* sysmobts-mgr: generate coredump and exit upon SIGABRT received
|
||||||
|
* oc2g-mgr: generate coredump and exit upon SIGABRT received
|
||||||
|
* lc15-mgr: generate coredump and exit upon SIGABRT received
|
||||||
|
* nm_channel_fsm: Fix several FSM internal transitions not being made
|
||||||
|
* cosmetic: sysmobts-mgr: fix whitespace indentation
|
||||||
|
* tests: Explicitly drop category from log
|
||||||
|
* tests: Replace deprecated API log_set_print_filename
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* rsl: make IP DSCP configurable
|
||||||
|
* VTY: add "test send-failure-event-report"
|
||||||
|
* contrib: import RPM spec
|
||||||
|
* contrib: integrate RPM spec
|
||||||
|
* Makefile.am: EXTRA_DIST: debian, contrib/*.spec.in
|
||||||
|
* contrib/jenkins: don't build osmo-gsm-manuals
|
||||||
|
* configure.ac: set -std=gnu11
|
||||||
|
* common/measurement.c: fix gcc 4 + -std=gnu11 error
|
||||||
|
|
||||||
|
[ Harld Welte ]
|
||||||
|
* trx: Fix reported BER for TCH/H
|
||||||
|
* trx: Use NOPE indications from OsmoTRX for TCH/F and TCH/H
|
||||||
|
* trx: Use NOPE indications on SDCCH
|
||||||
|
|
||||||
|
[ Eric ]
|
||||||
|
* configure.ac: fix libtool issue with clang and sanitizer
|
||||||
|
|
||||||
|
[ Rafael Diniz ]
|
||||||
|
* osmo-bts-litecell15: Implement missing features.
|
||||||
|
|
||||||
|
[ Alexander Couzens ]
|
||||||
|
* measurement: replace u_int64_t with uint64_t
|
||||||
|
* pcuif_proto: version 0xa: add support for IPv6 NSVCs
|
||||||
|
* pcuif_proto: fix typo in comment
|
||||||
|
* Revert "pcuif_proto: version 0xa: add support for IPv6 NSVCs"
|
||||||
|
* pcuif_proto: version 10: add support for IPv6 NSVCs
|
||||||
|
* Introduce the new OML NM_ATT_OSMO_NS_LINK_CFG to configure IPv6 NSVC for PCU
|
||||||
|
* common/bts: set feature IPV6_NSVC
|
||||||
|
* OML: correct parse the NM_ATT_OSMO_NS_LINK_CFG field address_family
|
||||||
|
|
||||||
|
[ Daniel Willmann ]
|
||||||
|
* osmo-bts-trx: Use much lower clock advance values towards PCU and TRX
|
||||||
|
|
||||||
|
[ Neels Hofmeyr ]
|
||||||
|
* rename to release_sapi_ul_rach(), simplify
|
||||||
|
* part 1 of: fix SAPIs for handover to match 48.058 4.1.{3,4}
|
||||||
|
* part 2 of: fix SAPIs for handover, osmo-bts-sysmo
|
||||||
|
* part 3 of: fix SAPIs for handover, osmo-bts-trx
|
||||||
|
* part 4 of: fix SAPIs for handover, osmo-bts-lc15
|
||||||
|
* part 5 of: fix SAPIs for handover, osmo-bts-oc2g
|
||||||
|
* log: rsl_rx_chan_activ: show chan type as human readable string
|
||||||
|
* chan activ: activate DL SACCH only when TA is known
|
||||||
|
* GSMTAP: make remote host for Um logging configurable via VTY
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 23 Feb 2021 16:35:17 +0100
|
||||||
|
|
||||||
osmo-bts (1.2.0) unstable; urgency=medium
|
osmo-bts (1.2.0) unstable; urgency=medium
|
||||||
|
|
||||||
[ Oliver Smith ]
|
[ Oliver Smith ]
|
||||||
|
|||||||
33
debian/control
vendored
33
debian/control
vendored
@@ -1,26 +1,42 @@
|
|||||||
Source: osmo-bts
|
Source: osmo-bts
|
||||||
Maintainer: Holger Hans Peter Freyther <holger@moiji-mobile.com>
|
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Build-Depends: debhelper (>= 9),
|
Build-Depends: debhelper (>= 9),
|
||||||
pkg-config,
|
pkg-config,
|
||||||
dh-autoreconf,
|
dh-autoreconf,
|
||||||
dh-systemd (>= 1.5),
|
|
||||||
autotools-dev,
|
autotools-dev,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
libosmocore-dev,
|
libosmocore-dev (>= 1.7.0),
|
||||||
libosmo-abis-dev,
|
libosmo-abis-dev (>= 1.3.0),
|
||||||
|
libosmo-netif-dev (>= 1.2.0),
|
||||||
libgps-dev,
|
libgps-dev,
|
||||||
txt2man,
|
txt2man,
|
||||||
osmo-gsm-manuals-dev
|
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||||
Standards-Version: 3.9.8
|
Standards-Version: 3.9.8
|
||||||
Vcs-Browser: http://git.osmocom.org/osmo-bts/
|
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
Vcs-Git: git://git.osmocom.org/osmo-bts
|
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
Homepage: https://projects.osmocom.org/projects/osmobts
|
Homepage: https://projects.osmocom.org/projects/osmobts
|
||||||
|
|
||||||
|
Package: osmo-bts
|
||||||
|
Architecture: any
|
||||||
|
Depends: osmo-bts-trx, osmo-bts-virtual, ${misc:Depends}
|
||||||
|
Description: Base Transceiver Station for GSM
|
||||||
|
OsmoBTS is a software implementation of Layer2/3 of a BTS. It implements the
|
||||||
|
following protocols/interfaces:
|
||||||
|
LAPDm (GSM 04.06)
|
||||||
|
RTP
|
||||||
|
A-bis/IP in IPA multiplex
|
||||||
|
OML (GSM TS 12.21)
|
||||||
|
RSL (GSM TS 08.58)
|
||||||
|
.
|
||||||
|
OsmoBTS is modular and has support for multiple back-ends. A back-end talks to
|
||||||
|
a specific L1/PHY implementation of the respective BTS hardware. Based on this
|
||||||
|
architecture, it should be relatively easy to add a new back-end to support
|
||||||
|
so-far unsupported GSM PHY/L1 and associated hardware.
|
||||||
|
|
||||||
Package: osmo-bts-trx
|
Package: osmo-bts-trx
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Conflicts: osmo-bts
|
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
Description: osmo-bts-trx GSM BTS with osmo-trx
|
Description: osmo-bts-trx GSM BTS with osmo-trx
|
||||||
osmo-bts-trx to be used with the osmo-trx application
|
osmo-bts-trx to be used with the osmo-trx application
|
||||||
@@ -35,7 +51,6 @@ Description: Debug symbols for the osmo-bts-trx
|
|||||||
|
|
||||||
Package: osmo-bts-virtual
|
Package: osmo-bts-virtual
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Conflicts: osmo-bts
|
|
||||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||||
Description: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
|
Description: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
|
||||||
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but
|
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but
|
||||||
|
|||||||
1
debian/osmo-bts-virtual.install
vendored
1
debian/osmo-bts-virtual.install
vendored
@@ -3,4 +3,3 @@ lib/systemd/system/osmo-bts-virtual.service
|
|||||||
usr/bin/osmo-bts-virtual
|
usr/bin/osmo-bts-virtual
|
||||||
usr/bin/osmo-bts-omldummy
|
usr/bin/osmo-bts-omldummy
|
||||||
usr/share/doc/osmo-bts/examples/osmo-bts-virtual/osmo-bts-virtual.cfg
|
usr/share/doc/osmo-bts/examples/osmo-bts-virtual/osmo-bts-virtual.cfg
|
||||||
usr/share/doc/osmo-bts/examples/osmo-bts-virtual/openbsc-virtual.cfg
|
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
|
|||||||
|
|
||||||
doc_virtualdir = $(docdir)/examples/osmo-bts-virtual
|
doc_virtualdir = $(docdir)/examples/osmo-bts-virtual
|
||||||
doc_virtual_DATA = \
|
doc_virtual_DATA = \
|
||||||
virtual/osmo-bts-virtual.cfg \
|
virtual/osmo-bts-virtual.cfg
|
||||||
virtual/openbsc-virtual.cfg
|
|
||||||
EXTRA_DIST = $(doc_virtual_DATA)
|
EXTRA_DIST = $(doc_virtual_DATA)
|
||||||
|
|
||||||
if ENABLE_SYSMOBTS
|
if ENABLE_SYSMOBTS
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
!
|
!
|
||||||
! OsmoBTS configuration example for CalypsoBTS
|
! OsmoBTS configuration example for CalypsoBTS
|
||||||
! http://osmocom.org/projects/baseband/wiki/CalypsoBTS
|
! https://osmocom.org/projects/baseband/wiki/CalypsoBTS
|
||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
@@ -24,14 +24,15 @@ phy 0
|
|||||||
instance 0
|
instance 0
|
||||||
osmotrx ip local 127.0.0.1
|
osmotrx ip local 127.0.0.1
|
||||||
osmotrx ip remote 127.0.0.1
|
osmotrx ip remote 127.0.0.1
|
||||||
osmotrx timing-advance-loop
|
|
||||||
osmotrx ms-power-loop -65
|
|
||||||
osmotrx legacy-setbsic
|
osmotrx legacy-setbsic
|
||||||
|
osmotrx fn-advance 20
|
||||||
|
osmotrx rts-advance 5
|
||||||
bts 0
|
bts 0
|
||||||
oml remote-ip 127.0.0.1
|
oml remote-ip 127.0.0.1
|
||||||
ipa unit-id 1801 0
|
ipa unit-id 6969 0
|
||||||
gsmtap-sapi pdtch
|
gsmtap-sapi pdtch
|
||||||
gsmtap-sapi ccch
|
gsmtap-sapi ccch
|
||||||
band 900
|
band 900
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
nominal-tx-power 23
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
!
|
|
||||||
! OpenBSC (0.15.0.629-34f0-dirty) configuration saved from vty
|
|
||||||
!!
|
|
||||||
!
|
|
||||||
log stderr
|
|
||||||
logging filter all 1
|
|
||||||
logging color 0
|
|
||||||
logging print category 1
|
|
||||||
logging timestamp 1
|
|
||||||
logging level all info
|
|
||||||
logging level rll notice
|
|
||||||
logging level cc notice
|
|
||||||
logging level mm debug
|
|
||||||
logging level rr notice
|
|
||||||
logging level rsl notice
|
|
||||||
logging level nm info
|
|
||||||
logging level mncc notice
|
|
||||||
logging level pag notice
|
|
||||||
logging level meas notice
|
|
||||||
logging level sccp notice
|
|
||||||
logging level msc notice
|
|
||||||
logging level mgcp notice
|
|
||||||
logging level ho notice
|
|
||||||
logging level db notice
|
|
||||||
logging level ref notice
|
|
||||||
logging level gprs debug
|
|
||||||
logging level ns info
|
|
||||||
logging level bssgp debug
|
|
||||||
logging level llc debug
|
|
||||||
logging level sndcp debug
|
|
||||||
logging level nat notice
|
|
||||||
logging level ctrl notice
|
|
||||||
logging level smpp debug
|
|
||||||
logging level filter debug
|
|
||||||
logging level ranap debug
|
|
||||||
logging level sua debug
|
|
||||||
logging level lglobal notice
|
|
||||||
logging level llapd notice
|
|
||||||
logging level linp notice
|
|
||||||
logging level lmux notice
|
|
||||||
logging level lmi notice
|
|
||||||
logging level lmib notice
|
|
||||||
logging level lsms notice
|
|
||||||
logging level lctrl notice
|
|
||||||
logging level lgtp notice
|
|
||||||
logging level lstats notice
|
|
||||||
logging level lgsup notice
|
|
||||||
logging level loap notice
|
|
||||||
!
|
|
||||||
stats interval 5
|
|
||||||
!
|
|
||||||
line vty
|
|
||||||
no login
|
|
||||||
!
|
|
||||||
e1_input
|
|
||||||
e1_line 0 driver ipa
|
|
||||||
e1_line 0 port 0
|
|
||||||
no e1_line 0 keepalive
|
|
||||||
network
|
|
||||||
network country code 262
|
|
||||||
mobile network code 42
|
|
||||||
short name OpenBSC
|
|
||||||
long name OpenBSC
|
|
||||||
auth policy accept-all
|
|
||||||
authorized-regexp .*
|
|
||||||
location updating reject cause 13
|
|
||||||
encryption a5 0
|
|
||||||
neci 1
|
|
||||||
paging any use tch 0
|
|
||||||
rrlp mode ms-based
|
|
||||||
mm info 1
|
|
||||||
handover 0
|
|
||||||
handover window rxlev averaging 10
|
|
||||||
handover window rxqual averaging 1
|
|
||||||
handover window rxlev neighbor averaging 10
|
|
||||||
handover power budget interval 6
|
|
||||||
handover power budget hysteresis 3
|
|
||||||
handover maximum distance 9999
|
|
||||||
timer t3101 10
|
|
||||||
timer t3103 0
|
|
||||||
timer t3105 0
|
|
||||||
timer t3107 0
|
|
||||||
timer t3109 4
|
|
||||||
timer t3111 0
|
|
||||||
timer t3113 60
|
|
||||||
timer t3115 0
|
|
||||||
timer t3117 0
|
|
||||||
timer t3119 0
|
|
||||||
timer t3122 10
|
|
||||||
timer t3141 0
|
|
||||||
subscriber-keep-in-ram 0
|
|
||||||
bts 0
|
|
||||||
type sysmobts
|
|
||||||
band DCS1800
|
|
||||||
cell_identity 6969
|
|
||||||
location_area_code 1
|
|
||||||
base_station_id_code 63
|
|
||||||
ms max power 0
|
|
||||||
cell reselection hysteresis 4
|
|
||||||
rxlev access min 0
|
|
||||||
periodic location update 30
|
|
||||||
radio-link-timeout 32
|
|
||||||
channel allocator descending
|
|
||||||
rach tx integer 9
|
|
||||||
rach max transmission 7
|
|
||||||
channel-descrption attach 1
|
|
||||||
channel-descrption bs-pa-mfrms 5
|
|
||||||
channel-descrption bs-ag-blks-res 1
|
|
||||||
ip.access unit_id 6969 0
|
|
||||||
oml ip.access stream_id 255 line 0
|
|
||||||
neighbor-list mode automatic
|
|
||||||
codec-support fr
|
|
||||||
gprs mode none
|
|
||||||
no force-combined-si
|
|
||||||
trx 0
|
|
||||||
rf_locked 0
|
|
||||||
arfcn 666
|
|
||||||
nominal power 0
|
|
||||||
max_power_red 0
|
|
||||||
rsl e1 tei 0
|
|
||||||
timeslot 0
|
|
||||||
phys_chan_config CCCH+SDCCH4
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 1
|
|
||||||
phys_chan_config SDCCH8
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 2
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 3
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 4
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 5
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 6
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
timeslot 7
|
|
||||||
phys_chan_config TCH/F
|
|
||||||
hopping enabled 0
|
|
||||||
mncc-int
|
|
||||||
default-codec tch-f fr
|
|
||||||
default-codec tch-h hr
|
|
||||||
nitb
|
|
||||||
subscriber-create-on-demand
|
|
||||||
subscriber-create-on-demand random 1 24
|
|
||||||
assign-tmsi
|
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging filter all 0
|
logging filter all 1
|
||||||
logging color 0
|
logging color 0
|
||||||
logging print category 1
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
@@ -50,7 +50,6 @@ bts 0
|
|||||||
rtp jitter-buffer 100
|
rtp jitter-buffer 100
|
||||||
paging queue-size 200
|
paging queue-size 200
|
||||||
paging lifetime 0
|
paging lifetime 0
|
||||||
uplink-power-target -75
|
|
||||||
min-qual-rach 50
|
min-qual-rach 50
|
||||||
min-qual-norm -5
|
min-qual-norm -5
|
||||||
trx 0
|
trx 0
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ EXTRA_DIST = dtx.dot \
|
|||||||
osmobts-abis-docinfo.xml \
|
osmobts-abis-docinfo.xml \
|
||||||
osmobts-usermanual.adoc \
|
osmobts-usermanual.adoc \
|
||||||
osmobts-usermanual-docinfo.xml \
|
osmobts-usermanual-docinfo.xml \
|
||||||
osmobts-vty-reference.xml \
|
|
||||||
rtp-amr.adoc \
|
rtp-amr.adoc \
|
||||||
rtp-amr-docinfo.xml \
|
rtp-amr-docinfo.xml \
|
||||||
regen_doc.sh \
|
regen_doc.sh \
|
||||||
@@ -18,8 +17,32 @@ if BUILD_MANUALS
|
|||||||
osmobts-abis.pdf: $(srcdir)/abis/*.adoc $(srcdir)/abis/*.msc
|
osmobts-abis.pdf: $(srcdir)/abis/*.adoc $(srcdir)/abis/*.msc
|
||||||
rtp-amr.pdf: $(srcdir)/dtx.dot
|
rtp-amr.pdf: $(srcdir)/dtx.dot
|
||||||
|
|
||||||
VTY_REFERENCE = osmobts-vty-reference.xml
|
# NOTE: osmo-bts-omldummy has no VTY interface
|
||||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
|
VARIANTS = virtual
|
||||||
|
|
||||||
|
if ENABLE_SYSMOBTS
|
||||||
|
VARIANTS += sysmo
|
||||||
|
endif
|
||||||
|
|
||||||
|
if ENABLE_TRX
|
||||||
|
VARIANTS += trx
|
||||||
|
endif
|
||||||
|
|
||||||
|
if ENABLE_OCTPHY
|
||||||
|
VARIANTS += octphy
|
||||||
|
endif
|
||||||
|
|
||||||
|
if ENABLE_LC15BTS
|
||||||
|
VARIANTS += lc15
|
||||||
|
endif
|
||||||
|
|
||||||
|
if ENABLE_OC2GBTS
|
||||||
|
VARIANTS += oc2g
|
||||||
|
endif
|
||||||
|
|
||||||
|
# This is a significantly modified, multi-target adopted copy of
|
||||||
|
# $(OSMO_GSM_MANUALS_DIR)/build/Makefile.vty-reference.inc
|
||||||
|
include $(srcdir)/vty/Makefile.vty-reference.inc
|
||||||
|
|
||||||
OSMO_REPOSITORY = osmo-bts
|
OSMO_REPOSITORY = osmo-bts
|
||||||
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
|
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.common.inc
|
||||||
|
|||||||
@@ -3,16 +3,17 @@
|
|||||||
=== List of Messages
|
=== List of Messages
|
||||||
|
|
||||||
The following tables list the OML messages used by OsmoBTS, grouped by their
|
The following tables list the OML messages used by OsmoBTS, grouped by their
|
||||||
level of compliance with 3GPP TS 12.21.
|
level of compliance with 3GPP TS 52.021 [[3gpp-ts-52-021]] (previously 3GPP TS
|
||||||
|
12.21).
|
||||||
|
|
||||||
==== Messages Compliant With TS 12.21
|
==== Messages Compliant With TS 52.021
|
||||||
|
|
||||||
Specific limitations apply, see the linked sections.
|
Specific limitations apply, see the linked sections.
|
||||||
|
|
||||||
.Messages compliant with TS 12.21
|
.Messages compliant with TS 52.021
|
||||||
[options="header",cols="10%,10%,20%,35%,5%,20%"]
|
[options="header",cols="10%,10%,20%,35%,5%,20%"]
|
||||||
|===
|
|===
|
||||||
| TS 12.21 § | type code (hex) | This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
| TS 52.021 § | type code (hex) | This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
||||||
6+<| *SW Download Management Messages:*
|
6+<| *SW Download Management Messages:*
|
||||||
| 8.3.7 | 0x10 | <<sw_act_rep>> | SW Activated Report | -> | Sent
|
| 8.3.7 | 0x10 | <<sw_act_rep>> | SW Activated Report | -> | Sent
|
||||||
6+<| *Air Interface Management Messages:*
|
6+<| *Air Interface Management Messages:*
|
||||||
@@ -34,12 +35,16 @@ Specific limitations apply, see the linked sections.
|
|||||||
.3+.| 8.9.2 | 0x74 .3+.| <<opstart>> | Opstart | <- | Received
|
.3+.| 8.9.2 | 0x74 .3+.| <<opstart>> | Opstart | <- | Received
|
||||||
| 0x75 | Opstart Ack | -> | Sent
|
| 0x75 | Opstart Ack | -> | Sent
|
||||||
| 0x76 | Opstart Nack | -> | Sent
|
| 0x76 | Opstart Nack | -> | Sent
|
||||||
|
6+<| *Other Messages:*
|
||||||
|
.3+.| 8.11.1 | 0x81 | <<get_attributes>> | Get Attributes | <- | Received
|
||||||
|
| 8.11.3 | 0x82 | <<get_attr_resp>> | Get Attribute Response | -> | Sent
|
||||||
|
| 8.11.1 | 0x83 | | Get Attributes Nack | -> | Sent
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
==== Messages Specific to OsmoBTS
|
==== Messages Specific to OsmoBTS
|
||||||
|
|
||||||
.Messages specific to OsmoBTS, not found in 3GPP TS 12.21
|
.Messages specific to OsmoBTS, not found in 3GPP TS 52.021
|
||||||
[options="header"]
|
[options="header"]
|
||||||
[options="header",cols="20%,55%,5%,20%"]
|
[options="header",cols="20%,55%,5%,20%"]
|
||||||
|===
|
|===
|
||||||
@@ -49,10 +54,10 @@ Specific limitations apply, see the linked sections.
|
|||||||
|
|
||||||
|
|
||||||
==== Messages Not Implemented by OsmoBTS
|
==== Messages Not Implemented by OsmoBTS
|
||||||
.3GPP TS 12.21 messages not implemented by OsmoBTS
|
.3GPP TS 52.021 messages not implemented by OsmoBTS
|
||||||
[options="header",cols="10%,10%,80%"]
|
[options="header",cols="10%,10%,80%"]
|
||||||
|===
|
|===
|
||||||
| TS 12.21 § | type code (hex) | Message
|
| TS 52.021 § | type code (hex) | Message
|
||||||
3+<| *SW Download Management Messages:*
|
3+<| *SW Download Management Messages:*
|
||||||
.3+.| 8.3.1 | 0x01 | Load Data Initiate
|
.3+.| 8.3.1 | 0x01 | Load Data Initiate
|
||||||
| 0x02 | Load Data Initiate Ack
|
| 0x02 | Load Data Initiate Ack
|
||||||
@@ -136,9 +141,6 @@ Specific limitations apply, see the linked sections.
|
|||||||
| 8.10.3 | 0x8C | Stop Measurement
|
| 8.10.3 | 0x8C | Stop Measurement
|
||||||
| 8.10.4 | 0x8D | Start Measurement
|
| 8.10.4 | 0x8D | Start Measurement
|
||||||
3+<| *Other Messages:*
|
3+<| *Other Messages:*
|
||||||
| 8.11.1 | 0x81 | Get Attributes
|
|
||||||
| 8.11.3 | 0x82 | Get Attribute(s) Response
|
|
||||||
| 8.11.1 | 0x83 | Get Attributes Nack
|
|
||||||
.3+.| 8.11.2 | 0x84 | Set Alarm Threshold
|
.3+.| 8.11.2 | 0x84 | Set Alarm Threshold
|
||||||
| 0x85 | Set Alarm Threshold Ack
|
| 0x85 | Set Alarm Threshold Ack
|
||||||
| 0x86 | Set Alarm Threshold Nack
|
| 0x86 | Set Alarm Threshold Nack
|
||||||
@@ -151,7 +153,7 @@ Specific limitations apply, see the linked sections.
|
|||||||
==== SW Activated Report
|
==== SW Activated Report
|
||||||
|
|
||||||
OsmoBTS will send an _SW Activated Report_ when RF has been activated
|
OsmoBTS will send an _SW Activated Report_ when RF has been activated
|
||||||
successfully. The message is compliant with 3GPP TS 12.21 § 8.3.7.
|
successfully. The message is compliant with 3GPP TS 52.021 § 8.3.7.
|
||||||
|
|
||||||
Upon RF activation, two _SW Activated Report_ messages will be sent, for the Object Classes
|
Upon RF activation, two _SW Activated Report_ messages will be sent, for the Object Classes
|
||||||
|
|
||||||
@@ -163,13 +165,13 @@ Upon RF activation, two _SW Activated Report_ messages will be sent, for the Obj
|
|||||||
|
|
||||||
OsmoBTS will receive a _Set BTS Attributes_ message and reply with a
|
OsmoBTS will receive a _Set BTS Attributes_ message and reply with a
|
||||||
corresponding ACK message on success. IE handling is fully compliant to TS
|
corresponding ACK message on success. IE handling is fully compliant to TS
|
||||||
12.21, except that a change of BCCH ARFCN or BSIC while in operation is not
|
52.021, except that a change of BCCH ARFCN or BSIC while in operation is not
|
||||||
supported, and hence the _Starting Time_ IE is rejected.
|
supported, and hence the _Starting Time_ IE is rejected.
|
||||||
|
|
||||||
._Set BTS Attributes_ IEs not handled by OsmoBTS
|
._Set BTS Attributes_ IEs not handled by OsmoBTS
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 12.21 § | IE Name | Handling
|
| TS 52.021 § | IE Name | Handling
|
||||||
| 9.4.52 | Starting Time | not supported (provokes NACK cause 0x10)
|
| 9.4.52 | Starting Time | not supported (provokes NACK cause 0x10)
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -177,13 +179,13 @@ supported, and hence the _Starting Time_ IE is rejected.
|
|||||||
[[set_radio_attr]]
|
[[set_radio_attr]]
|
||||||
==== Set Radio Carrier Attributes
|
==== Set Radio Carrier Attributes
|
||||||
|
|
||||||
This message conforms to 3GPP TS 12.21, with the following limitation,
|
This message conforms to 3GPP TS 52.021, with the following limitation,
|
||||||
as frequency hopping is not supported by OsmoBTS:
|
as frequency hopping is not supported by OsmoBTS:
|
||||||
|
|
||||||
._Set Radio Carrier Attributes_ IE limitations
|
._Set Radio Carrier Attributes_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 12.21 § | IE Name | Handling
|
| TS 52.021 § | IE Name | Handling
|
||||||
| 9.4.5 | ARFCN List | ignored
|
| 9.4.5 | ARFCN List | ignored
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -191,14 +193,14 @@ as frequency hopping is not supported by OsmoBTS:
|
|||||||
[[set_chan_attr]]
|
[[set_chan_attr]]
|
||||||
==== Set Channel Attributes
|
==== Set Channel Attributes
|
||||||
|
|
||||||
This message conforms to 3GPP TS 12.21, with the following limitation: the
|
This message conforms to 3GPP TS 52.021, with the following limitation: the
|
||||||
following 3GPP TS 12.21 IEs provoke a NACK response when sent to OsmoBTS, as
|
following 3GPP TS 52.021 IEs provoke a NACK response when sent to OsmoBTS, as
|
||||||
frequency hopping is not supported:
|
frequency hopping is not supported:
|
||||||
|
|
||||||
._Set Channel Attributes_ IE limitations
|
._Set Channel Attributes_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 12.21 § | IE Name | Handling
|
| TS 52.021 § | IE Name | Handling
|
||||||
| 9.4.21 | HSN | not supported (provokes NACK cause 0x10)
|
| 9.4.21 | HSN | not supported (provokes NACK cause 0x10)
|
||||||
| 9.4.27 | MAIO | not supported (provokes NACK cause 0x10)
|
| 9.4.27 | MAIO | not supported (provokes NACK cause 0x10)
|
||||||
| 9.4.52 | Starting Time | not supported (provokes NACK cause 0x10)
|
| 9.4.52 | Starting Time | not supported (provokes NACK cause 0x10)
|
||||||
@@ -207,34 +209,54 @@ frequency hopping is not supported:
|
|||||||
[[state_changed_rep]]
|
[[state_changed_rep]]
|
||||||
==== State Changed Event Report
|
==== State Changed Event Report
|
||||||
|
|
||||||
This message is compliant with 3GPP TS 12.21. Exactly these IEs are sent by
|
This message is compliant with 3GPP TS 52.021. Exactly these IEs are sent by
|
||||||
OsmoBTS:
|
OsmoBTS:
|
||||||
|
|
||||||
[options="header"]
|
[options="header"]
|
||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message Type (0xf5) | 3GPP TS 12.21 9.1 | M | V | 1
|
| Message Type (0xf5) | 3GPP TS 52.021 9.1 | M | V | 1
|
||||||
| Object Class | 3GPP TS 12.21 9.2 | M | V | 1
|
| Object Class | 3GPP TS 52.021 9.2 | M | V | 1
|
||||||
| Object Instance | 3GPP TS 12.21 9.3 | M | V | 3
|
| Object Instance | 3GPP TS 52.021 9.3 | M | V | 3
|
||||||
| Operational State | 3GPP TS 12.21 9.4.38 | O | TV | 2
|
| Operational State | 3GPP TS 52.021 9.4.38 | O | TV | 2
|
||||||
| Availability Status | 3GPP TS 12.21 9.4.7 | O | TL16V (with length of 1) | 3
|
| Availability Status | 3GPP TS 52.021 9.4.7 | O | TL16V (with length of 1) | 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[chg_adm_state]]
|
[[chg_adm_state]]
|
||||||
==== Change Administrative State
|
==== Change Administrative State
|
||||||
|
|
||||||
This message is compliant with 3GPP TS 12.21 § 8.8.5. It applies to all of the
|
This message is compliant with 3GPP TS 52.021 § 8.8.5. It applies to all of the
|
||||||
Object Classes defined in 3GPP TS 12.21 § 9.2 as well as
|
Object Classes defined in 3GPP TS 52.021 § 9.2 as well as
|
||||||
<<addnl_obj_classes>>.
|
<<addnl_obj_classes>>.
|
||||||
|
|
||||||
[[opstart]]
|
[[opstart]]
|
||||||
==== Opstart
|
==== Opstart
|
||||||
|
|
||||||
This message is compliant with 3GPP TS 12.21 § 8.9.2. It applies to all of the
|
This message is compliant with 3GPP TS 52.021 § 8.9.2. It applies to all of the
|
||||||
Object Classes defined in 3GPP TS 12.21 § 9.2 as well as
|
Object Classes defined in 3GPP TS 52.021 § 9.2 as well as
|
||||||
<<addnl_obj_classes>>.
|
<<addnl_obj_classes>>.
|
||||||
|
|
||||||
|
[[get_attributes]]
|
||||||
|
==== Get Attributes
|
||||||
|
|
||||||
|
This message is compliant with 3GPP TS 52.021 § 8.11.1.
|
||||||
|
|
||||||
|
For a list of supported attributes, see <<get_attr_resp>>.
|
||||||
|
|
||||||
|
[[get_attr_resp]]
|
||||||
|
==== Get Attribute Response
|
||||||
|
|
||||||
|
This message is compliant with 3GPP TS 52.021 § 8.11.3.
|
||||||
|
|
||||||
|
The following attributes are provided by OsmoBTS:
|
||||||
|
|
||||||
|
[options="header"]
|
||||||
|
|===
|
||||||
|
| 3GPP TS 52.021 chapter | description | see
|
||||||
|
| 9.4.61 | SW Configuration | <<NM_ATT_SW_CONFIG>>
|
||||||
|
| 9.4.30 | Manufacturer Id | <<NM_ATT_MANUF_ID>>
|
||||||
|
|===
|
||||||
|
|
||||||
=== Details on OsmoBTS Specific Messages
|
=== Details on OsmoBTS Specific Messages
|
||||||
|
|
||||||
@@ -252,9 +274,9 @@ The message specifics depend on the Object Class and are detailed in
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message Type (0xf5) | 3GPP TS 12.21 9.1 | M | V | 1
|
| Message Type (0xf5) | 3GPP TS 52.021 9.1 | M | V | 1
|
||||||
| Object Class | 3GPP TS 12.21 9.2 | M | V | 1
|
| Object Class | 3GPP TS 52.021 9.2 | M | V | 1
|
||||||
| Object Instance | 3GPP TS 12.21 9.3 | M | V | 3
|
| Object Instance | 3GPP TS 52.021 9.3 | M | V | 3
|
||||||
5+<| _Object Class specific IEs follow, see <<addnl_obj_classes>>..._
|
5+<| _Object Class specific IEs follow, see <<addnl_obj_classes>>..._
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -262,7 +284,7 @@ The message specifics depend on the Object Class and are detailed in
|
|||||||
[[addnl_obj_classes]]
|
[[addnl_obj_classes]]
|
||||||
=== Additional Object Classes
|
=== Additional Object Classes
|
||||||
|
|
||||||
In addition to 3GPP TS 12.21 Chapter 9.2, the following managed objects
|
In addition to 3GPP TS 52.021 Chapter 9.2, the following managed objects
|
||||||
are supported:
|
are supported:
|
||||||
|
|
||||||
.Additional Managed Object Classes
|
.Additional Managed Object Classes
|
||||||
@@ -284,9 +306,9 @@ with the following Information Elements:
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message Type | 3GPP TS 12.21 9.1 | M | V | 1
|
| Message Type | 3GPP TS 52.021 9.1 | M | V | 1
|
||||||
| Object Class | 3GPP TS 12.21 9.2 | M | V | 1
|
| Object Class | 3GPP TS 52.021 9.2 | M | V | 1
|
||||||
| Object Instance | 3GPP TS 12.21 9.3 | M | V | 3
|
| Object Instance | 3GPP TS 52.021 9.3 | M | V | 3
|
||||||
| GPRS NSEI | <<NM_ATT_IPACC_NSEI>> | O | TL16V | >= 5
|
| GPRS NSEI | <<NM_ATT_IPACC_NSEI>> | O | TL16V | >= 5
|
||||||
| GPRS NS Configuration | <<NM_ATT_IPACC_NS_LINK_CFG>> | O | TL16V | >= 10
|
| GPRS NS Configuration | <<NM_ATT_IPACC_NS_LINK_CFG>> | O | TL16V | >= 10
|
||||||
| GPRS BSSGP Configuration | <<NM_ATT_IPACC_BSSGP_CFG>> | O | TL16V | >= 14
|
| GPRS BSSGP Configuration | <<NM_ATT_IPACC_BSSGP_CFG>> | O | TL16V | >= 14
|
||||||
@@ -301,9 +323,9 @@ message with the following Information Elements:
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message Type | 3GPP TS 12.21 9.1 | M | V | 1
|
| Message Type | 3GPP TS 52.021 9.1 | M | V | 1
|
||||||
| Object Class | 3GPP TS 12.21 9.2 | M | V | 1
|
| Object Class | 3GPP TS 52.021 9.2 | M | V | 1
|
||||||
| Object Instance | 3GPP TS 12.21 9.3 | M | V | 3
|
| Object Instance | 3GPP TS 52.021 9.3 | M | V | 3
|
||||||
| GPRS Routing Area Code | <<NM_ATT_IPACC_RAC>> | O | TL16V | >= 4
|
| GPRS Routing Area Code | <<NM_ATT_IPACC_RAC>> | O | TL16V | >= 4
|
||||||
| GPRS Paging Configuration | <<NM_ATT_IPACC_GPRS_PAGING_CFG>> | O | TL16V | >= 5
|
| GPRS Paging Configuration | <<NM_ATT_IPACC_GPRS_PAGING_CFG>> | O | TL16V | >= 5
|
||||||
| GPRS RLC Configuration | <<NM_ATT_IPACC_RLC_CFG>> | O | TL16V | >= 12
|
| GPRS RLC Configuration | <<NM_ATT_IPACC_RLC_CFG>> | O | TL16V | >= 12
|
||||||
@@ -321,9 +343,9 @@ Attribute* message with the following Information Elements:
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message Type | 3GPP TS 12.21 9.1 | M | V | 1
|
| Message Type | 3GPP TS 52.021 9.1 | M | V | 1
|
||||||
| Object Class | 3GPP TS 12.21 9.2 | M | V | 1
|
| Object Class | 3GPP TS 52.021 9.2 | M | V | 1
|
||||||
| Object Instance | 3GPP TS 12.21 9.3 | M | V | 3
|
| Object Instance | 3GPP TS 52.021 9.3 | M | V | 3
|
||||||
| GPRS NSVCI | <<NM_ATT_IPACC_NSVCI>> | O | TL16V | >= 5
|
| GPRS NSVCI | <<NM_ATT_IPACC_NSVCI>> | O | TL16V | >= 5
|
||||||
| GPRS NS Link Configuration | <<NM_ATT_IPACC_NS_LINK_CFG>> | O | TL16V | >= 11
|
| GPRS NS Link Configuration | <<NM_ATT_IPACC_NS_LINK_CFG>> | O | TL16V | >= 11
|
||||||
|===
|
|===
|
||||||
@@ -332,9 +354,9 @@ Attribute* message with the following Information Elements:
|
|||||||
=== Information Elements Overview
|
=== Information Elements Overview
|
||||||
|
|
||||||
All of the IEs handled by OsmoBTS are listed below, with limitations and
|
All of the IEs handled by OsmoBTS are listed below, with limitations and
|
||||||
additions to TS 12.21 specified in more detail.
|
additions to TS 52.021 specified in more detail.
|
||||||
|
|
||||||
==== IEs Conforming to TS 12.21
|
==== IEs Conforming to TS 52.021
|
||||||
|
|
||||||
The following Information Elements are accepted by OsmoBTS.
|
The following Information Elements are accepted by OsmoBTS.
|
||||||
|
|
||||||
@@ -346,10 +368,10 @@ IEs marked __ignored__ and additionally marked as being received by OsmoBTS
|
|||||||
(<-) are in fact parsed and their values are stored by OsmoBTS, but these
|
(<-) are in fact parsed and their values are stored by OsmoBTS, but these
|
||||||
stored items are currently not used in the OsmoBTS code base.
|
stored items are currently not used in the OsmoBTS code base.
|
||||||
|
|
||||||
.IEs conforming to TS 12.21
|
.IEs conforming to TS 52.021
|
||||||
[options="header",cols="5%,10%,40%,5%,40%"]
|
[options="header",cols="5%,10%,40%,5%,40%"]
|
||||||
|===
|
|===
|
||||||
| tag (hex) | TS 12.21 § | IE name | <-/-> | Received/Sent by OsmoBTS
|
| tag (hex) | TS 52.021 § | IE name | <-/-> | Received/Sent by OsmoBTS
|
||||||
| 0x00 | 9.4.1 | Abis Channel | | _ignored_
|
| 0x00 | 9.4.1 | Abis Channel | | _ignored_
|
||||||
| 0x01 | 9.4.2 | Additional Info | | _ignored_
|
| 0x01 | 9.4.2 | Additional Info | | _ignored_
|
||||||
| 0x02 | 9.4.3 | Additional Text | | _ignored_
|
| 0x02 | 9.4.3 | Additional Text | | _ignored_
|
||||||
@@ -372,8 +394,8 @@ stored items are currently not used in the OsmoBTS code base.
|
|||||||
| 0x13 | 9.4.19 | File Version | | _ignored_
|
| 0x13 | 9.4.19 | File Version | | _ignored_
|
||||||
| 0x14 | 9.4.20 | GSM Time | | _ignored_
|
| 0x14 | 9.4.20 | GSM Time | | _ignored_
|
||||||
| 0x16 | 9.4.22 | HW Configuration | | _ignored_
|
| 0x16 | 9.4.22 | HW Configuration | | _ignored_
|
||||||
| 0x18 | 9.4.24 | Intave Parameter | <- | _ignored_
|
| 0x18 | 9.4.24 | Intave Parameter | <- |
|
||||||
| 0x19 | 9.4.25 | Interference level Boundaries | <- | _ignored_
|
| 0x19 | 9.4.25 | Interference level Boundaries | <- |
|
||||||
| 0x1a | 9.4.26 | List of Required Attributes | | _ignored_
|
| 0x1a | 9.4.26 | List of Required Attributes | | _ignored_
|
||||||
| 0x1c | 9.4.28 | Manufacturer Dependent State | | _ignored_
|
| 0x1c | 9.4.28 | Manufacturer Dependent State | | _ignored_
|
||||||
| 0x1d | 9.4.29 | Manufacturer Dependent Thresholds | | _ignored_
|
| 0x1d | 9.4.29 | Manufacturer Dependent Thresholds | | _ignored_
|
||||||
@@ -405,20 +427,20 @@ stored items are currently not used in the OsmoBTS code base.
|
|||||||
| 0x38 | 9.4.58 | VSWR Thresholds | | _ignored_
|
| 0x38 | 9.4.58 | VSWR Thresholds | | _ignored_
|
||||||
| 0x39 | 9.4.59 | Window Size | | _ignored_
|
| 0x39 | 9.4.59 | Window Size | | _ignored_
|
||||||
| 0x40 | 9.4.60 | TSC | <- | Received, with limitations: see <<NM_ATT_TSC>>
|
| 0x40 | 9.4.60 | TSC | <- | Received, with limitations: see <<NM_ATT_TSC>>
|
||||||
| 0x41 | 9.4.61 | SW Configuration | | _ignored_
|
| 0x41 | 9.4.61 | SW Configuration | -> | Sent, see <<NM_ATT_SW_CONFIG>>
|
||||||
| 0x43 | 9.4.63 | Perceived Severity | | _ignored_
|
| 0x43 | 9.4.63 | Perceived Severity | | _ignored_
|
||||||
| 0x44 | 9.4.64 | Get Attribute Response Info | | _ignored_
|
| 0x44 | 9.4.64 | Get Attribute Response Info | -> | Sent, see <<NM_ATT_MANUF_ID>>
|
||||||
| 0x45 | 9.4.65 | Outstanding Alarm Sequence | | _ignored_
|
| 0x45 | 9.4.65 | Outstanding Alarm Sequence | | _ignored_
|
||||||
| 0x46 | 9.4.66 | HW Conf Change Info | | _ignored_
|
| 0x46 | 9.4.66 | HW Conf Change Info | | _ignored_
|
||||||
| 0x47 | 9.4.32 | Measurement Result | | _ignored_
|
| 0x47 | 9.4.32 | Measurement Result | | _ignored_
|
||||||
|===
|
|===
|
||||||
|
|
||||||
==== IEs Not Conforming to TS 12.21
|
==== IEs Not Conforming to TS 52.021
|
||||||
|
|
||||||
.IEs not conforming to TS 12.21
|
.IEs not conforming to TS 52.021
|
||||||
[options="header",cols="5%,10%,30%,55%"]
|
[options="header",cols="5%,10%,30%,55%"]
|
||||||
|===
|
|===
|
||||||
| tag (hex) | TS 12.21 § | IE name | Description
|
| tag (hex) | TS 52.021 § | IE name | Description
|
||||||
| 0x15 | 9.4.21 | HSN | presence causes NACK response
|
| 0x15 | 9.4.21 | HSN | presence causes NACK response
|
||||||
| 0x17 | 9.4.23 | HW Description | _ignored_ by OsmoBTS, but coding may differ, see <<ie_hw_desc>>
|
| 0x17 | 9.4.23 | HW Description | _ignored_ by OsmoBTS, but coding may differ, see <<ie_hw_desc>>
|
||||||
| 0x1b | 9.4.27 | MAIO | presence causes NACK response
|
| 0x1b | 9.4.27 | MAIO | presence causes NACK response
|
||||||
@@ -431,14 +453,14 @@ stored items are currently not used in the OsmoBTS code base.
|
|||||||
==== Additional Attributes and Parameters
|
==== Additional Attributes and Parameters
|
||||||
|
|
||||||
The following Information Elements are defined in addition to those
|
The following Information Elements are defined in addition to those
|
||||||
specified in 3GPP TS 12.21 Chapter 9.4.
|
specified in 3GPP TS 52.021 Chapter 9.4.
|
||||||
|
|
||||||
All of these additional IEs are _received_ by OsmoBTS.
|
All of these additional IEs are _received_ by OsmoBTS.
|
||||||
|
|
||||||
These attributes are not used by OsmoBTS, but
|
These attributes are not used by OsmoBTS, but
|
||||||
simply passed to OsmoPCU connected to the PCU socket.
|
simply passed to OsmoPCU connected to the PCU socket.
|
||||||
|
|
||||||
.Additional IEs handled by OsmoBTS but not defined in TS 12.21
|
.Additional IEs handled by OsmoBTS but not defined in TS 52.021
|
||||||
[options="header",cols="5%,50%,45%"]
|
[options="header",cols="5%,50%,45%"]
|
||||||
|===
|
|===
|
||||||
| tag (hex) | IE name | Description
|
| tag (hex) | IE name | Description
|
||||||
@@ -465,7 +487,7 @@ simply passed to OsmoPCU connected to the PCU socket.
|
|||||||
[[ie_hw_desc]]
|
[[ie_hw_desc]]
|
||||||
==== HW Description
|
==== HW Description
|
||||||
|
|
||||||
TS 12.21 suggests a series of 5 length-value pairs for the _HW Description_ IE.
|
TS 52.021 suggests a series of 5 length-value pairs for the _HW Description_ IE.
|
||||||
Instead, OsmoBTS interprets it as a single TL16V. The value of this IE is
|
Instead, OsmoBTS interprets it as a single TL16V. The value of this IE is
|
||||||
ignored by OsmoBTS, yet the coding may affect message parsing.
|
ignored by OsmoBTS, yet the coding may affect message parsing.
|
||||||
|
|
||||||
@@ -487,7 +509,7 @@ exactly one ARFCN.
|
|||||||
[[ie_chan_comb]]
|
[[ie_chan_comb]]
|
||||||
==== Additional Channel Combinations
|
==== Additional Channel Combinations
|
||||||
|
|
||||||
In addition to 3GPP TS 12.21 Chapter 9.4.13, the following channel
|
In addition to 3GPP TS 52.021 Chapter 9.4.13, the following channel
|
||||||
combinations are supported:
|
combinations are supported:
|
||||||
|
|
||||||
.Additional Channel Combinations
|
.Additional Channel Combinations
|
||||||
@@ -513,7 +535,7 @@ work, please see the <<rsl-dynamic-channels>>.
|
|||||||
[[ie_conn_fail_crit]]
|
[[ie_conn_fail_crit]]
|
||||||
==== Connection Failure Criterion
|
==== Connection Failure Criterion
|
||||||
|
|
||||||
3GPP TS 12.21 Chapter 9.4.14 specifies two different options for the
|
3GPP TS 52.021 Chapter 9.4.14 specifies two different options for the
|
||||||
_Connection Failure Criterion_. OsmoBTS only implements the option
|
_Connection Failure Criterion_. OsmoBTS only implements the option
|
||||||
coded as 0x01, i.e. based upon uplink SACCH error rate
|
coded as 0x01, i.e. based upon uplink SACCH error rate
|
||||||
(RADIO_LINK_TIMEOUT).
|
(RADIO_LINK_TIMEOUT).
|
||||||
@@ -523,7 +545,7 @@ coded as 0x01, i.e. based upon uplink SACCH error rate
|
|||||||
|
|
||||||
Due to limitations in the currently supported PHY implementations,
|
Due to limitations in the currently supported PHY implementations,
|
||||||
OsmoBTS supports only one global TSC for all channels on one TRX, rather
|
OsmoBTS supports only one global TSC for all channels on one TRX, rather
|
||||||
than a separate TSC for each timeslot, as expected by 3GPP TS 12.21.
|
than a separate TSC for each timeslot, as expected by 3GPP TS 52.021.
|
||||||
|
|
||||||
|
|
||||||
[[NM_ATT_IPACC_DST_IP]]
|
[[NM_ATT_IPACC_DST_IP]]
|
||||||
@@ -783,10 +805,91 @@ It is encoded as follows:
|
|||||||
This attribute is not used by OsmoBTS, but
|
This attribute is not used by OsmoBTS, but
|
||||||
simply passed to OsmoPCU connected to the PCU socket.
|
simply passed to OsmoPCU connected to the PCU socket.
|
||||||
|
|
||||||
|
[[NM_ATT_SW_CONFIG]]
|
||||||
|
==== SW Configuration
|
||||||
|
|
||||||
|
The SW Configuration IE is compliant with 3GPP TS 52.021 9.4.61: it contains a
|
||||||
|
number of SW Description IEs (9.4.62).
|
||||||
|
|
||||||
|
|
||||||
|
.Coding of SW Configuration IE
|
||||||
|
[options="header",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| octet | value
|
||||||
|
| 1 | NM_ATT_SW_CONFIG IEI (0x41)
|
||||||
|
| 2-3 | length of value part
|
||||||
|
| 4 | NM_ATT_SW_DESCR IEI (0x42)
|
||||||
|
| 5 | NM_ATT_FILE_ID IEI (0x12)
|
||||||
|
| 6-7 | length of file name
|
||||||
|
| 8-N | ASCII coded file name (without terminating nul)
|
||||||
|
| N+1 | NM_ATT_FILE_VERSION IEI (0x13)
|
||||||
|
| N+2 - N+3 | length of file content
|
||||||
|
| N+4 - M | file content
|
||||||
|
| M+1 | NM_ATT_SW_DESCR IEI (0x42)
|
||||||
|
| M+2 | NM_ATT_FILE_ID IEI (0x12)
|
||||||
|
2+| ...
|
||||||
|
|===
|
||||||
|
|
||||||
|
.File names and content sent in the SW Configuration IE
|
||||||
|
[options="header",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| file name | content
|
||||||
|
| 'osmobts' | ASCII coded OsmoBTS version number like "1.2.3" or "1.2.3.4-abcd"
|
||||||
|
| 'BTS_TYPE_VARIANT' | one of "osmo-bts-lc15", "osmo-bts-oc2g", "osmo-bts-octphy",
|
||||||
|
"osmo-bts-omldummy", "osmo-bts-sysmo", "osmo-bts-trx", "osmo-bts-virtual"
|
||||||
|
| 'BTS_SUB_MODEL' | This file may be omitted; if present, may contain an ASCII
|
||||||
|
coded model number like "sysmoBTS 1002"
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
|
[[NM_ATT_MANUF_ID]]
|
||||||
|
==== Manufacturer Id
|
||||||
|
|
||||||
|
The coding of the Manufacturer Id attribute is a sequence of bit flags (a bit
|
||||||
|
vector), where a zero flag indicates absence and a set flag indicates presence
|
||||||
|
of a specific BTS feature.
|
||||||
|
|
||||||
|
The number of flags transmitted depends on the software version of OsmoBTS and
|
||||||
|
the BTS backend in use. More flags may be added in the future. The flag bits
|
||||||
|
transmitted are followed by zero bits up to the next full octet boundary.
|
||||||
|
|
||||||
|
These features are currently defined:
|
||||||
|
|
||||||
|
.coding of BTS feature flags sent in the Manufacturer Id attribute
|
||||||
|
[options="header",cols="5%,5%,30%,60%"]
|
||||||
|
|===
|
||||||
|
| octet | bit | feature name | description
|
||||||
|
.8+.| 0 | 7 | HSCSD | High-Speed Circuit-Switched Data
|
||||||
|
| 6 | GPRS | General Packet Radio Service
|
||||||
|
| 5 | EGPRS | Enhanced GPRS (EDGE)
|
||||||
|
| 4 | ECSD | Enhanced Circuit-Switched Data
|
||||||
|
| 3 | HOPPING | Frequency Hopping
|
||||||
|
| 2 | MULTI_TSC | Multi-TSC
|
||||||
|
| 1 | OML_ALERTS | OML Alerts
|
||||||
|
| 0 | AGCH_PCH_PROP | AGCH/PCH proportional allocation
|
||||||
|
.8+.| 1 | 7 | CBCH | Cell Broadcast Channel
|
||||||
|
| 6 | SPEECH_F_V1 | Fullrate speech V1
|
||||||
|
| 5 | SPEECH_H_V1 | Halfrate speech V1
|
||||||
|
| 4 | SPEECH_F_EFR | Fullrate speech EFR
|
||||||
|
| 3 | SPEECH_F_AMR | Fullrate speech AMR
|
||||||
|
| 2 | SPEECH_H_AMR | Halfrate speech AMR
|
||||||
|
| 1 | ETWS_PN | ETWS Primary Notification via PCH
|
||||||
|
| 0 | PAGING_COORDINATION | BSS Paging Coordination
|
||||||
|
.8+.| 2 | 7 | IPV6_NSVC | NSVC IPv6
|
||||||
|
| 6 | ACCH_REP | FACCH/SACCH Repetition
|
||||||
|
| 5 | CCN | Cell Change Notification
|
||||||
|
| 4 | VAMOS | Voice services over Adaptive Multi-user channels on One Slot
|
||||||
|
| 3 2.4+.| reserved for future use, sent as zero
|
||||||
|
| 2
|
||||||
|
| 1
|
||||||
|
| 0
|
||||||
|
|===
|
||||||
|
|
||||||
|
|
||||||
=== A-bis OML Initialization / BTS bring-up
|
=== A-bis OML Initialization / BTS bring-up
|
||||||
|
|
||||||
At the time an Abis/IP BTS connects to via OML to the BSC, it is
|
At the time an Abis/IP BTS connects to via OML to the BSC, it is
|
||||||
initialized according to the procedures described in 3GPP TS 12.21 as
|
initialized according to the procedures described in 3GPP TS 52.021 as
|
||||||
amended by this document.
|
amended by this document.
|
||||||
|
|
||||||
Each Managed Object (MO) is separately initialized. The initialization
|
Each Managed Object (MO) is separately initialized. The initialization
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
=== List of Messages
|
=== List of Messages
|
||||||
|
|
||||||
The following tables list the RSL messages used by OsmoBTS A-bis/IP,
|
The following tables list the RSL messages used by OsmoBTS A-bis/IP,
|
||||||
grouped by their level of compliance with 3GPP TS 08.58.
|
grouped by their level of compliance with 3GPP TS 48.058.
|
||||||
|
|
||||||
==== Messages Compliant With TS 08.58
|
==== Messages Compliant With TS 48.058
|
||||||
|
|
||||||
Specific additions and limitations apply, see the linked sections.
|
Specific additions and limitations apply, see the linked sections.
|
||||||
|
|
||||||
.Messages compliant with TS 08.58
|
.Messages compliant with TS 48.058
|
||||||
[options="header",cols="10%,20%,45%,5%,20%"]
|
[options="header",cols="10%,20%,45%,5%,20%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
| TS 48.058 § | This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
||||||
5+<| *Radio link layer management messages*
|
5+<| *Radio link layer management messages*
|
||||||
| 8.3.1 | - | DATA REQUEST | <- | Received
|
| 8.3.1 | - | DATA REQUEST | <- | Received
|
||||||
| 8.3.2 | - | DATA INDICATION | -> | Sent
|
| 8.3.2 | - | DATA INDICATION | -> | Sent
|
||||||
@@ -59,7 +59,7 @@ Specific additions and limitations apply, see the linked sections.
|
|||||||
|
|
||||||
==== Messages Specific to OsmoBTS
|
==== Messages Specific to OsmoBTS
|
||||||
|
|
||||||
.Messages specific to OsmoBTS, not found in 3GPP TS 08.58
|
.Messages specific to OsmoBTS, not found in 3GPP TS 48.058
|
||||||
[options="header",cols="15%,15%,45%,5%,20%"]
|
[options="header",cols="15%,15%,45%,5%,20%"]
|
||||||
|===
|
|===
|
||||||
2+| This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
2+| This document § | Message | <-/-> | Received/Sent by OsmoBTS
|
||||||
@@ -87,10 +87,10 @@ Specific additions and limitations apply, see the linked sections.
|
|||||||
|
|
||||||
==== Messages Not Implemented by OsmoBTS
|
==== Messages Not Implemented by OsmoBTS
|
||||||
|
|
||||||
.3GPP TS 08.58 messages not implemented by OsmoBTS
|
.3GPP TS 48.058 messages not implemented by OsmoBTS
|
||||||
[options="header",cols="10%,90%"]
|
[options="header",cols="10%,90%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | Message
|
| TS 48.058 § | Message
|
||||||
2+<| *DEDICATED CHANNEL MANAGEMENT MESSAGES*
|
2+<| *DEDICATED CHANNEL MANAGEMENT MESSAGES*
|
||||||
| 8.4.12 | PHYSICAL CONTEXT REQUEST
|
| 8.4.12 | PHYSICAL CONTEXT REQUEST
|
||||||
| 8.4.13 | PHYSICAL CONTEXT CONFIRM
|
| 8.4.13 | PHYSICAL CONTEXT CONFIRM
|
||||||
@@ -123,7 +123,7 @@ Specific additions and limitations apply, see the linked sections.
|
|||||||
==== Channel Activation
|
==== Channel Activation
|
||||||
|
|
||||||
When used on a timeslot using the non-standard channel combination
|
When used on a timeslot using the non-standard channel combination
|
||||||
'NM_CHANC_OSMO_TCHFull_TCHHalf_PDCH' as configured by OML, the regular
|
'NM_CHANC_OSMO_DYN' as configured by OML, the regular
|
||||||
RSL channel activation procedures can not only be used for activation
|
RSL channel activation procedures can not only be used for activation
|
||||||
of circuit-switched channels, but also for activation of a PDCH.
|
of circuit-switched channels, but also for activation of a PDCH.
|
||||||
|
|
||||||
@@ -135,24 +135,24 @@ dynamic PDCH protocol employed by nanoBTS devices (<<ipa_style_pdch_mgmt>>).
|
|||||||
[[MEASUREMENT_RESULT]]
|
[[MEASUREMENT_RESULT]]
|
||||||
==== Measurement Result
|
==== Measurement Result
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.4.8 with this limitation:
|
Conforms to 3GPP TS 48.058 § 8.4.8 with this limitation:
|
||||||
|
|
||||||
._Measurement Result_ IE limitations
|
._Measurement Result_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.37 | MS Timing Offset | never sent by OsmoBTS
|
| 9.3.37 | MS Timing Offset | never sent by OsmoBTS
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[MODE_MODIFY]]
|
[[MODE_MODIFY]]
|
||||||
==== Mode Modify
|
==== Mode Modify
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.4.9 with these limitations:
|
Conforms to 3GPP TS 48.058 § 8.4.9 with these limitations:
|
||||||
|
|
||||||
._Mode Modify_ IE limitations
|
._Mode Modify_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.45 | Main channel reference | _ignored_
|
| 9.3.45 | Main channel reference | _ignored_
|
||||||
| 9.3.53 | MultiRate Control | _ignored_
|
| 9.3.53 | MultiRate Control | _ignored_
|
||||||
| 9.3.54 | Supported Codec Types | _ignored_
|
| 9.3.54 | Supported Codec Types | _ignored_
|
||||||
@@ -161,12 +161,12 @@ Conforms to 3GPP TS 08.58 § 8.4.9 with these limitations:
|
|||||||
[[MS_POWER_CONTROL]]
|
[[MS_POWER_CONTROL]]
|
||||||
==== MS Power Control
|
==== MS Power Control
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.4.15 with these limitations:
|
Conforms to 3GPP TS 48.058 § 8.4.15 with these limitations:
|
||||||
|
|
||||||
._MS Power Control_ IE limitations
|
._MS Power Control_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.31 | MS Power Parameters | _ignored_
|
| 9.3.31 | MS Power Parameters | _ignored_
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -174,12 +174,12 @@ Conforms to 3GPP TS 08.58 § 8.4.15 with these limitations:
|
|||||||
[[SACCH_INFO_MODIFY]]
|
[[SACCH_INFO_MODIFY]]
|
||||||
==== SACCH Info Modify
|
==== SACCH Info Modify
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.4.20, with these exceptions:
|
Conforms to 3GPP TS 48.058 § 8.4.20, with these exceptions:
|
||||||
|
|
||||||
._SACCH Info Modify_ IE limitations
|
._SACCH Info Modify_ IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.30 | System Info Type | See below for available types
|
| 9.3.30 | System Info Type | See below for available types
|
||||||
| 9.3.23 | Starting Time | not supported, provokes an _Error Report_ response
|
| 9.3.23 | Starting Time | not supported, provokes an _Error Report_ response
|
||||||
|===
|
|===
|
||||||
@@ -199,12 +199,12 @@ Conforms to 3GPP TS 08.58 § 8.4.20, with these exceptions:
|
|||||||
[[BCCH_INFORMATION]]
|
[[BCCH_INFORMATION]]
|
||||||
==== BCCH Information
|
==== BCCH Information
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.5.1, with these limitations and extensions:
|
Conforms to 3GPP TS 48.058 § 8.5.1, with these limitations and extensions:
|
||||||
|
|
||||||
._BCCH Information_ IE details
|
._BCCH Information_ IE details
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.30 | System Info Type | See <<SACCH_INFO_MODIFY>> for available types
|
| 9.3.30 | System Info Type | See <<SACCH_INFO_MODIFY>> for available types
|
||||||
| 9.3.11 | L3 Info | This IE may be included instead of a 9.3.39 _Full BCCH Info_ IE.
|
| 9.3.11 | L3 Info | This IE may be included instead of a 9.3.39 _Full BCCH Info_ IE.
|
||||||
The _Full BCCH Info_ takes precedence over _L3 Info_.
|
The _Full BCCH Info_ takes precedence over _L3 Info_.
|
||||||
@@ -215,12 +215,12 @@ Conforms to 3GPP TS 08.58 § 8.5.1, with these limitations and extensions:
|
|||||||
[[CHANNEL_REQUIRED]]
|
[[CHANNEL_REQUIRED]]
|
||||||
==== Channel Required
|
==== Channel Required
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.5.3, with these limitations:
|
Conforms to 3GPP TS 48.058 § 8.5.3, with these limitations:
|
||||||
|
|
||||||
._Channel Required_ message IE details
|
._Channel Required_ message IE details
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.16 | Physical Context | never sent by OsmoBTS
|
| 9.3.16 | Physical Context | never sent by OsmoBTS
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -228,12 +228,12 @@ Conforms to 3GPP TS 08.58 § 8.5.3, with these limitations:
|
|||||||
[[PAGING_COMMAND]]
|
[[PAGING_COMMAND]]
|
||||||
==== Paging Command
|
==== Paging Command
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.5.5, with these limitations:
|
Conforms to 3GPP TS 48.058 § 8.5.5, with these limitations:
|
||||||
|
|
||||||
._Paging Command_ message IE details
|
._Paging Command_ message IE details
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.49 | eMLPP Priority | _ignored_
|
| 9.3.49 | eMLPP Priority | _ignored_
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -244,28 +244,28 @@ in any way.
|
|||||||
[[RF_RESOURCE_INDICATION]]
|
[[RF_RESOURCE_INDICATION]]
|
||||||
==== RF Resource Indication
|
==== RF Resource Indication
|
||||||
|
|
||||||
This message does not conform to 3GPP TS 08.58 § 8.6.1, in that it omits the
|
For all osmo-bts variants, except osmo-bts-trx, this message does not conform
|
||||||
_Resource Information_ IE that would contain the actual payload data, which
|
to 3GPP TS 48.058 § 8.6.1, in that it omits the _Resource Information_ IE that
|
||||||
renders this message void.
|
would contain the actual payload data, which renders this message void.
|
||||||
|
|
||||||
._RF Resource Indication_ message IE exceptions
|
._RF Resource Indication_ message IE exceptions
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.21 | Resource Information | OsmoBTS omits this IE, though TS 08.58
|
| 9.3.21 | Resource Information | DSP based osmo-bts variants omit this IE, though
|
||||||
specifies it as mandatory.
|
TS 48.058 specifies it as mandatory.
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
[[SACCH_FILLING]]
|
[[SACCH_FILLING]]
|
||||||
==== SACCH Filling
|
==== SACCH Filling
|
||||||
|
|
||||||
Conforms to 3GPP TS 08.58 § 8.6.2, with these limitations:
|
Conforms to 3GPP TS 48.058 § 8.6.2, with these limitations:
|
||||||
|
|
||||||
._SACCH Filling_ message IE limitations
|
._SACCH Filling_ message IE limitations
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.3.30 | System Info Type | See <<SACCH_INFO_MODIFY>> for available types
|
| 9.3.30 | System Info Type | See <<SACCH_INFO_MODIFY>> for available types
|
||||||
| 9.3.23 | Starting Time | _ignored_
|
| 9.3.23 | Starting Time | _ignored_
|
||||||
|===
|
|===
|
||||||
@@ -275,7 +275,7 @@ Conforms to 3GPP TS 08.58 § 8.6.2, with these limitations:
|
|||||||
=== User Plane Transport Management
|
=== User Plane Transport Management
|
||||||
|
|
||||||
This chapter defines the A-bis/IP specific RSL procedures that are
|
This chapter defines the A-bis/IP specific RSL procedures that are
|
||||||
introduced in addition to the 3GPP TS 08.58 standard procedures.
|
introduced in addition to the 3GPP TS 48.058 standard procedures.
|
||||||
|
|
||||||
In classic A-bis over E1, user plane traffic is carried over 16kBps
|
In classic A-bis over E1, user plane traffic is carried over 16kBps
|
||||||
sub-slots of 64kBps E1 time-slots according to ETSI/3GPP TS 08.60. As
|
sub-slots of 64kBps E1 time-slots according to ETSI/3GPP TS 08.60. As
|
||||||
@@ -417,16 +417,16 @@ include::dyn_ts_ipa_style2.msc[]
|
|||||||
==== Osmocom Style Dynamic Channels
|
==== Osmocom Style Dynamic Channels
|
||||||
|
|
||||||
This method is in use when OML uses
|
This method is in use when OML uses
|
||||||
'NM_CHANC_OSMO_TCHFull_TCHHalf_PDCH' (0x90) for the given time-slot.
|
'NM_CHANC_OSMO_DYN' (0x90) for the given time-slot.
|
||||||
|
|
||||||
The activation of PDCH is performed by using the regular 'RSL CHANNEL ACTIVATE'
|
The activation of PDCH is performed by using the regular 'RSL CHANNEL ACTIVATE'
|
||||||
procedure according to <<CHANNEL_ACTIVATION>>, with these modifications:
|
procedure according to <<CHANNEL_ACTIVATION>>, with these modifications:
|
||||||
|
|
||||||
* The 'C-bits' part of the 'Channel Number' IE take the non-standard binary
|
* The 'C-bits' part of the 'Channel Number' IE take the non-standard binary
|
||||||
value 11000 (C5 through C1 as seen in 3GPP TS 08.58 § 9.3.1).
|
value 11000 (C5 through C1 as seen in 3GPP TS 48.058 § 9.3.1).
|
||||||
* The 'A-bits' part of the 'Activation Type' IE take the non-standard binary
|
* The 'A-bits' part of the 'Activation Type' IE take the non-standard binary
|
||||||
value 1111, with an additional fourth bit (add A4 to A3 through A1 as seen in
|
value 1111, with an additional fourth bit (add A4 to A3 through A1 as seen in
|
||||||
3GPP TS 08.58 § 9.3.3; all remaining reserved bits as well as the 'R' bit are
|
3GPP TS 48.058 § 9.3.3; all remaining reserved bits as well as the 'R' bit are
|
||||||
coded as zero).
|
coded as zero).
|
||||||
* The normally mandatory 'Channel Mode' IE is omitted; none of the optional IEs
|
* The normally mandatory 'Channel Mode' IE is omitted; none of the optional IEs
|
||||||
are included.
|
are included.
|
||||||
@@ -436,7 +436,7 @@ Hence the message consists of exactly these IEs:
|
|||||||
.PDCH type _Channel Activation_ message IEs
|
.PDCH type _Channel Activation_ message IEs
|
||||||
[options="header",cols="10%,30%,60%"]
|
[options="header",cols="10%,30%,60%"]
|
||||||
|===
|
|===
|
||||||
| TS 08.58 § | IE Name | Handling
|
| TS 48.058 § | IE Name | Handling
|
||||||
| 9.1 | Message discriminator | Dedicated Channel Management
|
| 9.1 | Message discriminator | Dedicated Channel Management
|
||||||
| 9.2 | Message type | CHANnel ACTIVation
|
| 9.2 | Message type | CHANnel ACTIVation
|
||||||
| 9.3.1 | Channel number | 'C-bits' 11000, plus TS bits as usual
|
| 9.3.1 | Channel number | 'C-bits' 11000, plus TS bits as usual
|
||||||
@@ -476,6 +476,26 @@ signaling for it.
|
|||||||
See <<OSMO_ETWS_CMD>> for the Osmocom implementation.
|
See <<OSMO_ETWS_CMD>> for the Osmocom implementation.
|
||||||
|
|
||||||
|
|
||||||
|
=== BCCH carrier power reduction operation
|
||||||
|
|
||||||
|
According to 3GPP TS 45.008, section 7.1, the BCCH carrier (sometimes called C0) of
|
||||||
|
a BTS shall maintain discontinuous Downlink transmission at full power in order to
|
||||||
|
stay "visible" to the mobile stations. Because of that, early versions of this 3GPP
|
||||||
|
document prohibited BS power reduction on C0. However, a new feature was introduced
|
||||||
|
version 13.0.0 (2015-11) - "BCCH carrier power reduction operation".
|
||||||
|
|
||||||
|
This is a special mode of operation, in which the variation of RF power level for
|
||||||
|
some timeslots is relaxed for the purpose of energy saving. In other words, the
|
||||||
|
output power on some timeslots, except the timeslot(s) carrying BCCH/CCCH, can be
|
||||||
|
lower than the full power. In this case the maximum allowed difference is 6 dB.
|
||||||
|
|
||||||
|
Unfortunately, 3GPP did not specify in which way the BTS is instructed to activate
|
||||||
|
and deactivate the BCCH carrier power reduction mode. Osmocom had to invent their
|
||||||
|
own non-standard approach: the BSC needs to send _BS POWER CONTROL_ message with
|
||||||
|
the _Channel Number_ IE set to 0x80 (BCCH) and the _Message Discriminator_ set to
|
||||||
|
0x06 (Common Channel Management messages).
|
||||||
|
|
||||||
|
|
||||||
=== Message Formats and Contents
|
=== Message Formats and Contents
|
||||||
|
|
||||||
[[rsl_crcx_msg]]
|
[[rsl_crcx_msg]]
|
||||||
@@ -489,9 +509,9 @@ number*.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
||||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2
|
||||||
@@ -509,9 +529,9 @@ in response to the *Create Connection (CRCX)*.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | M | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | M | TV | 3
|
||||||
| Source IP Address | <<RSL_IE_IPAC_LOCAL_IP>> | O | TV | 5
|
| Source IP Address | <<RSL_IE_IPAC_LOCAL_IP>> | O | TV | 5
|
||||||
| Source IP Port | <<RSL_IE_IPAC_LOCAL_PORT>> | O | TV | 3
|
| Source IP Port | <<RSL_IE_IPAC_LOCAL_PORT>> | O | TV | 3
|
||||||
@@ -529,12 +549,12 @@ sent in response to the *Create Connection (CRCX)*.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
||||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||||
| Cause | 08.58 9.3.26 | O | TLV | >= 3
|
| Cause | 48.058 9.3.26 | O | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
@@ -548,9 +568,9 @@ properties of a user-plane RTP connection.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
||||||
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
| Destination IP Address | <<RSL_IE_IPAC_REMOTE_IP>> | O | TV | 5
|
||||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||||
@@ -569,9 +589,9 @@ response to a *Modify Connection (MDCX)*
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
||||||
| Source IP Address | <<RSL_IE_IPAC_LOCAL_IP>> | C | TV | 5
|
| Source IP Address | <<RSL_IE_IPAC_LOCAL_IP>> | C | TV | 5
|
||||||
| Source IP Port | <<RSL_IE_IPAC_LOCAL_PORT>> | C | TV | 3
|
| Source IP Port | <<RSL_IE_IPAC_LOCAL_PORT>> | C | TV | 3
|
||||||
@@ -590,10 +610,10 @@ Connection (MDCX)*.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Cause | 08.58 9.3.26 | M | TLV | >= 3
|
| Cause | 48.058 9.3.26 | M | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_dlcx_ind_msg]]
|
[[rsl_dlcx_ind_msg]]
|
||||||
@@ -607,12 +627,12 @@ time of RF Channel release.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | M | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | M | TV | 3
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_STAT>> | M | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_STAT>> | M | TV | 3
|
||||||
| Cause | 08.58 9.3.26 | M | TLV | >= 3
|
| Cause | 48.058 9.3.26 | M | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_dlcx_msg]]
|
[[rsl_dlcx_msg]]
|
||||||
@@ -626,9 +646,9 @@ number.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -644,9 +664,9 @@ Channel number. It is sent in response to the *Delete Connection
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
||||||
| Connection Statistics | <<RSL_IE_IPAC_CONN_STAT>> | C | TV | 29
|
| Connection Statistics | <<RSL_IE_IPAC_CONN_STAT>> | C | TV | 29
|
||||||
|===
|
|===
|
||||||
@@ -663,11 +683,11 @@ Channel number. It is sent in response to the *Delete Connection
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
| Connection Id | <<RSL_IE_IPAC_CONN_ID>> | O | TV | 3
|
||||||
| Cause | 08.58 9.3.26 | M | TLV | >= 3
|
| Cause | 48.058 9.3.26 | M | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_pdch_act]]
|
[[rsl_pdch_act]]
|
||||||
@@ -680,9 +700,9 @@ a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -697,10 +717,10 @@ of a PDCH on a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Frame Number | 08.58 9.3.8 | O | TV | 3
|
| Frame Number | 48.058 9.3.8 | O | TV | 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -715,10 +735,10 @@ of a PDCH on a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Cause | 08.58 9.3.26 | M | TLV | >= 3
|
| Cause | 48.058 9.3.26 | M | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -733,9 +753,9 @@ on a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -750,9 +770,9 @@ of a PDCH on a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -767,10 +787,10 @@ on a IPA style dynamic TCH/F+PDCH channel.
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| Cause | 08.58 9.3.26 | M | TLV | >= 3
|
| Cause | 48.058 9.3.26 | M | TLV | >= 3
|
||||||
|===
|
|===
|
||||||
|
|
||||||
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
NOTE:: This message is *not* used by Osmocom style dynamic channels
|
||||||
@@ -794,10 +814,10 @@ The Channel Number IE is set to the Downlink CCCH (PCH).
|
|||||||
[cols="30%,25%,15%,15%,15%"]
|
[cols="30%,25%,15%,15%,15%"]
|
||||||
|===
|
|===
|
||||||
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
| INFORMATION ELEMENT | REFERENCE | PRESENCE | FORMAT | LENGTH
|
||||||
| Message discriminator | 08.58 9.1 | M | V | 1
|
| Message discriminator | 48.058 9.1 | M | V | 1
|
||||||
| Message type | <<own_msg_types>> | M | V | 1
|
| Message type | <<own_msg_types>> | M | V | 1
|
||||||
| Channel number | 08.58 9.3.1 | M | TV | 2
|
| Channel number | 48.058 9.3.1 | M | TV | 2
|
||||||
| SMSCB Message | 08.58 9.3.42 | M | TLV | 2-58
|
| SMSCB Message | 48.058 9.3.42 | M | TLV | 2-58
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
|
||||||
@@ -807,7 +827,7 @@ The Channel Number IE is set to the Downlink CCCH (PCH).
|
|||||||
==== A-bis/IP specific RSL Message discriminators
|
==== A-bis/IP specific RSL Message discriminators
|
||||||
|
|
||||||
The following message discriminators are used in addition to those
|
The following message discriminators are used in addition to those
|
||||||
indicated in 3GPP TS 08.58 Section 9.1:
|
indicated in 3GPP TS 48.058 Section 9.1:
|
||||||
|
|
||||||
.OsmoBTS specific new message discriminators
|
.OsmoBTS specific new message discriminators
|
||||||
[options="header",cols="10%,50%,40%"]
|
[options="header",cols="10%,50%,40%"]
|
||||||
@@ -835,13 +855,15 @@ indicated in 3GPP TS 08.58 Section 9.1:
|
|||||||
==== A-bis/IP specific RSL IEIs
|
==== A-bis/IP specific RSL IEIs
|
||||||
|
|
||||||
The following Information Element Identifiers (IEIs) are used in
|
The following Information Element Identifiers (IEIs) are used in
|
||||||
addition to those indicated in 3GPP TS 08.58 Section 9.3:
|
addition to those indicated in 3GPP TS 48.058 Section 9.3:
|
||||||
|
|
||||||
.A-bis/IP specific information elements
|
.A-bis/IP specific information elements
|
||||||
[options="header",cols="10%,50%,40%"]
|
[options="header",cols="10%,50%,40%"]
|
||||||
|===
|
|===
|
||||||
| IEI | Name | This document §
|
| IEI | Name | This document §
|
||||||
| 0x01 | RSL_IE_CHAN_NR | <<RSL_IE_CHAN_NR>>
|
| 0x01 | RSL_IE_CHAN_NR | <<RSL_IE_CHAN_NR>>
|
||||||
|
| 0x60 | RSL_IE_OSMO_REP_ACCH_CAP | <<RSL_IE_OSMO_REP_ACCH_CAP>>
|
||||||
|
| 0x61 | RSL_IE_OSMO_TRAINING_SEQUENCE | <<RSL_IE_OSMO_TRAINING_SEQUENCE>>
|
||||||
| 0xf0 | RSL_IE_IPAC_REMOTE_IP | <<RSL_IE_IPAC_REMOTE_IP>>
|
| 0xf0 | RSL_IE_IPAC_REMOTE_IP | <<RSL_IE_IPAC_REMOTE_IP>>
|
||||||
| 0xf1 | RSL_IE_IPAC_REMOTE_PORT | <<RSL_IE_IPAC_REMOTE_PORT>>
|
| 0xf1 | RSL_IE_IPAC_REMOTE_PORT | <<RSL_IE_IPAC_REMOTE_PORT>>
|
||||||
| 0xf3 | RSL_IE_IPAC_LOCAL_PORT | <<RSL_IE_IPAC_LOCAL_PORT>>
|
| 0xf3 | RSL_IE_IPAC_LOCAL_PORT | <<RSL_IE_IPAC_LOCAL_PORT>>
|
||||||
@@ -855,17 +877,29 @@ addition to those indicated in 3GPP TS 08.58 Section 9.3:
|
|||||||
[[RSL_IE_CHAN_NR]]
|
[[RSL_IE_CHAN_NR]]
|
||||||
==== RSL_IE_CHAN_NR
|
==== RSL_IE_CHAN_NR
|
||||||
|
|
||||||
This information element is coded like 3GPP TS 08.58 Section 9.3.1,
|
This information element is coded as described in 3GPP TS 48.058 Section 9.3.1,
|
||||||
but in addition supports the following extended coding:
|
but in addition supports the following vendor specific values:
|
||||||
|
|
||||||
* C5..C1 bits 0b11000 for PDCH type channels
|
.RSL Channel Number extensions
|
||||||
|
[options="header",cols="5%,5%,5%,5%,5%,75%"]
|
||||||
|
|===
|
||||||
|
| C5 | C4 | C3 | C2 | C1 | Description
|
||||||
|
| 1 | 1 | 0 | 0 | 0 | PDCH `<1>`
|
||||||
|
| 1 | 1 | 0 | 0 | 1 | CBCH on SDCCH4
|
||||||
|
| 1 | 1 | 0 | 1 | 0 | CBCH on SDCCH8
|
||||||
|
| 1 | 1 | 1 | 0 | 1 | VAMOS TCH/F `<2>`
|
||||||
|
| 1 | 1 | 1 | 1 | T | VAMOS TCH/H `<2>`
|
||||||
|
|===
|
||||||
|
|
||||||
|
`<1>` This extension is only valid on an Osmocom-style dynamic channel, having
|
||||||
|
configured the 'NM_CHANC_IPAC_TCHFull_PDCH' channel combination by OML.
|
||||||
|
`<2>` These Osmocom specific values are used by osmo-bsc to address logical
|
||||||
|
channels on the shadow timeslots in VAMOS mode, iff the BTS is an osmo-bts
|
||||||
|
and VAMOS capable.
|
||||||
|
|
||||||
The TN-Bits are not re-defined in this case but use the same encoding
|
The TN-Bits are not re-defined in this case but use the same encoding
|
||||||
as specified in TS 08.58 Section 9.3.1.
|
as specified in TS 48.058 Section 9.3.1.
|
||||||
|
|
||||||
NOTE:: The above extension is only valid on an Osmocom-style dynamic
|
|
||||||
channel, having configured the 'NM_CHANC_IPAC_TCHFull_PDCH' channel
|
|
||||||
combination by OML.
|
|
||||||
|
|
||||||
[[RSL_IE_IPAC_REMOTE_IP]]
|
[[RSL_IE_IPAC_REMOTE_IP]]
|
||||||
==== RSL_IE_IPAC_REMOTE_IP
|
==== RSL_IE_IPAC_REMOTE_IP
|
||||||
@@ -919,8 +953,8 @@ IEI followed by four bytes IPv4 address.
|
|||||||
|
|
||||||
This information element contains statistics about the RTP connection.
|
This information element contains statistics about the RTP connection.
|
||||||
|
|
||||||
It is encoded as 29 bytes, with the first byte as IEI and 28 bytes
|
It is encoded as 30 bytes, with the first byte as IEI, the second byte as length
|
||||||
fixed-length payload encoded as follows:
|
(=28), and 28 bytes fixed-length payload encoded as follows:
|
||||||
|
|
||||||
.A-bis/IP Connection Statistics
|
.A-bis/IP Connection Statistics
|
||||||
[options="header",width="60%",cols="15%,15%,70%"]
|
[options="header",width="60%",cols="15%,15%,70%"]
|
||||||
@@ -953,6 +987,104 @@ This information element contains the RTP payload identifier, which is
|
|||||||
used in the PT (Payload Type) field of the RTP header in subsequent
|
used in the PT (Payload Type) field of the RTP header in subsequent
|
||||||
transmissions of the RTP flow.
|
transmissions of the RTP flow.
|
||||||
|
|
||||||
|
[[RSL_IE_OSMO_REP_ACCH_CAP]]
|
||||||
|
==== RSL_IE_OSMO_REP_ACCH_CAP
|
||||||
|
|
||||||
|
This is a one byte length TLV IE that is used to enable or disable repeated ACCH
|
||||||
|
capabilities on the BTS side during Channel Activation and Mode Modify.
|
||||||
|
|
||||||
|
The IE contains a bitfield in the lower nibble in order to set the ACCH repetition
|
||||||
|
policy for each of the two channel types individually. Depending on the state of the
|
||||||
|
bits (see table below) the ACCH repetition mode is either enabled or disabled completely.
|
||||||
|
|
||||||
|
The lower 3 bit of the higher nibble are used to signal an RXQUAL threshold to set the
|
||||||
|
BER on which UL-SACCH or DL-FACCH repetition shall be turned on. If the field is set
|
||||||
|
to 0, then UL-SACCH and DL-FACCH will be always on. DL-FACCH will also be turned on
|
||||||
|
automatically as soon as the MS requests a DL-SACCH repetition.
|
||||||
|
|
||||||
|
If the IE is not present, then ACCH repetition completely is disabled.
|
||||||
|
|
||||||
|
[options="header"]
|
||||||
|
|===
|
||||||
|
| *bit* | 7 | 6 - 4 | 3 | 2 | 1 | 0
|
||||||
|
| byte at offset 0 | 0 | RXQUAL | UL-SACCH | DL-SACCH | DL-FACCH/ALL | DL-FACCH/CMD
|
||||||
|
|===
|
||||||
|
|
||||||
|
(Bits 7 is reserved for future use and must be set to zero.)
|
||||||
|
|
||||||
|
[[RSL_IE_OSMO_TRAINING_SEQUENCE]]
|
||||||
|
==== RSL_IE_OSMO_TRAINING_SEQUENCE
|
||||||
|
|
||||||
|
This TLV IE instructs the BTS to use a specific training sequence set and
|
||||||
|
training sequence code for a given lchan. It is sent by OsmoBSC in RSL CHANNEL
|
||||||
|
ACTIVATION and MODE MODIFY messages to the BTS, iff the BTS is VAMOS-capable,
|
||||||
|
i.e. if an Abis-over-IP connected BTS indicated BTS_FEAT_VAMOS in the OML BTS
|
||||||
|
features (Manufacturer Id information element, see <<NM_ATT_MANUF_ID>>).
|
||||||
|
|
||||||
|
If this information element is present, the receiver shall ignore any other
|
||||||
|
training sequence set and training sequence code bits from other information
|
||||||
|
elements of the same RSL message.
|
||||||
|
|
||||||
|
This is an Osmocom-specific extension of the RSL layer, which was added to
|
||||||
|
express more than two TSC sets. For VAMOS operation, OsmoBSC selects from one
|
||||||
|
of four separate training sequence codings per modulation scheme, while usual
|
||||||
|
RSL IEs are only able to express a single-bit TSC set number. For clarity, this
|
||||||
|
IE contains both the TSC set and the TSC in one IE, and is defined as
|
||||||
|
overruling any other IEs containing TSC or TSC set numbers.
|
||||||
|
|
||||||
|
The first value octet indicates the training sequence set, and the second octet
|
||||||
|
indicates the training sequence code to be used. Receiving values from a
|
||||||
|
reserved value range should be considered an error condition.
|
||||||
|
|
||||||
|
.RSL_IE_OSMO_TRAINING_SEQUENCE
|
||||||
|
[options="header",width="80%",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| IE octet | value
|
||||||
|
| octet 1 | RSL_IE_OSMO_TRAINING_SEQUENCE IEI (0x61)
|
||||||
|
| octet 2 | length of the value part (2)
|
||||||
|
| octet 3 | TSC set
|
||||||
|
| octet 4 | TSC
|
||||||
|
|===
|
||||||
|
|
||||||
|
The training sequence set (TSC set) is coded like the 'CS Domain TSC Set' bits,
|
||||||
|
as defined in the 'Extended TSC Set' IE in 3GPP TS 44.018 10.5.2.82
|
||||||
|
<<3gpp-ts-44-018>>, and corresponds to the 'TSC Set' as defined in 3GPP TS
|
||||||
|
45.002 <<3gpp-ts-45-002>>. The encoded training sequence set number ranges from
|
||||||
|
0 to 3, any other values are reserved for future use. The encoded 0 corresponds
|
||||||
|
to TSC Set 1, see <<RSL_IE_OSMO_TRAINING_SEQUENCE__TSC_set_coding>>.
|
||||||
|
|
||||||
|
[[RSL_IE_OSMO_TRAINING_SEQUENCE__TSC_set_coding]]
|
||||||
|
.TSC set (octet 3) coding
|
||||||
|
[options="header",width="80%",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| octet 3 value | interpretation
|
||||||
|
| 0 | 'TSC Set 1' as in 3GPP TS 45.002
|
||||||
|
| 1 | 'TSC Set 2'
|
||||||
|
| 2 | 'TSC Set 3'
|
||||||
|
| 3 | 'TSC Set 4'
|
||||||
|
| 4..255 | reserved values
|
||||||
|
|===
|
||||||
|
|
||||||
|
The training sequence code (TSC) corresponds to the 'TSC' bits as defined in
|
||||||
|
the 'Channel Description 2' IE in 3GPP TS 44.018 10.5.2.5a <<3gpp-ts-44-018>>.
|
||||||
|
The training sequence code ranges from 0 to 7, any other values are reserved
|
||||||
|
for future use.
|
||||||
|
|
||||||
|
.TSC (octet 4) coding
|
||||||
|
[options="header",width="80%",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| octet 4 value | interpretation
|
||||||
|
| 0 | 'Training Sequence Code (TSC) 0' as in 3GPP TS 45.002
|
||||||
|
| 1 | 'Training Sequence Code (TSC) 1'
|
||||||
|
| 2 | 'Training Sequence Code (TSC) 2'
|
||||||
|
| 3 | 'Training Sequence Code (TSC) 3'
|
||||||
|
| 4 | 'Training Sequence Code (TSC) 4'
|
||||||
|
| 5 | 'Training Sequence Code (TSC) 5'
|
||||||
|
| 6 | 'Training Sequence Code (TSC) 6'
|
||||||
|
| 7 | 'Training Sequence Code (TSC) 7'
|
||||||
|
| 8..255 | reserved values
|
||||||
|
|===
|
||||||
|
|
||||||
=== A-bis RSL Initialization / BTS bring-up
|
=== A-bis RSL Initialization / BTS bring-up
|
||||||
|
|
||||||
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
|
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
|
||||||
@@ -977,4 +1109,3 @@ The initialization of the primary and secondary TRX slightly differ, as
|
|||||||
illustrated by the differences of <<rsl-msc-pri>> and <<rsl-msc-sec>>.
|
illustrated by the differences of <<rsl-msc-pri>> and <<rsl-msc-sec>>.
|
||||||
Since the secondary TRX has no BCCH, it does not (need to) receive any 'RSL
|
Since the secondary TRX has no BCCH, it does not (need to) receive any 'RSL
|
||||||
BCCH INFORMATION' messages from the BSC.
|
BCCH INFORMATION' messages from the BSC.
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ order to specify which PHY instance is allocated to this specific TRX.
|
|||||||
| common | abis_open() | Start of the A-bis connection to BSC
|
| common | abis_open() | Start of the A-bis connection to BSC
|
||||||
| common | phy_links_open() | Iterate over list of configured PHY links
|
| common | phy_links_open() | Iterate over list of configured PHY links
|
||||||
| bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links
|
| bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links
|
||||||
| common | write_pid_file() | Generate the pid file
|
| bts-specific | bts_model_phy_link_close() | Close each of the configured PHY links
|
||||||
| common | osmo_daemonize() | Fork as daemon in background (if configured)
|
| common | osmo_daemonize() | Fork as daemon in background (if configured)
|
||||||
| common | bts_main() | Run main loop until global variable quit >= 2
|
| common | bts_main() | Run main loop until global variable quit >= 2
|
||||||
|===
|
|===
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ current GSM frame number.
|
|||||||
GSM is a TDMA (time division multiple access) system on the radio
|
GSM is a TDMA (time division multiple access) system on the radio
|
||||||
interface. OsmoTRX is the "clock master" of that in the Osmocom
|
interface. OsmoTRX is the "clock master" of that in the Osmocom
|
||||||
implementation. It informs OsmoBTS of the current GSM frame
|
implementation. It informs OsmoBTS of the current GSM frame
|
||||||
number. However, as there is non-zero delays (UDP packet trnsmission
|
number. However, as there is non-zero delays (UDP packet transmission
|
||||||
delay, operating system scheduler delay on both OsmoTRX and OsmoBTS
|
delay, operating system scheduler delay on both OsmoTRX and OsmoBTS
|
||||||
side, ...), OsmoBTS must compensate for that delay by "advancing"
|
side, ...), OsmoBTS must compensate for that delay by "advancing"
|
||||||
the clock a certain amount of time.
|
the clock a certain amount of time.
|
||||||
@@ -266,12 +266,11 @@ underruns on the OsmoTRX side.
|
|||||||
|
|
||||||
The detailed value will depend on your underlying computer systems,
|
The detailed value will depend on your underlying computer systems,
|
||||||
operating system and related tuning parameters. Running OsmoTRX
|
operating system and related tuning parameters. Running OsmoTRX
|
||||||
on a remote host will inevitably require a higher fn-advance then
|
on a remote host will inevitably require a higher fn-advance than
|
||||||
running it on the same machine, where the UDP packetes are just passed
|
running it on the same machine, where the UDP packets are just passed
|
||||||
over the loopback device.
|
over the loopback device.
|
||||||
|
|
||||||
The default value for `fn-advance` is 20 (corresponding to 92
|
The default value for `fn-advance` is 2 (corresponding to 9.2 milliseconds).
|
||||||
milliseconds).
|
|
||||||
|
|
||||||
===== `osmotrx rts-advance <0-30>`
|
===== `osmotrx rts-advance <0-30>`
|
||||||
|
|
||||||
@@ -290,7 +289,7 @@ reported on L1SAP to higher layers will be computed as follows:
|
|||||||
|
|
||||||
N + fn-advance + rts-advance
|
N + fn-advance + rts-advance
|
||||||
|
|
||||||
The default value of `rts-advance` is 5 (corresponding to 23 milliseconds).
|
The default value of `rts-advance` is 3 (corresponding to 14 milliseconds).
|
||||||
Do not change this unless you have a good reason!
|
Do not change this unless you have a good reason!
|
||||||
|
|
||||||
===== `osmotrx rx-gain <0-50>`
|
===== `osmotrx rx-gain <0-50>`
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ The OsmoBTS executables (`osmo-bts-sysmo`, `osmo-bts-trx`,
|
|||||||
generic command line options:
|
generic command line options:
|
||||||
|
|
||||||
==== SYNOPSIS
|
==== SYNOPSIS
|
||||||
*osmo-bts-sysmo* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE' ] [-s] [-T] [-e 'LOGLEVEL'] [-r 'PRIO'] [-i 'GSMTAP-IP'] [-t <1-255>]
|
*osmo-bts-sysmo* [-h|-V] [-d 'DBGMASK'] [-D] [-c 'CONFIGFILE' ] [-s] [-T] [-e 'LOGLEVEL']
|
||||||
|
|
||||||
==== OPTIONS
|
==== OPTIONS
|
||||||
*-h, --help*::
|
*-h, --help*::
|
||||||
@@ -48,16 +48,6 @@ generic command line options:
|
|||||||
Set the global log level for logging to stderr. This has mostly
|
Set the global log level for logging to stderr. This has mostly
|
||||||
been deprecated by VTY based logging configuration, see
|
been deprecated by VTY based logging configuration, see
|
||||||
<<logging>> for further information.
|
<<logging>> for further information.
|
||||||
*-r, --realtime 'PRIO'*::
|
|
||||||
Enable use of the Linux kernel realtime priority scheduler with
|
|
||||||
the specified priority.
|
|
||||||
It is recommended you use this option on low-performance
|
|
||||||
embedded systems or systems that encounter high non-GSM/GPRS
|
|
||||||
load.
|
|
||||||
*-i, --gsmtap-ip 'GSMTAP-IP'*::
|
|
||||||
Specify the destination IP address for GSMTAP messages.
|
|
||||||
*-t, --trx-num <1-255>*::
|
|
||||||
Specify the number of TRX supported by this BTS.
|
|
||||||
|
|
||||||
There may be additional, hardware specific command line options by the
|
There may be additional, hardware specific command line options by the
|
||||||
different bts_model implementations.
|
different bts_model implementations.
|
||||||
@@ -118,11 +108,22 @@ them via UDP/IP. At that point, they can be captured with utilities like
|
|||||||
*tcpdump* or *tshark* for further analysis by the *wireshark* protocol
|
*tcpdump* or *tshark* for further analysis by the *wireshark* protocol
|
||||||
analyzer.
|
analyzer.
|
||||||
|
|
||||||
In order to activate this feature, you first need to make sure to start
|
In order to activate this feature, you first need to make sure to specify
|
||||||
OsmoBTS using the `-i` or `--gsmtap-ip` command line option, specifying
|
the remote address of _GSMTAP_ host in the configuration file. In most
|
||||||
the destination IP address for the GSMTAP messages. In most cases,
|
cases, using 127.0.0.1 for passing the messages over the loopback (`lo`)
|
||||||
using 127.0.0.1 for passing the messages over the loopback (`lo`) device
|
device will be sufficient:
|
||||||
will be sufficient.
|
|
||||||
|
.Example: Enabling GSMTAP Um-frame logging to localhost
|
||||||
|
----
|
||||||
|
bts 0
|
||||||
|
gsmtap-remote-host 127.0.0.1 <1>
|
||||||
|
----
|
||||||
|
<1> Destination address for _GSMTAP_ Um-frames
|
||||||
|
|
||||||
|
NOTE: Changing this parameter at run-time will not affect the existing
|
||||||
|
_GSMTAP_ connection, full program restart is required.
|
||||||
|
|
||||||
|
NOTE: Command line parameters `-i` and `--gsmtap-ip` have been deprecated.
|
||||||
|
|
||||||
OsmoBTS can selectively trace such messages by their L1 SAPI, for both
|
OsmoBTS can selectively trace such messages by their L1 SAPI, for both
|
||||||
Rx and Tx. For a complete list of L1 SAPI values, please refer to the
|
Rx and Tx. For a complete list of L1 SAPI values, please refer to the
|
||||||
@@ -137,8 +138,7 @@ node of the OsmoBTS VTY.
|
|||||||
OsmoBTS> enable
|
OsmoBTS> enable
|
||||||
OsmoBTS# configure terminal
|
OsmoBTS# configure terminal
|
||||||
OsmoBTS(config)# bts 0
|
OsmoBTS(config)# bts 0
|
||||||
OsmoBTS(bts)# trx 0
|
OsmoBTS(bts)# gsmtap-sapi sdcch
|
||||||
OsmoBTS(trx)# gsmtap-sapi sdcch
|
|
||||||
OsmoBTS(trx)# write <1>
|
OsmoBTS(trx)# write <1>
|
||||||
----
|
----
|
||||||
<1> the `write` command will make the configuration persistent in the
|
<1> the `write` command will make the configuration persistent in the
|
||||||
@@ -146,18 +146,37 @@ configuration file. This is not required if you wish to enable GSMTAP
|
|||||||
only in the current session of OsmoBTS.
|
only in the current session of OsmoBTS.
|
||||||
|
|
||||||
De-activation can be performed similarly by using the `no gsmtap-sapi
|
De-activation can be performed similarly by using the `no gsmtap-sapi
|
||||||
sdcch` command at the `trx` node of the OsmoBTS VTY.
|
sdcch` command at the `bts` node of the OsmoBTS VTY.
|
||||||
|
|
||||||
|
It may be useful to enable all SAPIs with a few exceptions, or vice versa
|
||||||
|
disable everything using one command. For this purpose, the VTY provides
|
||||||
|
`gsmtap-sapi enable-all` and `gsmtap-sapi disable-all` commands.
|
||||||
|
|
||||||
|
.Example: Enabling all SAPIs except PDTCH and PTCCH
|
||||||
|
----
|
||||||
|
bts 0
|
||||||
|
gsmtap-sapi enable-all <1>
|
||||||
|
no gsmtap-sapi pdtch <2>
|
||||||
|
no gsmtap-sapi ptcch <2>
|
||||||
|
----
|
||||||
|
<1> Enable all available SAPIs
|
||||||
|
<2> Exclude PDTCH and PTCCH SAPIs
|
||||||
|
|
||||||
From the moment they are enabled via VTY, GSMTAP messages will be
|
From the moment they are enabled via VTY, GSMTAP messages will be
|
||||||
generated and sent in UDP encapsulation to the IANA-registered UDP port
|
generated and sent in UDP encapsulation to the IANA-registered UDP port
|
||||||
for GSMTAP (4729) at the IP address specified in the command line
|
for GSMTAP (4729) of the specified remote address.
|
||||||
argument.
|
|
||||||
|
|
||||||
==== Configuring power ramping
|
==== Configuring power ramping
|
||||||
|
|
||||||
OsmoBTS can ramp up the power of its trx over time. This helps reduce
|
OsmoBTS can ramp up the power of its trx over time. This helps reduce
|
||||||
cell congestion in busy environments.
|
cell congestion in busy environments.
|
||||||
|
|
||||||
|
Some models of OsmoBTS (such as osmo-bts-trx) also support ramping down the
|
||||||
|
transmit power over time until finally ceasing broadcast, for instance due to a
|
||||||
|
trx becoming administratively locked or due to the whole BTS being gracefully
|
||||||
|
shut down. This allows for mobile stations camping on the cell to gradually move
|
||||||
|
to other cells in the area once the signal drop is detected.
|
||||||
|
|
||||||
In this example, the trx starts with 5dBm output power which increases by 1dB
|
In this example, the trx starts with 5dBm output power which increases by 1dB
|
||||||
every two seconds until it reaches nominal power.
|
every two seconds until it reaches nominal power.
|
||||||
Power ramping can use the power-ramp commands at the CONFIG TRX node of the
|
Power ramping can use the power-ramp commands at the CONFIG TRX node of the
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ See <<vty>> for further information.
|
|||||||
|
|
||||||
=== OsmoBTS Control Interface
|
=== OsmoBTS Control Interface
|
||||||
|
|
||||||
The general structure of the Omsocom control interface is described in
|
The general structure of the Osmocom control interface is described in
|
||||||
<<common-control-if>>.
|
<<common-control-if>>.
|
||||||
|
|
||||||
The number of control interface commands/attributes is currently quite
|
The number of control interface commands/attributes is currently quite
|
||||||
|
|||||||
39
doc/manuals/chapters/osmux_bts.adoc
Normal file
39
doc/manuals/chapters/osmux_bts.adoc
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
include::{commondir}/chapters/osmux/osmux.adoc[]
|
||||||
|
|
||||||
|
=== Osmux Support in {program-name}
|
||||||
|
|
||||||
|
Osmux usage in {program-name} in managed through the VTY commands in node
|
||||||
|
`osmux`. Command `use (on|off|only)` is used to configure use policy of Osmux
|
||||||
|
within {program-name}. Once enabled (`on` or `only`), {program-name} will
|
||||||
|
announce the _OSMUX_ BTS feature towards the BSC over OML. This way, the BSC
|
||||||
|
becomes aware that this BTS supports using Osmux to transfer voice call user
|
||||||
|
data when the AMR codec is selected.
|
||||||
|
|
||||||
|
It is then up to the BSC to decide whether to use Osmux or not when establishing
|
||||||
|
a new call. If the BSC decides to use Osmux for a given call, then the _IPACC
|
||||||
|
CRCX/MDCX_ messages sent by the BSC will contain an extra _Osmux CID_ IE
|
||||||
|
appended, which contains the Osmux CID to be used by the BTS to send Osmux
|
||||||
|
frames to the co-located BSC MGW (aka the BSC MGW' local CID, or {program-name}'
|
||||||
|
remote CID). The IP address and port provided in the same messages refer to the
|
||||||
|
address and port where Osmux frames with the provided CID are expected to be
|
||||||
|
received. Similarly, {program-name} appends an _Osmux CID_ IE to the _IPACC
|
||||||
|
CRCX/MDCX ACK_ message it generates, this time with its own local Osmux CID.
|
||||||
|
Same goes for the BTS' local IP address and port where Osmux frames are expected
|
||||||
|
to be received.
|
||||||
|
|
||||||
|
{program-name} will behave differently during call set up based on the VTY
|
||||||
|
command `use (on|off|only)` presented above:
|
||||||
|
|
||||||
|
* `off`: If _IPACC CRCX_ from BSC contains _Osmux CID_ IE, meaning
|
||||||
|
BSC wants to use Osmux for this call, then {program-name} will reject the
|
||||||
|
request and the call set up will fail.
|
||||||
|
* `on`: {program-name} will support and accept both Osmux and non-Osmux (RTP)
|
||||||
|
upon call set up. If _IPACC CRCX_ from BSC contains the _Osmux CID_ IE on a
|
||||||
|
AMR call (`Channel Mode GSM3`), it will set up an Osmux stream on its end and
|
||||||
|
provide the BSC with the BTS-local CID. If the BSC provides no _Osmux CID_ IE,
|
||||||
|
then {program-name} will set up a regular RTP based call.
|
||||||
|
* `only`: Same as per `on`, except that {program-name} will accept only Osmux
|
||||||
|
calls on the CN-side, this is, if _IPACC CRCX_ from BSC doesn't
|
||||||
|
contain an _Osmux CID_ IE, it will reject the assignment and the call set up
|
||||||
|
will fail. This means also that only AMR calls (`Channel Mode GSM3`) are
|
||||||
|
allowed.
|
||||||
50
doc/manuals/chapters/qos-example.adoc
Normal file
50
doc/manuals/chapters/qos-example.adoc
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
==== Full example of QoS for osmo-bts uplink QoS
|
||||||
|
|
||||||
|
In the below example we will show the full set of configuration required
|
||||||
|
for both DSCP and PCP differentiation of uplink Abis traffic by osmo-bts.
|
||||||
|
|
||||||
|
What we want to achieve in this example is the following configuration:
|
||||||
|
|
||||||
|
.DSCP and PCP assignments for osmo-bts uplink traffic in this example
|
||||||
|
[options="header",width="30%",cols="2,1,1"]
|
||||||
|
|===
|
||||||
|
|Traffic |DSCP|PCP
|
||||||
|
|A-bis RSL | 56| 7
|
||||||
|
|A-bis RTP | 46| 6
|
||||||
|
|A-bis OML | 34| 5
|
||||||
|
|===
|
||||||
|
|
||||||
|
. configure the osmocom program to set the DSCP value
|
||||||
|
. configure an egrees QoS map to map from priority to PCP
|
||||||
|
|
||||||
|
.Example Step 1: add related VTY configuration to `osmo-bts.cfg`
|
||||||
|
----
|
||||||
|
...
|
||||||
|
e1_input
|
||||||
|
ipa ip-dscp oml 34
|
||||||
|
ipa socket-priority oml 5
|
||||||
|
ipa ip-dscp rsl 56
|
||||||
|
ipa socket-priority rsl 7
|
||||||
|
...
|
||||||
|
bts 0
|
||||||
|
rtp ip-dscp 46
|
||||||
|
rtp socket-priority 6
|
||||||
|
...
|
||||||
|
----
|
||||||
|
|
||||||
|
.Example Step 2: egress QoS map to map from socket priority to PCP values
|
||||||
|
----
|
||||||
|
$ sudo ip link set dev eth0.9<1> type vlan egress-qos-map 0:0 1:1 5:5 6:6 7:7 <2>
|
||||||
|
----
|
||||||
|
<1> make sure to specify your specific VLAN interface name here instead of `eth0.9`.
|
||||||
|
<2> create a egress QoS map that maps the priority value 1:1 to the PCP. We also include the
|
||||||
|
mapping 1:1 from the osmo-pcu example (see <<userman-osmopcu>>) here.
|
||||||
|
|
||||||
|
NOTE:: The settings of the `ip` command are volatile and only active until
|
||||||
|
the next reboot (or the network device or VLAN is removed). Please refer to
|
||||||
|
the documentation of your specific Linux distribution in order to find out how
|
||||||
|
to make such settings persistent by means of an `ifup` hook whenever the interface
|
||||||
|
comes up. For CentOS/RHEL 8 this can e.g. be achieved by means of an `/sbin/ifup-local
|
||||||
|
script` (when using `network-scripts` and not NetworkManager). For Debian or Ubuntu,
|
||||||
|
this typically involves adding `up` lines to `/etc/network/interfaces` or a `/etc/network/if-up.d`
|
||||||
|
script.
|
||||||
@@ -1,39 +1,3 @@
|
|||||||
<revhistory>
|
|
||||||
<revision>
|
|
||||||
<revnumber>1</revnumber>
|
|
||||||
<date>December 2015</date>
|
|
||||||
<authorinitials>NJH, HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Initial version, reflecting OsmoBTS master branch as on 2015-Dec-7
|
|
||||||
(commit e28a20a2d9d049cd6312e218a7646593bbc43431).
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
<revision>
|
|
||||||
<revnumber>2</revnumber>
|
|
||||||
<date>February 2016</date>
|
|
||||||
<authorinitials>HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Updated version with Message Sequence Chart of OML and RSL bring-up.
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
<revision>
|
|
||||||
<revnumber>2.1</revnumber>
|
|
||||||
<date>February 2016</date>
|
|
||||||
<authorinitials>HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Fix A-bis OML/RSL port number swap in message seqeuence charts.
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
<revision>
|
|
||||||
<revnumber>2.2</revnumber>
|
|
||||||
<date>July 2016</date>
|
|
||||||
<authorinitials>NJH, HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Add description on Dynamic Channel Configuration in OML and activation in RSL.
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
|
|
||||||
</revhistory>
|
|
||||||
|
|
||||||
<authorgroup>
|
<authorgroup>
|
||||||
<author>
|
<author>
|
||||||
@@ -61,7 +25,7 @@
|
|||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2015-2016</year>
|
<year>2015-2021</year>
|
||||||
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ include::{srcdir}/abis/rtp.adoc[]
|
|||||||
|
|
||||||
include::./common/chapters/port_numbers.adoc[]
|
include::./common/chapters/port_numbers.adoc[]
|
||||||
|
|
||||||
|
include::./common/chapters/bibliography.adoc[]
|
||||||
|
|
||||||
include::./common/chapters/glossary.adoc[]
|
include::./common/chapters/glossary.adoc[]
|
||||||
|
|
||||||
include::./common/chapters/gfdl.adoc[]
|
include::./common/chapters/gfdl.adoc[]
|
||||||
|
|||||||
@@ -1,14 +1,3 @@
|
|||||||
<revhistory>
|
|
||||||
<revision>
|
|
||||||
<revnumber>1</revnumber>
|
|
||||||
<date>January 2016</date>
|
|
||||||
<authorinitials>HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Initial version, reflecting OsmoBTS master branch as on FIXME
|
|
||||||
(commit FIXME).
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
</revhistory>
|
|
||||||
|
|
||||||
<authorgroup>
|
<authorgroup>
|
||||||
<author>
|
<author>
|
||||||
@@ -25,7 +14,7 @@
|
|||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2016</year>
|
<year>2016-2021</year>
|
||||||
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
:gfdl-enabled:
|
:gfdl-enabled:
|
||||||
|
:program-name: OsmoBTS
|
||||||
|
|
||||||
OsmoBTS User Manual
|
OsmoBTS User Manual
|
||||||
===================
|
===================
|
||||||
@@ -30,6 +31,12 @@ include::{srcdir}/chapters/bts-models.adoc[]
|
|||||||
|
|
||||||
include::{srcdir}/chapters/architecture.adoc[]
|
include::{srcdir}/chapters/architecture.adoc[]
|
||||||
|
|
||||||
|
include::{srcdir}/chapters/osmux_bts.adoc[]
|
||||||
|
|
||||||
|
include::./common/chapters/qos-dscp-pcp.adoc[]
|
||||||
|
|
||||||
|
include::./common/chapters/vty_cpu_sched.adoc[]
|
||||||
|
|
||||||
include::./common/chapters/trx_if.adoc[]
|
include::./common/chapters/trx_if.adoc[]
|
||||||
|
|
||||||
include::./common/chapters/control_if.adoc[]
|
include::./common/chapters/control_if.adoc[]
|
||||||
|
|||||||
@@ -1,29 +1,3 @@
|
|||||||
<revhistory>
|
|
||||||
<revision>
|
|
||||||
<revnumber>1</revnumber>
|
|
||||||
<date>October 2016</date>
|
|
||||||
<authorinitials>HW</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Initial version
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
<revision>
|
|
||||||
<revnumber>2</revnumber>
|
|
||||||
<date>November 2016</date>
|
|
||||||
<authorinitials>MS</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
FSM added
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
<revision>
|
|
||||||
<revnumber>3</revnumber>
|
|
||||||
<date>July 2017</date>
|
|
||||||
<authorinitials>PE</authorinitials>
|
|
||||||
<revremark>
|
|
||||||
Add section and update sequence charts to describe requirement to receive all PH-DATA.ind events
|
|
||||||
</revremark>
|
|
||||||
</revision>
|
|
||||||
</revhistory>
|
|
||||||
|
|
||||||
<authorgroup>
|
<authorgroup>
|
||||||
<author>
|
<author>
|
||||||
@@ -51,7 +25,7 @@
|
|||||||
</authorgroup>
|
</authorgroup>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2016</year>
|
<year>2016-2021</year>
|
||||||
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
<holder>sysmocom - s.f.m.c. GmbH</holder>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
|
|||||||
37
doc/manuals/vty/Makefile.vty-reference.inc
Normal file
37
doc/manuals/vty/Makefile.vty-reference.inc
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
DOCBOOKS = $(foreach v,$(VARIANTS),vty/osmobts-$(v)-vty-reference.xml)
|
||||||
|
DOCBOOKS_DEPS = $(DOCBOOKS) $(addsuffix .inc,$(DOCBOOKS))
|
||||||
|
INC_DIR = $(abspath $(builddir)/vty)
|
||||||
|
|
||||||
|
include $(OSMO_GSM_MANUALS_DIR)/build/Makefile.docbook.inc
|
||||||
|
|
||||||
|
CLEAN_FILES += $(DOCBOOKS_DEPS)
|
||||||
|
CLEAN_FILES += $(addsuffix .inc.gen,$(DOCBOOKS))
|
||||||
|
CLEAN_FILES += $(addsuffix .inc.merged,$(DOCBOOKS))
|
||||||
|
|
||||||
|
$(INC_DIR):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
vty/osmobts-%-vty-reference.xml: $(top_srcdir)/src/osmo-bts-% $(INC_DIR)
|
||||||
|
sed -e "s|@@GENERATED@@|$@.inc|" \
|
||||||
|
-e "s|@@VARIANT@@|$(notdir $<)|" \
|
||||||
|
-e "s|@@REV_NUMBER@@|$(VERSION)|" \
|
||||||
|
-e "s|@@REV_DATE@@|$(shell date +"%dth %B %Y")|" \
|
||||||
|
-e "s|@@CR_YEAR@@|$(shell date +"%Y")|" \
|
||||||
|
$(srcdir)/vty/osmobts-vty-reference.xml > $@
|
||||||
|
|
||||||
|
vty/osmobts-%-vty-reference.xml.inc: $(top_builddir)/src/osmo-bts-*/osmo-bts-% \
|
||||||
|
$(OSMO_GSM_MANUALS_DIR)/common/vty_additions.xml \
|
||||||
|
$(OSMO_GSM_MANUALS_DIR)/common/chapters/vty.xml \
|
||||||
|
$(OSMO_GSM_MANUALS_DIR)/vty_reference.xsl \
|
||||||
|
$(srcdir)/vty/*.xml $(INC_DIR)
|
||||||
|
# a) Invoke osmo-bts-% to generate the list of commands first
|
||||||
|
$< --vty-ref-mode default --vty-ref-xml > "$@.gen"
|
||||||
|
# ... filter garbage potentially printed by libraries to stdout
|
||||||
|
sed -i '/^<vtydoc/,$$!d' "$@.gen"
|
||||||
|
# b) Merge the result of a) with global and local additions
|
||||||
|
$(OSMO_GSM_MANUALS_DIR)/build/vty_reference_combine.sh \
|
||||||
|
$(realpath $(OSMO_GSM_MANUALS_DIR)/merge_doc.xsl) "$@.gen" \
|
||||||
|
$(OSMO_GSM_MANUALS_DIR)/common/vty_additions.xml \
|
||||||
|
$(srcdir)/vty/*additions*.xml > "$@.merged"
|
||||||
|
# c) Convert the result of b) into a valid docbook
|
||||||
|
xsltproc $(OSMO_GSM_MANUALS_DIR)/vty_reference.xsl "$@.merged" > $@
|
||||||
@@ -1 +1,26 @@
|
|||||||
<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'/>
|
<!-- ex:ts=2:sw=2:et -->
|
||||||
|
<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'>
|
||||||
|
<node id='phy-inst'>
|
||||||
|
<!-- FIXME: This command appears twice for some reason. -->
|
||||||
|
<command id='osmotrx maxdly <0-63>'>
|
||||||
|
<description>
|
||||||
|
Access Burst is the first burst a mobile transmits in order to establish a connection and it
|
||||||
|
is used to estimate Timing Advance (TA) which is then applied to Normal Bursts to compensate
|
||||||
|
for signal delay due to distance. So changing this setting effectively changes maximum range
|
||||||
|
of the cell, because Access Bursts with a delay higher than this value will be ignored.
|
||||||
|
</description>
|
||||||
|
</command>
|
||||||
|
<!-- FIXME: This command appears unconditionally, despite being hidden. -->
|
||||||
|
<command id='osmotrx maxdlynb <0-63>'>
|
||||||
|
<description>
|
||||||
|
USE FOR TESTING ONLY, DO NOT CHANGE IN PRODUCTION USE!
|
||||||
|
During the normal operation, delay of Normal Bursts is controlled by the Timing Advance loop
|
||||||
|
and thus Normal Bursts arrive to a BTS with no more than a couple GSM symbols, which is
|
||||||
|
already taken into account in osmo-trx. Changing this setting will have no effect in
|
||||||
|
production installations except increasing osmo-trx CPU load. This setting is only useful
|
||||||
|
when testing with a transmitter which cannot precisely synchronize to the BTS downlink
|
||||||
|
signal, like R&S CMD57.
|
||||||
|
</description>
|
||||||
|
</command>
|
||||||
|
</node>
|
||||||
|
</vtydoc>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,24 +6,25 @@
|
|||||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML 5.0//EN"
|
||||||
"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
|
"http://docbook.org/xml/5.0/dtd/docbook.dtd" [
|
||||||
<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
|
<!ENTITY chapter-vty SYSTEM "./common/chapters/vty.xml" >
|
||||||
<!ENTITY sections-vty SYSTEM "generated/docbook_vty.xml" >
|
<!ENTITY sections-vty SYSTEM "@@GENERATED@@" >
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<book>
|
<book>
|
||||||
<info>
|
<info>
|
||||||
<revhistory>
|
<revhistory>
|
||||||
<revision>
|
<revision>
|
||||||
<revnumber>v1</revnumber>
|
<revnumber>v2</revnumber>
|
||||||
<date>13th October 2016</date>
|
<date>@@REV_DATE@@</date>
|
||||||
<authorinitials>hw</authorinitials>
|
<authorinitials>s.f.m.c.</authorinitials>
|
||||||
<revremark>Initial</revremark>
|
<revremark>Automatic build (@@REV_NUMBER@@)</revremark>
|
||||||
</revision>
|
</revision>
|
||||||
</revhistory>
|
</revhistory>
|
||||||
|
|
||||||
<title>OsmoBTS VTY Reference</title>
|
<title>OsmoBTS VTY Reference</title>
|
||||||
|
<subtitle>@@VARIANT@@</subtitle>
|
||||||
|
|
||||||
<copyright>
|
<copyright>
|
||||||
<year>2016</year>
|
<year>@@CR_YEAR@@</year>
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
<legalnotice>
|
<legalnotice>
|
||||||
@@ -27,7 +27,6 @@ The start-up procedure of OsmoBTS can be described as follows:
|
|||||||
| common | abis_open() | Start of the A-bis connection to BSC
|
| common | abis_open() | Start of the A-bis connection to BSC
|
||||||
| common | phy_links_open() | Iterate over list of configured PHY links
|
| common | phy_links_open() | Iterate over list of configured PHY links
|
||||||
| bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links
|
| bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links
|
||||||
| common | write_pid_file() | Generate the pid file
|
|
||||||
| common | osmo_daemonize() | Fork as daemon in background (if configured)
|
| common | osmo_daemonize() | Fork as daemon in background (if configured)
|
||||||
| common | bts_main() | Run main loop until global variable quit >= 2
|
| common | bts_main() | Run main loop until global variable quit >= 2
|
||||||
| bts-specific | bts_model_oml_estab() | Called by core once OML link is established
|
| bts-specific | bts_model_oml_estab() | Called by core once OML link is established
|
||||||
|
|||||||
@@ -1,5 +1,34 @@
|
|||||||
noinst_HEADERS = abis.h bts.h bts_model.h gsm_data.h gsm_data_shared.h logging.h measurement.h \
|
noinst_HEADERS = \
|
||||||
oml.h paging.h rsl.h signal.h vty.h amr.h pcu_if.h pcuif_proto.h \
|
abis.h \
|
||||||
handover.h msg_utils.h tx_power.h control_if.h cbch.h l1sap.h \
|
abis_osmo.h \
|
||||||
power_control.h scheduler.h scheduler_backend.h phy_link.h \
|
bts.h \
|
||||||
dtx_dl_amr_fsm.h ta_control.h
|
bts_model.h \
|
||||||
|
bts_shutdown_fsm.h \
|
||||||
|
bts_trx.h \
|
||||||
|
gsm_data.h \
|
||||||
|
logging.h \
|
||||||
|
measurement.h \
|
||||||
|
oml.h \
|
||||||
|
paging.h \
|
||||||
|
rsl.h \
|
||||||
|
signal.h \
|
||||||
|
vty.h \
|
||||||
|
amr.h \
|
||||||
|
pcu_if.h \
|
||||||
|
pcuif_proto.h \
|
||||||
|
handover.h \
|
||||||
|
msg_utils.h \
|
||||||
|
tx_power.h \
|
||||||
|
control_if.h \
|
||||||
|
cbch.h \
|
||||||
|
l1sap.h \
|
||||||
|
lchan.h \
|
||||||
|
power_control.h \
|
||||||
|
scheduler.h \
|
||||||
|
scheduler_backend.h \
|
||||||
|
phy_link.h \
|
||||||
|
dtx_dl_amr_fsm.h \
|
||||||
|
ta_control.h \
|
||||||
|
nm_common_fsm.h \
|
||||||
|
osmux.h \
|
||||||
|
$(NULL)
|
||||||
|
|||||||
@@ -6,19 +6,15 @@
|
|||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
#define OML_RETRY_TIMER 5
|
enum abis_link_fsm_event {
|
||||||
#define OML_PING_TIMER 20
|
ABIS_LINK_EV_SIGN_LINK_OML_UP,
|
||||||
|
ABIS_LINK_EV_SIGN_LINK_DOWN,
|
||||||
enum {
|
ABIS_LINK_EV_VTY_RM_ADDR, /* data: struct bsc_oml_host* being removed */
|
||||||
LINK_STATE_IDLE = 0,
|
|
||||||
LINK_STATE_RETRYING,
|
|
||||||
LINK_STATE_CONNECTING,
|
|
||||||
LINK_STATE_CONNECT,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void abis_init(struct gsm_bts *bts);
|
void abis_init(struct gsm_bts *bts);
|
||||||
struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host,
|
int abis_open(struct gsm_bts *bts, char *model_name);
|
||||||
char *model_name);
|
|
||||||
|
|
||||||
|
|
||||||
int abis_oml_sendmsg(struct msgb *msg);
|
int abis_oml_sendmsg(struct msgb *msg);
|
||||||
|
|||||||
10
include/osmo-bts/abis_osmo.h
Normal file
10
include/osmo-bts/abis_osmo.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/msgb.h>
|
||||||
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
|
||||||
|
struct gsm_bts;
|
||||||
|
|
||||||
|
int down_osmo(struct gsm_bts *bts, struct msgb *msg);
|
||||||
|
|
||||||
|
int abis_osmo_pcu_tx_container(struct gsm_bts *bts, const struct gsm_pcu_if_container *container);
|
||||||
@@ -14,5 +14,6 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
|
|||||||
void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc,
|
void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc,
|
||||||
uint8_t cmi, uint8_t cmr);
|
uint8_t cmi, uint8_t cmr);
|
||||||
unsigned int amr_get_initial_mode(struct gsm_lchan *lchan);
|
unsigned int amr_get_initial_mode(struct gsm_lchan *lchan);
|
||||||
|
void amr_init_mr_conf_def(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
#endif /* _OSMO_BTS_AMR_H */
|
#endif /* _OSMO_BTS_AMR_H */
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
#define _BTS_H
|
#define _BTS_H
|
||||||
|
|
||||||
#include <osmocom/core/rate_ctr.h>
|
#include <osmocom/core/rate_ctr.h>
|
||||||
|
#include <osmocom/core/socket.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
#include <osmo-bts/osmux.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct gsm_bts_trx;
|
||||||
|
|
||||||
enum bts_global_status {
|
enum bts_global_status {
|
||||||
BTS_STATUS_RF_ACTIVE,
|
BTS_STATUS_RF_ACTIVE,
|
||||||
@@ -13,7 +19,9 @@ enum bts_global_status {
|
|||||||
enum {
|
enum {
|
||||||
BTS_CTR_PAGING_RCVD,
|
BTS_CTR_PAGING_RCVD,
|
||||||
BTS_CTR_PAGING_DROP,
|
BTS_CTR_PAGING_DROP,
|
||||||
|
BTS_CTR_PAGING_DROP_PS,
|
||||||
BTS_CTR_PAGING_SENT,
|
BTS_CTR_PAGING_SENT,
|
||||||
|
BTS_CTR_PAGING_CONG,
|
||||||
BTS_CTR_RACH_RCVD,
|
BTS_CTR_RACH_RCVD,
|
||||||
BTS_CTR_RACH_DROP,
|
BTS_CTR_RACH_DROP,
|
||||||
BTS_CTR_RACH_HO,
|
BTS_CTR_RACH_HO,
|
||||||
@@ -24,40 +32,403 @@ enum {
|
|||||||
BTS_CTR_AGCH_DELETED,
|
BTS_CTR_AGCH_DELETED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Used by OML layer for BTS Attribute reporting */
|
||||||
|
enum bts_attribute {
|
||||||
|
BTS_TYPE_VARIANT,
|
||||||
|
BTS_SUB_MODEL,
|
||||||
|
TRX_PHY_VERSION,
|
||||||
|
};
|
||||||
|
const char *btsatttr2str(enum bts_attribute v);
|
||||||
|
|
||||||
|
enum gsm_bts_type_variant {
|
||||||
|
BTS_UNKNOWN,
|
||||||
|
BTS_OSMO_LITECELL15,
|
||||||
|
BTS_OSMO_OC2G,
|
||||||
|
BTS_OSMO_OCTPHY,
|
||||||
|
BTS_OSMO_SYSMO,
|
||||||
|
BTS_OSMO_TRX,
|
||||||
|
BTS_OSMO_VIRTUAL,
|
||||||
|
BTS_OSMO_OMLDUMMY,
|
||||||
|
_NUM_BTS_VARIANT
|
||||||
|
};
|
||||||
|
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
||||||
|
|
||||||
|
/* TODO: add a brief description of this flag */
|
||||||
|
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
|
||||||
|
/* When this flag is set then the measurement data is included in
|
||||||
|
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
||||||
|
* measurement data is passed using a separate MPH INFO MEAS IND.
|
||||||
|
* (See also ticket: OS#2977) */
|
||||||
|
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
|
||||||
|
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
||||||
|
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
||||||
|
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2)
|
||||||
|
/* Whether the BTS model reports interference measurements to L1SAP. */
|
||||||
|
#define BTS_INTERNAL_FLAG_INTERF_MEAS (1 << 3)
|
||||||
|
|
||||||
|
/* BTS implementation flags (internal use, not exposed via OML) */
|
||||||
|
#define bts_internal_flag_get(bts, flag) \
|
||||||
|
((bts->flags & (typeof(bts->flags)) flag) != 0)
|
||||||
|
#define bts_internal_flag_set(bts, flag) \
|
||||||
|
bts->flags |= (typeof(bts->flags)) flag
|
||||||
|
|
||||||
|
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;
|
||||||
|
uint16_t nsvci;
|
||||||
|
struct osmo_sockaddr local; /* on the BTS */
|
||||||
|
struct osmo_sockaddr remote; /* on the SGSN */
|
||||||
|
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gprs_rlc_cfg {
|
||||||
|
uint16_t parameter[_NUM_RLC_PAR];
|
||||||
|
struct {
|
||||||
|
uint16_t repeat_time; /* ms */
|
||||||
|
uint8_t repeat_count;
|
||||||
|
} paging;
|
||||||
|
uint32_t cs_mask; /* bitmask of gprs_cs */
|
||||||
|
uint8_t initial_cs;
|
||||||
|
uint8_t initial_mcs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bts_smscb_state {
|
||||||
|
struct llist_head queue; /* list of struct smscb_msg */
|
||||||
|
int queue_len;
|
||||||
|
struct rate_ctr_group *ctrs;
|
||||||
|
struct smscb_msg *cur_msg; /* current SMS-CB */
|
||||||
|
struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Tx power filtering algorithm */
|
||||||
|
enum bts_pf_algo {
|
||||||
|
BTS_PF_ALGO_NONE = 0,
|
||||||
|
BTS_PF_ALGO_EWMA,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* UL/DL power control parameters */
|
||||||
|
struct bts_power_ctrl_params {
|
||||||
|
/* Target value to strive to */
|
||||||
|
int target_dbm;
|
||||||
|
/* Tolerated deviation from target */
|
||||||
|
int hysteresis_db;
|
||||||
|
/* How many dB do we raise power at maximum */
|
||||||
|
int raise_step_max_db;
|
||||||
|
/* How many dB do we lower power at maximum */
|
||||||
|
int lower_step_max_db;
|
||||||
|
/* RxLev filtering algorithm */
|
||||||
|
enum bts_pf_algo pf_algo;
|
||||||
|
/* (Optional) filtering parameters */
|
||||||
|
union {
|
||||||
|
/* Exponentially Weighted Moving Average */
|
||||||
|
struct {
|
||||||
|
/* Smoothing factor: higher the value - less smoothing */
|
||||||
|
uint8_t alpha; /* 1 .. 99 (in %) */
|
||||||
|
} ewma;
|
||||||
|
} pf;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* BTS Site Manager */
|
||||||
|
struct gsm_bts_sm {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Struct that holds one OML-Address (Address of the BSC) */
|
||||||
|
struct bsc_oml_host {
|
||||||
|
struct llist_head list;
|
||||||
|
char *addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* One BTS */
|
||||||
|
struct gsm_bts {
|
||||||
|
/* list header in net->bts_list */
|
||||||
|
struct llist_head list;
|
||||||
|
|
||||||
|
/* number of the BTS in network */
|
||||||
|
uint8_t nr;
|
||||||
|
/* human readable name / description */
|
||||||
|
char *description;
|
||||||
|
/* Cell Identity */
|
||||||
|
uint16_t cell_identity;
|
||||||
|
/* location area code of this BTS */
|
||||||
|
uint16_t location_area_code;
|
||||||
|
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
||||||
|
* which is used as TSC for the CCCH */
|
||||||
|
uint8_t bsic;
|
||||||
|
/* type of BTS */
|
||||||
|
enum gsm_bts_type_variant variant;
|
||||||
|
enum gsm_band band;
|
||||||
|
char version[MAX_VERSION_LENGTH];
|
||||||
|
char sub_model[MAX_VERSION_LENGTH];
|
||||||
|
|
||||||
|
/* public features of a given BTS (set/reported via OML) */
|
||||||
|
struct bitvec *features;
|
||||||
|
/* implementation flags of a given BTS (not exposed via OML) */
|
||||||
|
uint16_t flags;
|
||||||
|
|
||||||
|
/* Connected PCU version (if any) */
|
||||||
|
char pcu_version[MAX_VERSION_LENGTH];
|
||||||
|
|
||||||
|
/* maximum Tx power that the MS is permitted to use in this cell */
|
||||||
|
int ms_max_power;
|
||||||
|
|
||||||
|
/* how do we talk OML with this TRX? */
|
||||||
|
struct e1inp_sign_link *oml_link;
|
||||||
|
struct timespec oml_conn_established_timestamp;
|
||||||
|
/* OSMO extenion link associated to same line as oml_link: */
|
||||||
|
struct e1inp_sign_link *osmo_link;
|
||||||
|
|
||||||
|
/* Abis network management O&M handle */
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
|
||||||
|
/* number of this BTS on given E1 link */
|
||||||
|
uint8_t bts_nr;
|
||||||
|
|
||||||
|
/* DTX features of this BTS */
|
||||||
|
bool dtxd;
|
||||||
|
|
||||||
|
/* CCCH is on C0 */
|
||||||
|
struct gsm_bts_trx *c0;
|
||||||
|
|
||||||
|
struct gsm_bts_sm site_mgr;
|
||||||
|
|
||||||
|
/* bitmask of all SI that are present/valid in si_buf */
|
||||||
|
uint32_t si_valid;
|
||||||
|
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
||||||
|
uint8_t si2q_index; /* distinguish individual SI2quater messages */
|
||||||
|
uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
|
||||||
|
/* buffers where we put the pre-computed SI */
|
||||||
|
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
||||||
|
/* offsets used while generating SI2quater */
|
||||||
|
size_t e_offset;
|
||||||
|
size_t u_offset;
|
||||||
|
/* decoded SI rest octets - *unmodified* as received from BSC */
|
||||||
|
struct osmo_gsm48_si_ro_info si3_ro_decoded;
|
||||||
|
struct osmo_gsm48_si_ro_info si4_ro_decoded;
|
||||||
|
/* is SI GPRS Indicator currently disabled due to lack of PCU connection? */
|
||||||
|
bool si_gprs_ind_disabled;
|
||||||
|
|
||||||
|
/* ip.access Unit ID's have Site/BTS/TRX layout */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint16_t site_id;
|
||||||
|
uint16_t bts_id;
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t rsl_ip;
|
||||||
|
} ip_access;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Not entirely sure how ip.access specific this is */
|
||||||
|
struct {
|
||||||
|
struct {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
uint16_t nsei;
|
||||||
|
uint8_t timer[7];
|
||||||
|
} nse;
|
||||||
|
struct {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
uint16_t bvci;
|
||||||
|
uint8_t timer[11];
|
||||||
|
struct gprs_rlc_cfg rlc_cfg;
|
||||||
|
} cell;
|
||||||
|
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||||
|
uint8_t rac;
|
||||||
|
} gprs;
|
||||||
|
|
||||||
|
/* transceivers */
|
||||||
|
int num_trx;
|
||||||
|
struct llist_head trx_list;
|
||||||
|
|
||||||
|
struct rate_ctr_group *ctrs;
|
||||||
|
bool supp_meas_toa256;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
/* Interference Boundaries for OML */
|
||||||
|
int16_t boundary[6];
|
||||||
|
uint8_t intave;
|
||||||
|
} interference;
|
||||||
|
unsigned int t200_ms[7];
|
||||||
|
unsigned int t3105_ms;
|
||||||
|
struct {
|
||||||
|
uint8_t overload_period;
|
||||||
|
struct {
|
||||||
|
/* Input parameters from OML */
|
||||||
|
uint8_t load_ind_thresh; /* percent */
|
||||||
|
uint8_t load_ind_period; /* seconds */
|
||||||
|
/* Internal data */
|
||||||
|
struct osmo_timer_list timer;
|
||||||
|
unsigned int pch_total;
|
||||||
|
unsigned int pch_used;
|
||||||
|
} ccch;
|
||||||
|
struct {
|
||||||
|
/* Input parameters from OML */
|
||||||
|
int16_t busy_thresh; /* in dBm */
|
||||||
|
uint16_t averaging_slots;
|
||||||
|
/* Internal data */
|
||||||
|
unsigned int total; /* total nr */
|
||||||
|
unsigned int busy; /* above busy_thresh */
|
||||||
|
unsigned int access; /* access bursts */
|
||||||
|
} rach;
|
||||||
|
} load;
|
||||||
|
uint8_t ny1;
|
||||||
|
uint8_t max_ta;
|
||||||
|
|
||||||
|
/* AGCH queuing */
|
||||||
|
struct {
|
||||||
|
struct llist_head queue;
|
||||||
|
int length;
|
||||||
|
int max_length;
|
||||||
|
|
||||||
|
int thresh_level; /* Cleanup threshold in percent of max len */
|
||||||
|
int low_level; /* Low water mark in percent of max len */
|
||||||
|
int high_level; /* High water mark in percent of max len */
|
||||||
|
|
||||||
|
/* TODO: Use a rate counter group instead */
|
||||||
|
uint64_t dropped_msgs;
|
||||||
|
uint64_t merged_msgs;
|
||||||
|
uint64_t rejected_msgs;
|
||||||
|
uint64_t agch_msgs;
|
||||||
|
uint64_t pch_msgs;
|
||||||
|
} agch_queue;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t *prim_notif; /* ETWS primary notification (NULL if none) */
|
||||||
|
ssize_t prim_notif_len; /* Length of prim_notif; expected 56 bytes */
|
||||||
|
uint8_t page_size;
|
||||||
|
uint8_t num_pages; /* total number of pages */
|
||||||
|
uint8_t next_page; /* next page number to be sent */
|
||||||
|
bool pni; /* Primary Notification Identifier */
|
||||||
|
} etws;
|
||||||
|
|
||||||
|
struct paging_state *paging_state;
|
||||||
|
struct llist_head bsc_oml_hosts;
|
||||||
|
unsigned int rtp_jitter_buf_ms;
|
||||||
|
bool rtp_jitter_adaptive;
|
||||||
|
|
||||||
|
uint16_t rtp_port_range_start;
|
||||||
|
uint16_t rtp_port_range_end;
|
||||||
|
uint16_t rtp_port_range_next;
|
||||||
|
int rtp_ip_dscp;
|
||||||
|
int rtp_priority;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
||||||
|
} support;
|
||||||
|
struct {
|
||||||
|
uint8_t tc4_ctr;
|
||||||
|
} si;
|
||||||
|
struct gsm_time gsm_time;
|
||||||
|
/* frame number statistics (FN in PH-RTS.ind vs. PH-DATA.ind */
|
||||||
|
struct {
|
||||||
|
int32_t min; /* minimum observed */
|
||||||
|
int32_t max; /* maximum observed */
|
||||||
|
int32_t avg256; /* accumulator */
|
||||||
|
uint32_t avg_count; /* number of samples accumulated in avg256 */
|
||||||
|
uint32_t avg_window; /* number of averages in avg_count */
|
||||||
|
} fn_stats;
|
||||||
|
/* Radio Link Timeout counter. -1 disables timeout for
|
||||||
|
* lab/measurement purpose */
|
||||||
|
struct {
|
||||||
|
int oml; /* value communicated by BSC in OML */
|
||||||
|
int current; /* actual currently applied value */
|
||||||
|
bool vty_override; /* OML value overridden by VTY */
|
||||||
|
} radio_link_timeout;
|
||||||
|
|
||||||
|
/* Default (fall-back) Dynamic Power Control parameters for all transceivers */
|
||||||
|
struct gsm_power_ctrl_params bs_dpc_params; /* BS Dynamic Power Control */
|
||||||
|
struct gsm_power_ctrl_params ms_dpc_params; /* MS Dynamic Power Control */
|
||||||
|
|
||||||
|
/* Maximum BCCH carrier power reduction */
|
||||||
|
uint8_t c0_power_red_db;
|
||||||
|
|
||||||
|
/* used by the sysmoBTS to adjust band */
|
||||||
|
uint8_t auto_band;
|
||||||
|
|
||||||
|
/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
|
||||||
|
struct bts_smscb_state smscb_basic;
|
||||||
|
struct bts_smscb_state smscb_extended;
|
||||||
|
int smscb_queue_tgt_len; /* ideal/target queue length */
|
||||||
|
int smscb_queue_max_len; /* maximum queue length */
|
||||||
|
int smscb_queue_hyst; /* hysteresis for CBCH load indications */
|
||||||
|
|
||||||
|
int16_t min_qual_rach; /* minimum link quality (in centiBels) for Access Bursts */
|
||||||
|
int16_t min_qual_norm; /* minimum link quality (in centiBels) for Normal Bursts */
|
||||||
|
uint16_t max_ber10k_rach; /* Maximum permitted RACH BER in 0.01% */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
char *sock_path;
|
||||||
|
} pcu;
|
||||||
|
|
||||||
|
/* GSMTAP Um logging (disabled by default) */
|
||||||
|
struct {
|
||||||
|
struct gsmtap_inst *inst;
|
||||||
|
char *remote_host;
|
||||||
|
uint32_t sapi_mask;
|
||||||
|
uint8_t sapi_acch;
|
||||||
|
} gsmtap;
|
||||||
|
|
||||||
|
struct osmux_state osmux;
|
||||||
|
|
||||||
|
struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
|
||||||
|
bool shutdown_fi_exit_proc; /* exit process when shutdown_fsm is finished? */
|
||||||
|
bool shutdown_fi_skip_power_ramp; /* Skip power ramping and change power in one step? */
|
||||||
|
struct osmo_fsm_inst *abis_link_fi; /* FSM instance to manage abis connection during process startup and link failure */
|
||||||
|
struct osmo_tdef *T_defs; /* Timer defines */
|
||||||
|
|
||||||
|
void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct value_string bts_impl_flag_desc[];
|
||||||
extern void *tall_bts_ctx;
|
extern void *tall_bts_ctx;
|
||||||
|
|
||||||
|
#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
|
||||||
|
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
|
||||||
|
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
||||||
|
|
||||||
|
static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
|
||||||
|
return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
|
||||||
|
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);
|
||||||
|
|
||||||
int bts_init(struct gsm_bts *bts);
|
int bts_init(struct gsm_bts *bts);
|
||||||
int bts_trx_init(struct gsm_bts_trx *trx);
|
|
||||||
void bts_shutdown(struct gsm_bts *bts, const char *reason);
|
void bts_shutdown(struct gsm_bts *bts, const char *reason);
|
||||||
|
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp);
|
||||||
|
|
||||||
int bts_link_estab(struct gsm_bts *bts);
|
int bts_link_estab(struct gsm_bts *bts);
|
||||||
int trx_link_estab(struct gsm_bts_trx *trx);
|
|
||||||
int trx_set_available(struct gsm_bts_trx *trx, int avail);
|
|
||||||
|
|
||||||
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg);
|
int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg);
|
||||||
struct msgb *bts_agch_dequeue(struct gsm_bts *bts);
|
struct msgb *bts_agch_dequeue(struct gsm_bts *bts);
|
||||||
int bts_agch_max_queue_length(int T, int bcch_conf);
|
int bts_agch_max_queue_length(int T, int bcch_conf);
|
||||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
|
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
|
||||||
int is_ag_res);
|
int is_ag_res);
|
||||||
|
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
|
||||||
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
|
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
|
||||||
void regenerate_si3_restoctets(struct gsm_bts *bts);
|
void regenerate_si3_restoctets(struct gsm_bts *bts);
|
||||||
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
|
void regenerate_si4_restoctets(struct gsm_bts *bts);
|
||||||
int lchan_init_lapdm(struct gsm_lchan *lchan);
|
int get_si4_ro_offset(const uint8_t *si4_buf);
|
||||||
|
|
||||||
void load_timer_start(struct gsm_bts *bts);
|
void load_timer_start(struct gsm_bts *bts);
|
||||||
uint8_t num_agch(struct gsm_bts_trx *trx, const char * arg);
|
void load_timer_stop(struct gsm_bts *bts);
|
||||||
|
bool load_timer_is_running(const struct gsm_bts *bts);
|
||||||
void bts_update_status(enum bts_global_status which, int on);
|
void bts_update_status(enum bts_global_status which, int on);
|
||||||
|
|
||||||
bool trx_ms_pwr_ctrl_is_osmo(struct gsm_bts_trx *trx);
|
|
||||||
|
|
||||||
struct gsm_time *get_time(struct gsm_bts *bts);
|
struct gsm_time *get_time(struct gsm_bts *bts);
|
||||||
|
|
||||||
int bts_main(int argc, char **argv);
|
int bts_main(int argc, char **argv);
|
||||||
|
|
||||||
int bts_supports_cm(struct gsm_bts *bts, enum gsm_phys_chan_config pchan,
|
int bts_supports_cm(const struct gsm_bts *bts,
|
||||||
enum gsm48_chan_mode cm);
|
const struct rsl_ie_chan_mode *cm);
|
||||||
|
|
||||||
int32_t bts_get_avg_fn_advance(struct gsm_bts *bts);
|
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
|
||||||
|
|
||||||
|
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
||||||
|
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
|
||||||
|
|
||||||
|
int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red);
|
||||||
|
|
||||||
#endif /* _BTS_H */
|
#endif /* _BTS_H */
|
||||||
|
|||||||
@@ -30,17 +30,20 @@ int bts_model_chg_adm_state(struct gsm_bts *bts, struct gsm_abis_mo *mo,
|
|||||||
void *obj, uint8_t adm_state);
|
void *obj, uint8_t adm_state);
|
||||||
|
|
||||||
int bts_model_trx_deact_rf(struct gsm_bts_trx *trx);
|
int bts_model_trx_deact_rf(struct gsm_bts_trx *trx);
|
||||||
int bts_model_trx_close(struct gsm_bts_trx *trx);
|
|
||||||
|
|
||||||
int bts_model_vty_init(struct gsm_bts *bts);
|
/* Implementation should call bts_model_trx_close_cb when done */
|
||||||
|
void bts_model_trx_close(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
void bts_model_config_write_bts(struct vty *vty, struct gsm_bts *bts);
|
int bts_model_vty_init(void *ctx);
|
||||||
void bts_model_config_write_trx(struct vty *vty, struct gsm_bts_trx *trx);
|
|
||||||
void bts_model_config_write_phy(struct vty *vty, struct phy_link *plink);
|
void bts_model_config_write_bts(struct vty *vty, const struct gsm_bts *bts);
|
||||||
void bts_model_config_write_phy_inst(struct vty *vty, struct phy_instance *pinst);
|
void bts_model_config_write_trx(struct vty *vty, const struct gsm_bts_trx *trx);
|
||||||
|
void bts_model_config_write_phy(struct vty *vty, const struct phy_link *plink);
|
||||||
|
void bts_model_config_write_phy_inst(struct vty *vty, const struct phy_instance *pinst);
|
||||||
|
|
||||||
int bts_model_oml_estab(struct gsm_bts *bts);
|
int bts_model_oml_estab(struct gsm_bts *bts);
|
||||||
|
|
||||||
|
/* Implementation should call power_trx_change_compl() to confirm power change applied */
|
||||||
int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm);
|
int bts_model_change_power(struct gsm_bts_trx *trx, int p_trxout_mdBm);
|
||||||
int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan);
|
int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
@@ -62,4 +65,10 @@ void bts_model_phy_instance_set_defaults(struct phy_instance *pinst);
|
|||||||
int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts);
|
int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts);
|
||||||
void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan);
|
void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan);
|
||||||
|
|
||||||
|
/* BTS model specific implementations are expected to call these functions as a
|
||||||
|
* response to some of the APIs above:
|
||||||
|
*/
|
||||||
|
|
||||||
|
void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
43
include/osmo-bts/bts_shutdown_fsm.h
Normal file
43
include/osmo-bts/bts_shutdown_fsm.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* BTS shutdown FSM */
|
||||||
|
|
||||||
|
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
|
enum bts_shutdown_fsm_states {
|
||||||
|
BTS_SHUTDOWN_ST_NONE,
|
||||||
|
BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL,
|
||||||
|
BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED,
|
||||||
|
BTS_SHUTDOWN_ST_EXIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum bts_shutdown_fsm_events {
|
||||||
|
BTS_SHUTDOWN_EV_START,
|
||||||
|
BTS_SHUTDOWN_EV_TRX_RAMP_COMPL,
|
||||||
|
BTS_SHUTDOWN_EV_TRX_CLOSED,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct osmo_fsm bts_shutdown_fsm;
|
||||||
|
|
||||||
|
struct gsm_bts;
|
||||||
|
bool bts_shutdown_in_progress(const struct gsm_bts *bts);
|
||||||
63
include/osmo-bts/bts_trx.h
Normal file
63
include/osmo-bts/bts_trx.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
|
struct gsm_bts_bb_trx {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* One TRX in a BTS */
|
||||||
|
struct gsm_bts_trx {
|
||||||
|
/* list header in bts->trx_list */
|
||||||
|
struct llist_head list;
|
||||||
|
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
/* number of this TRX in the BTS */
|
||||||
|
uint8_t nr;
|
||||||
|
/* human readable name / description */
|
||||||
|
char *description;
|
||||||
|
/* how do we talk RSL with this TRX? */
|
||||||
|
uint8_t rsl_tei;
|
||||||
|
struct e1inp_sign_link *rsl_link;
|
||||||
|
|
||||||
|
/* NM Radio Carrier and Baseband Transciever */
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
struct gsm_bts_bb_trx bb_transc;
|
||||||
|
|
||||||
|
uint16_t arfcn;
|
||||||
|
int nominal_power; /* in dBm */
|
||||||
|
unsigned int max_power_red; /* in actual dB */
|
||||||
|
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
||||||
|
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
||||||
|
|
||||||
|
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
|
||||||
|
|
||||||
|
struct trx_power_params power_params;
|
||||||
|
struct gsm_power_ctrl_params *bs_dpc_params; /* BS Dynamic Power Control */
|
||||||
|
struct gsm_power_ctrl_params *ms_dpc_params; /* MS Dynamic Power Control */
|
||||||
|
bool ms_pwr_ctl_soft; /* is power control loop done by osmocom software? */
|
||||||
|
|
||||||
|
/* The associated PHY instance */
|
||||||
|
struct phy_instance *pinst;
|
||||||
|
|
||||||
|
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct gsm_bts_trx *gsm_bts_bb_trx_get_trx(struct gsm_bts_bb_trx *bb_transc) {
|
||||||
|
return (struct gsm_bts_trx *)container_of(bb_transc, struct gsm_bts_trx, bb_transc);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
||||||
|
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
|
||||||
|
void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx);
|
||||||
|
void gsm_bts_trx_free_shadow_ts(struct gsm_bts_trx *trx);
|
||||||
|
char *gsm_trx_name(const struct gsm_bts_trx *trx);
|
||||||
|
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
|
int trx_link_estab(struct gsm_bts_trx *trx);
|
||||||
|
void trx_operability_update(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
|
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
|
||||||
|
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
|
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)
|
||||||
@@ -21,3 +21,5 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ
|
|||||||
/* call-back from bts model specific code when it wants to obtain a CBCH
|
/* call-back from bts model specific code when it wants to obtain a CBCH
|
||||||
* block for a given gsm_time. outbuf must have 23 bytes of space. */
|
* block for a given gsm_time. outbuf must have 23 bytes of space. */
|
||||||
int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time);
|
int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time);
|
||||||
|
|
||||||
|
void bts_cbch_reset(struct gsm_bts *bts);
|
||||||
|
|||||||
@@ -1,13 +1,33 @@
|
|||||||
#ifndef _GSM_DATA_H
|
#ifndef _GSM_DATA_H
|
||||||
#define _GSM_DATA_H
|
#define _GSM_DATA_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/core/bitvec.h>
|
||||||
|
#include <osmocom/core/statistics.h>
|
||||||
|
#include <osmocom/core/utils.h>
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
#include <osmocom/gsm/lapdm.h>
|
#include <osmocom/core/tdef.h>
|
||||||
#include <osmocom/gsm/gsm23003.h>
|
#include <osmocom/gsm/gsm23003.h>
|
||||||
|
#include <osmocom/gsm/gsm0502.h>
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/tlv.h>
|
||||||
|
#include <osmocom/gsm/rxlev_stat.h>
|
||||||
|
#include <osmocom/gsm/sysinfo.h>
|
||||||
|
#include <osmocom/gsm/bts_features.h>
|
||||||
|
#include <osmocom/gsm/gsm48_rest_octets.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
|
|
||||||
|
#include <osmocom/abis/e1_input.h>
|
||||||
|
|
||||||
#include <osmo-bts/paging.h>
|
#include <osmo-bts/paging.h>
|
||||||
#include <osmo-bts/tx_power.h>
|
#include <osmo-bts/tx_power.h>
|
||||||
|
#include <osmo-bts/oml.h>
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
|
||||||
#define GSM_FR_BITS 260
|
#define GSM_FR_BITS 260
|
||||||
#define GSM_EFR_BITS 244
|
#define GSM_EFR_BITS 244
|
||||||
@@ -16,16 +36,11 @@
|
|||||||
#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */
|
#define GSM_HR_BYTES 14 /* TS 101318 Chapter 5.2: 112 bits, no sig */
|
||||||
#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
|
#define GSM_EFR_BYTES 31 /* TS 101318 Chapter 5.3: 244 bits + 4bit sig */
|
||||||
|
|
||||||
#define GSM_SUPERFRAME (26*51) /* 1326 TDMA frames */
|
|
||||||
#define GSM_HYPERFRAME (2048*GSM_SUPERFRAME) /* GSM_HYPERFRAME frames */
|
|
||||||
|
|
||||||
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41
|
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DEFAULT 41
|
||||||
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
|
#define GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE 999999
|
||||||
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
|
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
|
||||||
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
|
#define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91
|
||||||
|
|
||||||
#define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args)
|
|
||||||
|
|
||||||
struct gsm_network {
|
struct gsm_network {
|
||||||
struct llist_head bts_list;
|
struct llist_head bts_list;
|
||||||
unsigned int num_bts;
|
unsigned int num_bts;
|
||||||
@@ -33,28 +48,151 @@ struct gsm_network {
|
|||||||
struct pcu_sock_state *pcu_state;
|
struct pcu_sock_state *pcu_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lchan_ciph_state {
|
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
|
||||||
LCHAN_CIPH_NONE,
|
4-bit index is used (2#1111 = 10#15) */
|
||||||
LCHAN_CIPH_RX_REQ,
|
#define SI2Q_MAX_NUM 16
|
||||||
LCHAN_CIPH_RX_CONF,
|
/* length in bits (for single SI2quater message) */
|
||||||
LCHAN_CIPH_RXTX_REQ,
|
#define SI2Q_MAX_LEN 160
|
||||||
LCHAN_CIPH_RX_CONF_TX_REQ,
|
#define SI2Q_MIN_LEN 18
|
||||||
LCHAN_CIPH_RXTX_CONF,
|
|
||||||
|
/* lchans 0..3 are SDCCH in combined channel configuration,
|
||||||
|
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||||
|
#define CCCH_LCHAN 4
|
||||||
|
|
||||||
|
#define TRX_NR_TS 8
|
||||||
|
#define TS_MAX_LCHAN 8
|
||||||
|
|
||||||
|
#define MAX_VERSION_LENGTH 64
|
||||||
|
|
||||||
|
enum gsm_bts_trx_ts_flags {
|
||||||
|
TS_F_PDCH_ACTIVE = 0x1000,
|
||||||
|
TS_F_PDCH_ACT_PENDING = 0x2000,
|
||||||
|
TS_F_PDCH_DEACT_PENDING = 0x4000,
|
||||||
|
TS_F_PDCH_PENDING_MASK = 0x6000 /*<
|
||||||
|
TS_F_PDCH_ACT_PENDING | TS_F_PDCH_DEACT_PENDING */
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <osmo-bts/gsm_data_shared.h>
|
/* One Timeslot in a TRX */
|
||||||
|
struct gsm_bts_trx_ts {
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
/* number of this timeslot at the TRX */
|
||||||
|
uint8_t nr;
|
||||||
|
|
||||||
|
enum gsm_phys_chan_config pchan;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
enum gsm_phys_chan_config pchan_is;
|
||||||
|
enum gsm_phys_chan_config pchan_want;
|
||||||
|
} dyn;
|
||||||
|
|
||||||
|
unsigned int flags;
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
|
||||||
|
/* Training Sequence Code (range 0..7) */
|
||||||
|
uint8_t tsc_oml; /* configured via OML */
|
||||||
|
uint8_t tsc; /* currently in use */
|
||||||
|
/* Training Sequence Set (range 0..3) */
|
||||||
|
uint8_t tsc_set;
|
||||||
|
|
||||||
|
/* Actual BCCH carrier power reduction */
|
||||||
|
uint8_t c0_power_red_db;
|
||||||
|
|
||||||
|
/* Frequency hopping parameters (configured via OML) */
|
||||||
|
struct {
|
||||||
|
bool enabled;
|
||||||
|
uint8_t maio;
|
||||||
|
uint8_t hsn;
|
||||||
|
uint16_t arfcn_list[64];
|
||||||
|
uint8_t arfcn_num;
|
||||||
|
} hopping;
|
||||||
|
|
||||||
|
/* Transceiver "cache" for frequency hopping */
|
||||||
|
const struct gsm_bts_trx *fh_trx_list[64];
|
||||||
|
|
||||||
|
/* Implementation specific structure(s) */
|
||||||
|
void *priv;
|
||||||
|
|
||||||
|
/* VAMOS specific fields */
|
||||||
|
struct {
|
||||||
|
/* NULL if BTS_FEAT_VAMOS is not set */
|
||||||
|
struct gsm_bts_trx_ts *peer;
|
||||||
|
bool is_shadow;
|
||||||
|
} vamos;
|
||||||
|
|
||||||
|
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum gprs_rlc_par {
|
||||||
|
RLC_T3142,
|
||||||
|
RLC_T3169,
|
||||||
|
RLC_T3191,
|
||||||
|
RLC_T3193,
|
||||||
|
RLC_T3195,
|
||||||
|
RLC_N3101,
|
||||||
|
RLC_N3103,
|
||||||
|
RLC_N3105,
|
||||||
|
CV_COUNTDOWN,
|
||||||
|
T_DL_TBF_EXT, /* ms */
|
||||||
|
T_UL_TBF_EXT, /* ms */
|
||||||
|
_NUM_RLC_PAR
|
||||||
|
};
|
||||||
|
|
||||||
|
enum gprs_cs {
|
||||||
|
GPRS_CS1,
|
||||||
|
GPRS_CS2,
|
||||||
|
GPRS_CS3,
|
||||||
|
GPRS_CS4,
|
||||||
|
GPRS_MCS1,
|
||||||
|
GPRS_MCS2,
|
||||||
|
GPRS_MCS3,
|
||||||
|
GPRS_MCS4,
|
||||||
|
GPRS_MCS5,
|
||||||
|
GPRS_MCS6,
|
||||||
|
GPRS_MCS7,
|
||||||
|
GPRS_MCS8,
|
||||||
|
GPRS_MCS9,
|
||||||
|
_NUM_GRPS_CS
|
||||||
|
};
|
||||||
|
|
||||||
|
/* The amount of time within which a sudden disconnect of a newly established
|
||||||
|
* OML connection will cause a special warning to be logged. */
|
||||||
|
#define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10 /* in seconds */
|
||||||
|
|
||||||
|
extern struct osmo_tdef_group bts_tdef_groups[];
|
||||||
|
extern struct osmo_tdef bts_T_defs[];
|
||||||
|
extern struct osmo_tdef abis_T_defs[];
|
||||||
|
|
||||||
|
extern const struct value_string gsm_pchant_names[13];
|
||||||
|
extern const struct value_string gsm_pchant_descs[13];
|
||||||
|
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
||||||
|
const char *gsm_lchant_name(enum gsm_chan_t c);
|
||||||
|
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
||||||
|
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
|
#define GSM_TS_NAME_FMT \
|
||||||
|
"bts=%u,trx=%u,ts=%u" "%s"
|
||||||
|
#define GSM_TS_NAME_ARGS(ts) \
|
||||||
|
(ts)->trx->bts->nr, (ts)->trx->nr, (ts)->nr, \
|
||||||
|
(ts)->vamos.is_shadow ? ",shadow" : ""
|
||||||
|
|
||||||
|
#define BSIC2BCC(bsic) ((bsic) & 0x07)
|
||||||
|
#define BTS_TSC(bts) BSIC2BCC((bts)->bsic)
|
||||||
|
|
||||||
|
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
||||||
|
int *rc);
|
||||||
|
|
||||||
|
enum gsm_phys_chan_config ts_pchan(const struct gsm_bts_trx_ts *ts);
|
||||||
|
uint8_t ts_subslots(const struct gsm_bts_trx_ts *ts);
|
||||||
|
bool ts_is_tch(const struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state);
|
|
||||||
int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
|
int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
|
||||||
enum gsm_phys_chan_config pchan);
|
enum gsm_phys_chan_config pchan);
|
||||||
|
|
||||||
/* cipher code */
|
/* cipher code */
|
||||||
#define CIPHER_A5(x) (1 << (x-1))
|
#define CIPHER_A5(x) (1 << (x-1))
|
||||||
|
|
||||||
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
|
|
||||||
|
|
||||||
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
|
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
int bts_model_check_cm_mode(enum gsm_phys_chan_config pchan, enum gsm48_chan_mode cm);
|
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
#endif /* _GSM_DATA_H */
|
#endif /* _GSM_DATA_H */
|
||||||
|
|||||||
@@ -1,877 +0,0 @@
|
|||||||
#ifndef _GSM_DATA_SHAREDH
|
|
||||||
#define _GSM_DATA_SHAREDH
|
|
||||||
|
|
||||||
#include <regex.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include <osmocom/codec/ecu.h>
|
|
||||||
#include <osmocom/core/timer.h>
|
|
||||||
#include <osmocom/core/bitvec.h>
|
|
||||||
#include <osmocom/core/statistics.h>
|
|
||||||
#include <osmocom/core/utils.h>
|
|
||||||
#include <osmocom/gsm/gsm_utils.h>
|
|
||||||
#include <osmocom/gsm/tlv.h>
|
|
||||||
#include <osmocom/gsm/rxlev_stat.h>
|
|
||||||
#include <osmocom/gsm/sysinfo.h>
|
|
||||||
#include <osmocom/gsm/meas_rep.h>
|
|
||||||
#include <osmocom/gsm/gsm48_rest_octets.h>
|
|
||||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
|
||||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
|
||||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
|
||||||
|
|
||||||
#include <osmocom/abis/e1_input.h>
|
|
||||||
#include <osmocom/gsm/lapdm.h>
|
|
||||||
|
|
||||||
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
|
|
||||||
4-bit index is used (2#1111 = 10#15) */
|
|
||||||
#define SI2Q_MAX_NUM 16
|
|
||||||
/* length in bits (for single SI2quater message) */
|
|
||||||
#define SI2Q_MAX_LEN 160
|
|
||||||
#define SI2Q_MIN_LEN 18
|
|
||||||
|
|
||||||
/* Channel Request reason */
|
|
||||||
enum gsm_chreq_reason_t {
|
|
||||||
GSM_CHREQ_REASON_EMERG,
|
|
||||||
GSM_CHREQ_REASON_PAG,
|
|
||||||
GSM_CHREQ_REASON_CALL,
|
|
||||||
GSM_CHREQ_REASON_LOCATION_UPD,
|
|
||||||
GSM_CHREQ_REASON_OTHER,
|
|
||||||
GSM_CHREQ_REASON_PDCH,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* lchans 0..3 are SDCCH in combined channel configuration,
|
|
||||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
|
||||||
#define CCCH_LCHAN 4
|
|
||||||
|
|
||||||
#define TRX_NR_TS 8
|
|
||||||
#define TS_MAX_LCHAN 8
|
|
||||||
|
|
||||||
#define HARDCODED_ARFCN 123
|
|
||||||
#define HARDCODED_BSIC 0x3f /* NCC = 7 / BCC = 7 */
|
|
||||||
|
|
||||||
/* for multi-drop config */
|
|
||||||
#define HARDCODED_BTS0_TS 1
|
|
||||||
#define HARDCODED_BTS1_TS 6
|
|
||||||
#define HARDCODED_BTS2_TS 11
|
|
||||||
|
|
||||||
#define MAX_VERSION_LENGTH 64
|
|
||||||
|
|
||||||
#define MAX_BTS_FEATURES 128
|
|
||||||
|
|
||||||
enum gsm_hooks {
|
|
||||||
GSM_HOOK_NM_SWLOAD,
|
|
||||||
GSM_HOOK_RR_PAGING,
|
|
||||||
GSM_HOOK_RR_SECURITY,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bts_gprs_mode {
|
|
||||||
BTS_GPRS_NONE = 0,
|
|
||||||
BTS_GPRS_GPRS = 1,
|
|
||||||
BTS_GPRS_EGPRS = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gsm_lchan;
|
|
||||||
struct osmo_rtp_socket;
|
|
||||||
struct pcu_sock_state;
|
|
||||||
struct smscb_msg;
|
|
||||||
|
|
||||||
/* Network Management State */
|
|
||||||
struct gsm_nm_state {
|
|
||||||
uint8_t operational;
|
|
||||||
uint8_t administrative;
|
|
||||||
uint8_t availability;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gsm_abis_mo {
|
|
||||||
/* A-bis OML Object Class */
|
|
||||||
uint8_t obj_class;
|
|
||||||
/* is there still some procedure pending? */
|
|
||||||
uint8_t procedure_pending;
|
|
||||||
/* A-bis OML Object Instance */
|
|
||||||
struct abis_om_obj_inst obj_inst;
|
|
||||||
/* human-readable name */
|
|
||||||
const char *name;
|
|
||||||
/* NM State */
|
|
||||||
struct gsm_nm_state nm_state;
|
|
||||||
/* Attributes configured in this MO */
|
|
||||||
struct tlv_parsed *nm_attr;
|
|
||||||
/* BTS to which this MO belongs */
|
|
||||||
struct gsm_bts *bts;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MAX_A5_KEY_LEN (128/8)
|
|
||||||
#define A38_XOR_MIN_KEY_LEN 12
|
|
||||||
#define A38_XOR_MAX_KEY_LEN 16
|
|
||||||
#define A38_COMP128_KEY_LEN 16
|
|
||||||
#define RSL_ENC_ALG_A5(x) (x+1)
|
|
||||||
#define MAX_EARFCN_LIST 32
|
|
||||||
|
|
||||||
/* is the data link established? who established it? */
|
|
||||||
#define LCHAN_SAPI_UNUSED 0
|
|
||||||
#define LCHAN_SAPI_MS 1
|
|
||||||
#define LCHAN_SAPI_NET 2
|
|
||||||
#define LCHAN_SAPI_REL 3
|
|
||||||
|
|
||||||
/* state of a logical channel */
|
|
||||||
enum gsm_lchan_state {
|
|
||||||
LCHAN_S_NONE, /* channel is not active */
|
|
||||||
LCHAN_S_ACT_REQ, /* channel activation 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_BROKEN, /* channel is somehow unusable */
|
|
||||||
LCHAN_S_INACTIVE, /* channel is set inactive */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* BTS ONLY */
|
|
||||||
#define MAX_NUM_UL_MEAS 104
|
|
||||||
#define LC_UL_M_F_L1_VALID (1 << 0)
|
|
||||||
#define LC_UL_M_F_RES_VALID (1 << 1)
|
|
||||||
#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2)
|
|
||||||
|
|
||||||
struct bts_ul_meas {
|
|
||||||
/* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */
|
|
||||||
uint16_t ber10k;
|
|
||||||
/* timing advance offset (in 1/256 bits) */
|
|
||||||
int16_t ta_offs_256bits;
|
|
||||||
/* C/I ratio in dB */
|
|
||||||
float c_i;
|
|
||||||
/* flags */
|
|
||||||
uint8_t is_sub:1;
|
|
||||||
/* RSSI in dBm * -1 */
|
|
||||||
uint8_t inv_rssi;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bts_codec_conf {
|
|
||||||
uint8_t hr;
|
|
||||||
uint8_t efr;
|
|
||||||
uint8_t amr;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct amr_mode {
|
|
||||||
uint8_t mode;
|
|
||||||
uint8_t threshold;
|
|
||||||
uint8_t hysteresis;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct amr_multirate_conf {
|
|
||||||
uint8_t gsm48_ie[2];
|
|
||||||
struct amr_mode ms_mode[4];
|
|
||||||
struct amr_mode bts_mode[4];
|
|
||||||
uint8_t num_modes;
|
|
||||||
};
|
|
||||||
/* /BTS ONLY */
|
|
||||||
|
|
||||||
enum lchan_csd_mode {
|
|
||||||
LCHAN_CSD_M_NT,
|
|
||||||
LCHAN_CSD_M_T_1200_75,
|
|
||||||
LCHAN_CSD_M_T_600,
|
|
||||||
LCHAN_CSD_M_T_1200,
|
|
||||||
LCHAN_CSD_M_T_2400,
|
|
||||||
LCHAN_CSD_M_T_9600,
|
|
||||||
LCHAN_CSD_M_T_14400,
|
|
||||||
LCHAN_CSD_M_T_29000,
|
|
||||||
LCHAN_CSD_M_T_32000,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* State of the SAPIs in the lchan */
|
|
||||||
enum lchan_sapi_state {
|
|
||||||
LCHAN_SAPI_S_NONE,
|
|
||||||
LCHAN_SAPI_S_REQ,
|
|
||||||
LCHAN_SAPI_S_ASSIGNED,
|
|
||||||
LCHAN_SAPI_S_REL,
|
|
||||||
LCHAN_SAPI_S_ERROR,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gsm_lchan {
|
|
||||||
/* The TS that we're part of */
|
|
||||||
struct gsm_bts_trx_ts *ts;
|
|
||||||
/* The logical subslot number in the TS */
|
|
||||||
uint8_t nr;
|
|
||||||
/* The logical channel type */
|
|
||||||
enum gsm_chan_t type;
|
|
||||||
/* RSL channel mode */
|
|
||||||
enum rsl_cmod_spd rsl_cmode;
|
|
||||||
/* If TCH, traffic channel mode */
|
|
||||||
enum gsm48_chan_mode tch_mode;
|
|
||||||
enum lchan_csd_mode csd_mode;
|
|
||||||
/* State */
|
|
||||||
enum gsm_lchan_state state;
|
|
||||||
const char *broken_reason;
|
|
||||||
/* Encryption information */
|
|
||||||
struct {
|
|
||||||
uint8_t alg_id;
|
|
||||||
uint8_t key_len;
|
|
||||||
uint8_t key[MAX_A5_KEY_LEN];
|
|
||||||
} encr;
|
|
||||||
|
|
||||||
/* AMR bits */
|
|
||||||
uint8_t mr_bts_lv[7];
|
|
||||||
|
|
||||||
/* Established data link layer services */
|
|
||||||
int sacch_deact;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint32_t bound_ip;
|
|
||||||
uint32_t connect_ip;
|
|
||||||
uint16_t bound_port;
|
|
||||||
uint16_t connect_port;
|
|
||||||
uint16_t conn_id;
|
|
||||||
uint8_t rtp_payload;
|
|
||||||
uint8_t rtp_payload2;
|
|
||||||
uint8_t speech_mode;
|
|
||||||
struct osmo_rtp_socket *rtp_socket;
|
|
||||||
} abis_ip;
|
|
||||||
|
|
||||||
uint8_t rqd_ta;
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
/* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23.
|
|
||||||
* Currently we don't share these headers so this is a magic number. */
|
|
||||||
struct llist_head sapi_cmds;
|
|
||||||
uint8_t sapis_dl[23];
|
|
||||||
uint8_t sapis_ul[23];
|
|
||||||
struct lapdm_channel lapdm_ch;
|
|
||||||
struct llist_head dl_tch_queue;
|
|
||||||
struct {
|
|
||||||
/* bitmask of all SI that are present/valid in si_buf */
|
|
||||||
uint32_t valid;
|
|
||||||
/* bitmask of all SI that do not mirror the BTS-global SI values */
|
|
||||||
uint32_t overridden;
|
|
||||||
uint32_t last;
|
|
||||||
/* buffers where we put the pre-computed SI:
|
|
||||||
SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */
|
|
||||||
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
|
||||||
} si;
|
|
||||||
struct {
|
|
||||||
uint8_t flags;
|
|
||||||
/* RSL measurement result number, 0 at lchan_act */
|
|
||||||
uint8_t res_nr;
|
|
||||||
/* current Tx power level of the BTS */
|
|
||||||
uint8_t bts_tx_pwr;
|
|
||||||
/* number of measurements stored in array below */
|
|
||||||
uint8_t num_ul_meas;
|
|
||||||
struct bts_ul_meas uplink[MAX_NUM_UL_MEAS];
|
|
||||||
/* last L1 header from the MS */
|
|
||||||
uint8_t l1_info[2];
|
|
||||||
struct gsm_meas_rep_unidir ul_res;
|
|
||||||
int16_t ms_toa256;
|
|
||||||
/* Frame number of the last measurement indication receceived */
|
|
||||||
uint32_t last_fn;
|
|
||||||
/* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */
|
|
||||||
struct {
|
|
||||||
/* minimum value of toa256 during measurement period */
|
|
||||||
int16_t toa256_min;
|
|
||||||
/* maximum value of toa256 during measurement period */
|
|
||||||
int16_t toa256_max;
|
|
||||||
/* standard deviation of toa256 value during measurement period */
|
|
||||||
uint16_t toa256_std_dev;
|
|
||||||
} ext;
|
|
||||||
} meas;
|
|
||||||
struct {
|
|
||||||
struct amr_multirate_conf amr_mr;
|
|
||||||
struct {
|
|
||||||
struct osmo_fsm_inst *dl_amr_fsm;
|
|
||||||
/* TCH cache */
|
|
||||||
uint8_t cache[20];
|
|
||||||
/* FACCH cache */
|
|
||||||
uint8_t facch[GSM_MACBLOCK_LEN];
|
|
||||||
uint8_t len;
|
|
||||||
uint32_t fn;
|
|
||||||
bool is_update;
|
|
||||||
/* set for each SID frame to detect talkspurt for codecs
|
|
||||||
without explicit ONSET event */
|
|
||||||
bool ul_sid;
|
|
||||||
/* indicates if DTXd was active during DL measurement
|
|
||||||
period */
|
|
||||||
bool dl_active;
|
|
||||||
/* last UL SPEECH resume flag */
|
|
||||||
bool is_speech_resume;
|
|
||||||
} dtx;
|
|
||||||
uint8_t last_cmr;
|
|
||||||
uint32_t last_fn;
|
|
||||||
} tch;
|
|
||||||
|
|
||||||
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
|
||||||
int16_t ms_t_offs;
|
|
||||||
/* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */
|
|
||||||
int16_t p_offs;
|
|
||||||
|
|
||||||
/* BTS-side ciphering state (rx only, bi-directional, ...) */
|
|
||||||
uint8_t ciph_state;
|
|
||||||
uint8_t ciph_ns;
|
|
||||||
uint8_t loopback;
|
|
||||||
struct {
|
|
||||||
uint8_t active;
|
|
||||||
uint8_t ref;
|
|
||||||
/* T3105: PHYS INF retransmission */
|
|
||||||
struct osmo_timer_list t3105;
|
|
||||||
/* counts up to Ny1 */
|
|
||||||
unsigned int phys_info_count;
|
|
||||||
} ho;
|
|
||||||
/* S counter for link loss */
|
|
||||||
int s;
|
|
||||||
/* Kind of the release/activation. E.g. RSL or PCU */
|
|
||||||
int rel_act_kind;
|
|
||||||
/* RTP header Marker bit to indicate beginning of speech after pause */
|
|
||||||
bool rtp_tx_marker;
|
|
||||||
/* power handling */
|
|
||||||
struct {
|
|
||||||
uint8_t current;
|
|
||||||
uint8_t max;
|
|
||||||
bool fixed;
|
|
||||||
} ms_power_ctrl;
|
|
||||||
/* Power levels for BTS */
|
|
||||||
uint8_t bs_power;
|
|
||||||
|
|
||||||
struct msgb *pending_rel_ind_msg;
|
|
||||||
|
|
||||||
/* ECU (Error Concealment Unit) state */
|
|
||||||
struct osmo_ecu_state *ecu_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint8_t lchan_get_ta(const struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
return lchan->meas.l1_info[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
extern const struct value_string lchan_ciph_state_names[];
|
|
||||||
static inline const char *lchan_ciph_state_name(uint8_t state) {
|
|
||||||
return get_value_string(lchan_ciph_state_names, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
TS_F_PDCH_ACTIVE = 0x1000,
|
|
||||||
TS_F_PDCH_ACT_PENDING = 0x2000,
|
|
||||||
TS_F_PDCH_DEACT_PENDING = 0x4000,
|
|
||||||
TS_F_PDCH_PENDING_MASK = 0x6000 /*<
|
|
||||||
TS_F_PDCH_ACT_PENDING | TS_F_PDCH_DEACT_PENDING */
|
|
||||||
} gsm_bts_trx_ts_flags;
|
|
||||||
|
|
||||||
/* One Timeslot in a TRX */
|
|
||||||
struct gsm_bts_trx_ts {
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
/* number of this timeslot at the TRX */
|
|
||||||
uint8_t nr;
|
|
||||||
|
|
||||||
enum gsm_phys_chan_config pchan;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
enum gsm_phys_chan_config pchan_is;
|
|
||||||
enum gsm_phys_chan_config pchan_want;
|
|
||||||
struct msgb *pending_chan_activ;
|
|
||||||
} dyn;
|
|
||||||
|
|
||||||
unsigned int flags;
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
struct tlv_parsed nm_attr;
|
|
||||||
uint8_t nm_chan_comb;
|
|
||||||
int tsc; /* -1 == use BTS TSC */
|
|
||||||
|
|
||||||
struct {
|
|
||||||
/* Parameters below are configured by VTY */
|
|
||||||
int enabled;
|
|
||||||
uint8_t maio;
|
|
||||||
uint8_t hsn;
|
|
||||||
struct bitvec arfcns;
|
|
||||||
uint8_t arfcns_data[1024/8];
|
|
||||||
/* This is the pre-computed MA for channel assignments */
|
|
||||||
struct bitvec ma;
|
|
||||||
uint8_t ma_len; /* part of ma_data that is used */
|
|
||||||
uint8_t ma_data[8]; /* 10.5.2.21: max 8 bytes value part */
|
|
||||||
} hopping;
|
|
||||||
|
|
||||||
struct gsm_lchan lchan[TS_MAX_LCHAN];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* One TRX in a BTS */
|
|
||||||
struct gsm_bts_trx {
|
|
||||||
/* list header in bts->trx_list */
|
|
||||||
struct llist_head list;
|
|
||||||
|
|
||||||
struct gsm_bts *bts;
|
|
||||||
/* number of this TRX in the BTS */
|
|
||||||
uint8_t nr;
|
|
||||||
/* human readable name / description */
|
|
||||||
char *description;
|
|
||||||
/* how do we talk RSL with this TRX? */
|
|
||||||
uint8_t rsl_tei;
|
|
||||||
struct e1inp_sign_link *rsl_link;
|
|
||||||
|
|
||||||
/* Some BTS (specifically Ericsson RBS) have a per-TRX OML Link */
|
|
||||||
struct e1inp_sign_link *oml_link;
|
|
||||||
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
struct tlv_parsed nm_attr;
|
|
||||||
struct {
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
} bb_transc;
|
|
||||||
|
|
||||||
uint16_t arfcn;
|
|
||||||
int nominal_power; /* in dBm */
|
|
||||||
unsigned int max_power_red; /* in actual dB */
|
|
||||||
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
|
||||||
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
|
||||||
|
|
||||||
|
|
||||||
struct trx_power_params power_params;
|
|
||||||
bool ms_pwr_ctl_soft; /* is power control loop done by osmocom software? */
|
|
||||||
|
|
||||||
struct {
|
|
||||||
void *l1h;
|
|
||||||
} role_bts;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned int test_state;
|
|
||||||
uint8_t test_nr;
|
|
||||||
struct rxlev_stats rxlev_stat;
|
|
||||||
} ipaccess;
|
|
||||||
};
|
|
||||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define GSM_BTS_SI2Q(bts, i) (struct gsm48_system_information_type_2quater *)((bts)->si_buf[SYSINFO_TYPE_2quater][i])
|
|
||||||
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
|
|
||||||
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
|
||||||
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
|
|
||||||
|
|
||||||
enum gsm_bts_type_variant {
|
|
||||||
BTS_UNKNOWN,
|
|
||||||
BTS_OSMO_LITECELL15,
|
|
||||||
BTS_OSMO_OC2G,
|
|
||||||
BTS_OSMO_OCTPHY,
|
|
||||||
BTS_OSMO_SYSMO,
|
|
||||||
BTS_OSMO_TRX,
|
|
||||||
BTS_OSMO_VIRTUAL,
|
|
||||||
BTS_OSMO_OMLDUMMY,
|
|
||||||
_NUM_BTS_VARIANT
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Used by OML layer for BTS Attribute reporting */
|
|
||||||
enum bts_attribute {
|
|
||||||
BTS_TYPE_VARIANT,
|
|
||||||
BTS_SUB_MODEL,
|
|
||||||
TRX_PHY_VERSION,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct vty;
|
|
||||||
|
|
||||||
/* N. B: always add new features to the end of the list (right before _NUM_BTS_FEAT) to avoid breaking compatibility
|
|
||||||
with BTS compiled against earlier version of this header. Also make sure that the description strings
|
|
||||||
gsm_bts_features_descs[] in gsm_data_shared.c are also updated accordingly! */
|
|
||||||
enum gsm_bts_features {
|
|
||||||
BTS_FEAT_HSCSD,
|
|
||||||
BTS_FEAT_GPRS,
|
|
||||||
BTS_FEAT_EGPRS,
|
|
||||||
BTS_FEAT_ECSD,
|
|
||||||
BTS_FEAT_HOPPING,
|
|
||||||
BTS_FEAT_MULTI_TSC,
|
|
||||||
BTS_FEAT_OML_ALERTS,
|
|
||||||
BTS_FEAT_AGCH_PCH_PROP,
|
|
||||||
BTS_FEAT_CBCH,
|
|
||||||
BTS_FEAT_SPEECH_F_V1,
|
|
||||||
BTS_FEAT_SPEECH_H_V1,
|
|
||||||
BTS_FEAT_SPEECH_F_EFR,
|
|
||||||
BTS_FEAT_SPEECH_F_AMR,
|
|
||||||
BTS_FEAT_SPEECH_H_AMR,
|
|
||||||
BTS_FEAT_ETWS_PN,
|
|
||||||
BTS_FEAT_MS_PWR_CTRL_DSP,
|
|
||||||
/* When the feature is set then the measurement data is included in
|
|
||||||
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
|
||||||
* measurement data is passed using a separate MPH INFO MEAS IND.
|
|
||||||
* (See also ticket: OS#2977) */
|
|
||||||
BTS_FEAT_MEAS_PAYLOAD_COMB,
|
|
||||||
_NUM_BTS_FEAT
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const struct value_string gsm_bts_features_descs[];
|
|
||||||
|
|
||||||
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;
|
|
||||||
uint16_t nsvci;
|
|
||||||
uint16_t local_port; /* on the BTS */
|
|
||||||
uint16_t remote_port; /* on the SGSN */
|
|
||||||
uint32_t remote_ip; /* on the SGSN */
|
|
||||||
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum gprs_rlc_par {
|
|
||||||
RLC_T3142,
|
|
||||||
RLC_T3169,
|
|
||||||
RLC_T3191,
|
|
||||||
RLC_T3193,
|
|
||||||
RLC_T3195,
|
|
||||||
RLC_N3101,
|
|
||||||
RLC_N3103,
|
|
||||||
RLC_N3105,
|
|
||||||
CV_COUNTDOWN,
|
|
||||||
T_DL_TBF_EXT, /* ms */
|
|
||||||
T_UL_TBF_EXT, /* ms */
|
|
||||||
_NUM_RLC_PAR
|
|
||||||
};
|
|
||||||
|
|
||||||
enum gprs_cs {
|
|
||||||
GPRS_CS1,
|
|
||||||
GPRS_CS2,
|
|
||||||
GPRS_CS3,
|
|
||||||
GPRS_CS4,
|
|
||||||
GPRS_MCS1,
|
|
||||||
GPRS_MCS2,
|
|
||||||
GPRS_MCS3,
|
|
||||||
GPRS_MCS4,
|
|
||||||
GPRS_MCS5,
|
|
||||||
GPRS_MCS6,
|
|
||||||
GPRS_MCS7,
|
|
||||||
GPRS_MCS8,
|
|
||||||
GPRS_MCS9,
|
|
||||||
_NUM_GRPS_CS
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gprs_rlc_cfg {
|
|
||||||
uint16_t parameter[_NUM_RLC_PAR];
|
|
||||||
struct {
|
|
||||||
uint16_t repeat_time; /* ms */
|
|
||||||
uint8_t repeat_count;
|
|
||||||
} paging;
|
|
||||||
uint32_t cs_mask; /* bitmask of gprs_cs */
|
|
||||||
uint8_t initial_cs;
|
|
||||||
uint8_t initial_mcs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bts_smscb_state {
|
|
||||||
struct llist_head queue; /* list of struct smscb_msg */
|
|
||||||
int queue_len;
|
|
||||||
struct rate_ctr_group *ctrs;
|
|
||||||
struct smscb_msg *cur_msg; /* current SMS-CB */
|
|
||||||
struct smscb_msg *default_msg; /* default broadcast message; NULL if none */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The amount of time within which a sudden disconnect of a newly established
|
|
||||||
* OML connection will cause a special warning to be logged. */
|
|
||||||
#define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10 /* in seconds */
|
|
||||||
|
|
||||||
/* One BTS */
|
|
||||||
struct gsm_bts {
|
|
||||||
/* list header in net->bts_list */
|
|
||||||
struct llist_head list;
|
|
||||||
|
|
||||||
/* number of the BTS in network */
|
|
||||||
uint8_t nr;
|
|
||||||
/* human readable name / description */
|
|
||||||
char *description;
|
|
||||||
/* Cell Identity */
|
|
||||||
uint16_t cell_identity;
|
|
||||||
/* location area code of this BTS */
|
|
||||||
uint16_t location_area_code;
|
|
||||||
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
|
||||||
* which is used as TSC for the CCCH */
|
|
||||||
uint8_t bsic;
|
|
||||||
/* type of BTS */
|
|
||||||
enum gsm_bts_type_variant variant;
|
|
||||||
enum gsm_band band;
|
|
||||||
char version[MAX_VERSION_LENGTH];
|
|
||||||
char sub_model[MAX_VERSION_LENGTH];
|
|
||||||
|
|
||||||
/* features of a given BTS set/reported via OML */
|
|
||||||
struct bitvec features;
|
|
||||||
uint8_t _features_data[MAX_BTS_FEATURES/8];
|
|
||||||
|
|
||||||
/* Connected PCU version (if any) */
|
|
||||||
char pcu_version[MAX_VERSION_LENGTH];
|
|
||||||
|
|
||||||
/* maximum Tx power that the MS is permitted to use in this cell */
|
|
||||||
int ms_max_power;
|
|
||||||
|
|
||||||
/* how do we talk OML with this TRX? */
|
|
||||||
uint8_t oml_tei;
|
|
||||||
struct e1inp_sign_link *oml_link;
|
|
||||||
struct timespec oml_conn_established_timestamp;
|
|
||||||
|
|
||||||
/* Abis network management O&M handle */
|
|
||||||
struct abis_nm_h *nmh;
|
|
||||||
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
|
|
||||||
/* number of this BTS on given E1 link */
|
|
||||||
uint8_t bts_nr;
|
|
||||||
|
|
||||||
/* DTX features of this BTS */
|
|
||||||
enum gsm48_dtx_mode dtxu;
|
|
||||||
bool dtxd;
|
|
||||||
|
|
||||||
/* CCCH is on C0 */
|
|
||||||
struct gsm_bts_trx *c0;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
} site_mgr;
|
|
||||||
|
|
||||||
/* bitmask of all SI that are present/valid in si_buf */
|
|
||||||
uint32_t si_valid;
|
|
||||||
/* 3GPP TS 44.018 Table 10.5.2.33b.1 INDEX and COUNT for SI2quater */
|
|
||||||
uint8_t si2q_index; /* distinguish individual SI2quater messages */
|
|
||||||
uint8_t si2q_count; /* si2q_index for the last (highest indexed) individual SI2quater message */
|
|
||||||
/* buffers where we put the pre-computed SI */
|
|
||||||
sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
|
||||||
/* offsets used while generating SI2quater */
|
|
||||||
size_t e_offset;
|
|
||||||
size_t u_offset;
|
|
||||||
/* decoded SI3 rest octets - *unmodified* as received from BSC */
|
|
||||||
struct osmo_gsm48_si_ro_info si3_ro_decoded;
|
|
||||||
/* is SI3 GPRS Indicator currently disabled due to lack of PCU connection? */
|
|
||||||
bool si3_gprs_ind_disabled;
|
|
||||||
|
|
||||||
/* ip.access Unit ID's have Site/BTS/TRX layout */
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint16_t site_id;
|
|
||||||
uint16_t bts_id;
|
|
||||||
uint32_t flags;
|
|
||||||
uint32_t rsl_ip;
|
|
||||||
} ip_access;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Not entirely sure how ip.access specific this is */
|
|
||||||
struct {
|
|
||||||
uint8_t supports_egprs_11bit_rach;
|
|
||||||
enum bts_gprs_mode mode;
|
|
||||||
struct {
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
uint16_t nsei;
|
|
||||||
uint8_t timer[7];
|
|
||||||
} nse;
|
|
||||||
struct {
|
|
||||||
struct gsm_abis_mo mo;
|
|
||||||
uint16_t bvci;
|
|
||||||
uint8_t timer[11];
|
|
||||||
struct gprs_rlc_cfg rlc_cfg;
|
|
||||||
} cell;
|
|
||||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
|
||||||
uint8_t rac;
|
|
||||||
uint8_t net_ctrl_ord;
|
|
||||||
bool ctrl_ack_type_use_block;
|
|
||||||
} gprs;
|
|
||||||
|
|
||||||
/* RACH NM values */
|
|
||||||
int rach_b_thresh;
|
|
||||||
int rach_ldavg_slots;
|
|
||||||
|
|
||||||
/* transceivers */
|
|
||||||
int num_trx;
|
|
||||||
struct llist_head trx_list;
|
|
||||||
|
|
||||||
/* SI related items */
|
|
||||||
int force_combined_si;
|
|
||||||
int bcch_change_mark;
|
|
||||||
|
|
||||||
struct rate_ctr_group *ctrs;
|
|
||||||
bool supp_meas_toa256;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
/* Interference Boundaries for OML */
|
|
||||||
int16_t boundary[6];
|
|
||||||
uint8_t intave;
|
|
||||||
} interference;
|
|
||||||
unsigned int t200_ms[7];
|
|
||||||
unsigned int t3105_ms;
|
|
||||||
struct {
|
|
||||||
uint8_t overload_period;
|
|
||||||
struct {
|
|
||||||
/* Input parameters from OML */
|
|
||||||
uint8_t load_ind_thresh; /* percent */
|
|
||||||
uint8_t load_ind_period; /* seconds */
|
|
||||||
/* Internal data */
|
|
||||||
struct osmo_timer_list timer;
|
|
||||||
unsigned int pch_total;
|
|
||||||
unsigned int pch_used;
|
|
||||||
} ccch;
|
|
||||||
struct {
|
|
||||||
/* Input parameters from OML */
|
|
||||||
int16_t busy_thresh; /* in dBm */
|
|
||||||
uint16_t averaging_slots;
|
|
||||||
/* Internal data */
|
|
||||||
unsigned int total; /* total nr */
|
|
||||||
unsigned int busy; /* above busy_thresh */
|
|
||||||
unsigned int access; /* access bursts */
|
|
||||||
} rach;
|
|
||||||
} load;
|
|
||||||
uint8_t ny1;
|
|
||||||
uint8_t max_ta;
|
|
||||||
|
|
||||||
/* AGCH queuing */
|
|
||||||
struct {
|
|
||||||
struct llist_head queue;
|
|
||||||
int length;
|
|
||||||
int max_length;
|
|
||||||
|
|
||||||
int thresh_level; /* Cleanup threshold in percent of max len */
|
|
||||||
int low_level; /* Low water mark in percent of max len */
|
|
||||||
int high_level; /* High water mark in percent of max len */
|
|
||||||
|
|
||||||
/* TODO: Use a rate counter group instead */
|
|
||||||
uint64_t dropped_msgs;
|
|
||||||
uint64_t merged_msgs;
|
|
||||||
uint64_t rejected_msgs;
|
|
||||||
uint64_t agch_msgs;
|
|
||||||
uint64_t pch_msgs;
|
|
||||||
} agch_queue;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint8_t *prim_notif; /* ETWS primary notification (NULL if none) */
|
|
||||||
ssize_t prim_notif_len; /* Length of prim_notif; expected 56 bytes */
|
|
||||||
uint8_t page_size;
|
|
||||||
uint8_t num_pages; /* total number of pages */
|
|
||||||
uint8_t next_page; /* next page number to be sent */
|
|
||||||
bool pni; /* Primary Notification Identifier */
|
|
||||||
} etws;
|
|
||||||
|
|
||||||
struct paging_state *paging_state;
|
|
||||||
char *bsc_oml_host;
|
|
||||||
struct llist_head oml_queue;
|
|
||||||
unsigned int rtp_jitter_buf_ms;
|
|
||||||
bool rtp_jitter_adaptive;
|
|
||||||
|
|
||||||
uint16_t rtp_port_range_start;
|
|
||||||
uint16_t rtp_port_range_end;
|
|
||||||
uint16_t rtp_port_range_next;
|
|
||||||
int rtp_ip_dscp;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
|
||||||
} support;
|
|
||||||
struct {
|
|
||||||
uint8_t tc4_ctr;
|
|
||||||
} si;
|
|
||||||
struct gsm_time gsm_time;
|
|
||||||
/* frame number statistics (FN in PH-RTS.ind vs. PH-DATA.ind */
|
|
||||||
struct {
|
|
||||||
int32_t min; /* minimum observed */
|
|
||||||
int32_t max; /* maximum observed */
|
|
||||||
int32_t avg256; /* accumulator */
|
|
||||||
uint32_t avg_count; /* number of samples accumulated in avg256 */
|
|
||||||
uint32_t avg_window; /* number of averages in avg_count */
|
|
||||||
} fn_stats;
|
|
||||||
/* Radio Link Timeout counter. -1 disables timeout for
|
|
||||||
* lab/measurement purpose */
|
|
||||||
int radio_link_timeout;
|
|
||||||
|
|
||||||
int ul_power_target; /* Uplink Rx power target */
|
|
||||||
|
|
||||||
/* used by the sysmoBTS to adjust band */
|
|
||||||
uint8_t auto_band;
|
|
||||||
|
|
||||||
/* State for SMSCB (Cell Broadcast) for BASIC and EXTENDED channel */
|
|
||||||
struct bts_smscb_state smscb_basic;
|
|
||||||
struct bts_smscb_state smscb_extended;
|
|
||||||
int smscb_queue_tgt_len; /* ideal/target queue length */
|
|
||||||
int smscb_queue_max_len; /* maximum queue length */
|
|
||||||
int smscb_queue_hyst; /* hysteresis for CBCH load indications */
|
|
||||||
|
|
||||||
int16_t min_qual_rach; /* minimum link quality (in centiBels) for Access Bursts */
|
|
||||||
int16_t min_qual_norm; /* minimum link quality (in centiBels) for Normal Bursts */
|
|
||||||
uint16_t max_ber10k_rach; /* Maximum permitted RACH BER in 0.01% */
|
|
||||||
|
|
||||||
struct {
|
|
||||||
char *sock_path;
|
|
||||||
} pcu;
|
|
||||||
|
|
||||||
void *model_priv; /* Allocated by bts_model, contains model specific data pointer */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
|
|
||||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num);
|
|
||||||
|
|
||||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
|
|
||||||
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num);
|
|
||||||
|
|
||||||
enum bts_attribute str2btsattr(const char *s);
|
|
||||||
const char *btsatttr2str(enum bts_attribute v);
|
|
||||||
|
|
||||||
enum gsm_bts_type_variant str2btsvariant(const char *arg);
|
|
||||||
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
|
||||||
|
|
||||||
extern const struct value_string gsm_chreq_descs[];
|
|
||||||
const struct value_string gsm_pchant_names[13];
|
|
||||||
const struct value_string gsm_pchant_descs[13];
|
|
||||||
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_lchant_name(enum gsm_chan_t c);
|
|
||||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
|
||||||
char *gsm_trx_name(const struct gsm_bts_trx *trx);
|
|
||||||
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
|
||||||
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts);
|
|
||||||
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan);
|
|
||||||
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
|
||||||
|
|
||||||
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
return lchan->name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int gsm_bts_set_feature(struct gsm_bts *bts, enum gsm_bts_features feat)
|
|
||||||
{
|
|
||||||
OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
|
|
||||||
return bitvec_set_bit_pos(&bts->features, feat, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gsm_bts_has_feature(const struct gsm_bts *bts, enum gsm_bts_features feat)
|
|
||||||
{
|
|
||||||
OSMO_ASSERT(_NUM_BTS_FEAT < MAX_BTS_FEATURES);
|
|
||||||
return bitvec_get_bit_pos(&bts->features, feat);
|
|
||||||
}
|
|
||||||
|
|
||||||
void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
|
||||||
|
|
||||||
struct gsm_abis_mo *
|
|
||||||
gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst);
|
|
||||||
|
|
||||||
struct gsm_nm_state *
|
|
||||||
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst);
|
|
||||||
void *
|
|
||||||
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst);
|
|
||||||
|
|
||||||
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
|
|
||||||
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
|
||||||
enum gsm_phys_chan_config as_pchan);
|
|
||||||
|
|
||||||
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
|
||||||
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* help with parsing regexps
|
|
||||||
*/
|
|
||||||
int gsm_parse_reg(void *ctx, regex_t *reg, char **str,
|
|
||||||
int argc, const char **argv) __attribute__ ((warn_unused_result));
|
|
||||||
|
|
||||||
#define BSIC2BCC(bsic) ((bsic) & 0x3)
|
|
||||||
|
|
||||||
static inline uint8_t gsm_ts_tsc(const struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
if (ts->tsc != -1)
|
|
||||||
return ts->tsc;
|
|
||||||
else
|
|
||||||
return ts->trx->bts->bsic & 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
|
||||||
int *rc);
|
|
||||||
|
|
||||||
enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts);
|
|
||||||
uint8_t ts_subslots(struct gsm_bts_trx_ts *ts);
|
|
||||||
bool ts_is_tch(struct gsm_bts_trx_ts *ts);
|
|
||||||
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx);
|
|
||||||
|
|
||||||
int lchan2ecu_codec(const struct gsm_lchan *lchan);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -4,6 +4,8 @@
|
|||||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||||
|
|
||||||
|
#define L1SAP_MSGB_HEADROOM 128
|
||||||
|
|
||||||
/* lchan link ID */
|
/* lchan link ID */
|
||||||
#define LID_SACCH 0x40
|
#define LID_SACCH 0x40
|
||||||
#define LID_DEDIC 0x00
|
#define LID_DEDIC 0x00
|
||||||
@@ -19,9 +21,11 @@
|
|||||||
#define L1SAP_IS_LINK_SACCH(link_id) \
|
#define L1SAP_IS_LINK_SACCH(link_id) \
|
||||||
((link_id & 0xC0) == LID_SACCH)
|
((link_id & 0xC0) == LID_SACCH)
|
||||||
#define L1SAP_IS_CHAN_TCHF(chan_nr) \
|
#define L1SAP_IS_CHAN_TCHF(chan_nr) \
|
||||||
((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs)
|
((chan_nr & 0xf8) == RSL_CHAN_Bm_ACCHs || \
|
||||||
|
(chan_nr & 0xf8) == RSL_CHAN_OSMO_VAMOS_Bm_ACCHs)
|
||||||
#define L1SAP_IS_CHAN_TCHH(chan_nr) \
|
#define L1SAP_IS_CHAN_TCHH(chan_nr) \
|
||||||
((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs)
|
((chan_nr & 0xf0) == RSL_CHAN_Lm_ACCHs || \
|
||||||
|
(chan_nr & 0xf0) == RSL_CHAN_OSMO_VAMOS_Lm_ACCHs)
|
||||||
#define L1SAP_IS_CHAN_SDCCH4(chan_nr) \
|
#define L1SAP_IS_CHAN_SDCCH4(chan_nr) \
|
||||||
((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH)
|
((chan_nr & 0xe0) == RSL_CHAN_SDCCH4_ACCH)
|
||||||
#define L1SAP_IS_CHAN_SDCCH8(chan_nr) \
|
#define L1SAP_IS_CHAN_SDCCH8(chan_nr) \
|
||||||
@@ -37,6 +41,9 @@
|
|||||||
#define L1SAP_IS_CHAN_CBCH(chan_nr) \
|
#define L1SAP_IS_CHAN_CBCH(chan_nr) \
|
||||||
((chan_nr & 0xf8) == RSL_CHAN_OSMO_CBCH4) \
|
((chan_nr & 0xf8) == RSL_CHAN_OSMO_CBCH4) \
|
||||||
|| ((chan_nr & 0xf8) == RSL_CHAN_OSMO_CBCH8)
|
|| ((chan_nr & 0xf8) == RSL_CHAN_OSMO_CBCH8)
|
||||||
|
#define L1SAP_IS_CHAN_VAMOS(chan_nr) \
|
||||||
|
((chan_nr & 0xf8) == RSL_CHAN_OSMO_VAMOS_Bm_ACCHs || \
|
||||||
|
(chan_nr & 0xf0) == RSL_CHAN_OSMO_VAMOS_Lm_ACCHs)
|
||||||
|
|
||||||
/* rach type from ra */
|
/* rach type from ra */
|
||||||
#define L1SAP_IS_PACKET_RACH(ra) ((ra & 0xf0) == 0x70 && (ra & 0x0f) != 0x0f)
|
#define L1SAP_IS_PACKET_RACH(ra) ((ra & 0xf0) == 0x70 && (ra & 0x0f) != 0x0f)
|
||||||
@@ -91,7 +98,7 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl,
|
|||||||
uint32_t timestamp, bool marker);
|
uint32_t timestamp, bool marker);
|
||||||
|
|
||||||
/* channel control */
|
/* channel control */
|
||||||
int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp);
|
int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
||||||
int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
||||||
int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
||||||
int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr);
|
||||||
@@ -127,11 +134,6 @@ enum l1sap_common_sapi {
|
|||||||
extern uint16_t l1sap_log_ctx_sapi;
|
extern uint16_t l1sap_log_ctx_sapi;
|
||||||
extern const struct value_string l1sap_common_sapi_names[];
|
extern const struct value_string l1sap_common_sapi_names[];
|
||||||
|
|
||||||
extern const struct value_string gsmtap_sapi_names[];
|
|
||||||
extern struct gsmtap_inst *gsmtap;
|
|
||||||
extern uint32_t gsmtap_sapi_mask;
|
|
||||||
extern uint8_t gsmtap_sapi_acch;
|
|
||||||
|
|
||||||
int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
|
int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
|
||||||
struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn,
|
struct gsm_lchan *lchan, uint8_t chan_nr, uint32_t fn,
|
||||||
uint16_t ber10k, int16_t lqual_cb, int8_t rssi,
|
uint16_t ber10k, int16_t lqual_cb, int8_t rssi,
|
||||||
|
|||||||
391
include/osmo-bts/lchan.h
Normal file
391
include/osmo-bts/lchan.h
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
#include <osmocom/core/logging.h>
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/codec/ecu.h>
|
||||||
|
#include <osmocom/gsm/lapdm.h>
|
||||||
|
#include <osmocom/gsm/sysinfo.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||||
|
#include <osmocom/gsm/gsm48_rest_octets.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
|
#include <osmocom/gsm/meas_rep.h>
|
||||||
|
#include <osmocom/netif/osmux.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/power_control.h>
|
||||||
|
|
||||||
|
#define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args)
|
||||||
|
|
||||||
|
enum lchan_ciph_state {
|
||||||
|
LCHAN_CIPH_NONE,
|
||||||
|
LCHAN_CIPH_RX_REQ,
|
||||||
|
LCHAN_CIPH_RX_CONF,
|
||||||
|
LCHAN_CIPH_RXTX_REQ,
|
||||||
|
LCHAN_CIPH_RX_CONF_TX_REQ,
|
||||||
|
LCHAN_CIPH_RXTX_CONF,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* state of a logical channel */
|
||||||
|
enum gsm_lchan_state {
|
||||||
|
LCHAN_S_NONE, /* channel is not active */
|
||||||
|
LCHAN_S_ACT_REQ, /* channel activation 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_BROKEN, /* channel is somehow unusable */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_NUM_UL_MEAS 104
|
||||||
|
#define LC_UL_M_F_L1_VALID (1 << 0)
|
||||||
|
#define LC_UL_M_F_RES_VALID (1 << 1)
|
||||||
|
#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2)
|
||||||
|
|
||||||
|
#define MAX_A5_KEY_LEN (128/8)
|
||||||
|
#define RSL_ENC_ALG_A5(x) (x+1)
|
||||||
|
|
||||||
|
struct bts_ul_meas {
|
||||||
|
/* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */
|
||||||
|
uint16_t ber10k;
|
||||||
|
/* timing advance offset (in 1/256 bits) */
|
||||||
|
int16_t ta_offs_256bits;
|
||||||
|
/* C/I ratio in cB */
|
||||||
|
int16_t ci_cb;
|
||||||
|
/* flags */
|
||||||
|
uint8_t is_sub:1;
|
||||||
|
/* RSSI in dBm * -1 */
|
||||||
|
uint8_t inv_rssi;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct amr_mode {
|
||||||
|
uint8_t mode;
|
||||||
|
uint8_t threshold;
|
||||||
|
uint8_t hysteresis;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct amr_multirate_conf {
|
||||||
|
uint8_t gsm48_ie[2];
|
||||||
|
struct amr_mode mode[4];
|
||||||
|
uint8_t num_modes;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum lchan_csd_mode {
|
||||||
|
LCHAN_CSD_M_NT,
|
||||||
|
LCHAN_CSD_M_T_1200_75,
|
||||||
|
LCHAN_CSD_M_T_600,
|
||||||
|
LCHAN_CSD_M_T_1200,
|
||||||
|
LCHAN_CSD_M_T_2400,
|
||||||
|
LCHAN_CSD_M_T_9600,
|
||||||
|
LCHAN_CSD_M_T_14400,
|
||||||
|
LCHAN_CSD_M_T_29000,
|
||||||
|
LCHAN_CSD_M_T_32000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* State of the SAPIs in the lchan */
|
||||||
|
enum lchan_sapi_state {
|
||||||
|
LCHAN_SAPI_S_NONE,
|
||||||
|
LCHAN_SAPI_S_REQ,
|
||||||
|
LCHAN_SAPI_S_ASSIGNED,
|
||||||
|
LCHAN_SAPI_S_REL,
|
||||||
|
LCHAN_SAPI_S_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* What kind of release/activation is done? A silent one for
|
||||||
|
* the PDCH or one triggered through RSL? */
|
||||||
|
enum lchan_rel_act_kind {
|
||||||
|
LCHAN_REL_ACT_RSL,
|
||||||
|
LCHAN_REL_ACT_PCU,
|
||||||
|
LCHAN_REL_ACT_OML,
|
||||||
|
LCHAN_REL_ACT_REACT, /* FIXME: remove once auto-activation hack is removed from opstart_compl() (OS#1575) */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gsm_rep_facch {
|
||||||
|
struct msgb *msg;
|
||||||
|
uint32_t fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct lchan_power_ctrl_state {
|
||||||
|
/* Dynamic Power Control parameters (NULL in static mode) */
|
||||||
|
const struct gsm_power_ctrl_params *dpc_params;
|
||||||
|
/* Measurement pre-processing state (for dynamic mode) */
|
||||||
|
struct gsm_power_ctrl_meas_proc_state rxlev_meas_proc;
|
||||||
|
struct gsm_power_ctrl_meas_proc_state rxqual_meas_proc;
|
||||||
|
struct gsm_power_ctrl_meas_proc_state ci_meas_proc;
|
||||||
|
/* Number of SACCH blocks to skip (for dynamic mode) */
|
||||||
|
int skip_block_num;
|
||||||
|
|
||||||
|
/* Depending on the context (MS or BS power control), fields 'current' and 'max'
|
||||||
|
* reflect either the MS power level (magic numbers), or BS Power reduction level
|
||||||
|
* (attenuation, in dB). */
|
||||||
|
uint8_t current;
|
||||||
|
uint8_t max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct lchan_ta_ctrl_state {
|
||||||
|
/* Number of SACCH blocks to skip */
|
||||||
|
int skip_block_num;
|
||||||
|
/* Currently requested TA */
|
||||||
|
uint8_t current;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gsm_lchan {
|
||||||
|
/* The TS that we're part of */
|
||||||
|
struct gsm_bts_trx_ts *ts;
|
||||||
|
/* The logical subslot number in the TS */
|
||||||
|
uint8_t nr;
|
||||||
|
/* The logical channel type */
|
||||||
|
enum gsm_chan_t type;
|
||||||
|
/* RSL channel mode */
|
||||||
|
enum rsl_cmod_spd rsl_cmode;
|
||||||
|
/* If TCH, traffic channel mode */
|
||||||
|
enum gsm48_chan_mode tch_mode;
|
||||||
|
enum lchan_csd_mode csd_mode;
|
||||||
|
/* State */
|
||||||
|
enum gsm_lchan_state state;
|
||||||
|
const char *broken_reason;
|
||||||
|
/* Encryption information */
|
||||||
|
struct {
|
||||||
|
uint8_t alg_id;
|
||||||
|
uint8_t key_len;
|
||||||
|
uint8_t key[MAX_A5_KEY_LEN];
|
||||||
|
} encr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t bound_ip;
|
||||||
|
uint32_t connect_ip;
|
||||||
|
uint16_t bound_port;
|
||||||
|
uint16_t connect_port;
|
||||||
|
uint16_t conn_id;
|
||||||
|
uint8_t rtp_payload;
|
||||||
|
uint8_t rtp_payload2;
|
||||||
|
uint8_t speech_mode;
|
||||||
|
struct {
|
||||||
|
bool use;
|
||||||
|
uint8_t local_cid;
|
||||||
|
uint8_t remote_cid;
|
||||||
|
/* Rx Osmux -> RTP, one allocated & owned per lchan */
|
||||||
|
struct osmux_out_handle *out;
|
||||||
|
/* Tx RTP -> Osmux, shared by all lchans sharing a
|
||||||
|
* remote endp (addr+port), see "struct osmux_handle" */
|
||||||
|
struct osmux_in_handle *in;
|
||||||
|
/* Used to build rtp messages we send to osmux */
|
||||||
|
struct osmo_rtp_handle *rtpst;
|
||||||
|
} osmux;
|
||||||
|
struct osmo_rtp_socket *rtp_socket;
|
||||||
|
} abis_ip;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* For handover, activation is described in 3GPP TS 48.058 4.1.3 and 4.1.4:
|
||||||
|
*
|
||||||
|
* | | Access || transmit | activate
|
||||||
|
* | MS Power | Delay || on main channel | dl SACCH
|
||||||
|
* ----------------------------------------------------------------------
|
||||||
|
* async ho no * --> yes no
|
||||||
|
* async ho yes * --> yes may be started
|
||||||
|
* sync ho no no --> yes no
|
||||||
|
* sync ho yes no --> yes may be started
|
||||||
|
* sync ho yes yes --> yes shall be started
|
||||||
|
*
|
||||||
|
* Always start the main channel immediately.
|
||||||
|
* want_dl_sacch_active indicates whether dl SACCH should be activated on CHAN ACT.
|
||||||
|
*/
|
||||||
|
bool want_dl_sacch_active;
|
||||||
|
|
||||||
|
/* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23.
|
||||||
|
* Currently we don't share these headers so this is a magic number. */
|
||||||
|
struct llist_head sapi_cmds;
|
||||||
|
uint8_t sapis_dl[23];
|
||||||
|
uint8_t sapis_ul[23];
|
||||||
|
struct lapdm_channel lapdm_ch;
|
||||||
|
struct llist_head dl_tch_queue;
|
||||||
|
unsigned int dl_tch_queue_len;
|
||||||
|
struct {
|
||||||
|
/* bitmask of all SI that are present/valid in si_buf */
|
||||||
|
uint32_t valid;
|
||||||
|
/* bitmask of all SI that do not mirror the BTS-global SI values */
|
||||||
|
uint32_t overridden;
|
||||||
|
uint32_t last;
|
||||||
|
/* buffers where we put the pre-computed SI:
|
||||||
|
SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */
|
||||||
|
sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM];
|
||||||
|
} si;
|
||||||
|
struct {
|
||||||
|
uint8_t flags;
|
||||||
|
/* RSL measurement result number, 0 at lchan_act */
|
||||||
|
uint8_t res_nr;
|
||||||
|
/* number of measurements stored in array below */
|
||||||
|
uint8_t num_ul_meas;
|
||||||
|
struct bts_ul_meas uplink[MAX_NUM_UL_MEAS];
|
||||||
|
/* last L1 header from the MS */
|
||||||
|
struct rsl_l1_info l1_info;
|
||||||
|
struct gsm_meas_rep_unidir ul_res;
|
||||||
|
int16_t ms_toa256;
|
||||||
|
int16_t ul_ci_cb_full;
|
||||||
|
int16_t ul_ci_cb_sub;
|
||||||
|
/* Frame number of the last measurement indication receceived */
|
||||||
|
uint32_t last_fn;
|
||||||
|
/* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */
|
||||||
|
struct {
|
||||||
|
/* minimum value of toa256 during measurement period */
|
||||||
|
int16_t toa256_min;
|
||||||
|
/* maximum value of toa256 during measurement period */
|
||||||
|
int16_t toa256_max;
|
||||||
|
/* standard deviation of toa256 value during measurement period */
|
||||||
|
uint16_t toa256_std_dev;
|
||||||
|
} ext;
|
||||||
|
/* Interference levels reported by PHY (in dBm) */
|
||||||
|
int16_t interf_meas_avg_dbm; /* Average value */
|
||||||
|
int16_t interf_meas_dbm[31]; /* Intave max is 31 */
|
||||||
|
uint8_t interf_meas_num;
|
||||||
|
uint8_t interf_band;
|
||||||
|
} meas;
|
||||||
|
struct {
|
||||||
|
struct amr_multirate_conf amr_mr;
|
||||||
|
struct {
|
||||||
|
struct osmo_fsm_inst *dl_amr_fsm;
|
||||||
|
/* TCH cache */
|
||||||
|
uint8_t cache[20];
|
||||||
|
/* FACCH cache */
|
||||||
|
uint8_t facch[GSM_MACBLOCK_LEN];
|
||||||
|
uint8_t len;
|
||||||
|
uint32_t fn;
|
||||||
|
bool is_update;
|
||||||
|
/* set for each SID frame to detect talkspurt for codecs
|
||||||
|
without explicit ONSET event */
|
||||||
|
bool ul_sid;
|
||||||
|
/* indicates if DTXd was active during DL measurement
|
||||||
|
period */
|
||||||
|
bool dl_active;
|
||||||
|
/* last UL SPEECH resume flag */
|
||||||
|
bool is_speech_resume;
|
||||||
|
} dtx;
|
||||||
|
uint8_t last_cmr;
|
||||||
|
uint32_t last_fn;
|
||||||
|
|
||||||
|
} tch;
|
||||||
|
|
||||||
|
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
||||||
|
int16_t ms_t_offs;
|
||||||
|
/* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */
|
||||||
|
int16_t p_offs;
|
||||||
|
|
||||||
|
/* BTS-side ciphering state (rx only, bi-directional, ...) */
|
||||||
|
uint8_t ciph_state;
|
||||||
|
uint8_t ciph_ns;
|
||||||
|
uint8_t loopback;
|
||||||
|
struct {
|
||||||
|
uint8_t active;
|
||||||
|
uint8_t ref;
|
||||||
|
/* T3105: PHYS INF retransmission */
|
||||||
|
struct osmo_timer_list t3105;
|
||||||
|
/* counts up to Ny1 */
|
||||||
|
unsigned int phys_info_count;
|
||||||
|
} ho;
|
||||||
|
/* S counter for link loss */
|
||||||
|
int s;
|
||||||
|
/* Kind of the release/activation. E.g. RSL or PCU */
|
||||||
|
enum lchan_rel_act_kind rel_act_kind;
|
||||||
|
/* Pending RSL CHANnel ACTIVation message */
|
||||||
|
struct msgb *pending_chan_activ;
|
||||||
|
/* RTP header Marker bit to indicate beginning of speech after pause */
|
||||||
|
bool rtp_tx_marker;
|
||||||
|
|
||||||
|
/* TA Control Loop */
|
||||||
|
struct lchan_ta_ctrl_state ta_ctrl;
|
||||||
|
|
||||||
|
/* MS/BS power control state */
|
||||||
|
struct lchan_power_ctrl_state ms_power_ctrl;
|
||||||
|
struct lchan_power_ctrl_state bs_power_ctrl;
|
||||||
|
|
||||||
|
/* MS/BS Dynamic Power Control parameters */
|
||||||
|
struct gsm_power_ctrl_params ms_dpc_params;
|
||||||
|
struct gsm_power_ctrl_params bs_dpc_params;
|
||||||
|
|
||||||
|
/* Temporary ACCH overpower capabilities and state */
|
||||||
|
struct abis_rsl_osmo_temp_ovp_acch_cap top_acch_cap;
|
||||||
|
bool top_acch_active;
|
||||||
|
|
||||||
|
struct msgb *pending_rel_ind_msg;
|
||||||
|
|
||||||
|
/* ECU (Error Concealment Unit) state */
|
||||||
|
struct osmo_ecu_state *ecu_state;
|
||||||
|
|
||||||
|
/* Repeated ACCH capabilities and current state */
|
||||||
|
struct abis_rsl_osmo_rep_acch_cap rep_acch_cap;
|
||||||
|
struct {
|
||||||
|
bool dl_facch_active;
|
||||||
|
bool ul_sacch_active;
|
||||||
|
bool dl_sacch_active;
|
||||||
|
|
||||||
|
/* Message buffers to store repeation candidates */
|
||||||
|
struct gsm_rep_facch dl_facch[2];
|
||||||
|
struct msgb *dl_sacch_msg;
|
||||||
|
} rep_acch;
|
||||||
|
|
||||||
|
/* Cached early Immediate Assignment message: if the Immediate Assignment arrives before the channel is
|
||||||
|
* confirmed active, then cache it here and send it once the channel is confirmed to be active. This is related
|
||||||
|
* to the Early IA feature, see OsmoBSC config option 'immediate-assignment pre-chan-ack'. */
|
||||||
|
struct msgb *early_rr_ia;
|
||||||
|
struct osmo_timer_list early_rr_ia_delay;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct value_string lchan_ciph_state_names[];
|
||||||
|
static inline const char *lchan_ciph_state_name(uint8_t state)
|
||||||
|
{
|
||||||
|
return get_value_string(lchan_ciph_state_names, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0])
|
||||||
|
|
||||||
|
void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr);
|
||||||
|
void gsm_lchan_name_update(struct gsm_lchan *lchan);
|
||||||
|
int lchan_init_lapdm(struct gsm_lchan *lchan);
|
||||||
|
void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind);
|
||||||
|
int lchan_deactivate(struct gsm_lchan *lchan);
|
||||||
|
const char *gsm_lchans_name(enum gsm_lchan_state s);
|
||||||
|
|
||||||
|
static inline char *gsm_lchan_name(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
return lchan->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan);
|
||||||
|
uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan);
|
||||||
|
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
||||||
|
enum gsm_phys_chan_config as_pchan);
|
||||||
|
|
||||||
|
void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm);
|
||||||
|
void gsm_lchan_interf_meas_calc_avg(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
int lchan2ecu_codec(const struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state);
|
||||||
|
|
||||||
|
int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip);
|
||||||
|
int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port);
|
||||||
|
void lchan_rtp_socket_free(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit);
|
||||||
|
|
||||||
|
static inline bool lchan_is_dcch(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
switch (lchan->type) {
|
||||||
|
case GSM_LCHAN_SDCCH:
|
||||||
|
case GSM_LCHAN_TCH_F:
|
||||||
|
case GSM_LCHAN_TCH_H:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lchan_is_tch(lchan) \
|
||||||
|
((lchan)->type == GSM_LCHAN_TCH_F || (lchan)->type == GSM_LCHAN_TCH_H)
|
||||||
@@ -20,7 +20,7 @@ enum {
|
|||||||
DLOOP,
|
DLOOP,
|
||||||
DABIS,
|
DABIS,
|
||||||
DRTP,
|
DRTP,
|
||||||
DSUM,
|
DOSMUX,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct log_info bts_log_info;
|
extern const struct log_info bts_log_info;
|
||||||
|
|||||||
@@ -4,16 +4,22 @@
|
|||||||
#define MEAS_MAX_TIMING_ADVANCE 63
|
#define MEAS_MAX_TIMING_ADVANCE 63
|
||||||
#define MEAS_MIN_TIMING_ADVANCE 0
|
#define MEAS_MIN_TIMING_ADVANCE 0
|
||||||
|
|
||||||
int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn);
|
int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
||||||
|
const struct bts_ul_meas *ulm,
|
||||||
|
uint32_t fn);
|
||||||
|
|
||||||
int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn);
|
int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn);
|
||||||
|
|
||||||
int lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn);
|
int lchan_meas_process_measurement(struct gsm_lchan *lchan,
|
||||||
|
const struct bts_ul_meas *ulm,
|
||||||
|
uint32_t fn);
|
||||||
|
|
||||||
void lchan_meas_reset(struct gsm_lchan *lchan);
|
void lchan_meas_reset(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_update);
|
bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn);
|
||||||
|
|
||||||
int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn);
|
int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn);
|
||||||
|
|
||||||
|
void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
97
include/osmo-bts/nm_common_fsm.h
Normal file
97
include/osmo-bts/nm_common_fsm.h
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
|
||||||
|
GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
|
||||||
|
|
||||||
|
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/core/msgb.h>
|
||||||
|
|
||||||
|
/* Common */
|
||||||
|
enum nm_fsm_events {
|
||||||
|
NM_EV_SW_ACT,
|
||||||
|
NM_EV_SETATTR_ACK, /* data: struct nm_fsm_ev_setattr_data */
|
||||||
|
NM_EV_SETATTR_NACK, /* data: struct nm_fsm_ev_setattr_data */
|
||||||
|
NM_EV_OPSTART_ACK,
|
||||||
|
NM_EV_OPSTART_NACK,
|
||||||
|
NM_EV_SHUTDOWN_START,
|
||||||
|
NM_EV_SHUTDOWN_FINISH,
|
||||||
|
NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
|
NM_EV_RSL_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
|
NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
|
NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
|
NM_EV_DISABLE, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
|
NM_EV_BBTRANSC_INSTALLED, /* Radio Channel only */
|
||||||
|
NM_EV_BBTRANSC_ENABLED, /* Radio Channel only */
|
||||||
|
NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
|
||||||
|
NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
|
||||||
|
NM_EV_RCARRIER_DISABLED, /* Radio Channel only */
|
||||||
|
};
|
||||||
|
extern const struct value_string nm_fsm_event_names[];
|
||||||
|
|
||||||
|
struct nm_fsm_ev_setattr_data {
|
||||||
|
struct msgb *msg; /* msgb ownership is transferred to FSM */
|
||||||
|
int cause;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* BTS SiteManager */
|
||||||
|
enum nm_bts_sm_op_fsm_states {
|
||||||
|
NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_BTS_SM_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_BTS_SM_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_bts_sm_fsm;
|
||||||
|
|
||||||
|
/* BTS */
|
||||||
|
enum nm_bts_op_fsm_states {
|
||||||
|
NM_BTS_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_BTS_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_BTS_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_bts_fsm;
|
||||||
|
|
||||||
|
/* BaseBand Transceiver */
|
||||||
|
enum nm_bb_transc_op_fsm_states {
|
||||||
|
NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_BBTRANSC_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_BBTRANSC_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_bb_transc_fsm;
|
||||||
|
|
||||||
|
/* Radio Carrier */
|
||||||
|
enum nm_rcarrier_op_fsm_states {
|
||||||
|
NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_RCARRIER_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_RCARRIER_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_rcarrier_fsm;
|
||||||
|
|
||||||
|
/* Radio channel */
|
||||||
|
enum nm_chan_op_fsm_states {
|
||||||
|
NM_CHAN_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_CHAN_ST_OP_DISABLED_DEPENDENCY,
|
||||||
|
NM_CHAN_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_CHAN_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_chan_fsm;
|
||||||
@@ -8,8 +8,35 @@ struct gsm_abis_mo;
|
|||||||
struct msgb;
|
struct msgb;
|
||||||
struct gsm_lchan;
|
struct gsm_lchan;
|
||||||
|
|
||||||
|
/* Network Management State */
|
||||||
|
struct gsm_nm_state {
|
||||||
|
enum abis_nm_op_state operational;
|
||||||
|
enum abis_nm_adm_state administrative;
|
||||||
|
enum abis_nm_avail_state availability;
|
||||||
|
};
|
||||||
|
|
||||||
int oml_init(struct gsm_abis_mo *mo);
|
struct gsm_abis_mo {
|
||||||
|
/* A-bis OML Object Class */
|
||||||
|
uint8_t obj_class;
|
||||||
|
/* is there still some procedure pending? */
|
||||||
|
uint8_t procedure_pending;
|
||||||
|
/* A-bis OML Object Instance */
|
||||||
|
struct abis_om_obj_inst obj_inst;
|
||||||
|
/* human-readable name */
|
||||||
|
const char *name;
|
||||||
|
/* NM State */
|
||||||
|
struct gsm_nm_state nm_state;
|
||||||
|
/* Attributes configured in this MO */
|
||||||
|
struct tlv_parsed *nm_attr;
|
||||||
|
/* BTS to which this MO belongs */
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
/* NM BTS Site Manager FSM */
|
||||||
|
struct osmo_fsm_inst *fi;
|
||||||
|
bool setattr_success;
|
||||||
|
bool opstart_success;
|
||||||
|
};
|
||||||
|
|
||||||
|
int oml_init(void);
|
||||||
int down_oml(struct gsm_bts *bts, struct msgb *msg);
|
int down_oml(struct gsm_bts *bts, struct msgb *msg);
|
||||||
|
|
||||||
struct msgb *oml_msgb_alloc(void);
|
struct msgb *oml_msgb_alloc(void);
|
||||||
@@ -21,7 +48,7 @@ int oml_mo_statechg_ack(const struct gsm_abis_mo *mo);
|
|||||||
int oml_mo_statechg_nack(const struct gsm_abis_mo *mo, uint8_t nack_cause);
|
int oml_mo_statechg_nack(const struct gsm_abis_mo *mo, uint8_t nack_cause);
|
||||||
|
|
||||||
/* Change the state and send STATE CHG REP */
|
/* Change the state and send STATE CHG REP */
|
||||||
int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state);
|
int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state, int adm_state);
|
||||||
|
|
||||||
/* First initialization of MO, does _not_ generate state changes */
|
/* First initialization of MO, does _not_ generate state changes */
|
||||||
void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state);
|
void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state);
|
||||||
@@ -46,4 +73,15 @@ extern const unsigned int oml_default_t200_ms[7];
|
|||||||
int oml_tx_failure_event_rep(const struct gsm_abis_mo *mo, enum abis_nm_severity severity,
|
int oml_tx_failure_event_rep(const struct gsm_abis_mo *mo, enum abis_nm_severity severity,
|
||||||
uint16_t cause_value, const char *fmt, ...);
|
uint16_t cause_value, const char *fmt, ...);
|
||||||
|
|
||||||
|
void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
|
||||||
|
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);
|
||||||
|
|
||||||
|
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
||||||
|
const struct abis_om_obj_inst *obj_inst);
|
||||||
|
|
||||||
|
struct gsm_nm_state *gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
||||||
|
const struct abis_om_obj_inst *obj_inst);
|
||||||
|
void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
||||||
|
const struct abis_om_obj_inst *obj_inst);
|
||||||
|
|
||||||
#endif // _OML_H */
|
#endif // _OML_H */
|
||||||
|
|||||||
48
include/osmo-bts/osmux.h
Normal file
48
include/osmo-bts/osmux.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <osmocom/core/select.h>
|
||||||
|
#include <osmocom/netif/osmux.h>
|
||||||
|
|
||||||
|
struct gsm_bts;
|
||||||
|
struct gsm_lchan;
|
||||||
|
|
||||||
|
enum osmux_usage {
|
||||||
|
OSMUX_USAGE_OFF = 0,
|
||||||
|
OSMUX_USAGE_ON = 1,
|
||||||
|
OSMUX_USAGE_ONLY = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct osmux_state {
|
||||||
|
enum osmux_usage use;
|
||||||
|
char *local_addr;
|
||||||
|
uint16_t local_port;
|
||||||
|
struct osmo_fd fd;
|
||||||
|
uint8_t batch_factor;
|
||||||
|
unsigned int batch_size;
|
||||||
|
bool dummy_padding;
|
||||||
|
struct llist_head osmux_handle_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Contains a "struct osmux_in_handle" towards a specific peer (remote IPaddr+port) */
|
||||||
|
struct osmux_handle {
|
||||||
|
struct llist_head head;
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
struct osmux_in_handle *in;
|
||||||
|
struct osmo_sockaddr rem_addr;
|
||||||
|
int refcnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
int bts_osmux_init(struct gsm_bts *bts);
|
||||||
|
void bts_osmux_release(struct gsm_bts *bts);
|
||||||
|
int bts_osmux_open(struct gsm_bts *bts);
|
||||||
|
|
||||||
|
int lchan_osmux_init(struct gsm_lchan *lchan, uint8_t rtp_payload);
|
||||||
|
void lchan_osmux_release(struct gsm_lchan *lchan);
|
||||||
|
int lchan_osmux_connect(struct gsm_lchan *lchan);
|
||||||
|
bool lchan_osmux_connected(const struct gsm_lchan *lchan);
|
||||||
|
int lchan_osmux_send_frame(struct gsm_lchan *lchan, const uint8_t *payload,
|
||||||
|
unsigned int payload_len, unsigned int duration, bool marker);
|
||||||
|
|
||||||
|
int lchan_osmux_skipped_frame(struct gsm_lchan *lchan, unsigned int duration);
|
||||||
@@ -37,7 +37,7 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
|
|||||||
|
|
||||||
/* Add an IMM.ASS message to the paging queue */
|
/* Add an IMM.ASS message to the paging queue */
|
||||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||||
uint8_t len);
|
uint8_t len, bool from_pcu);
|
||||||
|
|
||||||
/* generate paging message for given gsm time */
|
/* generate paging message for given gsm time */
|
||||||
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
#ifndef _PCU_IF_H
|
#ifndef _PCU_IF_H
|
||||||
#define _PCU_IF_H
|
#define _PCU_IF_H
|
||||||
|
|
||||||
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
|
||||||
extern int pcu_direct;
|
extern int pcu_direct;
|
||||||
|
|
||||||
|
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
|
||||||
|
|
||||||
int pcu_tx_info_ind(void);
|
int pcu_tx_info_ind(void);
|
||||||
int pcu_tx_si13(const struct gsm_bts *bts, bool enable);
|
int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable);
|
||||||
int pcu_tx_app_info_req(struct gsm_bts *bts, uint8_t app_type, uint8_t len, const uint8_t *app_data);
|
int pcu_tx_app_info_req(struct gsm_bts *bts, uint8_t app_type, uint8_t len, const uint8_t *app_data);
|
||||||
int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
|
int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn,
|
||||||
uint16_t arfcn, uint8_t block_nr);
|
uint16_t arfcn, uint8_t block_nr);
|
||||||
@@ -15,9 +19,11 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
|||||||
int16_t qta, uint16_t ra, uint32_t fn, uint8_t is_11bit,
|
int16_t qta, uint16_t ra, uint32_t fn, uint8_t is_11bit,
|
||||||
enum ph_burst_type burst_type, uint8_t sapi);
|
enum ph_burst_type burst_type, uint8_t sapi);
|
||||||
int pcu_tx_time_ind(uint32_t fn);
|
int pcu_tx_time_ind(uint32_t fn);
|
||||||
|
int pcu_tx_interf_ind(const struct gsm_bts_trx *trx, uint32_t fn);
|
||||||
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
|
int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed);
|
||||||
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
|
int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len);
|
||||||
int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);
|
int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause);
|
||||||
|
int pcu_sock_send(struct gsm_network *net, struct msgb *msg);
|
||||||
|
|
||||||
int pcu_sock_init(const char *path);
|
int pcu_sock_init(const char *path);
|
||||||
void pcu_sock_exit(void);
|
void pcu_sock_exit(void);
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
#define _PCUIF_PROTO_H
|
#define _PCUIF_PROTO_H
|
||||||
|
|
||||||
#include <osmocom/gsm/l1sap.h>
|
#include <osmocom/gsm/l1sap.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
|
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
|
||||||
|
|
||||||
#define PCU_IF_VERSION 0x09
|
#define PCU_IF_VERSION 0x0a
|
||||||
#define TXT_MAX_LEN 128
|
#define TXT_MAX_LEN 128
|
||||||
|
|
||||||
/* msg_type */
|
/* msg_type */
|
||||||
@@ -13,15 +14,17 @@
|
|||||||
#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */
|
#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */
|
||||||
#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */
|
#define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */
|
||||||
#define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */
|
#define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */
|
||||||
#define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to tranmit APP INFO via PACCH */
|
#define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to transmit APP INFO via PACCH */
|
||||||
#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */
|
#define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */
|
||||||
#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */
|
#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */
|
||||||
#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */
|
#define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */
|
||||||
#define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */
|
#define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */
|
||||||
#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */
|
#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */
|
||||||
#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */
|
#define PCU_IF_MSG_TIME_IND 0x52 /* GSM time indication */
|
||||||
|
#define PCU_IF_MSG_INTERF_IND 0x53 /* interference report */
|
||||||
#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */
|
#define PCU_IF_MSG_PAG_REQ 0x60 /* paging request */
|
||||||
#define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */
|
#define PCU_IF_MSG_TXT_IND 0x70 /* Text indication for BTS */
|
||||||
|
#define PCU_IF_MSG_CONTAINER 0x80 /* Transparent container message */
|
||||||
|
|
||||||
/* sapi */
|
/* sapi */
|
||||||
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
|
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
|
||||||
@@ -50,6 +53,14 @@
|
|||||||
#define PCU_IF_FLAG_MCS8 (1 << 27)
|
#define PCU_IF_FLAG_MCS8 (1 << 27)
|
||||||
#define PCU_IF_FLAG_MCS9 (1 << 28)
|
#define PCU_IF_FLAG_MCS9 (1 << 28)
|
||||||
|
|
||||||
|
/* NSVC address type */
|
||||||
|
#define PCU_IF_ADDR_TYPE_UNSPEC 0x00 /* No address - empty entry */
|
||||||
|
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */
|
||||||
|
#define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */
|
||||||
|
|
||||||
|
#define PCU_IF_NUM_NSVC 2
|
||||||
|
#define PCU_IF_NUM_TRX 8
|
||||||
|
|
||||||
enum gsm_pcu_if_text_type {
|
enum gsm_pcu_if_text_type {
|
||||||
PCU_VERSION,
|
PCU_VERSION,
|
||||||
PCU_OML_ALERT,
|
PCU_OML_ALERT,
|
||||||
@@ -112,18 +123,27 @@ struct gsm_pcu_if_rach_ind {
|
|||||||
uint8_t ts_nr;
|
uint8_t ts_nr;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
struct gsm_pcu_if_info_trx_ts {
|
||||||
|
uint8_t tsc;
|
||||||
|
uint8_t hopping;
|
||||||
|
uint8_t hsn;
|
||||||
|
uint8_t maio;
|
||||||
|
uint8_t ma_bit_len;
|
||||||
|
uint8_t ma[8];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if_info_trx {
|
struct gsm_pcu_if_info_trx {
|
||||||
uint16_t arfcn;
|
uint16_t arfcn;
|
||||||
uint8_t pdch_mask; /* PDCH channels per TS */
|
uint8_t pdch_mask; /* PDCH timeslot mask */
|
||||||
uint8_t spare;
|
uint8_t spare;
|
||||||
uint8_t tsc[8]; /* TSC per channel */
|
|
||||||
uint32_t hlayer1;
|
uint32_t hlayer1;
|
||||||
|
struct gsm_pcu_if_info_trx_ts ts[8];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if_info_ind {
|
struct gsm_pcu_if_info_ind {
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
struct gsm_pcu_if_info_trx trx[8]; /* TRX infos per BTS */
|
struct gsm_pcu_if_info_trx trx[PCU_IF_NUM_TRX]; /* TRX infos per BTS */
|
||||||
uint8_t bsic;
|
uint8_t bsic;
|
||||||
/* RAI */
|
/* RAI */
|
||||||
uint16_t mcc, mnc;
|
uint16_t mcc, mnc;
|
||||||
@@ -152,10 +172,14 @@ struct gsm_pcu_if_info_ind {
|
|||||||
uint8_t initial_cs;
|
uint8_t initial_cs;
|
||||||
uint8_t initial_mcs;
|
uint8_t initial_mcs;
|
||||||
/* NSVC */
|
/* NSVC */
|
||||||
uint16_t nsvci[2];
|
uint16_t nsvci[PCU_IF_NUM_NSVC];
|
||||||
uint16_t local_port[2];
|
uint16_t local_port[PCU_IF_NUM_NSVC];
|
||||||
uint16_t remote_port[2];
|
uint16_t remote_port[PCU_IF_NUM_NSVC];
|
||||||
uint32_t remote_ip[2];
|
uint8_t address_type[PCU_IF_NUM_NSVC];
|
||||||
|
union {
|
||||||
|
struct in_addr v4;
|
||||||
|
struct in6_addr v6;
|
||||||
|
} remote_ip[PCU_IF_NUM_NSVC];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if_act_req {
|
struct gsm_pcu_if_act_req {
|
||||||
@@ -189,6 +213,22 @@ struct gsm_pcu_if_susp_req {
|
|||||||
uint8_t cause;
|
uint8_t cause;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* Interference measurements on PDCH timeslots */
|
||||||
|
struct gsm_pcu_if_interf_ind {
|
||||||
|
uint8_t trx_nr;
|
||||||
|
uint8_t spare[3];
|
||||||
|
uint32_t fn;
|
||||||
|
uint8_t interf[8];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* Contains messages transmitted BSC<->PCU, potentially forwarded by BTS via IPA/PCU */
|
||||||
|
struct gsm_pcu_if_container {
|
||||||
|
uint8_t msg_type;
|
||||||
|
uint8_t spare;
|
||||||
|
uint16_t length; /* network byte order */
|
||||||
|
uint8_t data[0];
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if {
|
struct gsm_pcu_if {
|
||||||
/* context based information */
|
/* context based information */
|
||||||
uint8_t msg_type; /* message type */
|
uint8_t msg_type; /* message type */
|
||||||
@@ -209,6 +249,8 @@ struct gsm_pcu_if {
|
|||||||
struct gsm_pcu_if_time_ind time_ind;
|
struct gsm_pcu_if_time_ind time_ind;
|
||||||
struct gsm_pcu_if_pag_req pag_req;
|
struct gsm_pcu_if_pag_req pag_req;
|
||||||
struct gsm_pcu_if_app_info_req app_info_req;
|
struct gsm_pcu_if_app_info_req app_info_req;
|
||||||
|
struct gsm_pcu_if_interf_ind interf_ind;
|
||||||
|
struct gsm_pcu_if_container container;
|
||||||
} u;
|
} u;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,12 @@
|
|||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
|
||||||
#include <osmo-bts/scheduler.h>
|
#include <osmo-bts/scheduler.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
#include "btsconfig.h"
|
#include "btsconfig.h"
|
||||||
|
|
||||||
struct gsm_bts_trx;
|
|
||||||
struct virt_um_inst;
|
struct virt_um_inst;
|
||||||
|
|
||||||
enum phy_link_type {
|
enum phy_link_type {
|
||||||
@@ -47,9 +48,10 @@ struct phy_link {
|
|||||||
uint32_t clock_advance;
|
uint32_t clock_advance;
|
||||||
uint32_t rts_advance;
|
uint32_t rts_advance;
|
||||||
bool use_legacy_setbsic;
|
bool use_legacy_setbsic;
|
||||||
uint8_t trxd_hdr_ver_max; /* Maximum TRXD header version to negotiate */
|
uint8_t trxd_pdu_ver_max; /* Maximum TRXD PDU version to negotiate */
|
||||||
bool powered; /* last POWERON (true) or POWEROFF (false) confirmed */
|
bool powered; /* last POWERON (true) or POWEROFF (false) confirmed */
|
||||||
bool poweronoff_sent; /* is there a POWERON/POWEROFF in transit? (one or the other based on ->powered) */
|
bool poweron_sent; /* is there a POWERON in transit? */
|
||||||
|
bool poweroff_sent; /* is there a POWEROFF in transit? */
|
||||||
} osmotrx;
|
} osmotrx;
|
||||||
struct {
|
struct {
|
||||||
char *mcast_dev; /* Network device for multicast */
|
char *mcast_dev; /* Network device for multicast */
|
||||||
@@ -96,7 +98,7 @@ struct phy_instance {
|
|||||||
struct phy_link *phy_link;
|
struct phy_link *phy_link;
|
||||||
|
|
||||||
/* back-pointer to the TRX to which we're associated */
|
/* back-pointer to the TRX to which we're associated */
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx; /* NOTE: may be NULL! */
|
||||||
|
|
||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
@@ -111,11 +113,8 @@ struct phy_instance {
|
|||||||
} sysmobts;
|
} sysmobts;
|
||||||
struct {
|
struct {
|
||||||
struct trx_l1h *hdl;
|
struct trx_l1h *hdl;
|
||||||
bool sw_act_reported;
|
struct trx_dl_burst_req br[TRX_NR_TS];
|
||||||
} osmotrx;
|
} osmotrx;
|
||||||
struct {
|
|
||||||
struct l1sched_trx sched;
|
|
||||||
} virt;
|
|
||||||
struct {
|
struct {
|
||||||
/* logical transceiver number within one PHY */
|
/* logical transceiver number within one PHY */
|
||||||
uint32_t trx_id;
|
uint32_t trx_id;
|
||||||
@@ -135,6 +134,7 @@ struct phy_instance {
|
|||||||
uint8_t dsp_alive_period; /* DSP alive timer period */
|
uint8_t dsp_alive_period; /* DSP alive timer period */
|
||||||
uint8_t tx_pwr_adj_mode; /* 0: no auto adjust power, 1: auto adjust power using RMS detector */
|
uint8_t tx_pwr_adj_mode; /* 0: no auto adjust power, 1: auto adjust power using RMS detector */
|
||||||
uint8_t tx_pwr_red_8psk; /* 8-PSK maximum Tx power reduction level in dB */
|
uint8_t tx_pwr_red_8psk; /* 8-PSK maximum Tx power reduction level in dB */
|
||||||
|
uint8_t tx_c0_idle_pwr_red; /* C0 idle slot Tx power reduction level in dB */
|
||||||
} lc15;
|
} lc15;
|
||||||
struct {
|
struct {
|
||||||
/* configuration */
|
/* configuration */
|
||||||
@@ -156,25 +156,26 @@ struct phy_instance {
|
|||||||
struct phy_link *phy_link_by_num(int num);
|
struct phy_link *phy_link_by_num(int num);
|
||||||
struct phy_link *phy_link_create(void *ctx, int num);
|
struct phy_link *phy_link_create(void *ctx, int num);
|
||||||
void phy_link_destroy(struct phy_link *plink);
|
void phy_link_destroy(struct phy_link *plink);
|
||||||
|
const char *phy_link_name(const struct phy_link *plink);
|
||||||
void phy_link_state_set(struct phy_link *plink, enum phy_link_state state);
|
void phy_link_state_set(struct phy_link *plink, enum phy_link_state state);
|
||||||
enum phy_link_state phy_link_state_get(struct phy_link *plink);
|
enum phy_link_state phy_link_state_get(struct phy_link *plink);
|
||||||
const char *phy_link_state_name(enum phy_link_state state);
|
const char *phy_link_state_name(enum phy_link_state state);
|
||||||
int phy_links_open(void);
|
int phy_links_open(void);
|
||||||
|
|
||||||
struct phy_instance *phy_instance_by_num(struct phy_link *plink, int num);
|
struct phy_instance *phy_instance_by_num(const struct phy_link *plink, int num);
|
||||||
struct phy_instance *phy_instance_create(struct phy_link *plink, int num);
|
struct phy_instance *phy_instance_create(struct phy_link *plink, int num);
|
||||||
void phy_instance_link_to_trx(struct phy_instance *pinst, struct gsm_bts_trx *trx);
|
void phy_instance_link_to_trx(struct phy_instance *pinst, struct gsm_bts_trx *trx);
|
||||||
void phy_instance_destroy(struct phy_instance *pinst);
|
void phy_instance_destroy(struct phy_instance *pinst);
|
||||||
const char *phy_instance_name(struct phy_instance *pinst);
|
const char *phy_instance_name(const struct phy_instance *pinst);
|
||||||
|
|
||||||
void phy_user_statechg_notif(struct phy_instance *pinst, enum phy_link_state link_state);
|
|
||||||
|
|
||||||
static inline struct phy_instance *trx_phy_instance(const struct gsm_bts_trx *trx)
|
static inline struct phy_instance *trx_phy_instance(const struct gsm_bts_trx *trx)
|
||||||
{
|
{
|
||||||
OSMO_ASSERT(trx);
|
OSMO_ASSERT(trx);
|
||||||
return trx->role_bts.l1h;
|
return trx->pinst;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bts_model_phy_link_open(struct phy_link *plink);
|
int bts_model_phy_link_open(struct phy_link *plink);
|
||||||
|
int bts_model_phy_link_close(struct phy_link *plink);
|
||||||
|
|
||||||
|
#define LOGPPHL(plink, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_link_name(plink), ##args)
|
||||||
#define LOGPPHI(pinst, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_instance_name(pinst), ##args)
|
#define LOGPPHI(pinst, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_instance_name(pinst), ##args)
|
||||||
|
|||||||
@@ -1,7 +1,90 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* MS/BS Power related measurement averaging algo */
|
||||||
|
enum gsm_power_ctrl_meas_avg_algo {
|
||||||
|
GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE = 0x00,
|
||||||
|
GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED = 0x01,
|
||||||
|
GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED = 0x02,
|
||||||
|
GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN = 0x03,
|
||||||
|
/* EWMA is an Osmocom specific algo */
|
||||||
|
GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA = 0x04,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MS/BS Power related measurement parameters */
|
||||||
|
struct gsm_power_ctrl_meas_params {
|
||||||
|
/* Thresholds (see 3GPP TS 45.008, section A.3.2.1) */
|
||||||
|
uint8_t lower_thresh; /* lower (decreasing) direction */
|
||||||
|
uint8_t upper_thresh; /* upper (increasing) direction */
|
||||||
|
|
||||||
|
/* Threshold Comparators for lower (decreasing) direction */
|
||||||
|
uint8_t lower_cmp_p; /* P1 for RxLev, P3 for RxQual */
|
||||||
|
uint8_t lower_cmp_n; /* N1 for RxLev, N3 for RxQual */
|
||||||
|
/* Threshold Comparators for upper (increasing) direction */
|
||||||
|
uint8_t upper_cmp_p; /* P2 for RxLev, P4 for RxQual */
|
||||||
|
uint8_t upper_cmp_n; /* N2 for RxLev, N4 for RxQual */
|
||||||
|
|
||||||
|
/* Hreqave and Hreqt (see 3GPP TS 45.008, Annex A) */
|
||||||
|
uint8_t h_reqave;
|
||||||
|
uint8_t h_reqt;
|
||||||
|
|
||||||
|
/* AVG algorithm and its specific parameters */
|
||||||
|
enum gsm_power_ctrl_meas_avg_algo algo;
|
||||||
|
union {
|
||||||
|
/* Exponentially Weighted Moving Average */
|
||||||
|
struct {
|
||||||
|
/* Smoothing factor: higher the value - less smoothing */
|
||||||
|
uint8_t alpha; /* 1 .. 99 (in %) */
|
||||||
|
} ewma;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* MS/BS Power Control parameters */
|
||||||
|
struct gsm_power_ctrl_params {
|
||||||
|
/* Minimum interval between power level changes */
|
||||||
|
uint8_t ctrl_interval; /* 1 step is 2 SACCH periods */
|
||||||
|
|
||||||
|
/* Power change step size (maximum) */
|
||||||
|
uint8_t inc_step_size_db; /* increasing direction */
|
||||||
|
uint8_t red_step_size_db; /* reducing direction */
|
||||||
|
|
||||||
|
/* Measurement averaging parameters for RxLev & RxQual */
|
||||||
|
struct gsm_power_ctrl_meas_params rxqual_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params rxlev_meas;
|
||||||
|
|
||||||
|
/* Measurement averaging parameters for C/I, per chan type */
|
||||||
|
struct gsm_power_ctrl_meas_params ci_fr_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params ci_hr_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params ci_amr_fr_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params ci_amr_hr_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params ci_sdcch_meas;
|
||||||
|
struct gsm_power_ctrl_meas_params ci_gprs_meas;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Measurement pre-processing state */
|
||||||
|
struct gsm_power_ctrl_meas_proc_state {
|
||||||
|
/* Number of measurements processed */
|
||||||
|
unsigned int meas_num;
|
||||||
|
/* Algorithm specific data */
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
/* Scaled up 100 times average value */
|
||||||
|
int Avg100;
|
||||||
|
} ewma;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Default MS/BS Power Control parameters */
|
||||||
|
extern const struct gsm_power_ctrl_params power_ctrl_params_def;
|
||||||
|
void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr);
|
||||||
|
|
||||||
|
struct gsm_lchan;
|
||||||
int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan,
|
int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan,
|
||||||
const uint8_t ms_power, const int rxLevel);
|
const uint8_t ms_power_lvl,
|
||||||
|
const int8_t ul_rssi_dbm,
|
||||||
|
const int16_t ul_lqual_cb);
|
||||||
|
|
||||||
|
int lchan_bs_pwr_ctrl(struct gsm_lchan *lchan,
|
||||||
|
const struct gsm48_meas_res *mr);
|
||||||
|
|||||||
@@ -1,22 +1,9 @@
|
|||||||
#ifndef _RSL_H
|
#ifndef _RSL_H
|
||||||
#define _RSL_H
|
#define _RSL_H
|
||||||
|
|
||||||
/**
|
|
||||||
* What kind of release/activation is done? A silent one for
|
|
||||||
* the PDCH or one triggered through RSL?
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
LCHAN_REL_ACT_RSL,
|
|
||||||
LCHAN_REL_ACT_PCU,
|
|
||||||
LCHAN_REL_ACT_OML,
|
|
||||||
LCHAN_REL_ACT_REACT, /* remove once auto-activation hack is removed from opstart_compl() */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LCHAN_FN_DUMMY 0xFFFFFFFF
|
#define LCHAN_FN_DUMMY 0xFFFFFFFF
|
||||||
#define LCHAN_FN_WAIT 0xFFFFFFFE
|
#define LCHAN_FN_WAIT 0xFFFFFFFE
|
||||||
|
|
||||||
int msgb_queue_flush(struct llist_head *list);
|
|
||||||
|
|
||||||
int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg);
|
int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg);
|
||||||
int rsl_tx_rf_res(struct gsm_bts_trx *trx);
|
int rsl_tx_rf_res(struct gsm_bts_trx *trx);
|
||||||
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
|
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
|
||||||
@@ -24,12 +11,10 @@ int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
|
|||||||
int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len);
|
int rsl_tx_est_ind(struct gsm_lchan *lchan, uint8_t link_id, uint8_t *data, int len);
|
||||||
|
|
||||||
int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
|
int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
|
||||||
int rsl_tx_conn_fail(struct gsm_lchan *lchan, uint8_t cause);
|
int rsl_tx_conn_fail(const struct gsm_lchan *lchan, uint8_t cause);
|
||||||
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan);
|
int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan);
|
||||||
int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay);
|
int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay);
|
||||||
|
|
||||||
int lchan_deactivate(struct gsm_lchan *lchan);
|
|
||||||
|
|
||||||
/* call-back for LAPDm code, called when it wants to send msgs UP */
|
/* call-back for LAPDm code, called when it wants to send msgs UP */
|
||||||
int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
|
int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
|
||||||
|
|
||||||
@@ -45,6 +30,6 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc);
|
|||||||
|
|
||||||
int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount);
|
int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount);
|
||||||
|
|
||||||
int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le);
|
int rsl_tx_meas_res(struct gsm_lchan *lchan, const uint8_t *l3, unsigned int l3_len, int timing_offset);
|
||||||
|
|
||||||
#endif // _RSL_H */
|
#endif // _RSL_H */
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
#ifndef TRX_SCHEDULER_H
|
#pragma once
|
||||||
#define TRX_SCHEDULER_H
|
|
||||||
|
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/core/rate_ctr.h>
|
||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
/* Whether a logical channel must be activated automatically */
|
/* Whether a logical channel must be activated automatically */
|
||||||
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
|
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
|
||||||
/* Whether a logical channel belongs to PDCH (packet switched data) */
|
|
||||||
#define TRX_CHAN_FLAG_PDCH (1 << 1)
|
|
||||||
|
|
||||||
/* FIXME: we should actually activate 'auto-active' channels */
|
/* FIXME: we should actually activate 'auto-active' channels */
|
||||||
#define TRX_CHAN_IS_ACTIVE(state, chan) \
|
#define TRX_CHAN_IS_ACTIVE(state, chan) \
|
||||||
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
|
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
|
||||||
|
|
||||||
|
#define TRX_GMSK_NB_TSC(br) \
|
||||||
|
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
||||||
|
|
||||||
|
#define TRX_8PSK_NB_TSC(br) \
|
||||||
|
_sched_train_seq_8psk_nb[(br)->tsc]
|
||||||
|
|
||||||
|
#define TRX_CHAN_IS_DEDIC(chan) \
|
||||||
|
(chan >= TRXC_TCHF)
|
||||||
|
|
||||||
/* These types define the different channels on a multiframe.
|
/* These types define the different channels on a multiframe.
|
||||||
* Each channel has queues and can be activated individually.
|
* Each channel has queues and can be activated individually.
|
||||||
*/
|
*/
|
||||||
@@ -24,6 +31,10 @@ enum trx_chan_type {
|
|||||||
TRXC_BCCH,
|
TRXC_BCCH,
|
||||||
TRXC_RACH,
|
TRXC_RACH,
|
||||||
TRXC_CCCH,
|
TRXC_CCCH,
|
||||||
|
TRXC_CBCH,
|
||||||
|
TRXC_PDTCH,
|
||||||
|
TRXC_PTCCH,
|
||||||
|
/* Dedicated channels start here */
|
||||||
TRXC_TCHF,
|
TRXC_TCHF,
|
||||||
TRXC_TCHH_0,
|
TRXC_TCHH_0,
|
||||||
TRXC_TCHH_1,
|
TRXC_TCHH_1,
|
||||||
@@ -54,9 +65,6 @@ enum trx_chan_type {
|
|||||||
TRXC_SACCH8_5,
|
TRXC_SACCH8_5,
|
||||||
TRXC_SACCH8_6,
|
TRXC_SACCH8_6,
|
||||||
TRXC_SACCH8_7,
|
TRXC_SACCH8_7,
|
||||||
TRXC_PDTCH,
|
|
||||||
TRXC_PTCCH,
|
|
||||||
TRXC_CBCH,
|
|
||||||
_TRX_CHAN_MAX
|
_TRX_CHAN_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -64,31 +72,37 @@ enum trx_chan_type {
|
|||||||
#define GPRS_BURST_LEN GSM_BURST_LEN
|
#define GPRS_BURST_LEN GSM_BURST_LEN
|
||||||
#define EGPRS_BURST_LEN 444
|
#define EGPRS_BURST_LEN 444
|
||||||
|
|
||||||
enum trx_burst_type {
|
enum trx_mod_type {
|
||||||
TRX_BURST_GMSK,
|
TRX_MOD_T_GMSK,
|
||||||
TRX_BURST_8PSK,
|
TRX_MOD_T_8PSK,
|
||||||
|
TRX_MOD_T_AQPSK,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* A set of measurements belonging to one Uplink burst */
|
||||||
|
struct l1sched_meas_set {
|
||||||
|
uint32_t fn; /* TDMA frame number */
|
||||||
|
int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */
|
||||||
|
int16_t ci_cb; /* Carrier-to-Interference (cB) */
|
||||||
|
float rssi; /* RSSI (dBm) */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* States each channel on a multiframe */
|
/* States each channel on a multiframe */
|
||||||
struct l1sched_chan_state {
|
struct l1sched_chan_state {
|
||||||
|
/* Pointer to the associated logical channel state from gsm_data_shared.
|
||||||
|
* Initialized during channel activation, thus may be NULL for inactive
|
||||||
|
* or auto-active channels. Always check before dereferencing! */
|
||||||
|
struct gsm_lchan *lchan;
|
||||||
|
|
||||||
/* scheduler */
|
/* scheduler */
|
||||||
uint8_t active; /* Channel is active */
|
bool active; /* Channel is active */
|
||||||
ubit_t *dl_bursts; /* burst buffer for TX */
|
ubit_t *dl_bursts; /* burst buffer for TX */
|
||||||
enum trx_burst_type dl_burst_type; /* GMSK or 8PSK burst type */
|
enum trx_mod_type dl_mod_type; /* Downlink modulation type */
|
||||||
sbit_t *ul_bursts; /* burst buffer for RX */
|
sbit_t *ul_bursts; /* burst buffer for RX */
|
||||||
|
sbit_t *ul_bursts_prev;/* previous burst buffer for RX (repeated SACCH) */
|
||||||
uint32_t ul_first_fn; /* fn of first burst */
|
uint32_t ul_first_fn; /* fn of first burst */
|
||||||
uint8_t ul_mask; /* mask of received bursts */
|
uint8_t ul_mask; /* mask of received bursts */
|
||||||
|
|
||||||
/* measurements */
|
|
||||||
uint8_t rssi_num; /* number of RSSI values */
|
|
||||||
float rssi_sum; /* sum of RSSI values */
|
|
||||||
uint8_t toa_num; /* number of TOA values */
|
|
||||||
int32_t toa256_sum; /* sum of TOA values (1/256 symbol) */
|
|
||||||
uint8_t ci_cb_num; /* number of C/I values */
|
|
||||||
int32_t ci_cb_sum; /* sum of C/I values (in centiBels) */
|
|
||||||
|
|
||||||
/* loss detection */
|
/* loss detection */
|
||||||
uint8_t lost_frames; /* how many L2 frames were lost */
|
|
||||||
uint32_t last_tdma_fn; /* last processed TDMA frame number */
|
uint32_t last_tdma_fn; /* last processed TDMA frame number */
|
||||||
uint32_t proc_tdma_fs; /* how many TDMA frames were processed */
|
uint32_t proc_tdma_fs; /* how many TDMA frames were processed */
|
||||||
uint32_t lost_tdma_fs; /* how many TDMA frames were lost */
|
uint32_t lost_tdma_fs; /* how many TDMA frames were lost */
|
||||||
@@ -99,18 +113,20 @@ struct l1sched_chan_state {
|
|||||||
/* AMR */
|
/* AMR */
|
||||||
uint8_t codec[4]; /* 4 possible codecs for amr */
|
uint8_t codec[4]; /* 4 possible codecs for amr */
|
||||||
int codecs; /* number of possible codecs */
|
int codecs; /* number of possible codecs */
|
||||||
float ber_sum; /* sum of bit error rates */
|
int lqual_cb_sum; /* sum of link quality samples (in cB) */
|
||||||
int ber_num; /* number of bit error rates */
|
int lqual_cb_num; /* number of link quality samples */
|
||||||
uint8_t ul_ft; /* current uplink FT index */
|
uint8_t ul_ft; /* current uplink FT index */
|
||||||
uint8_t dl_ft; /* current downlink FT index */
|
uint8_t dl_ft; /* current downlink FT index */
|
||||||
uint8_t ul_cmr; /* current uplink CMR index */
|
uint8_t ul_cmr; /* current uplink CMR index */
|
||||||
uint8_t dl_cmr; /* current downlink CMR index */
|
uint8_t dl_cmr; /* current downlink CMR index */
|
||||||
uint8_t amr_loop; /* if AMR loop is enabled */
|
uint8_t amr_last_dtx; /* last received dtx frame type */
|
||||||
|
|
||||||
/* TCH/H */
|
/* TCH/H */
|
||||||
uint8_t dl_ongoing_facch; /* FACCH/H on downlink */
|
uint8_t dl_ongoing_facch; /* FACCH/H on downlink */
|
||||||
uint8_t ul_ongoing_facch; /* FACCH/H on uplink */
|
uint8_t ul_ongoing_facch; /* FACCH/H on uplink */
|
||||||
|
|
||||||
|
uint8_t dl_facch_bursts; /* number of remaining DL FACCH bursts */
|
||||||
|
|
||||||
/* encryption */
|
/* encryption */
|
||||||
int ul_encr_algo; /* A5/x encry algo downlink */
|
int ul_encr_algo; /* A5/x encry algo downlink */
|
||||||
int dl_encr_algo; /* A5/x encry algo uplink */
|
int dl_encr_algo; /* A5/x encry algo uplink */
|
||||||
@@ -119,10 +135,14 @@ struct l1sched_chan_state {
|
|||||||
uint8_t ul_encr_key[MAX_A5_KEY_LEN];
|
uint8_t ul_encr_key[MAX_A5_KEY_LEN];
|
||||||
uint8_t dl_encr_key[MAX_A5_KEY_LEN];
|
uint8_t dl_encr_key[MAX_A5_KEY_LEN];
|
||||||
|
|
||||||
/* measurements */
|
/* Uplink measurements */
|
||||||
struct {
|
struct {
|
||||||
int32_t toa256_sum; /* sum of TOA values (1/256 symbol) */
|
/* Active channel measurements (simple ring buffer) */
|
||||||
int toa_num; /* number of TOA value */
|
struct l1sched_meas_set buf[8]; /* up to 8 entries */
|
||||||
|
unsigned int current; /* current position */
|
||||||
|
|
||||||
|
/* Interference measurements */
|
||||||
|
int interf_avg; /* sliding average */
|
||||||
} meas;
|
} meas;
|
||||||
|
|
||||||
/* handover */
|
/* handover */
|
||||||
@@ -130,42 +150,32 @@ struct l1sched_chan_state {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct l1sched_ts {
|
struct l1sched_ts {
|
||||||
|
struct gsm_bts_trx_ts *ts; /* timeslot we belong to */
|
||||||
|
|
||||||
uint8_t mf_index; /* selected multiframe index */
|
uint8_t mf_index; /* selected multiframe index */
|
||||||
uint8_t mf_period; /* period of multiframe */
|
uint8_t mf_period; /* period of multiframe */
|
||||||
const struct trx_sched_frame *mf_frames; /* pointer to frame layout */
|
const struct trx_sched_frame *mf_frames; /* pointer to frame layout */
|
||||||
|
|
||||||
struct llist_head dl_prims; /* Queue primitives for TX */
|
struct llist_head dl_prims; /* Queue primitives for TX */
|
||||||
|
|
||||||
|
struct rate_ctr_group *ctrs; /* rate counters */
|
||||||
|
|
||||||
/* Channel states for all logical channels */
|
/* Channel states for all logical channels */
|
||||||
struct l1sched_chan_state chan_state[_TRX_CHAN_MAX];
|
struct l1sched_chan_state chan_state[_TRX_CHAN_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct l1sched_trx {
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
struct l1sched_ts ts[TRX_NR_TS];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct l1sched_ts *l1sched_trx_get_ts(struct l1sched_trx *l1t, uint8_t tn);
|
|
||||||
|
|
||||||
/*! \brief how many frame numbers in advance we should send bursts to PHY */
|
|
||||||
extern uint32_t trx_clock_advance;
|
|
||||||
/*! \brief advance RTS.ind to L2 by that many clocks */
|
|
||||||
extern uint32_t trx_rts_advance;
|
|
||||||
/*! \brief last frame number as received from PHY */
|
|
||||||
extern uint32_t transceiver_last_fn;
|
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Initialize the scheduler data structures */
|
/*! \brief Initialize the scheduler data structures */
|
||||||
int trx_sched_init(struct l1sched_trx *l1t, struct gsm_bts_trx *trx);
|
void trx_sched_init(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
/*! \brief De-initialize the scheduler data structures */
|
/*! \brief De-initialize the scheduler data structures */
|
||||||
void trx_sched_exit(struct l1sched_trx *l1t);
|
void trx_sched_clean(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
/*! \brief Handle a PH-DATA.req from L2 down to L1 */
|
/*! \brief Handle a PH-DATA.req from L2 down to L1 */
|
||||||
int trx_sched_ph_data_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);
|
int trx_sched_ph_data_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);
|
||||||
|
|
||||||
/*! \brief Handle a PH-TCH.req from L2 down to L1 */
|
/*! \brief Handle a PH-TCH.req from L2 down to L1 */
|
||||||
int trx_sched_tch_req(struct l1sched_trx *l1t, struct osmo_phsap_prim *l1sap);
|
int trx_sched_tch_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap);
|
||||||
|
|
||||||
/*! \brief PHY informs us of new (current) GSM frame number */
|
/*! \brief PHY informs us of new (current) GSM frame number */
|
||||||
int trx_sched_clock(struct gsm_bts *bts, uint32_t fn);
|
int trx_sched_clock(struct gsm_bts *bts, uint32_t fn);
|
||||||
@@ -177,26 +187,19 @@ int trx_sched_clock_started(struct gsm_bts *bts);
|
|||||||
int trx_sched_clock_stopped(struct gsm_bts *bts);
|
int trx_sched_clock_stopped(struct gsm_bts *bts);
|
||||||
|
|
||||||
/*! \brief set multiframe scheduler to given physical channel config */
|
/*! \brief set multiframe scheduler to given physical channel config */
|
||||||
int trx_sched_set_pchan(struct l1sched_trx *l1t, uint8_t tn,
|
int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan);
|
||||||
enum gsm_phys_chan_config pchan);
|
|
||||||
|
|
||||||
/*! \brief set all matching logical channels active/inactive */
|
/*! \brief set all matching logical channels active/inactive */
|
||||||
int trx_sched_set_lchan(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t link_id,
|
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
|
||||||
int active);
|
|
||||||
|
|
||||||
/*! \brief set mode of all matching logical channels to given mode(s) */
|
/*! \brief set mode of all matching logical channels to given mode(s) */
|
||||||
int trx_sched_set_mode(struct l1sched_trx *l1t, uint8_t chan_nr, uint8_t rsl_cmode,
|
int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode,
|
||||||
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1,
|
||||||
uint8_t codec2, uint8_t codec3, uint8_t initial_codec,
|
uint8_t codec2, uint8_t codec3, uint8_t initial_codec,
|
||||||
uint8_t handover);
|
uint8_t handover);
|
||||||
|
|
||||||
/*! \brief set ciphering on given logical channels */
|
/*! \brief set ciphering on given logical channels */
|
||||||
int trx_sched_set_cipher(struct l1sched_trx *l1t, uint8_t chan_nr, int downlink,
|
int trx_sched_set_cipher(struct gsm_lchan *lchan, uint8_t chan_nr, bool downlink);
|
||||||
int algo, uint8_t *key, int key_len);
|
|
||||||
|
|
||||||
/* \brief close all logical channels and reset timeslots */
|
|
||||||
void trx_sched_reset(struct l1sched_trx *l1t);
|
|
||||||
|
|
||||||
|
|
||||||
/* frame structures */
|
/* frame structures */
|
||||||
struct trx_sched_frame {
|
struct trx_sched_frame {
|
||||||
@@ -227,13 +230,17 @@ struct trx_sched_multiframe {
|
|||||||
int find_sched_mframe_idx(enum gsm_phys_chan_config pchan, uint8_t tn);
|
int find_sched_mframe_idx(enum gsm_phys_chan_config pchan, uint8_t tn);
|
||||||
|
|
||||||
/*! Determine if given frame number contains SACCH (true) or other (false) burst */
|
/*! Determine if given frame number contains SACCH (true) or other (false) burst */
|
||||||
bool trx_sched_is_sacch_fn(struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink);
|
bool trx_sched_is_sacch_fn(const struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink);
|
||||||
extern const struct trx_sched_multiframe trx_sched_multiframes[];
|
extern const struct trx_sched_multiframe trx_sched_multiframes[];
|
||||||
|
|
||||||
#define TRX_BI_F_NOPE_IND (1 << 0)
|
#define TRX_BI_F_NOPE_IND (1 << 0)
|
||||||
#define TRX_BI_F_MOD_TYPE (1 << 1)
|
#define TRX_BI_F_MOD_TYPE (1 << 1)
|
||||||
#define TRX_BI_F_TS_INFO (1 << 2)
|
#define TRX_BI_F_TS_INFO (1 << 2)
|
||||||
#define TRX_BI_F_CI_CB (1 << 3)
|
#define TRX_BI_F_CI_CB (1 << 3)
|
||||||
|
#define TRX_BI_F_TRX_NUM (1 << 4)
|
||||||
|
#define TRX_BI_F_BATCH_IND (1 << 5)
|
||||||
|
#define TRX_BI_F_SHADOW_IND (1 << 6)
|
||||||
|
#define TRX_BI_F_ACCESS_BURST (1 << 7)
|
||||||
|
|
||||||
/*! UL burst indication with the corresponding meta info */
|
/*! UL burst indication with the corresponding meta info */
|
||||||
struct trx_ul_burst_ind {
|
struct trx_ul_burst_ind {
|
||||||
@@ -247,17 +254,76 @@ struct trx_ul_burst_ind {
|
|||||||
int8_t rssi; /*!< Received Signal Strength Indication */
|
int8_t rssi; /*!< Received Signal Strength Indication */
|
||||||
|
|
||||||
/* Optional fields (defined by flags) */
|
/* Optional fields (defined by flags) */
|
||||||
enum trx_burst_type bt; /*!< Modulation type */
|
enum trx_mod_type mod; /*!< Modulation type */
|
||||||
uint8_t tsc_set; /*!< Training Sequence Set */
|
uint8_t tsc_set; /*!< Training Sequence Set */
|
||||||
uint8_t tsc; /*!< Training Sequence Code */
|
uint8_t tsc; /*!< Training Sequence Code */
|
||||||
int16_t ci_cb; /*!< Carrier-to-Interference ratio (in centiBels) */
|
int16_t ci_cb; /*!< Carrier-to-Interference ratio (in centiBels) */
|
||||||
|
uint8_t trx_num; /*!< TRX (RF channel) number */
|
||||||
|
|
||||||
|
/* Used internally by the PDU parser */
|
||||||
|
uint8_t _num_pdus; /*!< Number of processed PDUs */
|
||||||
|
|
||||||
|
/* Internally used by the scheduler */
|
||||||
|
enum trx_chan_type chan;
|
||||||
|
uint8_t bid;
|
||||||
|
|
||||||
/*! Burst soft-bits buffer */
|
/*! Burst soft-bits buffer */
|
||||||
sbit_t burst[EGPRS_BURST_LEN];
|
sbit_t burst[EGPRS_BURST_LEN];
|
||||||
size_t burst_len;
|
size_t burst_len;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! Handle an UL burst received by PHY */
|
#define TRX_BR_F_FACCH (1 << 0)
|
||||||
int trx_sched_ul_burst(struct l1sched_trx *l1t, struct trx_ul_burst_ind *bi);
|
|
||||||
|
|
||||||
#endif /* TRX_SCHEDULER_H */
|
/*! DL burst request with the corresponding meta info */
|
||||||
|
struct trx_dl_burst_req {
|
||||||
|
uint8_t flags; /*!< see TRX_BR_F_* */
|
||||||
|
|
||||||
|
/* Mandatory fields */
|
||||||
|
uint32_t fn; /*!< TDMA frame number */
|
||||||
|
uint8_t tn; /*!< TDMA timeslot number */
|
||||||
|
uint8_t att; /*!< Tx power attenuation */
|
||||||
|
int8_t scpir; /*!< SCPIR (for AQPSK only) */
|
||||||
|
uint8_t trx_num; /*!< TRX (RF channel) number */
|
||||||
|
|
||||||
|
enum trx_mod_type mod; /*!< Modulation type */
|
||||||
|
uint8_t tsc_set; /*!< Training Sequence Set */
|
||||||
|
uint8_t tsc; /*!< Training Sequence Code */
|
||||||
|
|
||||||
|
/* Internally used by the scheduler */
|
||||||
|
enum trx_chan_type chan;
|
||||||
|
uint8_t bid;
|
||||||
|
|
||||||
|
/*! Burst hard-bits buffer */
|
||||||
|
ubit_t burst[EGPRS_BURST_LEN];
|
||||||
|
size_t burst_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Handle an UL burst received by PHY */
|
||||||
|
int trx_sched_route_burst_ind(const struct gsm_bts_trx *trx, struct trx_ul_burst_ind *bi);
|
||||||
|
int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi);
|
||||||
|
|
||||||
|
/* Averaging mode for trx_sched_meas_avg() */
|
||||||
|
enum sched_meas_avg_mode {
|
||||||
|
/* last 4 bursts (default for xCCH, PTCCH and PDTCH) */
|
||||||
|
SCHED_MEAS_AVG_M_S4N4,
|
||||||
|
/* last 8 bursts (default for TCH/F and FACCH/F) */
|
||||||
|
SCHED_MEAS_AVG_M_S8N8,
|
||||||
|
/* first 4 of last 6 bursts (default for TCH/H) */
|
||||||
|
SCHED_MEAS_AVG_M_S6N4,
|
||||||
|
/* last 6 bursts (default for FACCH/H) */
|
||||||
|
SCHED_MEAS_AVG_M_S6N6,
|
||||||
|
/* first 4 of last 8 bursts */
|
||||||
|
SCHED_MEAS_AVG_M_S8N4,
|
||||||
|
/* first 2 of last 6 bursts */
|
||||||
|
SCHED_MEAS_AVG_M_S6N2,
|
||||||
|
/* middle 2 of last 6 bursts */
|
||||||
|
SCHED_MEAS_AVG_M_S4N2,
|
||||||
|
};
|
||||||
|
|
||||||
|
void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
|
||||||
|
const struct trx_ul_burst_ind *bi);
|
||||||
|
void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state,
|
||||||
|
struct l1sched_meas_set *avg,
|
||||||
|
enum sched_meas_avg_mode mode);
|
||||||
|
uint32_t trx_sched_lookup_fn(const struct l1sched_chan_state *chan_state,
|
||||||
|
const unsigned int shift);
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define LOGL1S(subsys, level, l1t, tn, chan, fn, fmt, args ...) \
|
#define LOGL1S(subsys, level, l1ts, chan, fn, fmt, args ...) \
|
||||||
LOGP(subsys, level, "%s %s %s: " fmt, \
|
LOGP(subsys, level, "%s %s %s: " fmt, \
|
||||||
gsm_fn_as_gsmtime_str(fn), \
|
gsm_fn_as_gsmtime_str(fn), \
|
||||||
gsm_ts_name(&(l1t)->trx->ts[tn]), \
|
gsm_ts_name((l1ts)->ts), \
|
||||||
chan >=0 ? trx_chan_desc[chan].name : "", ## args)
|
chan >=0 ? trx_chan_desc[chan].name : "", ## args)
|
||||||
|
|
||||||
typedef int trx_sched_rts_func(struct l1sched_trx *l1t, uint8_t tn,
|
/* Logging helper adding context from trx_{ul,dl}_burst_{ind,req} */
|
||||||
uint32_t fn, enum trx_chan_type chan);
|
#define LOGL1SB(subsys, level, l1ts, b, fmt, args ...) \
|
||||||
|
LOGL1S(subsys, level, l1ts, (b)->chan, (b)->fn, fmt, ## args)
|
||||||
|
|
||||||
typedef ubit_t *trx_sched_dl_func(struct l1sched_trx *l1t, uint8_t tn,
|
typedef int trx_sched_rts_func(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
|
||||||
uint32_t fn, enum trx_chan_type chan,
|
typedef int trx_sched_dl_func(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
uint8_t bid, uint16_t *nbits);
|
typedef int trx_sched_ul_func(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
|
|
||||||
typedef int trx_sched_ul_func(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
|
|
||||||
struct trx_chan_desc {
|
struct trx_chan_desc {
|
||||||
/*! \brief Human-readable name */
|
/*! \brief Human-readable name */
|
||||||
@@ -31,58 +29,43 @@ struct trx_chan_desc {
|
|||||||
trx_sched_dl_func *dl_fn;
|
trx_sched_dl_func *dl_fn;
|
||||||
/*! \brief function to call when burst received from PHY */
|
/*! \brief function to call when burst received from PHY */
|
||||||
trx_sched_ul_func *ul_fn;
|
trx_sched_ul_func *ul_fn;
|
||||||
/*! \brief function to call when NOPE.ind received from PHY */
|
|
||||||
trx_sched_ul_func *nope_fn;
|
|
||||||
/*! \brief channel flags, see TRX_CHAN_FLAG_* */
|
/*! \brief channel flags, see TRX_CHAN_FLAG_* */
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
};
|
};
|
||||||
extern const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX];
|
extern const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX];
|
||||||
|
|
||||||
extern const ubit_t _sched_tsc[8][26];
|
extern const ubit_t _sched_dummy_burst[];
|
||||||
extern const ubit_t _sched_egprs_tsc[8][78];
|
extern const ubit_t _sched_train_seq_gmsk_nb[4][8][26];
|
||||||
const ubit_t _sched_fcch_burst[148];
|
extern const ubit_t _sched_train_seq_8psk_nb[8][78];
|
||||||
const ubit_t _sched_sch_train[64];
|
extern const ubit_t _sched_train_seq_gmsk_sb[64];
|
||||||
|
|
||||||
struct msgb *_sched_dequeue_prim(struct l1sched_trx *l1t, int8_t tn, uint32_t fn,
|
struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
|
||||||
enum trx_chan_type chan);
|
|
||||||
|
|
||||||
int _sched_compose_ph_data_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,
|
||||||
enum trx_chan_type chan, uint8_t *l2,
|
enum trx_chan_type chan, uint8_t *l2,
|
||||||
uint8_t l2_len, float rssi,
|
uint8_t l2_len, float rssi,
|
||||||
int16_t ta_offs_256bits, int16_t link_qual_cb,
|
int16_t ta_offs_256bits, int16_t link_qual_cb,
|
||||||
uint16_t ber10k,
|
uint16_t ber10k,
|
||||||
enum osmo_ph_pres_info_type presence_info);
|
enum osmo_ph_pres_info_type presence_info);
|
||||||
|
|
||||||
int _sched_compose_tch_ind(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
|
||||||
enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
|
enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
|
||||||
int16_t ta_offs_256bits, uint16_t ber10k, float rssi);
|
int16_t ta_offs_256bits, uint16_t ber10k, float rssi,
|
||||||
|
int16_t link_qual_cb, uint8_t is_sub);
|
||||||
|
|
||||||
ubit_t *tx_idle_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
ubit_t *tx_fcch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
int tx_data_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
ubit_t *tx_sch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
ubit_t *tx_data_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
|
||||||
ubit_t *tx_pdtch_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
|
||||||
ubit_t *tx_tchf_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
|
||||||
ubit_t *tx_tchh_fn(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn,
|
|
||||||
enum trx_chan_type chan, uint8_t bid, uint16_t *nbits);
|
|
||||||
int rx_rach_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
int rx_data_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
int rx_pdtch_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
int rx_tchf_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
int rx_tchh_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,
|
|
||||||
uint8_t bid, const struct trx_ul_burst_ind *bi);
|
|
||||||
|
|
||||||
const ubit_t *_sched_dl_burst(struct l1sched_trx *l1t, uint8_t tn,
|
int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
uint32_t fn, uint16_t *nbits);
|
int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
int _sched_rts(struct l1sched_trx *l1t, uint8_t tn, uint32_t fn);
|
int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
void _sched_act_rach_det(struct l1sched_trx *l1t, uint8_t tn, uint8_t ss, int activate);
|
int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
|
int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi);
|
||||||
|
|
||||||
|
void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
|
int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn);
|
||||||
|
void _sched_act_rach_det(struct gsm_bts_trx *trx, uint8_t tn, uint8_t ss, int activate);
|
||||||
|
|||||||
@@ -15,4 +15,10 @@ enum signals_global {
|
|||||||
S_NEW_NSVC_ATTR,
|
S_NEW_NSVC_ATTR,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nm_statechg_signal_data {
|
||||||
|
struct gsm_abis_mo *mo;
|
||||||
|
uint8_t old_state;
|
||||||
|
uint8_t new_state;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
void lchan_ms_ta_ctrl(struct gsm_lchan *lchan);
|
void lchan_ms_ta_ctrl(struct gsm_lchan *lchan, uint8_t ms_tx_ta, int16_t toa256);
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ struct power_amp {
|
|||||||
struct pa_calibration calib;
|
struct pa_calibration calib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*ramp_compl_cb_t)(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
/* Transmit power related parameters of a transceiver */
|
/* Transmit power related parameters of a transceiver */
|
||||||
struct trx_power_params {
|
struct trx_power_params {
|
||||||
/* specified maximum output of TRX at full power, has to be
|
/* specified maximum output of TRX at full power, has to be
|
||||||
@@ -55,24 +57,34 @@ struct trx_power_params {
|
|||||||
unsigned int step_size_mdB;
|
unsigned int step_size_mdB;
|
||||||
unsigned int step_interval_sec;
|
unsigned int step_interval_sec;
|
||||||
struct osmo_timer_list step_timer;
|
struct osmo_timer_list step_timer;
|
||||||
|
/* call-back called when target is reached */
|
||||||
|
ramp_compl_cb_t compl_cb;
|
||||||
} ramp;
|
} ramp;
|
||||||
};
|
};
|
||||||
|
|
||||||
int get_p_max_out_mdBm(struct gsm_bts_trx *trx);
|
int get_p_max_out_mdBm(const struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
int get_p_nominal_mdBm(struct gsm_bts_trx *trx);
|
int get_p_nominal_mdBm(const struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
int get_p_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
|
int get_p_target_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red);
|
||||||
int get_p_target_mdBm_lchan(struct gsm_lchan *lchan);
|
int get_p_target_mdBm_lchan(const struct gsm_lchan *lchan);
|
||||||
|
|
||||||
int get_p_trxout_target_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
|
int get_p_actual_mdBm(const struct gsm_bts_trx *trx, int p_target_mdBm);
|
||||||
int get_p_trxout_target_mdBm_lchan(struct gsm_lchan *lchan);
|
|
||||||
|
|
||||||
int get_p_trxout_actual_mdBm(struct gsm_bts_trx *trx, uint8_t bs_power_ie);
|
int get_p_trxout_target_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red);
|
||||||
int get_p_trxout_actual_mdBm_lchan(struct gsm_lchan *lchan);
|
int get_p_trxout_target_mdBm_lchan(const struct gsm_lchan *lchan);
|
||||||
|
|
||||||
int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass);
|
int get_p_trxout_actual_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red);
|
||||||
|
int get_p_trxout_actual_mdBm_lchan(const struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
int _power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass_max_power, ramp_compl_cb_t ramp_compl_cb, bool skip_ramping);
|
||||||
|
#define power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \
|
||||||
|
_power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, false)
|
||||||
|
#define power_ramp_force(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \
|
||||||
|
_power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, true)
|
||||||
|
|
||||||
|
void power_ramp_abort(struct gsm_bts_trx *trx);
|
||||||
|
|
||||||
void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm);
|
void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm);
|
||||||
|
|
||||||
int power_ramp_initial_power_mdBm(struct gsm_bts_trx *trx);
|
int power_ramp_initial_power_mdBm(const struct gsm_bts_trx *trx);
|
||||||
|
|||||||
@@ -12,11 +12,9 @@ enum bts_vty_node {
|
|||||||
PHY_INST_NODE,
|
PHY_INST_NODE,
|
||||||
BTS_NODE,
|
BTS_NODE,
|
||||||
TRX_NODE,
|
TRX_NODE,
|
||||||
|
OSMUX_NODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct cmd_element ournode_exit_cmd;
|
|
||||||
extern struct cmd_element ournode_end_cmd;
|
|
||||||
|
|
||||||
extern struct cmd_element cfg_bts_auto_band_cmd;
|
extern struct cmd_element cfg_bts_auto_band_cmd;
|
||||||
extern struct cmd_element cfg_bts_no_auto_band_cmd;
|
extern struct cmd_element cfg_bts_no_auto_band_cmd;
|
||||||
|
|
||||||
@@ -25,10 +23,17 @@ struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_
|
|||||||
int bts_vty_go_parent(struct vty *vty);
|
int bts_vty_go_parent(struct vty *vty);
|
||||||
int bts_vty_is_config_node(struct vty *vty, int node);
|
int bts_vty_is_config_node(struct vty *vty, int node);
|
||||||
|
|
||||||
int bts_vty_init(struct gsm_bts *bts);
|
int bts_vty_init(void *ctx);
|
||||||
|
|
||||||
struct gsm_network *gsmnet_from_vty(struct vty *v);
|
struct gsm_network *gsmnet_from_vty(struct vty *v);
|
||||||
|
|
||||||
extern struct vty_app_info bts_vty_info;
|
extern struct vty_app_info bts_vty_info;
|
||||||
|
extern struct gsm_bts *g_bts;
|
||||||
|
|
||||||
|
enum bts_vty_cmd_attr {
|
||||||
|
BTS_VTY_ATTR_NEW_LCHAN,
|
||||||
|
BTS_VTY_TRX_POWERCYCLE,
|
||||||
|
/* NOTE: up to 32 entries */
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ SUBDIRS += osmo-bts-octphy
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_LC15BTS
|
if ENABLE_LC15BTS
|
||||||
SUBDIRS += osmo-bts-litecell15
|
SUBDIRS += osmo-bts-lc15
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if ENABLE_OC2GBTS
|
if ENABLE_OC2GBTS
|
||||||
|
|||||||
@@ -1,17 +1,79 @@
|
|||||||
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
|
AM_CPPFLAGS = \
|
||||||
AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS)
|
$(all_includes) \
|
||||||
LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS)
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_builddir)/include \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
AM_CFLAGS = \
|
||||||
|
-Wall \
|
||||||
|
$(LIBOSMOCORE_CFLAGS) \
|
||||||
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
|
$(LIBOSMOCODEC_CFLAGS) \
|
||||||
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
LDADD = \
|
||||||
|
$(LIBOSMOCORE_LIBS) \
|
||||||
|
$(LIBOSMOTRAU_LIBS) \
|
||||||
|
$(LIBOSMOCODEC_LIBS) \
|
||||||
|
$(LIBOSMONETIF_LIBS) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
if ENABLE_LC15BTS
|
if ENABLE_LC15BTS
|
||||||
AM_CFLAGS += -DENABLE_LC15BTS
|
AM_CFLAGS += -DENABLE_LC15BTS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
noinst_LIBRARIES = libbts.a libl1sched.a
|
noinst_LIBRARIES = libbts.a libl1sched.a
|
||||||
libbts_a_SOURCES = gsm_data_shared.c sysinfo.c logging.c abis.c oml.c bts.c \
|
libbts_a_SOURCES = \
|
||||||
rsl.c vty.c paging.c measurement.c amr.c lchan.c \
|
gsm_data.c \
|
||||||
load_indication.c pcu_sock.c handover.c msg_utils.c \
|
sysinfo.c \
|
||||||
tx_power.c bts_ctrl_commands.c bts_ctrl_lookup.c \
|
logging.c \
|
||||||
l1sap.c cbch.c power_control.c main.c phy_link.c \
|
abis.c \
|
||||||
dtx_dl_amr_fsm.c scheduler_mframe.c ta_control.c
|
abis_osmo.c \
|
||||||
|
oml.c \
|
||||||
|
osmux.c \
|
||||||
|
bts.c \
|
||||||
|
bts_trx.c \
|
||||||
|
rsl.c \
|
||||||
|
vty.c \
|
||||||
|
paging.c \
|
||||||
|
measurement.c \
|
||||||
|
amr.c \
|
||||||
|
lchan.c \
|
||||||
|
load_indication.c \
|
||||||
|
pcu_sock.c \
|
||||||
|
handover.c \
|
||||||
|
msg_utils.c \
|
||||||
|
tx_power.c \
|
||||||
|
bts_ctrl_commands.c \
|
||||||
|
bts_ctrl_lookup.c \
|
||||||
|
bts_shutdown_fsm.c \
|
||||||
|
l1sap.c \
|
||||||
|
cbch.c \
|
||||||
|
power_control.c \
|
||||||
|
main.c \
|
||||||
|
phy_link.c \
|
||||||
|
dtx_dl_amr_fsm.c \
|
||||||
|
scheduler_mframe.c \
|
||||||
|
ta_control.c \
|
||||||
|
nm_common_fsm.c \
|
||||||
|
nm_bts_sm_fsm.c \
|
||||||
|
nm_bts_fsm.c \
|
||||||
|
nm_bb_transc_fsm.c \
|
||||||
|
nm_channel_fsm.c \
|
||||||
|
nm_radio_carrier_fsm.c \
|
||||||
|
probes.d \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
libl1sched_a_SOURCES = scheduler.c
|
libl1sched_a_SOURCES = scheduler.c
|
||||||
|
|
||||||
|
if ENABLE_SYSTEMTAP
|
||||||
|
probes.h: probes.d
|
||||||
|
$(DTRACE) -C -h -s $< -o $@
|
||||||
|
|
||||||
|
probes.lo: probes.d
|
||||||
|
$(LIBTOOL) --mode=compile $(AM_V_lt) --tag=CC env CFLAGS="$(CFLAGS)" $(DTRACE) -C -G -s $< -o $@
|
||||||
|
|
||||||
|
BUILT_SOURCES = probes.h probes.lo
|
||||||
|
libbts_la_LDADD = probes.lo
|
||||||
|
endif
|
||||||
|
|||||||
@@ -38,46 +38,319 @@
|
|||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
#include <osmocom/core/signal.h>
|
#include <osmocom/core/signal.h>
|
||||||
#include <osmocom/core/macaddr.h>
|
#include <osmocom/core/macaddr.h>
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
#include <osmocom/abis/abis.h>
|
#include <osmocom/abis/abis.h>
|
||||||
#include <osmocom/abis/e1_input.h>
|
#include <osmocom/abis/e1_input.h>
|
||||||
#include <osmocom/abis/ipaccess.h>
|
#include <osmocom/abis/ipaccess.h>
|
||||||
#include <osmocom/gsm/ipa.h>
|
#include <osmocom/gsm/ipa.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/abis.h>
|
||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
#include <osmo-bts/bts.h>
|
#include <osmo-bts/bts.h>
|
||||||
#include <osmo-bts/rsl.h>
|
#include <osmo-bts/rsl.h>
|
||||||
#include <osmo-bts/oml.h>
|
#include <osmo-bts/oml.h>
|
||||||
|
#include <osmo-bts/abis_osmo.h>
|
||||||
#include <osmo-bts/bts_model.h>
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
#include <osmo-bts/bts_shutdown_fsm.h>
|
||||||
|
|
||||||
static struct gsm_bts *g_bts;
|
static struct gsm_bts *g_bts;
|
||||||
|
|
||||||
|
static struct e1inp_line_ops line_ops;
|
||||||
|
|
||||||
|
static struct ipaccess_unit bts_dev_info;
|
||||||
|
|
||||||
|
#define S(x) (1 << (x))
|
||||||
|
#define OML_RETRY_TIMER 5
|
||||||
|
|
||||||
|
enum abis_link_fsm_state {
|
||||||
|
ABIS_LINK_ST_WAIT_RECONNECT, /* OML link has not yet been established */
|
||||||
|
ABIS_LINK_ST_CONNECTING, /* OML link in process of been established */
|
||||||
|
ABIS_LINK_ST_CONNECTED, /* OML link is established, RSL links may be established or not */
|
||||||
|
ABIS_LINK_ST_FAILED, /* There used to be an active OML connection but it became broken */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct value_string abis_link_fsm_event_names[] = {
|
||||||
|
{ ABIS_LINK_EV_SIGN_LINK_OML_UP, "SIGN_LINK_OML_UP", },
|
||||||
|
{ ABIS_LINK_EV_SIGN_LINK_DOWN, "SIGN_LINK_DOWN" },
|
||||||
|
{ ABIS_LINK_EV_VTY_RM_ADDR, "VTY_RM_ADDR" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct abis_link_fsm_priv {
|
||||||
|
struct bsc_oml_host *current_bsc;
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
char *model_name;
|
||||||
|
bool reconnect_to_current_bsc;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void reset_oml_link(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
if (bts->oml_link) {
|
||||||
|
struct timespec now;
|
||||||
|
|
||||||
|
e1inp_sign_link_destroy(bts->oml_link);
|
||||||
|
|
||||||
|
/* Log a special notice if the OML connection was dropped relatively quickly. */
|
||||||
|
if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
|
||||||
|
bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) {
|
||||||
|
LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. "
|
||||||
|
"If this situation persists, please check your BTS and BSC configuration files for errors. "
|
||||||
|
"A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",
|
||||||
|
(uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));
|
||||||
|
}
|
||||||
|
bts->oml_link = NULL;
|
||||||
|
}
|
||||||
|
memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));
|
||||||
|
|
||||||
|
/* Same for IPAC_PROTO_OSMO on the same ipa connection: */
|
||||||
|
if (bts->osmo_link) {
|
||||||
|
e1inp_sign_link_destroy(bts->osmo_link);
|
||||||
|
bts->osmo_link = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pick_next_bsc(struct osmo_fsm_inst *fi)
|
||||||
|
{
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
struct bsc_oml_host *last;
|
||||||
|
|
||||||
|
if (llist_empty(&bts->bsc_oml_hosts)) {
|
||||||
|
LOGPFSML(fi, LOGL_ERROR, "List of BSCs to connect to is empty!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep current pointer to priv->current_bsc: */
|
||||||
|
if (priv->reconnect_to_current_bsc) {
|
||||||
|
OSMO_ASSERT(priv->current_bsc);
|
||||||
|
priv->reconnect_to_current_bsc = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
last = (struct bsc_oml_host *)llist_last_entry(&bts->bsc_oml_hosts, struct bsc_oml_host, list);
|
||||||
|
|
||||||
|
if (!priv->current_bsc || priv->current_bsc == last) /* Pick first one (wrap around): */
|
||||||
|
priv->current_bsc = (struct bsc_oml_host *)llist_first_entry(&bts->bsc_oml_hosts, struct bsc_oml_host, list);
|
||||||
|
else
|
||||||
|
priv->current_bsc = (struct bsc_oml_host *)llist_entry(priv->current_bsc->list.next, struct bsc_oml_host, list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_connecting_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct e1inp_line *line;
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
|
||||||
|
if (bts_shutdown_in_progress(bts)) {
|
||||||
|
LOGPFSML(fi, LOGL_NOTICE, "BTS is shutting down, delaying A-bis connection establishment to BSC\n");
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick_next_bsc(fi) < 0) {
|
||||||
|
LOGPFSML(fi, LOGL_FATAL, "No BSC available, A-bis connection establishment failed\n");
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGP(DABIS, LOGL_NOTICE, "A-bis connection establishment to BSC (%s) in progress...\n", priv->current_bsc->addr);
|
||||||
|
|
||||||
|
/* patch in various data from VTY and other sources */
|
||||||
|
line_ops.cfg.ipa.addr = priv->current_bsc->addr;
|
||||||
|
osmo_get_macaddr(bts_dev_info.mac_addr, "eth0");
|
||||||
|
bts_dev_info.site_id = bts->ip_access.site_id;
|
||||||
|
bts_dev_info.bts_id = bts->ip_access.bts_id;
|
||||||
|
bts_dev_info.unit_name = priv->model_name;
|
||||||
|
if (bts->description)
|
||||||
|
bts_dev_info.unit_name = bts->description;
|
||||||
|
bts_dev_info.location2 = priv->model_name;
|
||||||
|
|
||||||
|
line = e1inp_line_find(0);
|
||||||
|
if (!line)
|
||||||
|
line = e1inp_line_create(0, "ipa");
|
||||||
|
if (!line) {
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Line always comes already with a "ctor" reference, enough to keep it alive forever. */
|
||||||
|
|
||||||
|
e1inp_line_bind_ops(line, &line_ops);
|
||||||
|
/* This will open the OML connection now */
|
||||||
|
if (e1inp_line_update(line) < 0) {
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The TCP connection to the BSC is now in progress.
|
||||||
|
* Wait for OML Link UP to transition to CONNECTED. */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_connecting(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case ABIS_LINK_EV_SIGN_LINK_OML_UP:
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTED, 0, 0);
|
||||||
|
break;
|
||||||
|
case ABIS_LINK_EV_SIGN_LINK_DOWN:
|
||||||
|
reset_oml_link(bts);
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_connected_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
bts_link_estab(g_bts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
OSMO_ASSERT(event == ABIS_LINK_EV_SIGN_LINK_DOWN);
|
||||||
|
|
||||||
|
/* First remove the OML signalling link */
|
||||||
|
reset_oml_link(bts);
|
||||||
|
|
||||||
|
/* Then iterate over the RSL signalling links */
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->rsl_link) {
|
||||||
|
e1inp_sign_link_destroy(trx->rsl_link);
|
||||||
|
trx->rsl_link = NULL;
|
||||||
|
if (trx == trx->bts->c0)
|
||||||
|
load_timer_stop(trx->bts);
|
||||||
|
} else {
|
||||||
|
/* If we have no rsl_link yet it may mean that lower
|
||||||
|
* layers are still establishing the socket (TCP, IPA).
|
||||||
|
* Let's tell it to stop connection establishment since
|
||||||
|
* we are shutting down. */
|
||||||
|
struct e1inp_line *line = e1inp_line_find(0);
|
||||||
|
if (line)
|
||||||
|
e1inp_ipa_bts_rsl_close_n(line, trx->nr);
|
||||||
|
}
|
||||||
|
/* Note: Here we could send NM_EV_RSL_DOWN to each
|
||||||
|
* trx->(bb_transc.)mo.fi, but we are starting shutdown of the
|
||||||
|
* entire BTS anyway through bts_model_abis_close(), so simply
|
||||||
|
* let bts_shutdown FSM take care of slowly powering down all
|
||||||
|
* the TRX. It would make sense to send NM_EV_RSL_DOWN only if a
|
||||||
|
* RSL link TRX!=C0 was going down, in order to selectively stop
|
||||||
|
* that TRX only. But libosmo-abis expects us to drop the entire
|
||||||
|
* line when something goes wrong... */
|
||||||
|
}
|
||||||
|
bts_model_abis_close(bts);
|
||||||
|
|
||||||
|
/* We want to try reconnecting to the current BSC at least once before switching to a new one: */
|
||||||
|
priv->reconnect_to_current_bsc = true;
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_failed_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
|
||||||
|
/* None of the configured BSCs was reachable or there was an existing
|
||||||
|
* OML/RSL connection that broke. Initiate BTS process shut down now. */
|
||||||
|
bts_model_abis_close(bts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void abis_link_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct abis_link_fsm_priv *priv = fi->priv;
|
||||||
|
struct gsm_bts *bts = priv->bts;
|
||||||
|
|
||||||
|
OSMO_ASSERT(event == ABIS_LINK_EV_VTY_RM_ADDR);
|
||||||
|
|
||||||
|
if (priv->current_bsc == data) {
|
||||||
|
if (llist_count(&bts->bsc_oml_hosts) <= 1)
|
||||||
|
priv->current_bsc = NULL;
|
||||||
|
else
|
||||||
|
pick_next_bsc(fi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int abis_link_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
|
{
|
||||||
|
switch (fi->state) {
|
||||||
|
case ABIS_LINK_ST_WAIT_RECONNECT:
|
||||||
|
osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTING, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct osmo_fsm_state abis_link_fsm_states[] = {
|
||||||
|
[ABIS_LINK_ST_WAIT_RECONNECT] = {
|
||||||
|
.name = "WAIT_RECONNECT",
|
||||||
|
.out_state_mask =
|
||||||
|
S(ABIS_LINK_ST_CONNECTING),
|
||||||
|
},
|
||||||
|
[ABIS_LINK_ST_CONNECTING] = {
|
||||||
|
.name = "CONNECTING",
|
||||||
|
.in_event_mask =
|
||||||
|
S(ABIS_LINK_EV_SIGN_LINK_OML_UP) |
|
||||||
|
S(ABIS_LINK_EV_SIGN_LINK_DOWN),
|
||||||
|
.out_state_mask =
|
||||||
|
S(ABIS_LINK_ST_WAIT_RECONNECT) |
|
||||||
|
S(ABIS_LINK_ST_CONNECTED) |
|
||||||
|
S(ABIS_LINK_ST_FAILED),
|
||||||
|
.onenter = abis_link_connecting_onenter,
|
||||||
|
.action = abis_link_connecting,
|
||||||
|
},
|
||||||
|
[ABIS_LINK_ST_CONNECTED] = {
|
||||||
|
.name = "CONNECTED",
|
||||||
|
.in_event_mask =
|
||||||
|
S(ABIS_LINK_EV_SIGN_LINK_DOWN),
|
||||||
|
.out_state_mask =
|
||||||
|
S(ABIS_LINK_ST_WAIT_RECONNECT),
|
||||||
|
.onenter = abis_link_connected_onenter,
|
||||||
|
.action = abis_link_connected,
|
||||||
|
},
|
||||||
|
[ABIS_LINK_ST_FAILED] = {
|
||||||
|
.name = "FAILED",
|
||||||
|
.onenter = abis_link_failed_onenter,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct osmo_fsm abis_link_fsm = {
|
||||||
|
.name = "abis_link",
|
||||||
|
.states = abis_link_fsm_states,
|
||||||
|
.num_states = ARRAY_SIZE(abis_link_fsm_states),
|
||||||
|
.log_subsys = DABIS,
|
||||||
|
.event_names = abis_link_fsm_event_names,
|
||||||
|
.allstate_action = abis_link_allstate,
|
||||||
|
.allstate_event_mask = S(ABIS_LINK_EV_VTY_RM_ADDR),
|
||||||
|
.timer_cb = abis_link_fsm_timer_cb,
|
||||||
|
};
|
||||||
|
|
||||||
int abis_oml_sendmsg(struct msgb *msg)
|
int abis_oml_sendmsg(struct msgb *msg)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = msg->trx->bts;
|
struct gsm_bts *bts = msg->trx->bts;
|
||||||
|
|
||||||
if (!bts->oml_link) {
|
if (!bts->oml_link) {
|
||||||
llist_add_tail(&msg->list, &bts->oml_queue);
|
LOGP(DABIS, LOGL_INFO, "Drop Tx OML msg, OML link is down\n");
|
||||||
|
msgb_free(msg);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
|
||||||
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
|
||||||
* the signalling link at msg->dst */
|
|
||||||
msg->dst = bts->oml_link;
|
|
||||||
return abis_sendmsg(msg);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void drain_oml_queue(struct gsm_bts *bts)
|
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
||||||
{
|
* the signalling link at msg->dst */
|
||||||
struct msgb *msg, *msg2;
|
msg->dst = bts->oml_link;
|
||||||
|
return abis_sendmsg(msg);
|
||||||
llist_for_each_entry_safe(msg, msg2, &bts->oml_queue, list) {
|
|
||||||
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
|
||||||
* the signalling link at msg->dst */
|
|
||||||
llist_del(&msg->list);
|
|
||||||
msg->dst = bts->oml_link;
|
|
||||||
abis_sendmsg(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int abis_bts_rsl_sendmsg(struct msgb *msg)
|
int abis_bts_rsl_sendmsg(struct msgb *msg)
|
||||||
@@ -98,25 +371,30 @@ int abis_bts_rsl_sendmsg(struct msgb *msg)
|
|||||||
static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
|
static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
|
||||||
enum e1inp_sign_type type)
|
enum e1inp_sign_type type)
|
||||||
{
|
{
|
||||||
struct e1inp_sign_link *sign_link = NULL;
|
struct e1inp_ts *sign_ts;
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx;
|
||||||
int trx_nr;
|
int trx_nr;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case E1INP_SIGN_OML:
|
case E1INP_SIGN_OML:
|
||||||
|
sign_ts = e1inp_line_ipa_oml_ts(line);
|
||||||
LOGP(DABIS, LOGL_INFO, "OML Signalling link up\n");
|
LOGP(DABIS, LOGL_INFO, "OML Signalling link up\n");
|
||||||
e1inp_ts_config_sign(&line->ts[E1INP_SIGN_OML-1], line);
|
e1inp_ts_config_sign(sign_ts, line);
|
||||||
sign_link = g_bts->oml_link =
|
g_bts->oml_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OML,
|
||||||
e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML-1],
|
g_bts->c0, IPAC_PROTO_OML, 0);
|
||||||
E1INP_SIGN_OML, g_bts->c0, 255, 0);
|
|
||||||
if (clock_gettime(CLOCK_MONOTONIC, &g_bts->oml_conn_established_timestamp) != 0)
|
if (clock_gettime(CLOCK_MONOTONIC, &g_bts->oml_conn_established_timestamp) != 0)
|
||||||
memset(&g_bts->oml_conn_established_timestamp, 0,
|
memset(&g_bts->oml_conn_established_timestamp, 0,
|
||||||
sizeof(g_bts->oml_conn_established_timestamp));
|
sizeof(g_bts->oml_conn_established_timestamp));
|
||||||
drain_oml_queue(g_bts);
|
g_bts->osmo_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OSMO,
|
||||||
bts_link_estab(g_bts);
|
g_bts->c0, IPAC_PROTO_OSMO, 0);
|
||||||
break;
|
osmo_fsm_inst_dispatch(g_bts->abis_link_fi, ABIS_LINK_EV_SIGN_LINK_OML_UP, NULL);
|
||||||
|
return g_bts->oml_link;
|
||||||
|
|
||||||
|
case E1INP_SIGN_RSL:
|
||||||
|
/* fall through to default to catch TRXn having type = E1INP_SIGN_RSL + n */
|
||||||
default:
|
default:
|
||||||
trx_nr = type - E1INP_SIGN_RSL;
|
trx_nr = type - E1INP_SIGN_RSL;
|
||||||
|
sign_ts = e1inp_line_ipa_rsl_ts(line, trx_nr);
|
||||||
LOGP(DABIS, LOGL_INFO, "RSL Signalling link for TRX%d up\n",
|
LOGP(DABIS, LOGL_INFO, "RSL Signalling link for TRX%d up\n",
|
||||||
trx_nr);
|
trx_nr);
|
||||||
trx = gsm_bts_trx_num(g_bts, trx_nr);
|
trx = gsm_bts_trx_num(g_bts, trx_nr);
|
||||||
@@ -125,50 +403,19 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
|
|||||||
trx_nr);
|
trx_nr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e1inp_ts_config_sign(&line->ts[type-1], line);
|
e1inp_ts_config_sign(sign_ts, line);
|
||||||
sign_link = trx->rsl_link =
|
trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||||
e1inp_sign_link_create(&line->ts[type-1],
|
trx, trx->rsl_tei, 0);
|
||||||
E1INP_SIGN_RSL, trx,
|
|
||||||
trx->rsl_tei, 0);
|
|
||||||
trx_link_estab(trx);
|
trx_link_estab(trx);
|
||||||
break;
|
return trx->rsl_link;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
return sign_link;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sign_link_down(struct e1inp_line *line)
|
static void sign_link_down(struct e1inp_line *line)
|
||||||
{
|
{
|
||||||
struct gsm_bts_trx *trx;
|
LOGPIL(line, DABIS, LOGL_ERROR, "Signalling link down\n");
|
||||||
LOGP(DABIS, LOGL_ERROR, "Signalling link down\n");
|
osmo_fsm_inst_dispatch(g_bts->abis_link_fi, ABIS_LINK_EV_SIGN_LINK_DOWN, NULL);
|
||||||
|
|
||||||
/* First remove the OML signalling link */
|
|
||||||
if (g_bts->oml_link) {
|
|
||||||
struct timespec now;
|
|
||||||
|
|
||||||
e1inp_sign_link_destroy(g_bts->oml_link);
|
|
||||||
|
|
||||||
/* Log a special notice if the OML connection was dropped relatively quickly. */
|
|
||||||
if (g_bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
|
|
||||||
g_bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) {
|
|
||||||
LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. "
|
|
||||||
"If this situation persists, please check your BTS and BSC configuration files for errors. "
|
|
||||||
"A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",
|
|
||||||
(uint64_t)(now.tv_sec - g_bts->oml_conn_established_timestamp.tv_sec));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_bts->oml_link = NULL;
|
|
||||||
memset(&g_bts->oml_conn_established_timestamp, 0, sizeof(g_bts->oml_conn_established_timestamp));
|
|
||||||
|
|
||||||
/* Then iterate over the RSL signalling links */
|
|
||||||
llist_for_each_entry(trx, &g_bts->trx_list, list) {
|
|
||||||
if (trx->rsl_link) {
|
|
||||||
e1inp_sign_link_destroy(trx->rsl_link);
|
|
||||||
trx->rsl_link = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bts_model_abis_close(g_bts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -189,6 +436,9 @@ static int sign_link_cb(struct msgb *msg)
|
|||||||
case E1INP_SIGN_RSL:
|
case E1INP_SIGN_RSL:
|
||||||
down_rsl(link->trx, msg);
|
down_rsl(link->trx, msg);
|
||||||
break;
|
break;
|
||||||
|
case E1INP_SIGN_OSMO:
|
||||||
|
down_osmo(link->trx->bts, msg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
break;
|
break;
|
||||||
@@ -234,7 +484,7 @@ static int inp_s_cbfn(unsigned int subsys, unsigned int signal,
|
|||||||
|
|
||||||
|
|
||||||
static struct ipaccess_unit bts_dev_info = {
|
static struct ipaccess_unit bts_dev_info = {
|
||||||
.unit_name = "sysmoBTS",
|
.unit_name = "osmo-bts",
|
||||||
.equipvers = "", /* FIXME: read this from hw */
|
.equipvers = "", /* FIXME: read this from hw */
|
||||||
.swversion = PACKAGE_VERSION,
|
.swversion = PACKAGE_VERSION,
|
||||||
.location1 = "",
|
.location1 = "",
|
||||||
@@ -258,37 +508,36 @@ void abis_init(struct gsm_bts *bts)
|
|||||||
{
|
{
|
||||||
g_bts = bts;
|
g_bts = bts;
|
||||||
|
|
||||||
oml_init(&bts->mo);
|
oml_init();
|
||||||
libosmo_abis_init(tall_bts_ctx);
|
libosmo_abis_init(tall_bts_ctx);
|
||||||
|
|
||||||
osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts);
|
osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host,
|
int abis_open(struct gsm_bts *bts, char *model_name)
|
||||||
char *model_name)
|
|
||||||
{
|
{
|
||||||
struct e1inp_line *line;
|
struct abis_link_fsm_priv *abis_link_fsm_priv;
|
||||||
|
|
||||||
/* patch in various data from VTY and other sources */
|
if (llist_empty(&bts->bsc_oml_hosts)) {
|
||||||
line_ops.cfg.ipa.addr = dst_host;
|
LOGP(DABIS, LOGL_FATAL, "No BSC configured, cannot start BTS without knowing BSC OML IP\n");
|
||||||
osmo_get_macaddr(bts_dev_info.mac_addr, "eth0");
|
return -EINVAL;
|
||||||
bts_dev_info.site_id = bts->ip_access.site_id;
|
}
|
||||||
bts_dev_info.bts_id = bts->ip_access.bts_id;
|
|
||||||
bts_dev_info.unit_name = model_name;
|
|
||||||
if (bts->description)
|
|
||||||
bts_dev_info.unit_name = bts->description;
|
|
||||||
bts_dev_info.location2 = model_name;
|
|
||||||
|
|
||||||
line = e1inp_line_find(0);
|
bts->abis_link_fi = osmo_fsm_inst_alloc(&abis_link_fsm, bts, NULL, LOGL_DEBUG, "abis_link");
|
||||||
if (!line)
|
OSMO_ASSERT(bts->abis_link_fi);
|
||||||
line = e1inp_line_create(0, "ipa");
|
|
||||||
if (!line)
|
|
||||||
return NULL;
|
|
||||||
e1inp_line_bind_ops(line, &line_ops);
|
|
||||||
|
|
||||||
/* This will open the OML connection now */
|
abis_link_fsm_priv = talloc_zero(bts->abis_link_fi, struct abis_link_fsm_priv);
|
||||||
if (e1inp_line_update(line) < 0)
|
OSMO_ASSERT(abis_link_fsm_priv);
|
||||||
return NULL;
|
abis_link_fsm_priv->bts = bts;
|
||||||
|
abis_link_fsm_priv->model_name = model_name;
|
||||||
|
bts->abis_link_fi->priv = abis_link_fsm_priv;
|
||||||
|
|
||||||
return line;
|
osmo_fsm_inst_state_chg(bts->abis_link_fi, ABIS_LINK_ST_CONNECTING, 0, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void abis_link_fsm_init(void)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(osmo_fsm_register(&abis_link_fsm) == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
136
src/common/abis_osmo.c
Normal file
136
src/common/abis_osmo.c
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
/* OSMO extenion link associated to same line as oml_link: */
|
||||||
|
|
||||||
|
/* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/msgb.h>
|
||||||
|
#include <osmocom/gsm/ipa.h>
|
||||||
|
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/pcu_if.h>
|
||||||
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
|
||||||
|
extern struct gsm_network bts_gsmnet;
|
||||||
|
|
||||||
|
#define OM_HEADROOM_SIZE 128
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// OSMO ABIS extensions (PCU)
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
static struct msgb *abis_osmo_pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr, size_t extra_size)
|
||||||
|
{
|
||||||
|
struct msgb *msg;
|
||||||
|
struct gsm_pcu_if *pcu_prim;
|
||||||
|
msg = msgb_alloc_headroom(OM_HEADROOM_SIZE + sizeof(struct gsm_pcu_if) + extra_size,
|
||||||
|
OM_HEADROOM_SIZE, "IPA/ABIS/OSMO");
|
||||||
|
/* Only header is filled, caller is responible for reserving + filling
|
||||||
|
* message type specific contents: */
|
||||||
|
msgb_put(msg, PCUIF_HDR_SIZE);
|
||||||
|
pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
|
||||||
|
pcu_prim->msg_type = msg_type;
|
||||||
|
pcu_prim->bts_nr = bts_nr;
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a OML NM Message from BSC to BTS */
|
||||||
|
int abis_osmo_sendmsg(struct gsm_bts *bts, struct msgb *msg)
|
||||||
|
{
|
||||||
|
msg->dst = bts->osmo_link;
|
||||||
|
msg->l2h = msg->data;
|
||||||
|
return abis_sendmsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Send IPA/OSMO/PCU extension Abis message from PCU to BSC */
|
||||||
|
static int abis_osmo_pcu_sendmsg(struct gsm_bts *bts, struct msgb *msg)
|
||||||
|
{
|
||||||
|
ipa_prepend_header_ext(msg, IPAC_PROTO_EXT_PCU);
|
||||||
|
return abis_osmo_sendmsg(bts, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int abis_osmo_pcu_tx_container(struct gsm_bts *bts, const struct gsm_pcu_if_container *container)
|
||||||
|
{
|
||||||
|
uint16_t data_length = osmo_load16be(&container->length);
|
||||||
|
struct msgb *msg = abis_osmo_pcu_msgb_alloc(PCU_IF_MSG_CONTAINER, bts->nr, data_length);
|
||||||
|
struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
|
||||||
|
struct gsm_pcu_if_container *tx_cont = &pcu_prim->u.container;
|
||||||
|
|
||||||
|
msgb_put(msg, sizeof(*tx_cont) + data_length);
|
||||||
|
tx_cont->msg_type = container->msg_type;
|
||||||
|
tx_cont->length = container->length;
|
||||||
|
if (data_length)
|
||||||
|
memcpy(tx_cont->data, container->data, data_length);
|
||||||
|
|
||||||
|
return abis_osmo_pcu_sendmsg(bts, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* incoming IPA/OSMOEXT/PCU Abis message from BSC */
|
||||||
|
static int rx_down_osmo_pcu(struct gsm_bts *bts, struct msgb *msg)
|
||||||
|
{
|
||||||
|
struct gsm_pcu_if *pcu_prim;
|
||||||
|
if (msgb_l2len(msg) < PCUIF_HDR_SIZE) {
|
||||||
|
LOGP(DPCU, LOGL_ERROR, "ABIS_OSMO_PCU message too short\n");
|
||||||
|
oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
|
||||||
|
"ABIS_OSMO_PCU message too short\n");
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
pcu_prim = msgb_l2(msg);
|
||||||
|
LOGP(DPCU, LOGL_INFO, "Rx BSC->BTS%d ABIS_OSMO_PCU msg type %u\n",
|
||||||
|
pcu_prim->bts_nr, pcu_prim->msg_type);
|
||||||
|
/* we patch the bts_nr received from BTS with the bts_nr we used to set up in the local PCU */
|
||||||
|
pcu_prim->bts_nr = bts->nr;
|
||||||
|
/* Trim Abis lower layers: */
|
||||||
|
msgb_pull_to_l2(msg);
|
||||||
|
/* we simply forward it to PCUIF: */
|
||||||
|
return pcu_sock_send(&bts_gsmnet, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* incoming IPA/OSMO extension Abis message from BSC */
|
||||||
|
int down_osmo(struct gsm_bts *bts, struct msgb *msg)
|
||||||
|
{
|
||||||
|
uint8_t *type;
|
||||||
|
|
||||||
|
if (msgb_l2len(msg) < 1) {
|
||||||
|
oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
|
||||||
|
"OSMO message too short\n");
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
type = msgb_l2(msg);
|
||||||
|
msg->l2h = type + 1;
|
||||||
|
|
||||||
|
switch (*type) {
|
||||||
|
case IPAC_PROTO_EXT_PCU:
|
||||||
|
return rx_down_osmo_pcu(bts, msg);
|
||||||
|
default:
|
||||||
|
oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
|
||||||
|
"OSMO message unknown extension %u\n", *type);
|
||||||
|
msgb_free(msg);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
142
src/common/amr.c
142
src/common/amr.c
@@ -6,6 +6,85 @@
|
|||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/amr.h>
|
#include <osmo-bts/amr.h>
|
||||||
|
|
||||||
|
/* Reasonable defaults for AMR-FR and AMR-HR rate configuration.
|
||||||
|
* The values are taken from 3GPP TS 51.010-1 (version 13.11.0).
|
||||||
|
* See 14.2.19.4.1 and 14.2.20.4.1 for AMR-FR and AMR-HR, respectively.
|
||||||
|
*
|
||||||
|
* ^ C/I (dB) | FR / HR |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* MODE4 | |
|
||||||
|
* = | ----+---- THR_MX_Up(3) | 20.5 / 18.0 |
|
||||||
|
* | | |
|
||||||
|
* | = ----+---- THR_MX_Dn(4) | 18.5 / 16.0 |
|
||||||
|
* MODE3 | |
|
||||||
|
* | = ----+---- THR_MX_Up(2) | 14.5 / 14.0 |
|
||||||
|
* | | |
|
||||||
|
* = | ----+---- THR_MX_Dn(3) | 12.5 / 12.0 |
|
||||||
|
* MODE2 | |
|
||||||
|
* = | ----+---- THR_MX_Up(1) | 8.5 / 10.0 |
|
||||||
|
* | | |
|
||||||
|
* | = ----+---- THR_MX_Dn(2) | 6.5 / 8.0 |
|
||||||
|
* MODE1 | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
*/
|
||||||
|
static const struct gsm48_multi_rate_conf amr_fr_mr_cfg_def = {
|
||||||
|
.m4_75 = 1,
|
||||||
|
.m5_90 = 1,
|
||||||
|
.m7_95 = 1,
|
||||||
|
.m12_2 = 1,
|
||||||
|
};
|
||||||
|
static const struct amr_mode amr_fr_bts_mode_def[] = {
|
||||||
|
{
|
||||||
|
.mode = 0, /* 4.75k */
|
||||||
|
.threshold = 13, /* THR_MX_Dn(2): 6.5 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(1): 8.5 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 2, /* 5.90k */
|
||||||
|
.threshold = 25, /* THR_MX_Dn(3): 12.5 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(2): 14.5 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 5, /* 7.95k */
|
||||||
|
.threshold = 37, /* THR_MX_Dn(4): 18.5 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(3): 20.5 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 7, /* 12.2k */
|
||||||
|
/* this is the last mode, so no threshold */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct gsm48_multi_rate_conf amr_hr_mr_cfg_def = {
|
||||||
|
.m4_75 = 1,
|
||||||
|
.m5_90 = 1,
|
||||||
|
.m6_70 = 1,
|
||||||
|
.m7_95 = 1,
|
||||||
|
};
|
||||||
|
static const struct amr_mode amr_hr_bts_mode_def[] = {
|
||||||
|
{
|
||||||
|
.mode = 0, /* 4.75k */
|
||||||
|
.threshold = 16, /* THR_MX_Dn(2): 8.0 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(1): 10.0 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 2, /* 5.90k */
|
||||||
|
.threshold = 24, /* THR_MX_Dn(3): 12.0 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(2): 14.0 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 3, /* 6.70k */
|
||||||
|
.threshold = 32, /* THR_MX_Dn(4): 16.0 dB */
|
||||||
|
.hysteresis = 4, /* THR_MX_Up(3): 18.0 dB */
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = 5, /* 7.95k */
|
||||||
|
/* this is the last mode, so no threshold */
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
void amr_log_mr_conf(int ss, int logl, const char *pfx,
|
void amr_log_mr_conf(int ss, int logl, const char *pfx,
|
||||||
struct amr_multirate_conf *amr_mrc)
|
struct amr_multirate_conf *amr_mrc)
|
||||||
{
|
{
|
||||||
@@ -16,9 +95,9 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx,
|
|||||||
|
|
||||||
for (i = 0; i < amr_mrc->num_modes; i++)
|
for (i = 0; i < amr_mrc->num_modes; i++)
|
||||||
LOGPC(ss, logl, ", mode[%u] = %u/%u/%u",
|
LOGPC(ss, logl, ", mode[%u] = %u/%u/%u",
|
||||||
i, amr_mrc->bts_mode[i].mode,
|
i, amr_mrc->mode[i].mode,
|
||||||
amr_mrc->bts_mode[i].threshold,
|
amr_mrc->mode[i].threshold,
|
||||||
amr_mrc->bts_mode[i].hysteresis);
|
amr_mrc->mode[i].hysteresis);
|
||||||
LOGPC(ss, logl, "\n");
|
LOGPC(ss, logl, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +106,7 @@ static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc,
|
|||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (i = 0; i < amr_mrc->num_modes; i++) {
|
for (i = 0; i < amr_mrc->num_modes; i++) {
|
||||||
if (amr_mrc->bts_mode[i].mode == cmi)
|
if (amr_mrc->mode[i].mode == cmi)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -78,13 +157,16 @@ void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc,
|
|||||||
int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
|
int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
|
||||||
const uint8_t *mr_conf, unsigned int len)
|
const uint8_t *mr_conf, unsigned int len)
|
||||||
{
|
{
|
||||||
uint8_t mr_version = mr_conf[0] >> 5;
|
|
||||||
uint8_t num_codecs = 0;
|
uint8_t num_codecs = 0;
|
||||||
int i, j = 0;
|
int i, j = 0;
|
||||||
|
|
||||||
if (mr_version != 1) {
|
if (len < 2) {
|
||||||
LOGP(DRSL, LOGL_ERROR, "AMR Multirate Version %u unknown\n",
|
LOGP(DRSL, LOGL_ERROR, "AMR Multirate IE is too short (%u)\n", len);
|
||||||
mr_version);
|
goto ret_einval;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((mr_conf[0] >> 5) != 1) {
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "AMR Multirate Version %u unknown\n", (mr_conf[0] >> 5));
|
||||||
goto ret_einval;
|
goto ret_einval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,23 +196,26 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc,
|
|||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
if (mr_conf[1] & (1 << i)) {
|
if (mr_conf[1] & (1 << i)) {
|
||||||
amr_mrc->bts_mode[j++].mode = i;
|
amr_mrc->mode[j++].mode = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* skip the first two octets of the IE */
|
||||||
|
mr_conf += 2;
|
||||||
|
|
||||||
if (num_codecs >= 2) {
|
if (num_codecs >= 2) {
|
||||||
amr_mrc->bts_mode[0].threshold = mr_conf[1] & 0x3F;
|
amr_mrc->mode[0].threshold = mr_conf[0] & 0x3F;
|
||||||
amr_mrc->bts_mode[0].hysteresis = mr_conf[2] >> 4;
|
amr_mrc->mode[0].hysteresis = mr_conf[1] >> 4;
|
||||||
}
|
}
|
||||||
if (num_codecs >= 3) {
|
if (num_codecs >= 3) {
|
||||||
amr_mrc->bts_mode[1].threshold =
|
amr_mrc->mode[1].threshold =
|
||||||
((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6);
|
((mr_conf[1] & 0xF) << 2) | (mr_conf[2] >> 6);
|
||||||
amr_mrc->bts_mode[1].hysteresis = (mr_conf[3] >> 2) & 0xF;
|
amr_mrc->mode[1].hysteresis = (mr_conf[2] >> 2) & 0xF;
|
||||||
}
|
}
|
||||||
if (num_codecs >= 4) {
|
if (num_codecs >= 4) {
|
||||||
amr_mrc->bts_mode[2].threshold =
|
amr_mrc->mode[2].threshold =
|
||||||
((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4);
|
((mr_conf[2] & 0x3) << 4) | (mr_conf[3] >> 4);
|
||||||
amr_mrc->bts_mode[2].hysteresis = mr_conf[4] & 0xF;
|
amr_mrc->mode[2].hysteresis = mr_conf[3] & 0xF;
|
||||||
}
|
}
|
||||||
|
|
||||||
return num_codecs;
|
return num_codecs;
|
||||||
@@ -168,3 +253,26 @@ unsigned int amr_get_initial_mode(struct gsm_lchan *lchan)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void amr_init_mr_conf_def(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
const struct gsm48_multi_rate_conf *mr_cfg;
|
||||||
|
const struct amr_mode *bts_mode;
|
||||||
|
unsigned int num_modes;
|
||||||
|
|
||||||
|
if (lchan->type == GSM_LCHAN_TCH_F) {
|
||||||
|
num_modes = ARRAY_SIZE(amr_fr_bts_mode_def);
|
||||||
|
bts_mode = &amr_fr_bts_mode_def[0];
|
||||||
|
mr_cfg = &amr_fr_mr_cfg_def;
|
||||||
|
} else {
|
||||||
|
num_modes = ARRAY_SIZE(amr_hr_bts_mode_def);
|
||||||
|
bts_mode = &amr_hr_bts_mode_def[0];
|
||||||
|
mr_cfg = &amr_hr_mr_cfg_def;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(lchan->tch.amr_mr.gsm48_ie, mr_cfg,
|
||||||
|
sizeof(lchan->tch.amr_mr.gsm48_ie));
|
||||||
|
memcpy(&lchan->tch.amr_mr.mode[0], &bts_mode[0],
|
||||||
|
sizeof(lchan->tch.amr_mr.mode));
|
||||||
|
lchan->tch.amr_mr.num_modes = num_modes;
|
||||||
|
}
|
||||||
|
|||||||
546
src/common/bts.c
546
src/common/bts.c
@@ -32,6 +32,7 @@
|
|||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
#include <osmocom/core/msgb.h>
|
#include <osmocom/core/msgb.h>
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
|
#include <osmocom/core/tdef.h>
|
||||||
#include <osmocom/core/stats.h>
|
#include <osmocom/core/stats.h>
|
||||||
#include <osmocom/core/rate_ctr.h>
|
#include <osmocom/core/rate_ctr.h>
|
||||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
@@ -50,6 +51,10 @@
|
|||||||
#include <osmo-bts/signal.h>
|
#include <osmo-bts/signal.h>
|
||||||
#include <osmo-bts/dtx_dl_amr_fsm.h>
|
#include <osmo-bts/dtx_dl_amr_fsm.h>
|
||||||
#include <osmo-bts/cbch.h>
|
#include <osmo-bts/cbch.h>
|
||||||
|
#include <osmo-bts/bts_shutdown_fsm.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
#include <osmo-bts/power_control.h>
|
||||||
|
#include <osmo-bts/osmux.h>
|
||||||
|
|
||||||
#define MIN_QUAL_RACH 50 /* minimum link quality (in centiBels) for Access Bursts */
|
#define MIN_QUAL_RACH 50 /* minimum link quality (in centiBels) for Access Bursts */
|
||||||
#define MIN_QUAL_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */
|
#define MIN_QUAL_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */
|
||||||
@@ -86,6 +91,8 @@ static int bts_signal_cbfn(unsigned int subsys, unsigned int signal,
|
|||||||
static const struct rate_ctr_desc bts_ctr_desc[] = {
|
static const struct rate_ctr_desc bts_ctr_desc[] = {
|
||||||
[BTS_CTR_PAGING_RCVD] = {"paging:rcvd", "Received paging requests (Abis)"},
|
[BTS_CTR_PAGING_RCVD] = {"paging:rcvd", "Received paging requests (Abis)"},
|
||||||
[BTS_CTR_PAGING_DROP] = {"paging:drop", "Dropped paging requests (Abis)"},
|
[BTS_CTR_PAGING_DROP] = {"paging:drop", "Dropped paging requests (Abis)"},
|
||||||
|
[BTS_CTR_PAGING_DROP_PS] = {"paging:drop-ps", "Dropped paging requests (PS/PCU)"},
|
||||||
|
[BTS_CTR_PAGING_CONG] = {"paging:cong", "Paging congestion detected (Abis)"},
|
||||||
[BTS_CTR_PAGING_SENT] = {"paging:sent", "Sent paging requests (Um)"},
|
[BTS_CTR_PAGING_SENT] = {"paging:sent", "Sent paging requests (Um)"},
|
||||||
|
|
||||||
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
|
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
|
||||||
@@ -122,6 +129,184 @@ static const struct rate_ctr_group_desc cbch_ctrg_desc = {
|
|||||||
cbch_ctr_desc
|
cbch_ctr_desc
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct osmo_tdef bts_T_defs[] = {
|
||||||
|
/* T-1: FIXME: Ideally should be dynamically calculated per trx at
|
||||||
|
* shutdown start based on params below, and highest trx value taken:
|
||||||
|
* + VTY's power-ramp step-interval.
|
||||||
|
* + Amount of steps needed (taking into account how many dB each step moves).
|
||||||
|
* + Extra time to get response back for each step.
|
||||||
|
* For now we simply give 5 mins, which should be enough for any
|
||||||
|
* acceptable setup, while still ensuring will timeout at some point if
|
||||||
|
* something fails in the ramp down procedure.
|
||||||
|
*/
|
||||||
|
{ .T=-1, .default_val=300, .desc="Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s)" },
|
||||||
|
{ .T=-2, .default_val=3, .desc="Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s)" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct osmo_tdef abis_T_defs[] = {
|
||||||
|
{ .T=-15, .default_val=0, .unit=OSMO_TDEF_MS, .desc="Time to wait between Channel Activation and dispatching a cached early Immediate Assignment" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
|
||||||
|
static const uint8_t bts_cell_timer_default[] =
|
||||||
|
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
||||||
|
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
||||||
|
.parameter = {
|
||||||
|
[RLC_T3142] = 20,
|
||||||
|
[RLC_T3169] = 5,
|
||||||
|
[RLC_T3191] = 5,
|
||||||
|
[RLC_T3193] = 160, /* 10ms */
|
||||||
|
[RLC_T3195] = 5,
|
||||||
|
[RLC_N3101] = 10,
|
||||||
|
[RLC_N3103] = 4,
|
||||||
|
[RLC_N3105] = 8,
|
||||||
|
[CV_COUNTDOWN] = 15,
|
||||||
|
[T_DL_TBF_EXT] = 250 * 10, /* ms */
|
||||||
|
[T_UL_TBF_EXT] = 250 * 10, /* ms */
|
||||||
|
},
|
||||||
|
.paging = {
|
||||||
|
.repeat_time = 5 * 50, /* ms */
|
||||||
|
.repeat_count = 3,
|
||||||
|
},
|
||||||
|
.cs_mask = 0x1fff,
|
||||||
|
.initial_cs = 2,
|
||||||
|
.initial_mcs = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
|
||||||
|
{ BTS_UNKNOWN, "unknown" },
|
||||||
|
{ BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
|
||||||
|
{ BTS_OSMO_OC2G, "osmo-bts-oc2g" },
|
||||||
|
{ BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
|
||||||
|
{ BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
|
||||||
|
{ BTS_OSMO_TRX, "osmo-bts-trx" },
|
||||||
|
{ BTS_OSMO_VIRTUAL, "osmo-bts-virtual" },
|
||||||
|
{ BTS_OSMO_OMLDUMMY, "osmo-bts-omldummy" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *btsvariant2str(enum gsm_bts_type_variant v)
|
||||||
|
{
|
||||||
|
return get_value_string(osmo_bts_variant_names, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct value_string bts_attribute_names[] = {
|
||||||
|
OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
|
||||||
|
OSMO_VALUE_STRING(BTS_SUB_MODEL),
|
||||||
|
OSMO_VALUE_STRING(TRX_PHY_VERSION),
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *btsatttr2str(enum bts_attribute v)
|
||||||
|
{
|
||||||
|
return get_value_string(bts_attribute_names, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct value_string bts_impl_flag_desc[] = {
|
||||||
|
{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
|
||||||
|
{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
if (bts->site_mgr.mo.fi) {
|
||||||
|
osmo_fsm_inst_free(bts->site_mgr.mo.fi);
|
||||||
|
bts->site_mgr.mo.fi = NULL;
|
||||||
|
}
|
||||||
|
if (bts->mo.fi) {
|
||||||
|
osmo_fsm_inst_free(bts->mo.fi);
|
||||||
|
bts->mo.fi = NULL;
|
||||||
|
}
|
||||||
|
if (bts->shutdown_fi) {
|
||||||
|
osmo_fsm_inst_free(bts->shutdown_fi);
|
||||||
|
bts->shutdown_fi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bts_osmux_release(bts);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!bts)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
talloc_set_destructor(bts, gsm_bts_talloc_destructor);
|
||||||
|
|
||||||
|
bts->nr = bts_num;
|
||||||
|
bts->num_trx = 0;
|
||||||
|
INIT_LLIST_HEAD(&bts->trx_list);
|
||||||
|
bts->ms_max_power = 15; /* dBm */
|
||||||
|
|
||||||
|
bts->T_defs = bts_T_defs;
|
||||||
|
osmo_tdefs_reset(bts->T_defs);
|
||||||
|
osmo_tdefs_reset(abis_T_defs);
|
||||||
|
bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
|
||||||
|
|
||||||
|
bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr,
|
||||||
|
LOGL_INFO, "bts_sm");
|
||||||
|
gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
|
||||||
|
0xff, 0xff, 0xff);
|
||||||
|
|
||||||
|
bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
|
||||||
|
gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
|
||||||
|
bts->gprs.nsvc[i].bts = bts;
|
||||||
|
bts->gprs.nsvc[i].id = i;
|
||||||
|
gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
|
||||||
|
bts->nr, i, 0xff);
|
||||||
|
}
|
||||||
|
memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
|
||||||
|
sizeof(bts->gprs.nse.timer));
|
||||||
|
gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
|
||||||
|
bts->nr, 0xff, 0xff);
|
||||||
|
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
|
||||||
|
sizeof(bts->gprs.cell.timer));
|
||||||
|
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
|
||||||
|
bts->nr, 0xff, 0xff);
|
||||||
|
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
|
||||||
|
sizeof(bts->gprs.cell.rlc_cfg));
|
||||||
|
|
||||||
|
/* create our primary TRX. It will be initialized during bts_init() */
|
||||||
|
bts->c0 = gsm_bts_trx_alloc(bts);
|
||||||
|
if (!bts->c0) {
|
||||||
|
talloc_free(bts);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
|
||||||
|
|
||||||
|
bts->features = bitvec_alloc(MAX_BTS_FEATURES / 8, bts);
|
||||||
|
OSMO_ASSERT(bts->features != NULL);
|
||||||
|
|
||||||
|
return bts;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
|
||||||
|
if (num >= net->num_bts)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||||
|
if (bts->nr == num)
|
||||||
|
return bts;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize the BTS data structures, called before config
|
/* Initialize the BTS data structures, called before config
|
||||||
* file reading */
|
* file reading */
|
||||||
int bts_init(struct gsm_bts *bts)
|
int bts_init(struct gsm_bts *bts)
|
||||||
@@ -154,16 +339,19 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
|
|
||||||
/* configurable via VTY */
|
/* configurable via VTY */
|
||||||
bts->paging_state = paging_init(bts, 200, 0);
|
bts->paging_state = paging_init(bts, 200, 0);
|
||||||
bts->ul_power_target = -75; /* dBm default */
|
|
||||||
bts->rtp_jitter_adaptive = false;
|
bts->rtp_jitter_adaptive = false;
|
||||||
bts->rtp_port_range_start = 16384;
|
bts->rtp_port_range_start = 16384;
|
||||||
bts->rtp_port_range_end = 17407;
|
bts->rtp_port_range_end = 17407;
|
||||||
bts->rtp_port_range_next = bts->rtp_port_range_start;
|
bts->rtp_port_range_next = bts->rtp_port_range_start;
|
||||||
bts->rtp_ip_dscp = -1;
|
bts->rtp_ip_dscp = -1;
|
||||||
|
bts->rtp_priority = -1;
|
||||||
|
|
||||||
|
/* Default (fall-back) MS/BS Power control parameters */
|
||||||
|
power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
|
||||||
|
power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
|
||||||
|
|
||||||
/* configurable via OML */
|
/* configurable via OML */
|
||||||
bts->load.ccch.load_ind_period = 112;
|
bts->load.ccch.load_ind_period = 112;
|
||||||
load_timer_start(bts);
|
|
||||||
bts->rtp_jitter_buf_ms = 100;
|
bts->rtp_jitter_buf_ms = 100;
|
||||||
bts->max_ta = 63;
|
bts->max_ta = 63;
|
||||||
bts->ny1 = 4;
|
bts->ny1 = 4;
|
||||||
@@ -176,25 +364,39 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
bts->t200_ms[i] = oml_default_t200_ms[i];
|
bts->t200_ms[i] = oml_default_t200_ms[i];
|
||||||
|
|
||||||
/* default RADIO_LINK_TIMEOUT */
|
/* default RADIO_LINK_TIMEOUT */
|
||||||
bts->radio_link_timeout = 32;
|
bts->radio_link_timeout.oml = 32;
|
||||||
|
bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
|
||||||
|
|
||||||
/* Start with the site manager */
|
/* Start with the site manager */
|
||||||
oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
|
oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
|
||||||
/* set BTS to dependency */
|
/* set BTS attr to dependency */
|
||||||
oml_mo_state_init(&bts->mo, -1, NM_AVSTATE_DEPENDENCY);
|
oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
||||||
oml_mo_state_init(&bts->gprs.nse.mo, -1, NM_AVSTATE_DEPENDENCY);
|
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
||||||
oml_mo_state_init(&bts->gprs.cell.mo, -1, NM_AVSTATE_DEPENDENCY);
|
oml_mo_state_init(&bts->gprs.nsvc[0].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
||||||
oml_mo_state_init(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_DEPENDENCY);
|
oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
||||||
oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
|
|
||||||
|
|
||||||
/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
|
/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
|
||||||
* to the libc malloc all the time */
|
* to the libc malloc all the time */
|
||||||
tall_rtp_ctx = talloc_pool(tall_bts_ctx, 262144);
|
tall_rtp_ctx = talloc_pool(tall_bts_ctx, 262144);
|
||||||
osmo_rtp_init(tall_rtp_ctx);
|
osmo_rtp_init(tall_rtp_ctx);
|
||||||
|
|
||||||
/* features implemented in 'common', available for all models */
|
/* Osmux */
|
||||||
gsm_bts_set_feature(bts, BTS_FEAT_ETWS_PN);
|
rc = bts_osmux_init(bts);
|
||||||
|
if (rc < 0) {
|
||||||
|
llist_del(&bts->list);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* features implemented in 'common', available for all models,
|
||||||
|
* order alphabetically */
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_CCN);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_DYN_TS_SDCCH8);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
|
||||||
|
|
||||||
rc = bts_model_init(bts);
|
rc = bts_model_init(bts);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -203,7 +405,7 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */
|
/* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */
|
||||||
bts_trx_init(bts->c0);
|
bts_model_trx_init(bts->c0);
|
||||||
bts_gsmnet.num_bts++;
|
bts_gsmnet.num_bts++;
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
@@ -221,7 +423,7 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
bts->smscb_queue_tgt_len = 2;
|
bts->smscb_queue_tgt_len = 2;
|
||||||
bts->smscb_queue_hyst = 2;
|
bts->smscb_queue_hyst = 2;
|
||||||
|
|
||||||
INIT_LLIST_HEAD(&bts->oml_queue);
|
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
|
||||||
|
|
||||||
/* register DTX DL FSM */
|
/* register DTX DL FSM */
|
||||||
rc = osmo_fsm_register(&dtx_dl_amr_fsm);
|
rc = osmo_fsm_register(&dtx_dl_amr_fsm);
|
||||||
@@ -235,83 +437,16 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the TRX data structures, called before config
|
|
||||||
* file reading */
|
|
||||||
int bts_trx_init(struct gsm_bts_trx *trx)
|
|
||||||
{
|
|
||||||
/* initialize bts data structure */
|
|
||||||
struct trx_power_params *tpp = &trx->power_params;
|
|
||||||
int rc, i;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
|
|
||||||
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
|
||||||
int k;
|
|
||||||
|
|
||||||
for (k = 0; k < ARRAY_SIZE(ts->lchan); k++) {
|
|
||||||
struct gsm_lchan *lchan = &ts->lchan[k];
|
|
||||||
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Default values for the power adjustments */
|
|
||||||
tpp->ramp.max_initial_pout_mdBm = to_mdB(0);
|
|
||||||
tpp->ramp.step_size_mdB = to_mdB(2);
|
|
||||||
tpp->ramp.step_interval_sec = 1;
|
|
||||||
|
|
||||||
/* IF BTS model doesn't DSP/HW support MS Power Control Loop, enable osmo algo by default: */
|
|
||||||
if (!gsm_bts_has_feature(trx->bts, BTS_FEAT_MS_PWR_CTRL_DSP))
|
|
||||||
trx->ms_pwr_ctl_soft = true;
|
|
||||||
|
|
||||||
rc = bts_model_trx_init(trx);
|
|
||||||
if (rc < 0) {
|
|
||||||
llist_del(&trx->list);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void shutdown_timer_cb(void *data)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Shutdown timer expired\n");
|
|
||||||
exit(42);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct osmo_timer_list shutdown_timer = {
|
|
||||||
.cb = &shutdown_timer_cb,
|
|
||||||
};
|
|
||||||
|
|
||||||
void bts_shutdown(struct gsm_bts *bts, const char *reason)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
|
|
||||||
if (osmo_timer_pending(&shutdown_timer)) {
|
|
||||||
LOGP(DOML, LOGL_NOTICE,
|
|
||||||
"BTS is already being shutdown.\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGP(DOML, LOGL_NOTICE, "Shutting down BTS %u, Reason %s\n",
|
|
||||||
bts->nr, reason);
|
|
||||||
|
|
||||||
llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
|
|
||||||
bts_model_trx_deact_rf(trx);
|
|
||||||
bts_model_trx_close(trx);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* schedule a timer to make sure select loop logic can run again
|
|
||||||
* to dispatch any pending primitives */
|
|
||||||
osmo_timer_schedule(&shutdown_timer, 3, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* main link is established, send status report */
|
/* main link is established, send status report */
|
||||||
int bts_link_estab(struct gsm_bts *bts)
|
int bts_link_estab(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
LOGP(DSUM, LOGL_INFO, "Main link established, sending Status'.\n");
|
LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status.\n");
|
||||||
|
|
||||||
/* BTS and SITE MGR are EANBLED, BTS is DEPENDENCY */
|
/* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
|
||||||
oml_tx_state_changed(&bts->site_mgr.mo);
|
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL);
|
||||||
oml_tx_state_changed(&bts->mo);
|
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL);
|
||||||
|
|
||||||
/* those should all be in DEPENDENCY */
|
/* those should all be in DEPENDENCY */
|
||||||
oml_tx_state_changed(&bts->gprs.nse.mo);
|
oml_tx_state_changed(&bts->gprs.nse.mo);
|
||||||
@@ -336,109 +471,6 @@ int bts_link_estab(struct gsm_bts *bts)
|
|||||||
return bts_model_oml_estab(bts);
|
return bts_model_oml_estab(bts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RSL link is established, send status report */
|
|
||||||
int trx_link_estab(struct gsm_bts_trx *trx)
|
|
||||||
{
|
|
||||||
struct e1inp_sign_link *link = trx->rsl_link;
|
|
||||||
uint8_t radio_state = link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
LOGP(DSUM, LOGL_INFO, "RSL link (TRX %02x) state changed to %s, sending Status'.\n",
|
|
||||||
trx->nr, link ? "up" : "down");
|
|
||||||
|
|
||||||
oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK);
|
|
||||||
|
|
||||||
if (link)
|
|
||||||
rc = rsl_tx_rf_res(trx);
|
|
||||||
else
|
|
||||||
rc = bts_model_trx_deact_rf(trx);
|
|
||||||
if (rc < 0) {
|
|
||||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
|
||||||
link ?
|
|
||||||
"Failed to establish RSL link (%d)" :
|
|
||||||
"Failed to deactivate RF (%d)", rc);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set the availability of the TRX (used by PHY driver) */
|
|
||||||
int trx_set_available(struct gsm_bts_trx *trx, int avail)
|
|
||||||
{
|
|
||||||
int tn;
|
|
||||||
|
|
||||||
LOGP(DSUM, LOGL_INFO, "TRX(%d): Setting available = %d\n",
|
|
||||||
trx->nr, avail);
|
|
||||||
if (avail) {
|
|
||||||
int op_state = trx->rsl_link ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
|
|
||||||
oml_mo_state_chg(&trx->mo, op_state, NM_AVSTATE_OK);
|
|
||||||
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
|
|
||||||
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
|
|
||||||
oml_mo_state_chg(&trx->ts[tn].mo, op_state, NM_AVSTATE_OK);
|
|
||||||
} else {
|
|
||||||
oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
|
||||||
oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_NOT_INSTALLED);
|
|
||||||
|
|
||||||
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++)
|
|
||||||
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prepare the per-SAPI T200 arrays for a given lchan */
|
|
||||||
static int t200_by_lchan(int *t200_ms_dcch, int *t200_ms_acch, struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
struct gsm_bts *bts = lchan->ts->trx->bts;
|
|
||||||
|
|
||||||
/* we have to compensate for the "RTS advance" due to the asynchronous interface between
|
|
||||||
* the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
|
|
||||||
int32_t fn_advance = bts_get_avg_fn_advance(bts);
|
|
||||||
int32_t fn_advance_us = fn_advance * 4615;
|
|
||||||
int fn_advance_ms = fn_advance_us / 1000;
|
|
||||||
|
|
||||||
t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
|
||||||
t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
|
||||||
|
|
||||||
switch (lchan->type) {
|
|
||||||
case GSM_LCHAN_SDCCH:
|
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
|
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
|
|
||||||
break;
|
|
||||||
case GSM_LCHAN_TCH_F:
|
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
|
||||||
break;
|
|
||||||
case GSM_LCHAN_TCH_H:
|
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lchan_init_lapdm(struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
struct lapdm_channel *lc = &lchan->lapdm_ch;
|
|
||||||
int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
|
|
||||||
|
|
||||||
if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) {
|
|
||||||
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
|
|
||||||
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
|
|
||||||
t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
|
|
||||||
t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
|
|
||||||
lapdm_channel_init2(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type);
|
|
||||||
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
|
|
||||||
lapdm_channel_set_l1(lc, NULL, lchan);
|
|
||||||
}
|
|
||||||
/* We still need to set Rx callback to receive RACH requests: */
|
|
||||||
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CCCH_RACH_RATIO_COMBINED256 (256*1/9)
|
#define CCCH_RACH_RATIO_COMBINED256 (256*1/9)
|
||||||
#define CCCH_RACH_RATIO_SEPARATE256 (256*10/55)
|
#define CCCH_RACH_RATIO_SEPARATE256 (256*10/55)
|
||||||
|
|
||||||
@@ -633,7 +665,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
|
|||||||
struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg);
|
struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg);
|
||||||
|
|
||||||
if (bts->agch_queue.length > hard_limit) {
|
if (bts->agch_queue.length > hard_limit) {
|
||||||
LOGP(DSUM, LOGL_ERROR,
|
LOGP(DRR, LOGL_ERROR,
|
||||||
"AGCH: too many messages in queue, "
|
"AGCH: too many messages in queue, "
|
||||||
"refusing message type %s, length = %d/%d\n",
|
"refusing message type %s, length = %d/%d\n",
|
||||||
gsm48_rr_msg_name(((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type),
|
gsm48_rr_msg_name(((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type),
|
||||||
@@ -783,38 +815,44 @@ int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher)
|
|||||||
return sup > 0;
|
return sup > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool trx_ms_pwr_ctrl_is_osmo(struct gsm_bts_trx *trx)
|
|
||||||
{
|
|
||||||
return trx->ms_pwr_ctl_soft;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gsm_time *get_time(struct gsm_bts *bts)
|
struct gsm_time *get_time(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
return &bts->gsm_time;
|
return &bts->gsm_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bts_supports_cm(struct gsm_bts *bts, enum gsm_phys_chan_config pchan,
|
int bts_supports_cm(const struct gsm_bts *bts,
|
||||||
enum gsm48_chan_mode cm)
|
const struct rsl_ie_chan_mode *cm)
|
||||||
{
|
{
|
||||||
enum gsm_bts_features feature = _NUM_BTS_FEAT;
|
enum osmo_bts_features feature = _NUM_BTS_FEAT;
|
||||||
|
|
||||||
/* We assume that signalling support is mandatory,
|
switch (cm->spd_ind) {
|
||||||
* there is no BTS_FEAT_* definition to check that. */
|
case RSL_CMOD_SPD_SIGN:
|
||||||
if (cm == GSM48_CMODE_SIGN)
|
/* We assume that signalling support is mandatory,
|
||||||
|
* there is no BTS_FEAT_* definition to check that. */
|
||||||
return 1;
|
return 1;
|
||||||
|
case RSL_CMOD_SPD_SPEECH:
|
||||||
|
break;
|
||||||
|
case RSL_CMOD_SPD_DATA:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Before the requested pchan/cm combination can be checked, we need to
|
/* Before the requested pchan/cm combination can be checked, we need to
|
||||||
* convert it to a feature identifier we can check */
|
* convert it to a feature identifier we can check */
|
||||||
switch (pchan) {
|
switch (cm->chan_rt) {
|
||||||
case GSM_PCHAN_TCH_F:
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
|
||||||
switch(cm) {
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
return 0;
|
||||||
|
/* fall-through */
|
||||||
|
case RSL_CMOD_CRT_TCH_Bm:
|
||||||
|
switch (cm->chan_rate) {
|
||||||
|
case RSL_CMOD_SP_GSM1:
|
||||||
feature = BTS_FEAT_SPEECH_F_V1;
|
feature = BTS_FEAT_SPEECH_F_V1;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SPEECH_EFR:
|
case RSL_CMOD_SP_GSM2:
|
||||||
feature = BTS_FEAT_SPEECH_F_EFR;
|
feature = BTS_FEAT_SPEECH_F_EFR;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
case RSL_CMOD_SP_GSM3:
|
||||||
feature = BTS_FEAT_SPEECH_F_AMR;
|
feature = BTS_FEAT_SPEECH_F_AMR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -823,12 +861,16 @@ int bts_supports_cm(struct gsm_bts *bts, enum gsm_phys_chan_config pchan,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GSM_PCHAN_TCH_H:
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
|
||||||
switch(cm) {
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
return 0;
|
||||||
|
/* fall-through */
|
||||||
|
case RSL_CMOD_CRT_TCH_Lm:
|
||||||
|
switch (cm->chan_rate) {
|
||||||
|
case RSL_CMOD_SP_GSM1:
|
||||||
feature = BTS_FEAT_SPEECH_H_V1;
|
feature = BTS_FEAT_SPEECH_H_V1;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
case RSL_CMOD_SP_GSM3:
|
||||||
feature = BTS_FEAT_SPEECH_H_AMR;
|
feature = BTS_FEAT_SPEECH_H_AMR;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -838,14 +880,92 @@ int bts_supports_cm(struct gsm_bts *bts, enum gsm_phys_chan_config pchan,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOGP(DRSL, LOGL_ERROR, "BTS %u: unhandled pchan %s when checking mode %s\n",
|
LOGP(DRSL, LOGL_ERROR,
|
||||||
bts->nr, gsm_pchan_name(pchan), gsm48_chan_mode_name(cm));
|
"Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
|
||||||
|
cm->chan_rt, cm->chan_rate);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the feature is supported by this BTS */
|
/* Check if the feature is supported by this BTS */
|
||||||
if (gsm_bts_has_feature(bts, feature))
|
if (osmo_bts_has_feature(bts->features, feature))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
||||||
|
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx = bts->c0;
|
||||||
|
|
||||||
|
/* According to 3GPP TS 45.002, table 3, CBCH can be allocated
|
||||||
|
* either on C0/TS0 (CCCH+SDCCH4) or on C0..n/TS0..3 (SDCCH/8). */
|
||||||
|
if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
||||||
|
return &trx->ts[0].lchan[2]; /* C0/TS0 */
|
||||||
|
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */
|
||||||
|
unsigned int tn;
|
||||||
|
for (tn = 0; tn <= 3; tn++) { /* TS0..3 */
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
|
if (ts->pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
|
||||||
|
return &ts->lchan[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BCCH carrier power reduction (see 3GPP TS 45.008, section 7.1) */
|
||||||
|
int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *c0 = bts->c0;
|
||||||
|
unsigned int tn;
|
||||||
|
|
||||||
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_BCCH_POWER_RED)) {
|
||||||
|
LOGPTRX(c0, DRSL, LOGL_ERROR, "BCCH carrier power reduction "
|
||||||
|
"is not supported by this BTS model\n");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (red > 6 || red % 2 != 0) {
|
||||||
|
LOGPTRX(c0, DRSL, LOGL_ERROR, "BCCH carrier power reduction "
|
||||||
|
"value (%u dB) is incorrect or out of range\n", red);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGPTRX(c0, DRSL, LOGL_NOTICE, "BCCH carrier power reduction: "
|
||||||
|
"%u dB (%s)\n", red, red ? "enabled" : "disabled");
|
||||||
|
|
||||||
|
/* Timeslot 0 is always transmitting BCCH/CCCH */
|
||||||
|
c0->ts[0].c0_power_red_db = 0;
|
||||||
|
|
||||||
|
for (tn = 1; tn < ARRAY_SIZE(c0->ts); tn++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &c0->ts[tn];
|
||||||
|
struct gsm_bts_trx_ts *prev = ts - 1;
|
||||||
|
|
||||||
|
switch (ts_pchan(ts)) {
|
||||||
|
/* Not allowed on CCCH/BCCH */
|
||||||
|
case GSM_PCHAN_CCCH:
|
||||||
|
/* Preceeding timeslot shall not exceed 2 dB */
|
||||||
|
if (prev->c0_power_red_db > 0)
|
||||||
|
prev->c0_power_red_db = 2;
|
||||||
|
/* fall-through */
|
||||||
|
/* Not recommended on SDCCH/8 */
|
||||||
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
|
ts->c0_power_red_db = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ts->c0_power_red_db = red;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timeslot 7 is always preceding BCCH/CCCH */
|
||||||
|
if (c0->ts[7].c0_power_red_db > 0)
|
||||||
|
c0->ts[7].c0_power_red_db = 2;
|
||||||
|
|
||||||
|
bts->c0_power_red_db = red;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ static int set_therm_att(struct ctrl_cmd *cmd, void *data)
|
|||||||
|
|
||||||
tpp->thermal_attenuation_mdB = val;
|
tpp->thermal_attenuation_mdB = val;
|
||||||
|
|
||||||
power_ramp_start(trx, tpp->p_total_cur_mdBm, 0);
|
power_ramp_start(trx, tpp->p_total_cur_mdBm, 0, NULL);
|
||||||
|
|
||||||
return get_therm_att(cmd, data);
|
return get_therm_att(cmd, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
#include <osmo-bts/control_if.h>
|
#include <osmo-bts/control_if.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
|
||||||
extern vector ctrl_node_vec;
|
extern vector ctrl_node_vec;
|
||||||
|
|
||||||
|
|||||||
282
src/common/bts_shutdown_fsm.c
Normal file
282
src/common/bts_shutdown_fsm.c
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
/* BTS shutdown FSM */
|
||||||
|
|
||||||
|
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
#include <osmocom/core/tdef.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/bts_shutdown_fsm.h>
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
|
||||||
|
#define X(s) (1 << (s))
|
||||||
|
|
||||||
|
#define BTS_SHUTDOWN_POWER_RAMP_TGT -10
|
||||||
|
|
||||||
|
static const struct osmo_tdef_state_timeout bts_shutdown_fsm_timeouts[32] = {
|
||||||
|
[BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL] = { .T = -1 },
|
||||||
|
[BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED] = { .T = -2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
#define bts_shutdown_fsm_state_chg(fi, NEXT_STATE) \
|
||||||
|
osmo_tdef_fsm_inst_state_chg(fi, NEXT_STATE, bts_shutdown_fsm_timeouts, ((struct gsm_bts *)fi->priv)->T_defs, -1)
|
||||||
|
|
||||||
|
static unsigned int count_trx_operational(struct gsm_bts *bts) {
|
||||||
|
unsigned int count = 0;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
unsigned int count;
|
||||||
|
switch(event) {
|
||||||
|
case BTS_SHUTDOWN_EV_START:
|
||||||
|
/* Firt announce to NM objects that we are starting a shutdown procedure: */
|
||||||
|
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_START, NULL);
|
||||||
|
|
||||||
|
count = count_trx_operational(bts);
|
||||||
|
if (count) {
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL);
|
||||||
|
} else {
|
||||||
|
/* we can skip ramp down since no TRX is running anyway.
|
||||||
|
* Let's jump into WAIT_TRX_CLOSED to make sure we
|
||||||
|
* tell lower layer to close all TRX in case there's some
|
||||||
|
* open() WIP */
|
||||||
|
LOGPFSML(fi, LOGL_INFO, "No TRX is operational, skipping power ramp down\n");
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ramp_down_compl_cb(struct gsm_bts_trx *trx) {
|
||||||
|
osmo_fsm_inst_dispatch(trx->bts->shutdown_fi, BTS_SHUTDOWN_EV_TRX_RAMP_COMPL, trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
||||||
|
continue;
|
||||||
|
if (bts->shutdown_fi_skip_power_ramp)
|
||||||
|
power_ramp_force(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
||||||
|
else
|
||||||
|
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct gsm_bts_trx *src_trx;
|
||||||
|
unsigned int remaining = 0;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
|
||||||
|
switch(event) {
|
||||||
|
case BTS_SHUTDOWN_EV_TRX_RAMP_COMPL:
|
||||||
|
src_trx = (struct gsm_bts_trx *)data;
|
||||||
|
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED &&
|
||||||
|
trx->power_params.p_total_cur_mdBm > BTS_SHUTDOWN_POWER_RAMP_TGT)
|
||||||
|
remaining++;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGPFSML(fi, LOGL_INFO, "%s Ramping down complete, %u TRX remaining\n",
|
||||||
|
gsm_trx_name(src_trx), remaining);
|
||||||
|
if (remaining == 0) {
|
||||||
|
/* Make sure we end up any remaining ongoing power ramp
|
||||||
|
* down under target shutdown tx power level, then
|
||||||
|
* finally transit to next state:
|
||||||
|
*/
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list)
|
||||||
|
power_ramp_abort(trx);
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_wait_trx_closed_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
|
||||||
|
bts_model_trx_deact_rf(trx);
|
||||||
|
}
|
||||||
|
llist_for_each_entry_reverse(trx, &bts->trx_list, list) {
|
||||||
|
bts_model_trx_close(trx);
|
||||||
|
}
|
||||||
|
/* Now wait until all TRX are closed asynchronously, we'll get feedback through events... */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_wait_trx_closed(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct gsm_bts_trx *src_trx;
|
||||||
|
unsigned int remaining;
|
||||||
|
|
||||||
|
switch(event) {
|
||||||
|
case BTS_SHUTDOWN_EV_TRX_CLOSED:
|
||||||
|
src_trx = (struct gsm_bts_trx *)data;
|
||||||
|
remaining = count_trx_operational(bts);
|
||||||
|
|
||||||
|
LOGPFSML(fi, LOGL_INFO, "%s TRX closed, %u TRX remaining\n",
|
||||||
|
gsm_trx_name(src_trx), remaining);
|
||||||
|
if (remaining == 0)
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
|
||||||
|
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
|
||||||
|
|
||||||
|
if (bts->shutdown_fi_exit_proc) {
|
||||||
|
LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct osmo_fsm_state bts_shutdown_fsm_states[] = {
|
||||||
|
[BTS_SHUTDOWN_ST_NONE] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(BTS_SHUTDOWN_EV_START),
|
||||||
|
.out_state_mask =
|
||||||
|
X(BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL) |
|
||||||
|
X(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED),
|
||||||
|
.name = "NONE",
|
||||||
|
.action = st_none,
|
||||||
|
},
|
||||||
|
[BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL),
|
||||||
|
.out_state_mask =
|
||||||
|
X(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED),
|
||||||
|
.name = "WAIT_RAMP_DOWN_COMPL",
|
||||||
|
.onenter = st_wait_ramp_down_compl_on_enter,
|
||||||
|
.action = st_wait_ramp_down_compl,
|
||||||
|
},
|
||||||
|
[BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(BTS_SHUTDOWN_EV_TRX_CLOSED),
|
||||||
|
.out_state_mask =
|
||||||
|
X(BTS_SHUTDOWN_ST_EXIT),
|
||||||
|
.name = "WAIT_TRX_CLOSED",
|
||||||
|
.onenter = st_wait_trx_closed_on_enter,
|
||||||
|
.action = st_wait_trx_closed,
|
||||||
|
},
|
||||||
|
[BTS_SHUTDOWN_ST_EXIT] = {
|
||||||
|
.name = "EXIT",
|
||||||
|
.out_state_mask =
|
||||||
|
X(BTS_SHUTDOWN_ST_NONE),
|
||||||
|
.onenter = st_exit_on_enter,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct value_string bts_shutdown_fsm_event_names[] = {
|
||||||
|
OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_START),
|
||||||
|
OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL),
|
||||||
|
OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_CLOSED),
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
int bts_shutdown_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
||||||
|
{
|
||||||
|
switch (fi->state) {
|
||||||
|
case BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL:
|
||||||
|
LOGPFSML(fi, LOGL_ERROR, "Timer expired waiting for ramp down complete\n");
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED);
|
||||||
|
break;
|
||||||
|
case BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED:
|
||||||
|
LOGPFSML(fi, LOGL_ERROR, "Timer expired waiting for TRX close\n");
|
||||||
|
bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_EXIT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(false);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct osmo_fsm bts_shutdown_fsm = {
|
||||||
|
.name = "BTS_SHUTDOWN",
|
||||||
|
.states = bts_shutdown_fsm_states,
|
||||||
|
.num_states = ARRAY_SIZE(bts_shutdown_fsm_states),
|
||||||
|
.event_names = bts_shutdown_fsm_event_names,
|
||||||
|
.log_subsys = DOML,
|
||||||
|
.timer_cb = bts_shutdown_fsm_timer_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void bts_shutdown_fsm_init(void)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(osmo_fsm_register(&bts_shutdown_fsm) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bts_shutdown_in_progress(const struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
const struct osmo_fsm_inst *fi = bts->shutdown_fi;
|
||||||
|
return fi->state != BTS_SHUTDOWN_ST_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp)
|
||||||
|
{
|
||||||
|
struct osmo_fsm_inst *fi = bts->shutdown_fi;
|
||||||
|
if (bts_shutdown_in_progress(bts)) {
|
||||||
|
LOGPFSML(fi, LOGL_NOTICE, "BTS is already being shutdown.\n");
|
||||||
|
if (exit_proc)
|
||||||
|
bts->shutdown_fi_exit_proc = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bts->shutdown_fi_exit_proc = exit_proc;
|
||||||
|
bts->shutdown_fi_skip_power_ramp = skip_power_ramp;
|
||||||
|
LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n",
|
||||||
|
exit_proc, reason);
|
||||||
|
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bts_shutdown(struct gsm_bts *bts, const char *reason)
|
||||||
|
{
|
||||||
|
bts_shutdown_ext(bts, reason, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc)
|
||||||
|
{
|
||||||
|
struct osmo_fsm_inst *fi = trx->bts->shutdown_fi;
|
||||||
|
LOGPFSML(fi, LOGL_DEBUG, "%s Received TRX close cb rc=%d\n", gsm_trx_name(trx), rc);
|
||||||
|
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_TRX_CLOSED, trx);
|
||||||
|
}
|
||||||
244
src/common/bts_trx.c
Normal file
244
src/common/bts_trx.c
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
/* (C) 2008-2010 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* (C) 2020-2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
|
#include <osmocom/gsm/abis_nm.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/phy_link.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
|
||||||
|
static int gsm_bts_trx_talloc_destructor(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (trx->bb_transc.mo.fi) {
|
||||||
|
osmo_fsm_inst_free(trx->bb_transc.mo.fi);
|
||||||
|
trx->bb_transc.mo.fi = NULL;
|
||||||
|
}
|
||||||
|
if (trx->mo.fi) {
|
||||||
|
osmo_fsm_inst_free(trx->mo.fi);
|
||||||
|
trx->mo.fi = NULL;
|
||||||
|
}
|
||||||
|
for (i = 0; i < TRX_NR_TS; i++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||||
|
if (ts->mo.fi) {
|
||||||
|
osmo_fsm_inst_free(ts->mo.fi);
|
||||||
|
ts->mo.fi = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize all logical channels of the given timeslot */
|
||||||
|
static void gsm_bts_trx_ts_init_lchan(struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
unsigned int ln;
|
||||||
|
|
||||||
|
for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) {
|
||||||
|
struct gsm_lchan *lchan = &ts->lchan[ln];
|
||||||
|
gsm_lchan_init(lchan, ts, ln);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize primary timeslots of the given transceiver */
|
||||||
|
static void gsm_bts_trx_init_ts(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
unsigned int tn;
|
||||||
|
|
||||||
|
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
|
|
||||||
|
ts->trx = trx;
|
||||||
|
ts->nr = tn;
|
||||||
|
|
||||||
|
ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
|
||||||
|
trx->bb_transc.mo.fi->id, ts->nr);
|
||||||
|
gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
|
||||||
|
trx->bts->nr, trx->nr, ts->nr);
|
||||||
|
|
||||||
|
gsm_bts_trx_ts_init_lchan(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize shadow timeslots of the given transceiver */
|
||||||
|
void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
unsigned int tn;
|
||||||
|
|
||||||
|
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
||||||
|
struct gsm_bts_trx_ts *ts;
|
||||||
|
|
||||||
|
ts = talloc_zero(trx, struct gsm_bts_trx_ts);
|
||||||
|
OSMO_ASSERT(ts != NULL);
|
||||||
|
|
||||||
|
ts->trx = trx;
|
||||||
|
ts->nr = tn;
|
||||||
|
|
||||||
|
/* Link both primary and shadow */
|
||||||
|
trx->ts[tn].vamos.peer = ts;
|
||||||
|
ts->vamos.peer = &trx->ts[tn];
|
||||||
|
ts->vamos.is_shadow = true;
|
||||||
|
|
||||||
|
/* Shadow timeslot uses the primary's NM FSM */
|
||||||
|
OSMO_ASSERT(trx->ts[tn].mo.fi != NULL);
|
||||||
|
ts->mo.fi = trx->ts[tn].mo.fi;
|
||||||
|
|
||||||
|
gsm_bts_trx_ts_init_lchan(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gsm_bts_trx_free_shadow_ts(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
unsigned int tn;
|
||||||
|
unsigned int ln;
|
||||||
|
|
||||||
|
for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) {
|
||||||
|
struct gsm_bts_trx_ts *shadow_ts = trx->ts[tn].vamos.peer;
|
||||||
|
if (!shadow_ts)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* free lchan related mem allocated on the trx object: */
|
||||||
|
for (ln = 0; ln < ARRAY_SIZE(shadow_ts->lchan); ln++) {
|
||||||
|
struct gsm_lchan *lchan = &shadow_ts->lchan[ln];
|
||||||
|
TALLOC_FREE(lchan->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
talloc_free(shadow_ts);
|
||||||
|
trx->ts[tn].vamos.peer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
|
||||||
|
|
||||||
|
if (!trx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
talloc_set_destructor(trx, gsm_bts_trx_talloc_destructor);
|
||||||
|
|
||||||
|
trx->bts = bts;
|
||||||
|
trx->nr = bts->num_trx++;
|
||||||
|
|
||||||
|
trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
||||||
|
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
|
||||||
|
bts->nr, trx->nr, 0xff);
|
||||||
|
|
||||||
|
trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
||||||
|
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
|
||||||
|
bts->nr, trx->nr, 0xff);
|
||||||
|
|
||||||
|
gsm_bts_trx_init_ts(trx);
|
||||||
|
|
||||||
|
if (trx->nr != 0)
|
||||||
|
trx->nominal_power = bts->c0->nominal_power;
|
||||||
|
|
||||||
|
/* Default values for the power adjustments */
|
||||||
|
trx->power_params.ramp.max_initial_pout_mdBm = to_mdB(0);
|
||||||
|
trx->power_params.ramp.step_size_mdB = to_mdB(2);
|
||||||
|
trx->power_params.ramp.step_interval_sec = 1;
|
||||||
|
|
||||||
|
/* Default (fall-back) Dynamic Power Control parameters */
|
||||||
|
trx->bs_dpc_params = &bts->bs_dpc_params;
|
||||||
|
trx->ms_dpc_params = &bts->ms_dpc_params;
|
||||||
|
|
||||||
|
/* IF BTS model doesn't DSP/HW support MS Power Control Loop, enable osmo algo by default: */
|
||||||
|
if (!bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP))
|
||||||
|
trx->ms_pwr_ctl_soft = true;
|
||||||
|
|
||||||
|
llist_add_tail(&trx->list, &bts->trx_list);
|
||||||
|
|
||||||
|
return trx;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
|
||||||
|
if (num >= bts->num_trx)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->nr == num)
|
||||||
|
return trx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char ts2str[255];
|
||||||
|
|
||||||
|
char *gsm_trx_name(const struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
if (!trx)
|
||||||
|
snprintf(ts2str, sizeof(ts2str), "(trx=NULL)");
|
||||||
|
else
|
||||||
|
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d)",
|
||||||
|
trx->bts->nr, trx->nr);
|
||||||
|
|
||||||
|
return ts2str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
static char buf[23];
|
||||||
|
|
||||||
|
snprintf(buf, sizeof(buf), "%u/%u/%u", trx->bts->ip_access.site_id,
|
||||||
|
trx->bts->ip_access.bts_id, trx->nr);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RSL link is established, send status report */
|
||||||
|
int trx_link_estab(struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
LOGPTRX(trx, DRSL, LOGL_INFO, "RSL link up\n");
|
||||||
|
|
||||||
|
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL);
|
||||||
|
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
|
||||||
|
|
||||||
|
if ((rc = rsl_tx_rf_res(trx)) < 0)
|
||||||
|
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
||||||
|
"Failed to establish RSL link (%d)", rc);
|
||||||
|
|
||||||
|
if (trx == trx->bts->c0)
|
||||||
|
load_timer_start(trx->bts);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx)
|
||||||
|
{
|
||||||
|
return trx->ms_pwr_ctl_soft;
|
||||||
|
}
|
||||||
@@ -198,7 +198,7 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
scm = talloc_zero_size(bts, sizeof(*scm));
|
scm = talloc_zero(bts, struct smscb_msg);
|
||||||
if (!scm)
|
if (!scm)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -233,10 +233,10 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ
|
|||||||
rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED);
|
rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED);
|
||||||
break;
|
break;
|
||||||
case RSL_CB_CMD_TYPE_DEFAULT:
|
case RSL_CB_CMD_TYPE_DEFAULT:
|
||||||
/* old default msg will be free'd in get_smscb_block() if it is currently in transit
|
/* clear the cur_msg pointer if it is the old default message */
|
||||||
* and we set a new default_msg here */
|
|
||||||
if (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg)
|
if (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg)
|
||||||
talloc_free(bts_ss->cur_msg);
|
bts_ss->cur_msg = NULL;
|
||||||
|
talloc_free(bts_ss->default_msg);
|
||||||
if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL)
|
if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL)
|
||||||
/* def_bcast == 0: normal message */
|
/* def_bcast == 0: normal message */
|
||||||
bts_ss->default_msg = scm;
|
bts_ss->default_msg = scm;
|
||||||
@@ -322,3 +322,25 @@ int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time)
|
|||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void bts_smscb_state_reset(struct bts_smscb_state *bts_ss)
|
||||||
|
{
|
||||||
|
struct smscb_msg *scm, *tmp;
|
||||||
|
llist_for_each_entry_safe(scm, tmp, &bts_ss->queue, list) {
|
||||||
|
llist_del(&scm->list);
|
||||||
|
talloc_free(scm);
|
||||||
|
}
|
||||||
|
bts_ss->queue_len = 0;
|
||||||
|
rate_ctr_group_reset(bts_ss->ctrs);
|
||||||
|
/* avoid double-free of default_msg in case cur_msg == default_msg */
|
||||||
|
if (bts_ss->cur_msg && bts_ss->cur_msg != bts_ss->default_msg)
|
||||||
|
talloc_free(bts_ss->cur_msg);
|
||||||
|
bts_ss->cur_msg = NULL;
|
||||||
|
TALLOC_FREE(bts_ss->default_msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bts_cbch_reset(struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
bts_smscb_state_reset(&bts->smscb_basic);
|
||||||
|
bts_smscb_state_reset(&bts->smscb_extended);
|
||||||
|
}
|
||||||
|
|||||||
321
src/common/gsm_data.c
Normal file
321
src/common/gsm_data.c
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
/* (C) 2008-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 Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
#include <osmocom/core/talloc.h>
|
||||||
|
#include <osmocom/core/statistics.h>
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/abis_nm.h>
|
||||||
|
#include <osmocom/codec/ecu.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/bts_trx.h>
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
|
||||||
|
struct osmo_tdef_group bts_tdef_groups[] = {
|
||||||
|
{ .name = "bts", .tdefs = bts_T_defs, .desc = "BTS process timers" },
|
||||||
|
{ .name = "abis", .tdefs = abis_T_defs, .desc = "Abis (RSL) related timers" },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct value_string gsm_pchant_names[13] = {
|
||||||
|
{ GSM_PCHAN_NONE, "NONE" },
|
||||||
|
{ GSM_PCHAN_CCCH, "CCCH" },
|
||||||
|
{ GSM_PCHAN_CCCH_SDCCH4,"CCCH+SDCCH4" },
|
||||||
|
{ GSM_PCHAN_TCH_F, "TCH/F" },
|
||||||
|
{ GSM_PCHAN_TCH_H, "TCH/H" },
|
||||||
|
{ GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
|
||||||
|
{ GSM_PCHAN_PDCH, "PDCH" },
|
||||||
|
{ GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" },
|
||||||
|
{ GSM_PCHAN_UNKNOWN, "UNKNOWN" },
|
||||||
|
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" },
|
||||||
|
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" },
|
||||||
|
{ GSM_PCHAN_OSMO_DYN, "TCH/F_TCH/H_SDCCH8_PDCH" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct value_string gsm_pchant_descs[13] = {
|
||||||
|
{ GSM_PCHAN_NONE, "Physical Channel not configured" },
|
||||||
|
{ GSM_PCHAN_CCCH, "FCCH + SCH + BCCH + CCCH (Comb. IV)" },
|
||||||
|
{ GSM_PCHAN_CCCH_SDCCH4,
|
||||||
|
"FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V)" },
|
||||||
|
{ GSM_PCHAN_TCH_F, "TCH/F + FACCH/F + SACCH (Comb. I)" },
|
||||||
|
{ GSM_PCHAN_TCH_H, "2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" },
|
||||||
|
{ GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" },
|
||||||
|
{ GSM_PCHAN_PDCH, "Packet Data Channel for GPRS/EDGE" },
|
||||||
|
{ GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" },
|
||||||
|
{ GSM_PCHAN_UNKNOWN, "Unknown / Unsupported channel combination" },
|
||||||
|
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" },
|
||||||
|
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" },
|
||||||
|
{ GSM_PCHAN_OSMO_DYN, "Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *gsm_pchan_name(enum gsm_phys_chan_config c)
|
||||||
|
{
|
||||||
|
return get_value_string(gsm_pchant_names, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: move to libosmocore, next to gsm_chan_t_names? */
|
||||||
|
const char *gsm_lchant_name(enum gsm_chan_t c)
|
||||||
|
{
|
||||||
|
return get_value_string(gsm_chan_t_names, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char ts2str[255];
|
||||||
|
|
||||||
|
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
snprintf(ts2str, sizeof(ts2str),
|
||||||
|
"(" GSM_TS_NAME_FMT ")",
|
||||||
|
GSM_TS_NAME_ARGS(ts));
|
||||||
|
|
||||||
|
return ts2str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Log timeslot number with full pchan information */
|
||||||
|
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
switch (ts->pchan) {
|
||||||
|
case GSM_PCHAN_OSMO_DYN:
|
||||||
|
if (ts->dyn.pchan_is == ts->dyn.pchan_want)
|
||||||
|
snprintf(ts2str, sizeof(ts2str),
|
||||||
|
"(" GSM_TS_NAME_FMT ",pchan=%s as %s)",
|
||||||
|
GSM_TS_NAME_ARGS(ts),
|
||||||
|
gsm_pchan_name(ts->pchan),
|
||||||
|
gsm_pchan_name(ts->dyn.pchan_is));
|
||||||
|
else
|
||||||
|
snprintf(ts2str, sizeof(ts2str),
|
||||||
|
"(" GSM_TS_NAME_FMT ",pchan=%s switching %s -> %s)",
|
||||||
|
GSM_TS_NAME_ARGS(ts),
|
||||||
|
gsm_pchan_name(ts->pchan),
|
||||||
|
gsm_pchan_name(ts->dyn.pchan_is),
|
||||||
|
gsm_pchan_name(ts->dyn.pchan_want));
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_TCH_F_PDCH:
|
||||||
|
if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
|
||||||
|
snprintf(ts2str, sizeof(ts2str),
|
||||||
|
"(" GSM_TS_NAME_FMT ",pchan=%s as %s)",
|
||||||
|
GSM_TS_NAME_ARGS(ts),
|
||||||
|
gsm_pchan_name(ts->pchan),
|
||||||
|
(ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
|
||||||
|
: "TCH/F");
|
||||||
|
else
|
||||||
|
snprintf(ts2str, sizeof(ts2str),
|
||||||
|
"(" GSM_TS_NAME_FMT ",pchan=%s switching %s -> %s)",
|
||||||
|
GSM_TS_NAME_ARGS(ts),
|
||||||
|
gsm_pchan_name(ts->pchan),
|
||||||
|
(ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
|
||||||
|
: "TCH/F",
|
||||||
|
(ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
|
||||||
|
: "TCH/F");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(ts2str, sizeof(ts2str), "(" GSM_TS_NAME_FMT ",pchan=%s)",
|
||||||
|
GSM_TS_NAME_ARGS(ts), gsm_pchan_name(ts->pchan));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ts2str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine logical channel based on TRX and channel number IE */
|
||||||
|
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
||||||
|
int *rc)
|
||||||
|
{
|
||||||
|
uint8_t ts_nr = chan_nr & 0x07;
|
||||||
|
uint8_t cbits = chan_nr >> 3;
|
||||||
|
uint8_t lch_idx;
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
|
||||||
|
bool ok = true;
|
||||||
|
|
||||||
|
if (rc)
|
||||||
|
*rc = -EINVAL;
|
||||||
|
|
||||||
|
switch (cbits) {
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Bm_ACCHs:
|
||||||
|
if (ts->vamos.peer == NULL)
|
||||||
|
return NULL;
|
||||||
|
ts = ts->vamos.peer;
|
||||||
|
/* fall-through */
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs:
|
||||||
|
lch_idx = 0; /* TCH/F */
|
||||||
|
if (ts->pchan != GSM_PCHAN_TCH_F &&
|
||||||
|
ts->pchan != GSM_PCHAN_PDCH &&
|
||||||
|
ts->pchan != GSM_PCHAN_TCH_F_PDCH &&
|
||||||
|
ts->pchan != GSM_PCHAN_OSMO_DYN)
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(0):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_OSMO_VAMOS_Lm_ACCHs(1):
|
||||||
|
if (ts->vamos.peer == NULL)
|
||||||
|
return NULL;
|
||||||
|
ts = ts->vamos.peer;
|
||||||
|
/* fall-through */
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(0):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(1):
|
||||||
|
lch_idx = cbits & 0x1; /* TCH/H */
|
||||||
|
if (ts->pchan != GSM_PCHAN_TCH_H &&
|
||||||
|
ts->pchan != GSM_PCHAN_OSMO_DYN)
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(0):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(1):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(2):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(3):
|
||||||
|
lch_idx = cbits & 0x3; /* SDCCH/4 */
|
||||||
|
if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
|
||||||
|
ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(0):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(1):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(2):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(3):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(4):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(5):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(6):
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(7):
|
||||||
|
lch_idx = cbits & 0x7; /* SDCCH/8 */
|
||||||
|
if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C &&
|
||||||
|
ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C_CBCH &&
|
||||||
|
ts->pchan != GSM_PCHAN_OSMO_DYN)
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_BCCH:
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_RACH:
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_PCH_AGCH:
|
||||||
|
lch_idx = 0;
|
||||||
|
if (ts->pchan != GSM_PCHAN_CCCH &&
|
||||||
|
ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
|
||||||
|
ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
||||||
|
ok = false;
|
||||||
|
/* FIXME: we should not return first sdcch4 !!! */
|
||||||
|
break;
|
||||||
|
case ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH:
|
||||||
|
lch_idx = 0;
|
||||||
|
if (ts->pchan != GSM_PCHAN_OSMO_DYN)
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc && ok)
|
||||||
|
*rc = 0;
|
||||||
|
|
||||||
|
return &ts->lchan[lch_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const uint8_t subslots_per_pchan[] = {
|
||||||
|
[GSM_PCHAN_NONE] = 0,
|
||||||
|
[GSM_PCHAN_CCCH] = 0,
|
||||||
|
[GSM_PCHAN_PDCH] = 0,
|
||||||
|
[GSM_PCHAN_CCCH_SDCCH4] = 4,
|
||||||
|
[GSM_PCHAN_TCH_F] = 1,
|
||||||
|
[GSM_PCHAN_TCH_H] = 2,
|
||||||
|
[GSM_PCHAN_SDCCH8_SACCH8C] = 8,
|
||||||
|
[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4,
|
||||||
|
[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8,
|
||||||
|
/*
|
||||||
|
* GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_OSMO_DYN should not be
|
||||||
|
* part of this, those TS are handled according to their dynamic state.
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
/*! Return the actual pchan type, also heeding dynamic TS. */
|
||||||
|
enum gsm_phys_chan_config ts_pchan(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
switch (ts->pchan) {
|
||||||
|
case GSM_PCHAN_OSMO_DYN:
|
||||||
|
return ts->dyn.pchan_is;
|
||||||
|
case GSM_PCHAN_TCH_F_PDCH:
|
||||||
|
if (ts->flags & TS_F_PDCH_ACTIVE)
|
||||||
|
return GSM_PCHAN_PDCH;
|
||||||
|
else
|
||||||
|
return GSM_PCHAN_TCH_F;
|
||||||
|
default:
|
||||||
|
return ts->pchan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! According to ts->pchan and possibly ts->dyn_pchan, return the number of
|
||||||
|
* logical channels available in the timeslot. */
|
||||||
|
uint8_t ts_subslots(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
return subslots_per_pchan[ts_pchan(ts)];
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
|
||||||
|
{
|
||||||
|
switch (pchan) {
|
||||||
|
case GSM_PCHAN_TCH_F:
|
||||||
|
case GSM_PCHAN_TCH_H:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ts_is_tch(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
return pchan_is_tch(ts_pchan(ts));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
switch (ts->pchan) {
|
||||||
|
case GSM_PCHAN_PDCH:
|
||||||
|
return true;
|
||||||
|
case GSM_PCHAN_TCH_F_PDCH:
|
||||||
|
return (ts->flags & TS_F_PDCH_ACTIVE)
|
||||||
|
&& !(ts->flags & TS_F_PDCH_PENDING_MASK);
|
||||||
|
case GSM_PCHAN_OSMO_DYN:
|
||||||
|
return ts->dyn.pchan_is == GSM_PCHAN_PDCH
|
||||||
|
&& ts->dyn.pchan_want == ts->dyn.pchan_is;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gsm_ts_release(struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
unsigned int ln;
|
||||||
|
|
||||||
|
for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) {
|
||||||
|
struct gsm_lchan *lchan = &ts->lchan[ln];
|
||||||
|
gsm_lchan_release(lchan, LCHAN_REL_ACT_OML);
|
||||||
|
}
|
||||||
|
ts->pchan = GSM_PCHAN_NONE;
|
||||||
|
/* Make sure pchan_is is reset, since PCU act_req to release it will be
|
||||||
|
* ignored as the lchan will already be released. */
|
||||||
|
ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
|
||||||
|
}
|
||||||
@@ -1,833 +0,0 @@
|
|||||||
/* (C) 2008-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 Affero General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#include <netinet/in.h>
|
|
||||||
|
|
||||||
#include <osmocom/core/linuxlist.h>
|
|
||||||
#include <osmocom/core/talloc.h>
|
|
||||||
#include <osmocom/gsm/gsm_utils.h>
|
|
||||||
#include <osmocom/gsm/abis_nm.h>
|
|
||||||
#include <osmocom/core/statistics.h>
|
|
||||||
#include <osmocom/codec/ecu.h>
|
|
||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
|
||||||
|
|
||||||
void gsm_abis_mo_reset(struct gsm_abis_mo *mo)
|
|
||||||
{
|
|
||||||
mo->nm_state.operational = NM_OPSTATE_NULL;
|
|
||||||
mo->nm_state.availability = NM_AVSTATE_POWER_OFF;
|
|
||||||
mo->nm_state.administrative = NM_STATE_LOCKED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
|
|
||||||
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3)
|
|
||||||
{
|
|
||||||
mo->bts = bts;
|
|
||||||
mo->obj_class = obj_class;
|
|
||||||
mo->obj_inst.bts_nr = p1;
|
|
||||||
mo->obj_inst.trx_nr = p2;
|
|
||||||
mo->obj_inst.ts_nr = p3;
|
|
||||||
gsm_abis_mo_reset(mo);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct value_string bts_attribute_names[] = {
|
|
||||||
OSMO_VALUE_STRING(BTS_TYPE_VARIANT),
|
|
||||||
OSMO_VALUE_STRING(BTS_SUB_MODEL),
|
|
||||||
OSMO_VALUE_STRING(TRX_PHY_VERSION),
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
enum bts_attribute str2btsattr(const char *s)
|
|
||||||
{
|
|
||||||
return get_string_value(bts_attribute_names, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *btsatttr2str(enum bts_attribute v)
|
|
||||||
{
|
|
||||||
return get_value_string(bts_attribute_names, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
|
|
||||||
{ BTS_UNKNOWN, "unknown" },
|
|
||||||
{ BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
|
|
||||||
{ BTS_OSMO_OC2G, "osmo-bts-oc2g" },
|
|
||||||
{ BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
|
|
||||||
{ BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
|
|
||||||
{ BTS_OSMO_TRX, "omso-bts-trx" },
|
|
||||||
{ BTS_OSMO_VIRTUAL, "omso-bts-virtual" },
|
|
||||||
{ BTS_OSMO_OMLDUMMY, "omso-bts-omldummy" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
enum gsm_bts_type_variant str2btsvariant(const char *arg)
|
|
||||||
{
|
|
||||||
return get_string_value(osmo_bts_variant_names, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *btsvariant2str(enum gsm_bts_type_variant v)
|
|
||||||
{
|
|
||||||
return get_value_string(osmo_bts_variant_names, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct value_string gsm_bts_features_descs[] = {
|
|
||||||
{ BTS_FEAT_HSCSD, "HSCSD" },
|
|
||||||
{ BTS_FEAT_GPRS, "GPRS" },
|
|
||||||
{ BTS_FEAT_EGPRS, "EGPRS" },
|
|
||||||
{ BTS_FEAT_ECSD, "ECSD" },
|
|
||||||
{ BTS_FEAT_HOPPING, "Frequency Hopping" },
|
|
||||||
{ BTS_FEAT_MULTI_TSC, "Multi-TSC" },
|
|
||||||
{ BTS_FEAT_OML_ALERTS, "OML Alerts" },
|
|
||||||
{ BTS_FEAT_AGCH_PCH_PROP, "AGCH/PCH proportional allocation" },
|
|
||||||
{ BTS_FEAT_CBCH, "CBCH" },
|
|
||||||
{ BTS_FEAT_SPEECH_F_V1, "Fullrate speech V1" },
|
|
||||||
{ BTS_FEAT_SPEECH_H_V1, "Halfrate speech V1" },
|
|
||||||
{ BTS_FEAT_SPEECH_F_EFR, "Fullrate speech EFR" },
|
|
||||||
{ BTS_FEAT_SPEECH_F_AMR, "Fullrate speech AMR" },
|
|
||||||
{ BTS_FEAT_SPEECH_H_AMR, "Halfrate speech AMR" },
|
|
||||||
{ BTS_FEAT_ETWS_PN, "ETWS Primary Notification on PCH" },
|
|
||||||
{ BTS_FEAT_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
|
|
||||||
{ BTS_FEAT_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined"},
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct value_string gsm_chreq_descs[] = {
|
|
||||||
{ GSM_CHREQ_REASON_EMERG, "emergency call" },
|
|
||||||
{ GSM_CHREQ_REASON_PAG, "answer to paging" },
|
|
||||||
{ GSM_CHREQ_REASON_CALL, "call re-establishment" },
|
|
||||||
{ GSM_CHREQ_REASON_LOCATION_UPD,"Location updating" },
|
|
||||||
{ GSM_CHREQ_REASON_PDCH, "one phase packet access" },
|
|
||||||
{ GSM_CHREQ_REASON_OTHER, "other" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct value_string gsm_pchant_names[13] = {
|
|
||||||
{ GSM_PCHAN_NONE, "NONE" },
|
|
||||||
{ GSM_PCHAN_CCCH, "CCCH" },
|
|
||||||
{ GSM_PCHAN_CCCH_SDCCH4,"CCCH+SDCCH4" },
|
|
||||||
{ GSM_PCHAN_TCH_F, "TCH/F" },
|
|
||||||
{ GSM_PCHAN_TCH_H, "TCH/H" },
|
|
||||||
{ GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" },
|
|
||||||
{ GSM_PCHAN_PDCH, "PDCH" },
|
|
||||||
{ GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" },
|
|
||||||
{ GSM_PCHAN_UNKNOWN, "UNKNOWN" },
|
|
||||||
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" },
|
|
||||||
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" },
|
|
||||||
{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "TCH/F_TCH/H_PDCH" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct value_string gsm_pchant_descs[13] = {
|
|
||||||
{ GSM_PCHAN_NONE, "Physical Channel not configured" },
|
|
||||||
{ GSM_PCHAN_CCCH, "FCCH + SCH + BCCH + CCCH (Comb. IV)" },
|
|
||||||
{ GSM_PCHAN_CCCH_SDCCH4,
|
|
||||||
"FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V)" },
|
|
||||||
{ GSM_PCHAN_TCH_F, "TCH/F + FACCH/F + SACCH (Comb. I)" },
|
|
||||||
{ GSM_PCHAN_TCH_H, "2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" },
|
|
||||||
{ GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" },
|
|
||||||
{ GSM_PCHAN_PDCH, "Packet Data Channel for GPRS/EDGE" },
|
|
||||||
{ GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" },
|
|
||||||
{ GSM_PCHAN_UNKNOWN, "Unknown / Unsupported channel combination" },
|
|
||||||
{ GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" },
|
|
||||||
{ GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" },
|
|
||||||
{ GSM_PCHAN_TCH_F_TCH_H_PDCH, "Dynamic TCH/F or TCH/H or GPRS PDCH" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c)
|
|
||||||
{
|
|
||||||
return get_value_string(gsm_pchant_names, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name)
|
|
||||||
{
|
|
||||||
return get_string_value(gsm_pchant_names, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: move to libosmocore, next to gsm_chan_t_names? */
|
|
||||||
const char *gsm_lchant_name(enum gsm_chan_t c)
|
|
||||||
{
|
|
||||||
return get_value_string(gsm_chan_t_names, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct value_string lchan_s_names[] = {
|
|
||||||
{ LCHAN_S_NONE, "NONE" },
|
|
||||||
{ LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },
|
|
||||||
{ LCHAN_S_ACTIVE, "ACTIVE" },
|
|
||||||
{ LCHAN_S_INACTIVE, "INACTIVE" },
|
|
||||||
{ LCHAN_S_REL_REQ, "RELEASE REQUESTED" },
|
|
||||||
{ LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },
|
|
||||||
{ LCHAN_S_BROKEN, "BROKEN UNUSABLE" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *gsm_lchans_name(enum gsm_lchan_state s)
|
|
||||||
{
|
|
||||||
return get_value_string(lchan_s_names, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct value_string chreq_names[] = {
|
|
||||||
{ GSM_CHREQ_REASON_EMERG, "EMERGENCY" },
|
|
||||||
{ GSM_CHREQ_REASON_PAG, "PAGING" },
|
|
||||||
{ GSM_CHREQ_REASON_CALL, "CALL" },
|
|
||||||
{ GSM_CHREQ_REASON_LOCATION_UPD,"LOCATION_UPDATE" },
|
|
||||||
{ GSM_CHREQ_REASON_OTHER, "OTHER" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c)
|
|
||||||
{
|
|
||||||
return get_value_string(chreq_names, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_num(struct gsm_network *net, int num)
|
|
||||||
{
|
|
||||||
struct gsm_bts *bts;
|
|
||||||
|
|
||||||
if (num >= net->num_bts)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
|
||||||
if (bts->nr == num)
|
|
||||||
return bts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx);
|
|
||||||
int k;
|
|
||||||
|
|
||||||
if (!trx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
trx->bts = bts;
|
|
||||||
trx->nr = bts->num_trx++;
|
|
||||||
|
|
||||||
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
|
|
||||||
bts->nr, trx->nr, 0xff);
|
|
||||||
|
|
||||||
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
|
|
||||||
bts->nr, trx->nr, 0xff);
|
|
||||||
|
|
||||||
for (k = 0; k < TRX_NR_TS; k++) {
|
|
||||||
struct gsm_bts_trx_ts *ts = &trx->ts[k];
|
|
||||||
int l;
|
|
||||||
|
|
||||||
ts->trx = trx;
|
|
||||||
ts->nr = k;
|
|
||||||
ts->pchan = GSM_PCHAN_NONE;
|
|
||||||
ts->dyn.pchan_is = GSM_PCHAN_NONE;
|
|
||||||
ts->dyn.pchan_want = GSM_PCHAN_NONE;
|
|
||||||
ts->tsc = -1;
|
|
||||||
|
|
||||||
gsm_mo_init(&ts->mo, bts, NM_OC_CHANNEL,
|
|
||||||
bts->nr, trx->nr, ts->nr);
|
|
||||||
|
|
||||||
ts->hopping.arfcns.data_len = sizeof(ts->hopping.arfcns_data);
|
|
||||||
ts->hopping.arfcns.data = ts->hopping.arfcns_data;
|
|
||||||
ts->hopping.ma.data_len = sizeof(ts->hopping.ma_data);
|
|
||||||
ts->hopping.ma.data = ts->hopping.ma_data;
|
|
||||||
|
|
||||||
for (l = 0; l < TS_MAX_LCHAN; l++) {
|
|
||||||
struct gsm_lchan *lchan;
|
|
||||||
char *name;
|
|
||||||
lchan = &ts->lchan[l];
|
|
||||||
|
|
||||||
lchan->ts = ts;
|
|
||||||
lchan->nr = l;
|
|
||||||
lchan->type = GSM_LCHAN_NONE;
|
|
||||||
|
|
||||||
name = gsm_lchan_name_compute(lchan);
|
|
||||||
lchan->name = talloc_strdup(trx, name);
|
|
||||||
INIT_LLIST_HEAD(&lchan->sapi_cmds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trx->nr != 0)
|
|
||||||
trx->nominal_power = bts->c0->nominal_power;
|
|
||||||
|
|
||||||
llist_add_tail(&trx->list, &bts->trx_list);
|
|
||||||
|
|
||||||
return trx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
|
|
||||||
static const uint8_t bts_cell_timer_default[] =
|
|
||||||
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
|
||||||
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
|
||||||
.parameter = {
|
|
||||||
[RLC_T3142] = 20,
|
|
||||||
[RLC_T3169] = 5,
|
|
||||||
[RLC_T3191] = 5,
|
|
||||||
[RLC_T3193] = 160, /* 10ms */
|
|
||||||
[RLC_T3195] = 5,
|
|
||||||
[RLC_N3101] = 10,
|
|
||||||
[RLC_N3103] = 4,
|
|
||||||
[RLC_N3105] = 8,
|
|
||||||
[CV_COUNTDOWN] = 15,
|
|
||||||
[T_DL_TBF_EXT] = 250 * 10, /* ms */
|
|
||||||
[T_UL_TBF_EXT] = 250 * 10, /* ms */
|
|
||||||
},
|
|
||||||
.paging = {
|
|
||||||
.repeat_time = 5 * 50, /* ms */
|
|
||||||
.repeat_count = 3,
|
|
||||||
},
|
|
||||||
.cs_mask = 0x1fff,
|
|
||||||
.initial_cs = 2,
|
|
||||||
.initial_mcs = 6,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
|
||||||
{
|
|
||||||
struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!bts)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
bts->nr = bts_num;
|
|
||||||
bts->num_trx = 0;
|
|
||||||
INIT_LLIST_HEAD(&bts->trx_list);
|
|
||||||
bts->ms_max_power = 15; /* dBm */
|
|
||||||
|
|
||||||
gsm_mo_init(&bts->mo, bts, NM_OC_BTS,
|
|
||||||
bts->nr, 0xff, 0xff);
|
|
||||||
gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
|
|
||||||
0xff, 0xff, 0xff);
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
|
|
||||||
bts->gprs.nsvc[i].bts = bts;
|
|
||||||
bts->gprs.nsvc[i].id = i;
|
|
||||||
gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
|
|
||||||
bts->nr, i, 0xff);
|
|
||||||
}
|
|
||||||
memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
|
|
||||||
sizeof(bts->gprs.nse.timer));
|
|
||||||
gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
|
|
||||||
bts->nr, 0xff, 0xff);
|
|
||||||
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
|
|
||||||
sizeof(bts->gprs.cell.timer));
|
|
||||||
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
|
|
||||||
bts->nr, 0xff, 0xff);
|
|
||||||
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
|
|
||||||
sizeof(bts->gprs.cell.rlc_cfg));
|
|
||||||
|
|
||||||
/* create our primary TRX. It will be initialized during bts_init() */
|
|
||||||
bts->c0 = gsm_bts_trx_alloc(bts);
|
|
||||||
if (!bts->c0) {
|
|
||||||
talloc_free(bts);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
bts->c0->ts[0].pchan = GSM_PCHAN_CCCH_SDCCH4;
|
|
||||||
|
|
||||||
bts->rach_b_thresh = -1;
|
|
||||||
bts->rach_ldavg_slots = -1;
|
|
||||||
bts->features.data = &bts->_features_data[0];
|
|
||||||
bts->features.data_len = sizeof(bts->_features_data);
|
|
||||||
|
|
||||||
/* si handling */
|
|
||||||
bts->bcch_change_mark = 1;
|
|
||||||
|
|
||||||
return bts;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
|
|
||||||
if (num >= bts->num_trx)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
|
||||||
if (trx->nr == num)
|
|
||||||
return trx;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char ts2str[255];
|
|
||||||
|
|
||||||
char *gsm_trx_name(const struct gsm_bts_trx *trx)
|
|
||||||
{
|
|
||||||
if (!trx)
|
|
||||||
snprintf(ts2str, sizeof(ts2str), "(trx=NULL)");
|
|
||||||
else
|
|
||||||
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d)",
|
|
||||||
trx->bts->nr, trx->nr);
|
|
||||||
|
|
||||||
return ts2str;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr);
|
|
||||||
|
|
||||||
return ts2str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Log timeslot number with full pchan information */
|
|
||||||
char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
switch (ts->pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
|
||||||
if (ts->dyn.pchan_is == ts->dyn.pchan_want)
|
|
||||||
snprintf(ts2str, sizeof(ts2str),
|
|
||||||
"(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
||||||
gsm_pchan_name(ts->pchan),
|
|
||||||
gsm_pchan_name(ts->dyn.pchan_is));
|
|
||||||
else
|
|
||||||
snprintf(ts2str, sizeof(ts2str),
|
|
||||||
"(bts=%d,trx=%d,ts=%d,pchan=%s"
|
|
||||||
" switching %s -> %s)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
||||||
gsm_pchan_name(ts->pchan),
|
|
||||||
gsm_pchan_name(ts->dyn.pchan_is),
|
|
||||||
gsm_pchan_name(ts->dyn.pchan_want));
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_TCH_F_PDCH:
|
|
||||||
if ((ts->flags & TS_F_PDCH_PENDING_MASK) == 0)
|
|
||||||
snprintf(ts2str, sizeof(ts2str),
|
|
||||||
"(bts=%d,trx=%d,ts=%d,pchan=%s as %s)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
||||||
gsm_pchan_name(ts->pchan),
|
|
||||||
(ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
|
|
||||||
: "TCH/F");
|
|
||||||
else
|
|
||||||
snprintf(ts2str, sizeof(ts2str),
|
|
||||||
"(bts=%d,trx=%d,ts=%d,pchan=%s"
|
|
||||||
" switching %s -> %s)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
||||||
gsm_pchan_name(ts->pchan),
|
|
||||||
(ts->flags & TS_F_PDCH_ACTIVE)? "PDCH"
|
|
||||||
: "TCH/F",
|
|
||||||
(ts->flags & TS_F_PDCH_ACT_PENDING)? "PDCH"
|
|
||||||
: "TCH/F");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,pchan=%s)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr,
|
|
||||||
gsm_pchan_name(ts->pchan));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ts2str;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *gsm_lchan_name_compute(const struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx_ts *ts = lchan->ts;
|
|
||||||
|
|
||||||
snprintf(ts2str, sizeof(ts2str), "(bts=%d,trx=%d,ts=%d,ss=%d)",
|
|
||||||
ts->trx->bts->nr, ts->trx->nr, ts->nr, lchan->nr);
|
|
||||||
|
|
||||||
return ts2str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* obtain the MO structure for a given object instance */
|
|
||||||
struct gsm_abis_mo *
|
|
||||||
gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
struct gsm_abis_mo *mo = NULL;
|
|
||||||
|
|
||||||
switch (obj_class) {
|
|
||||||
case NM_OC_BTS:
|
|
||||||
mo = &bts->mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_RADIO_CARRIER:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
mo = &trx->mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_BASEB_TRANSC:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
mo = &trx->bb_transc.mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_CHANNEL:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
if (obj_inst->ts_nr >= TRX_NR_TS)
|
|
||||||
return NULL;
|
|
||||||
mo = &trx->ts[obj_inst->ts_nr].mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_SITE_MANAGER:
|
|
||||||
mo = &bts->site_mgr.mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_NSE:
|
|
||||||
mo = &bts->gprs.nse.mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_CELL:
|
|
||||||
mo = &bts->gprs.cell.mo;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_NSVC:
|
|
||||||
if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
|
|
||||||
return NULL;
|
|
||||||
mo = &bts->gprs.nsvc[obj_inst->trx_nr].mo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return mo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* obtain the gsm_nm_state data structure for a given object instance */
|
|
||||||
struct gsm_nm_state *
|
|
||||||
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst)
|
|
||||||
{
|
|
||||||
struct gsm_abis_mo *mo;
|
|
||||||
|
|
||||||
mo = gsm_objclass2mo(bts, obj_class, obj_inst);
|
|
||||||
if (!mo)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return &mo->nm_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* obtain the in-memory data structure of a given object instance */
|
|
||||||
void *
|
|
||||||
gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
|
||||||
const struct abis_om_obj_inst *obj_inst)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx *trx;
|
|
||||||
void *obj = NULL;
|
|
||||||
|
|
||||||
switch (obj_class) {
|
|
||||||
case NM_OC_BTS:
|
|
||||||
obj = bts;
|
|
||||||
break;
|
|
||||||
case NM_OC_RADIO_CARRIER:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
obj = trx;
|
|
||||||
break;
|
|
||||||
case NM_OC_BASEB_TRANSC:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
obj = &trx->bb_transc;
|
|
||||||
break;
|
|
||||||
case NM_OC_CHANNEL:
|
|
||||||
if (obj_inst->trx_nr >= bts->num_trx) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
|
|
||||||
if (obj_inst->ts_nr >= TRX_NR_TS)
|
|
||||||
return NULL;
|
|
||||||
obj = &trx->ts[obj_inst->ts_nr];
|
|
||||||
break;
|
|
||||||
case NM_OC_SITE_MANAGER:
|
|
||||||
obj = &bts->site_mgr;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_NSE:
|
|
||||||
obj = &bts->gprs.nse;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_CELL:
|
|
||||||
obj = &bts->gprs.cell;
|
|
||||||
break;
|
|
||||||
case NM_OC_GPRS_NSVC:
|
|
||||||
if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc))
|
|
||||||
return NULL;
|
|
||||||
obj = &bts->gprs.nsvc[obj_inst->trx_nr];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* See Table 10.5.25 of GSM04.08 */
|
|
||||||
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
|
||||||
uint8_t ts_nr, uint8_t lchan_nr)
|
|
||||||
{
|
|
||||||
uint8_t cbits, chan_nr;
|
|
||||||
|
|
||||||
OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH);
|
|
||||||
OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);
|
|
||||||
|
|
||||||
switch (pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F:
|
|
||||||
OSMO_ASSERT(lchan_nr == 0);
|
|
||||||
cbits = 0x01;
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_PDCH:
|
|
||||||
OSMO_ASSERT(lchan_nr == 0);
|
|
||||||
cbits = RSL_CHAN_OSMO_PDCH >> 3;
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_TCH_H:
|
|
||||||
OSMO_ASSERT(lchan_nr < 2);
|
|
||||||
cbits = 0x02;
|
|
||||||
cbits += lchan_nr;
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_CCCH_SDCCH4:
|
|
||||||
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
|
||||||
/*
|
|
||||||
* As a special hack for BCCH, lchan_nr == 4 may be passed
|
|
||||||
* here. This should never be sent in an RSL message.
|
|
||||||
* See osmo-bts-xxx/oml.c:opstart_compl().
|
|
||||||
*/
|
|
||||||
if (lchan_nr == CCCH_LCHAN)
|
|
||||||
cbits = 0x10; /* BCCH */
|
|
||||||
else {
|
|
||||||
OSMO_ASSERT(lchan_nr < 4);
|
|
||||||
cbits = 0x04;
|
|
||||||
cbits += lchan_nr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
|
||||||
OSMO_ASSERT(lchan_nr < 8);
|
|
||||||
cbits = 0x08;
|
|
||||||
cbits += lchan_nr;
|
|
||||||
break;
|
|
||||||
case GSM_PCHAN_CCCH:
|
|
||||||
default:
|
|
||||||
/* OSMO_ASSERT(lchan_nr == 0);
|
|
||||||
* FIXME: On octphy and litecell, we hit above assertion (see
|
|
||||||
* Max's comment at https://gerrit.osmocom.org/589 ); disabled
|
|
||||||
* for BTS until this is clarified; remove the #ifdef when it
|
|
||||||
* is fixed. Tracked in OS#2906.
|
|
||||||
*/
|
|
||||||
#pragma message "fix caller that passes lchan_nr != 0"
|
|
||||||
cbits = 0x10;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
chan_nr = (cbits << 3) | (ts_nr & 0x7);
|
|
||||||
|
|
||||||
return chan_nr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
switch (lchan->ts->pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
|
||||||
/* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the
|
|
||||||
* nonstandard value reflecting PDCH for Osmocom style dyn TS. */
|
|
||||||
return gsm_lchan_as_pchan2chan_nr(lchan,
|
|
||||||
lchan->ts->dyn.pchan_is);
|
|
||||||
case GSM_PCHAN_TCH_F_PDCH:
|
|
||||||
/* For ip.access style dyn TS, we always want to use the chan_nr as if it was TCH/F.
|
|
||||||
* We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */
|
|
||||||
return gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);
|
|
||||||
default:
|
|
||||||
return gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
|
||||||
enum gsm_phys_chan_config as_pchan)
|
|
||||||
{
|
|
||||||
if (lchan->ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH
|
|
||||||
&& as_pchan == GSM_PCHAN_PDCH)
|
|
||||||
return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);
|
|
||||||
return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
|
||||||
struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts)
|
|
||||||
{
|
|
||||||
struct gsm_lchan *lchan = NULL;
|
|
||||||
struct gsm_bts_trx *trx = bts->c0;
|
|
||||||
|
|
||||||
if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
|
||||||
lchan = &trx->ts[0].lchan[2];
|
|
||||||
else {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
|
|
||||||
lchan = &trx->ts[i].lchan[2];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lchan;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* determine logical channel based on TRX and channel number IE */
|
|
||||||
struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr,
|
|
||||||
int *rc)
|
|
||||||
{
|
|
||||||
uint8_t ts_nr = chan_nr & 0x07;
|
|
||||||
uint8_t cbits = chan_nr >> 3;
|
|
||||||
uint8_t lch_idx;
|
|
||||||
struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
if (rc)
|
|
||||||
*rc = -EINVAL;
|
|
||||||
|
|
||||||
if (cbits == 0x01) {
|
|
||||||
lch_idx = 0; /* TCH/F */
|
|
||||||
if (ts->pchan != GSM_PCHAN_TCH_F &&
|
|
||||||
ts->pchan != GSM_PCHAN_PDCH &&
|
|
||||||
ts->pchan != GSM_PCHAN_TCH_F_PDCH &&
|
|
||||||
ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
|
|
||||||
ok = false;
|
|
||||||
} else if ((cbits & 0x1e) == 0x02) {
|
|
||||||
lch_idx = cbits & 0x1; /* TCH/H */
|
|
||||||
if (ts->pchan != GSM_PCHAN_TCH_H &&
|
|
||||||
ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
|
|
||||||
ok = false;
|
|
||||||
} else if ((cbits & 0x1c) == 0x04) {
|
|
||||||
lch_idx = cbits & 0x3; /* SDCCH/4 */
|
|
||||||
if (ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
|
|
||||||
ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
|
||||||
ok = false;
|
|
||||||
} else if ((cbits & 0x18) == 0x08) {
|
|
||||||
lch_idx = cbits & 0x7; /* SDCCH/8 */
|
|
||||||
if (ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C &&
|
|
||||||
ts->pchan != GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
|
|
||||||
ok = false;
|
|
||||||
} else if (cbits == 0x10 || cbits == 0x11 || cbits == 0x12) {
|
|
||||||
lch_idx = 0;
|
|
||||||
if (ts->pchan != GSM_PCHAN_CCCH &&
|
|
||||||
ts->pchan != GSM_PCHAN_CCCH_SDCCH4 &&
|
|
||||||
ts->pchan != GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
|
||||||
ok = false;
|
|
||||||
/* FIXME: we should not return first sdcch4 !!! */
|
|
||||||
} else if ((chan_nr & RSL_CHAN_NR_MASK) == RSL_CHAN_OSMO_PDCH) {
|
|
||||||
lch_idx = 0;
|
|
||||||
if (ts->pchan != GSM_PCHAN_TCH_F_TCH_H_PDCH)
|
|
||||||
ok = false;
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (rc && ok)
|
|
||||||
*rc = 0;
|
|
||||||
|
|
||||||
return &ts->lchan[lch_idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
static const uint8_t subslots_per_pchan[] = {
|
|
||||||
[GSM_PCHAN_NONE] = 0,
|
|
||||||
[GSM_PCHAN_CCCH] = 0,
|
|
||||||
[GSM_PCHAN_PDCH] = 0,
|
|
||||||
[GSM_PCHAN_CCCH_SDCCH4] = 4,
|
|
||||||
[GSM_PCHAN_TCH_F] = 1,
|
|
||||||
[GSM_PCHAN_TCH_H] = 2,
|
|
||||||
[GSM_PCHAN_SDCCH8_SACCH8C] = 8,
|
|
||||||
[GSM_PCHAN_CCCH_SDCCH4_CBCH] = 4,
|
|
||||||
[GSM_PCHAN_SDCCH8_SACCH8C_CBCH] = 8,
|
|
||||||
/*
|
|
||||||
* GSM_PCHAN_TCH_F_PDCH and GSM_PCHAN_TCH_F_TCH_H_PDCH should not be
|
|
||||||
* part of this, those TS are handled according to their dynamic state.
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Return the actual pchan type, also heeding dynamic TS. */
|
|
||||||
enum gsm_phys_chan_config ts_pchan(struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
switch (ts->pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
|
||||||
return ts->dyn.pchan_is;
|
|
||||||
case GSM_PCHAN_TCH_F_PDCH:
|
|
||||||
if (ts->flags & TS_F_PDCH_ACTIVE)
|
|
||||||
return GSM_PCHAN_PDCH;
|
|
||||||
else
|
|
||||||
return GSM_PCHAN_TCH_F;
|
|
||||||
default:
|
|
||||||
return ts->pchan;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! According to ts->pchan and possibly ts->dyn_pchan, return the number of
|
|
||||||
* logical channels available in the timeslot. */
|
|
||||||
uint8_t ts_subslots(struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
return subslots_per_pchan[ts_pchan(ts)];
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool pchan_is_tch(enum gsm_phys_chan_config pchan)
|
|
||||||
{
|
|
||||||
switch (pchan) {
|
|
||||||
case GSM_PCHAN_TCH_F:
|
|
||||||
case GSM_PCHAN_TCH_H:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ts_is_tch(struct gsm_bts_trx_ts *ts)
|
|
||||||
{
|
|
||||||
return pchan_is_tch(ts_pchan(ts));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *gsm_trx_unit_id(struct gsm_bts_trx *trx)
|
|
||||||
{
|
|
||||||
static char buf[23];
|
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%u/%u/%u", trx->bts->ip_access.site_id,
|
|
||||||
trx->bts->ip_access.bts_id, trx->nr);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct value_string lchan_ciph_state_names[] = {
|
|
||||||
{ LCHAN_CIPH_NONE, "NONE" },
|
|
||||||
{ LCHAN_CIPH_RX_REQ, "RX_REQ" },
|
|
||||||
{ LCHAN_CIPH_RX_CONF, "RX_CONF" },
|
|
||||||
{ LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" },
|
|
||||||
{ LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" },
|
|
||||||
{ LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" },
|
|
||||||
{ 0, NULL }
|
|
||||||
};
|
|
||||||
|
|
||||||
/* determine the ECU codec constant for the codec used by given lchan */
|
|
||||||
int lchan2ecu_codec(const struct gsm_lchan *lchan)
|
|
||||||
{
|
|
||||||
struct gsm_bts_trx_ts *ts = lchan->ts;
|
|
||||||
|
|
||||||
switch (lchan->tch_mode) {
|
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
|
||||||
if (ts_pchan(ts) == GSM_PCHAN_TCH_H)
|
|
||||||
return OSMO_ECU_CODEC_HR;
|
|
||||||
else
|
|
||||||
return OSMO_ECU_CODEC_FR;
|
|
||||||
break;
|
|
||||||
case GSM48_CMODE_SPEECH_EFR:
|
|
||||||
return OSMO_ECU_CODEC_EFR;
|
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
|
||||||
return OSMO_ECU_CODEC_AMR;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -51,7 +51,7 @@ static int ho_tx_phys_info(struct gsm_lchan *lchan)
|
|||||||
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh));
|
||||||
gh->proto_discr = GSM48_PDISC_RR;
|
gh->proto_discr = GSM48_PDISC_RR;
|
||||||
gh->msg_type = GSM48_MT_RR_HANDO_INFO;
|
gh->msg_type = GSM48_MT_RR_HANDO_INFO;
|
||||||
msgb_put_u8(msg, lchan->rqd_ta);
|
msgb_put_u8(msg, lchan->ta_ctrl.current);
|
||||||
|
|
||||||
rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan),
|
rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan),
|
||||||
0x00, 0);
|
0x00, 0);
|
||||||
@@ -111,7 +111,8 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay)
|
|||||||
"TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra);
|
"TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra);
|
||||||
|
|
||||||
/* Set timing advance */
|
/* Set timing advance */
|
||||||
lchan->rqd_ta = acc_delay;
|
lchan->ta_ctrl.current = acc_delay;
|
||||||
|
lchan->want_dl_sacch_active = true;
|
||||||
|
|
||||||
/* Stop handover detection, wait for valid frame */
|
/* Stop handover detection, wait for valid frame */
|
||||||
lchan->ho.active = HANDOVER_WAIT_FRAME;
|
lchan->ho.active = HANDOVER_WAIT_FRAME;
|
||||||
@@ -122,7 +123,7 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Send HANDover DETect to BSC */
|
/* Send HANDover DETect to BSC */
|
||||||
rsl_tx_hando_det(lchan, &lchan->rqd_ta);
|
rsl_tx_hando_det(lchan, &lchan->ta_ctrl.current);
|
||||||
|
|
||||||
/* Send PHYS INFO */
|
/* Send PHYS INFO */
|
||||||
lchan->ho.phys_info_count = 1;
|
lchan->ho.phys_info_count = 1;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -19,31 +19,642 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "btsconfig.h" /* for PACKAGE_VERSION */
|
||||||
|
|
||||||
#include <osmocom/core/logging.h>
|
#include <osmocom/core/logging.h>
|
||||||
|
|
||||||
|
#include <osmocom/trau/osmo_ortp.h>
|
||||||
|
|
||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/lchan.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/pcu_if.h>
|
||||||
|
#include <osmo-bts/handover.h>
|
||||||
|
#include <osmo-bts/l1sap.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
static const struct value_string lchan_s_names[] = {
|
||||||
|
{ LCHAN_S_NONE, "NONE" },
|
||||||
|
{ LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" },
|
||||||
|
{ LCHAN_S_ACTIVE, "ACTIVE" },
|
||||||
|
{ LCHAN_S_REL_REQ, "RELEASE REQUESTED" },
|
||||||
|
{ LCHAN_S_REL_ERR, "RELEASE DUE ERROR" },
|
||||||
|
{ LCHAN_S_BROKEN, "BROKEN UNUSABLE" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct value_string lchan_ciph_state_names[] = {
|
||||||
|
{ LCHAN_CIPH_NONE, "NONE" },
|
||||||
|
{ LCHAN_CIPH_RX_REQ, "RX_REQ" },
|
||||||
|
{ LCHAN_CIPH_RX_CONF, "RX_CONF" },
|
||||||
|
{ LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" },
|
||||||
|
{ LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" },
|
||||||
|
{ LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* prepare the per-SAPI T200 arrays for a given lchan */
|
||||||
|
static int t200_by_lchan(int *t200_ms_dcch, int *t200_ms_acch, struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
|
||||||
|
/* we have to compensate for the "RTS advance" due to the asynchronous interface between
|
||||||
|
* the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
|
||||||
|
int32_t fn_advance = bts_get_avg_fn_advance(bts);
|
||||||
|
int32_t fn_advance_us = fn_advance * 4615;
|
||||||
|
int fn_advance_ms = fn_advance_us / 1000;
|
||||||
|
|
||||||
|
t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
||||||
|
t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
||||||
|
|
||||||
|
if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
|
||||||
|
t200_ms_acch[DL_SAPI0] *= 2;
|
||||||
|
t200_ms_acch[DL_SAPI3] *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (lchan->type) {
|
||||||
|
case GSM_LCHAN_SDCCH:
|
||||||
|
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
|
||||||
|
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
|
||||||
|
break;
|
||||||
|
case GSM_LCHAN_TCH_F:
|
||||||
|
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
||||||
|
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
||||||
|
break;
|
||||||
|
case GSM_LCHAN_TCH_H:
|
||||||
|
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
||||||
|
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void early_rr_ia_delay_cb(void *data)
|
||||||
|
{
|
||||||
|
struct gsm_lchan *lchan = data;
|
||||||
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
|
||||||
|
if (!lchan->early_rr_ia) {
|
||||||
|
/* The IA message has disappeared since the timer was started. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||||
|
/* Release has happened since the timer was started. */
|
||||||
|
msgb_free(lchan->early_rr_ia);
|
||||||
|
lchan->early_rr_ia = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Activation is done, send the RR IA now. Put RR IA msg into the AGCH queue of the BTS. */
|
||||||
|
if (bts_agch_enqueue(bts, lchan->early_rr_ia) < 0) {
|
||||||
|
/* if there is no space in the queue: send DELETE IND */
|
||||||
|
rsl_tx_delete_ind(bts, lchan->early_rr_ia->data, lchan->early_rr_ia->len);
|
||||||
|
rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_DELETED);
|
||||||
|
msgb_free(lchan->early_rr_ia);
|
||||||
|
}
|
||||||
|
lchan->early_rr_ia = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr)
|
||||||
|
{
|
||||||
|
lchan->ts = ts;
|
||||||
|
lchan->nr = lchan_nr;
|
||||||
|
lchan->type = GSM_LCHAN_NONE;
|
||||||
|
gsm_lchan_name_update(lchan);
|
||||||
|
|
||||||
|
osmo_timer_setup(&lchan->early_rr_ia_delay, early_rr_ia_delay_cb, lchan);
|
||||||
|
|
||||||
|
INIT_LLIST_HEAD(&lchan->sapi_cmds);
|
||||||
|
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
|
||||||
|
lchan->dl_tch_queue_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gsm_lchan_name_update(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
const struct gsm_bts_trx_ts *ts = lchan->ts;
|
||||||
|
const struct gsm_bts_trx *trx = ts->trx;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)",
|
||||||
|
GSM_TS_NAME_ARGS(ts), lchan->nr);
|
||||||
|
if (lchan->name != NULL)
|
||||||
|
talloc_free(lchan->name);
|
||||||
|
lchan->name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lchan_init_lapdm(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
struct lapdm_channel *lc = &lchan->lapdm_ch;
|
||||||
|
int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
|
||||||
|
|
||||||
|
if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) {
|
||||||
|
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
|
||||||
|
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
|
||||||
|
t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
|
||||||
|
t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
|
||||||
|
lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type,
|
||||||
|
gsm_lchan_name(lchan));
|
||||||
|
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
|
||||||
|
lapdm_channel_set_l1(lc, NULL, lchan);
|
||||||
|
}
|
||||||
|
/* We still need to set Rx callback to receive RACH requests: */
|
||||||
|
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dyn_ts_pdch_release(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx_ts *ts = lchan->ts;
|
||||||
|
|
||||||
|
if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "%s: PDCH release requested but already"
|
||||||
|
" in switchover\n", gsm_ts_and_pchan_name(ts));
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Indicate PDCH Disconnect in dyn_pdch.want, let pcu_tx_info_ind()
|
||||||
|
* pick it up and wait for PCU to disable the channel.
|
||||||
|
*/
|
||||||
|
ts->dyn.pchan_want = GSM_PCHAN_NONE;
|
||||||
|
|
||||||
|
if (!pcu_connected()) {
|
||||||
|
/* PCU not connected yet. Just record the new type and done,
|
||||||
|
* the PCU will pick it up once connected. */
|
||||||
|
ts->dyn.pchan_is = GSM_PCHAN_NONE;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pcu_tx_info_ind();
|
||||||
|
}
|
||||||
|
|
||||||
|
void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (lchan->abis_ip.rtp_socket) {
|
||||||
|
rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC);
|
||||||
|
osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO,
|
||||||
|
"Closing RTP socket on Channel Release ");
|
||||||
|
lchan_rtp_socket_free(lchan);
|
||||||
|
} else if (lchan->abis_ip.osmux.use) {
|
||||||
|
lchan_osmux_release(lchan);
|
||||||
|
}
|
||||||
|
/* reset all Abis related config: */
|
||||||
|
memset(&lchan->abis_ip, 0, sizeof(lchan->abis_ip));
|
||||||
|
|
||||||
|
/* FIXME: right now we allow creating the rtp_socket even if chan is not
|
||||||
|
* activated... Once we check for that, we can move this check at the
|
||||||
|
* start of the function */
|
||||||
|
if (lchan->state == LCHAN_S_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* release handover state */
|
||||||
|
handover_reset(lchan);
|
||||||
|
|
||||||
|
lchan->rel_act_kind = rel_kind;
|
||||||
|
|
||||||
|
/* Dynamic channel in PDCH mode is released via PCU */
|
||||||
|
if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN
|
||||||
|
&& lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) {
|
||||||
|
rc = dyn_ts_pdch_release(lchan);
|
||||||
|
if (rc == 1) {
|
||||||
|
/* If the PCU is not connected, continue to rel ack right away. */
|
||||||
|
lchan->rel_act_kind = LCHAN_REL_ACT_PCU;
|
||||||
|
rsl_tx_rf_rel_ack(lchan);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Waiting for PDCH release */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
l1sap_chan_rel(lchan->ts->trx, gsm_lchan2chan_nr(lchan));
|
||||||
|
}
|
||||||
|
|
||||||
|
int lchan_deactivate(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(lchan);
|
||||||
|
|
||||||
|
lchan->ciph_state = 0;
|
||||||
|
return bts_model_lchan_deactivate(lchan);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *gsm_lchans_name(enum gsm_lchan_state s)
|
||||||
|
{
|
||||||
|
return get_value_string(lchan_s_names, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* obtain the next to-be transmitted dowlink SACCH frame (L2 hdr + L3); returns pointer to lchan->si buffer */
|
||||||
|
uint8_t *lchan_sacch_get(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
uint32_t tmp, i;
|
||||||
|
|
||||||
|
for (i = 0; i < _MAX_SYSINFO_TYPE; i++) {
|
||||||
|
tmp = (lchan->si.last + 1 + i) % _MAX_SYSINFO_TYPE;
|
||||||
|
if (!(lchan->si.valid & (1 << tmp)))
|
||||||
|
continue;
|
||||||
|
lchan->si.last = tmp;
|
||||||
|
return GSM_LCHAN_SI(lchan, tmp);
|
||||||
|
}
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "SACCH no SI available\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
||||||
{
|
{
|
||||||
DEBUGP(DL1C, "%s state %s -> %s\n",
|
if (lchan->state == state)
|
||||||
gsm_lchan_name(lchan),
|
return;
|
||||||
gsm_lchans_name(lchan->state),
|
LOGPLCHAN(lchan, DL1C, LOGL_INFO, "state %s -> %s\n",
|
||||||
gsm_lchans_name(state));
|
gsm_lchans_name(lchan->state), gsm_lchans_name(state));
|
||||||
lchan->state = state;
|
lchan->state = state;
|
||||||
}
|
|
||||||
|
|
||||||
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
|
switch (lchan->state) {
|
||||||
{
|
case LCHAN_S_ACT_REQ:
|
||||||
switch (ts->pchan) {
|
/* Early Immediate Assignment: Activation is requested, keep the
|
||||||
case GSM_PCHAN_PDCH:
|
* early IA until active. This allows the BSC to send the IA
|
||||||
return true;
|
* even before a dynamic timeslot is done switching to a
|
||||||
case GSM_PCHAN_TCH_F_PDCH:
|
* different pchan kind (experimental). */
|
||||||
return (ts->flags & TS_F_PDCH_ACTIVE)
|
break;
|
||||||
&& !(ts->flags & TS_F_PDCH_PENDING_MASK);
|
case LCHAN_S_ACTIVE:
|
||||||
case GSM_PCHAN_TCH_F_TCH_H_PDCH:
|
lchan_init_lapdm(lchan);
|
||||||
return ts->dyn.pchan_is == GSM_PCHAN_PDCH
|
if (lchan->early_rr_ia) {
|
||||||
&& ts->dyn.pchan_want == ts->dyn.pchan_is;
|
/* Early Immediate Assignment: Activation is done, send
|
||||||
|
* the RR IA now. Delay a bit more to give Um time to
|
||||||
|
* let the lchan light up for the MS */
|
||||||
|
osmo_timer_del(&lchan->early_rr_ia_delay);
|
||||||
|
osmo_timer_schedule(&lchan->early_rr_ia_delay, 0,
|
||||||
|
osmo_tdef_get(abis_T_defs, -15, OSMO_TDEF_US, -1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LCHAN_S_NONE:
|
||||||
|
lapdm_channel_exit(&lchan->lapdm_ch);
|
||||||
|
/* Also ensure that there are no leftovers from repeated FACCH or
|
||||||
|
* repeated SACCH that might cause memory leakage. */
|
||||||
|
msgb_free(lchan->rep_acch.dl_facch[0].msg);
|
||||||
|
msgb_free(lchan->rep_acch.dl_facch[1].msg);
|
||||||
|
lchan->rep_acch.dl_facch[0].msg = NULL;
|
||||||
|
lchan->rep_acch.dl_facch[1].msg = NULL;
|
||||||
|
msgb_free(lchan->rep_acch.dl_sacch_msg);
|
||||||
|
lchan->rep_acch.dl_sacch_msg = NULL;
|
||||||
|
/* free() pending messages */
|
||||||
|
msgb_free(lchan->pending_rel_ind_msg);
|
||||||
|
lchan->pending_rel_ind_msg = NULL;
|
||||||
|
msgb_free(lchan->pending_chan_activ);
|
||||||
|
lchan->pending_chan_activ = NULL;
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
return false;
|
if (lchan->early_rr_ia) {
|
||||||
|
/* Early Immediate Assignment: Transition to any other
|
||||||
|
* state means whatever IA the BSC has sent shall now
|
||||||
|
* not be relevant anymore. */
|
||||||
|
osmo_timer_del(&lchan->early_rr_ia_delay);
|
||||||
|
msgb_free(lchan->early_rr_ia);
|
||||||
|
lchan->early_rr_ia = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See Table 10.5.25 of GSM04.08 */
|
||||||
|
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||||
|
uint8_t ts_nr, uint8_t lchan_nr)
|
||||||
|
{
|
||||||
|
uint8_t cbits, chan_nr;
|
||||||
|
|
||||||
|
OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN);
|
||||||
|
OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH);
|
||||||
|
|
||||||
|
switch (pchan) {
|
||||||
|
case GSM_PCHAN_TCH_F:
|
||||||
|
OSMO_ASSERT(lchan_nr == 0);
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs;
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_PDCH:
|
||||||
|
OSMO_ASSERT(lchan_nr == 0);
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH;
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_TCH_H:
|
||||||
|
OSMO_ASSERT(lchan_nr < 2);
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr);
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_CCCH_SDCCH4:
|
||||||
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
||||||
|
/*
|
||||||
|
* As a special hack for BCCH, lchan_nr == 4 may be passed
|
||||||
|
* here. This should never be sent in an RSL message.
|
||||||
|
* See osmo-bts-xxx/oml.c:opstart_compl().
|
||||||
|
*/
|
||||||
|
if (lchan_nr == CCCH_LCHAN)
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
||||||
|
else {
|
||||||
|
OSMO_ASSERT(lchan_nr < 4);
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
|
OSMO_ASSERT(lchan_nr < 8);
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr);
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_CCCH:
|
||||||
|
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_NONE:
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
|
||||||
|
gsm_pchan_name(pchan));
|
||||||
|
cbits = 0x00;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
|
||||||
|
gsm_pchan_name(pchan), (int)pchan);
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
chan_nr = (cbits << 3) | (ts_nr & 0x7);
|
||||||
|
|
||||||
|
return chan_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t _gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool rsl)
|
||||||
|
{
|
||||||
|
uint8_t chan_nr;
|
||||||
|
|
||||||
|
switch (lchan->ts->pchan) {
|
||||||
|
case GSM_PCHAN_OSMO_DYN:
|
||||||
|
/* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the
|
||||||
|
* nonstandard value reflecting PDCH for Osmocom style dyn TS. */
|
||||||
|
chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is);
|
||||||
|
break;
|
||||||
|
case GSM_PCHAN_TCH_F_PDCH:
|
||||||
|
/* For ip.access style dyn TS, on RSL we want to use the chan_nr as if it was TCH/F.
|
||||||
|
* We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */
|
||||||
|
if (rsl)
|
||||||
|
chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);
|
||||||
|
else if (~lchan->ts->flags & TS_F_PDCH_ACTIVE)
|
||||||
|
chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F);
|
||||||
|
else
|
||||||
|
chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect
|
||||||
|
* this in the channel number. Convert it to Osmocom specific value. */
|
||||||
|
if (lchan->ts->vamos.is_shadow)
|
||||||
|
chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK;
|
||||||
|
|
||||||
|
return chan_nr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
return _gsm_lchan2chan_nr(lchan, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
return _gsm_lchan2chan_nr(lchan, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan,
|
||||||
|
enum gsm_phys_chan_config as_pchan)
|
||||||
|
{
|
||||||
|
if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN
|
||||||
|
&& as_pchan == GSM_PCHAN_PDCH)
|
||||||
|
return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK);
|
||||||
|
return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called by the model specific code every 104 TDMA frames (SACCH period) */
|
||||||
|
void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm)
|
||||||
|
{
|
||||||
|
const uint8_t meas_num = lchan->meas.interf_meas_num;
|
||||||
|
|
||||||
|
if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) {
|
||||||
|
LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room "
|
||||||
|
"to store interference report (%ddBm)\n", dbm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lchan->meas.interf_meas_dbm[meas_num] = dbm;
|
||||||
|
lchan->meas.interf_meas_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called by the higher layers every Intave * 104 TDMA frames */
|
||||||
|
void gsm_lchan_interf_meas_calc_avg(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
const uint8_t meas_num = lchan->meas.interf_meas_num;
|
||||||
|
const struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
int b, meas_avg, meas_sum = 0;
|
||||||
|
|
||||||
|
/* There must be at least one sample */
|
||||||
|
OSMO_ASSERT(meas_num > 0);
|
||||||
|
|
||||||
|
/* Calculate the sum of all collected samples (in -x dBm) */
|
||||||
|
while (lchan->meas.interf_meas_num) {
|
||||||
|
uint8_t i = --lchan->meas.interf_meas_num;
|
||||||
|
meas_sum += lchan->meas.interf_meas_dbm[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate the average of all collected samples */
|
||||||
|
meas_avg = meas_sum / (int) meas_num;
|
||||||
|
|
||||||
|
/* 3GPP TS 48.008 defines 5 interference bands, and 6 interference level
|
||||||
|
* boundaries (0, X1, ... X5). It's not clear how to handle values
|
||||||
|
* exceeding the outer boundaries (0 or X5), because bands 0 and 6 do
|
||||||
|
* not exist (sigh). Let's map such values to closest bands 1 and 5. */
|
||||||
|
if (bts->interference.boundary[0] < bts->interference.boundary[5]) {
|
||||||
|
/* Ascending order (band=1 indicates lowest interference) */
|
||||||
|
for (b = 1; b < ARRAY_SIZE(bts->interference.boundary) - 1; b++) {
|
||||||
|
if (meas_avg < bts->interference.boundary[b])
|
||||||
|
break; /* Current 'b' is the band value */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Descending order (band=1 indicates highest interference) */
|
||||||
|
for (b = 1; b < ARRAY_SIZE(bts->interference.boundary) - 1; b++) {
|
||||||
|
if (meas_avg >= bts->interference.boundary[b])
|
||||||
|
break; /* Current 'b' is the band value */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGPLCHAN(lchan, DL1C, LOGL_DEBUG,
|
||||||
|
"Interference AVG: %ddBm (band %d, samples %u)\n",
|
||||||
|
meas_avg, b, meas_num);
|
||||||
|
|
||||||
|
lchan->meas.interf_meas_avg_dbm = meas_avg;
|
||||||
|
lchan->meas.interf_band = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* determine the ECU codec constant for the codec used by given lchan */
|
||||||
|
int lchan2ecu_codec(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
const struct gsm_bts_trx_ts *ts = lchan->ts;
|
||||||
|
|
||||||
|
switch (lchan->tch_mode) {
|
||||||
|
case GSM48_CMODE_SPEECH_V1:
|
||||||
|
if (ts_pchan(ts) == GSM_PCHAN_TCH_H)
|
||||||
|
return OSMO_ECU_CODEC_HR;
|
||||||
|
else
|
||||||
|
return OSMO_ECU_CODEC_FR;
|
||||||
|
break;
|
||||||
|
case GSM48_CMODE_SPEECH_EFR:
|
||||||
|
return OSMO_ECU_CODEC_EFR;
|
||||||
|
case GSM48_CMODE_SPEECH_AMR:
|
||||||
|
return OSMO_ECU_CODEC_AMR;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
unsigned int i;
|
||||||
|
unsigned int tries;
|
||||||
|
|
||||||
|
tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2;
|
||||||
|
for (i = 0; i < tries; i++) {
|
||||||
|
|
||||||
|
if (bts->rtp_port_range_next >= bts->rtp_port_range_end)
|
||||||
|
bts->rtp_port_range_next = bts->rtp_port_range_start;
|
||||||
|
|
||||||
|
rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next);
|
||||||
|
|
||||||
|
bts->rtp_port_range_next += 2;
|
||||||
|
|
||||||
|
if (rc != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (bts->rtp_ip_dscp != -1) {
|
||||||
|
if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp))
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%d: %s\n",
|
||||||
|
bts->rtp_ip_dscp, strerror(errno));
|
||||||
|
}
|
||||||
|
if (bts->rtp_priority != -1) {
|
||||||
|
if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority))
|
||||||
|
LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n",
|
||||||
|
bts->rtp_priority, strerror(errno));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
char cname[256+4];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (lchan->abis_ip.rtp_socket) {
|
||||||
|
LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, "
|
||||||
|
"but we already have socket!\n");
|
||||||
|
return -EALREADY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: select default value depending on speech_mode */
|
||||||
|
//if (!payload_type)
|
||||||
|
lchan->tch.last_fn = LCHAN_FN_DUMMY;
|
||||||
|
lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx,
|
||||||
|
OSMO_RTP_F_POLL);
|
||||||
|
|
||||||
|
if (!lchan->abis_ip.rtp_socket) {
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n");
|
||||||
|
oml_tx_failure_event_rep(&lchan->ts->trx->mo,
|
||||||
|
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
|
||||||
|
"%s IPAC Failed to create RTP/RTCP sockets",
|
||||||
|
gsm_lchan_name(lchan));
|
||||||
|
return -ENOTCONN;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket,
|
||||||
|
bts->rtp_jitter_adaptive ?
|
||||||
|
OSMO_RTP_P_JIT_ADAP :
|
||||||
|
OSMO_RTP_P_JITBUF,
|
||||||
|
bts->rtp_jitter_buf_ms);
|
||||||
|
if (rc < 0)
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR,
|
||||||
|
"IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc));
|
||||||
|
else
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc);
|
||||||
|
|
||||||
|
lchan->abis_ip.rtp_socket->priv = lchan;
|
||||||
|
lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb;
|
||||||
|
|
||||||
|
rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, bind_ip);
|
||||||
|
if (rc < 0) {
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n");
|
||||||
|
oml_tx_failure_event_rep(&lchan->ts->trx->mo,
|
||||||
|
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
|
||||||
|
"%s IPAC Failed to bind RTP/RTCP sockets",
|
||||||
|
gsm_lchan_name(lchan));
|
||||||
|
lchan_rtp_socket_free(lchan);
|
||||||
|
return -EBADFD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure RTCP SDES contains some useful information */
|
||||||
|
snprintf(cname, sizeof(cname), "bts@%s", bind_ip);
|
||||||
|
osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname,
|
||||||
|
gsm_lchan_name(lchan), NULL, NULL,
|
||||||
|
gsm_trx_unit_id(lchan->ts->trx),
|
||||||
|
"OsmoBTS-" PACKAGE_VERSION, NULL);
|
||||||
|
/* FIXME: multiplex connection, BSC proxy */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port)
|
||||||
|
{
|
||||||
|
int bound_port = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket,
|
||||||
|
inet_ntoa(*ia), connect_port);
|
||||||
|
if (rc < 0) {
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n");
|
||||||
|
return -ECONNREFUSED;
|
||||||
|
}
|
||||||
|
/* save IP address and port number */
|
||||||
|
lchan->abis_ip.connect_ip = ntohl(ia->s_addr);
|
||||||
|
lchan->abis_ip.connect_port = connect_port;
|
||||||
|
|
||||||
|
rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket,
|
||||||
|
&lchan->abis_ip.bound_ip,
|
||||||
|
&bound_port);
|
||||||
|
if (rc < 0)
|
||||||
|
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc);
|
||||||
|
lchan->abis_ip.bound_port = bound_port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lchan_rtp_socket_free(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
osmo_rtp_socket_free(lchan->abis_ip.rtp_socket);
|
||||||
|
lchan->abis_ip.rtp_socket = NULL;
|
||||||
|
msgb_queue_free(&lchan->dl_tch_queue);
|
||||||
|
lchan->dl_tch_queue_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! limit number of queue entries to %u; drops any surplus messages */
|
||||||
|
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit)
|
||||||
|
{
|
||||||
|
if (lchan->dl_tch_queue_len > limit)
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n",
|
||||||
|
lchan->dl_tch_queue_len - limit);
|
||||||
|
while (lchan->dl_tch_queue_len > limit) {
|
||||||
|
struct msgb *tmp = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len);
|
||||||
|
msgb_free(tmp);
|
||||||
|
}
|
||||||
|
msgb_enqueue_count(&lchan->dl_tch_queue, msg, &lchan->dl_tch_queue_len);
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
#include <osmo-bts/rsl.h>
|
#include <osmo-bts/rsl.h>
|
||||||
#include <osmo-bts/paging.h>
|
#include <osmo-bts/paging.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
|
||||||
static void reset_load_counters(struct gsm_bts *bts)
|
static void reset_load_counters(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
@@ -40,6 +41,10 @@ static void load_timer_cb(void *data)
|
|||||||
struct gsm_bts *bts = data;
|
struct gsm_bts *bts = data;
|
||||||
unsigned int pch_percent, rach_percent;
|
unsigned int pch_percent, rach_percent;
|
||||||
|
|
||||||
|
/* It makes no sense to send Load Indication if CCCH is still disabled...*/
|
||||||
|
if (bts->c0->ts[0].mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
||||||
|
goto retry_later;
|
||||||
|
|
||||||
/* compute percentages */
|
/* compute percentages */
|
||||||
if (bts->load.ccch.pch_total == 0)
|
if (bts->load.ccch.pch_total == 0)
|
||||||
pch_percent = 0;
|
pch_percent = 0;
|
||||||
@@ -72,6 +77,7 @@ static void load_timer_cb(void *data)
|
|||||||
bts->load.rach.access);
|
bts->load.rach.access);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retry_later:
|
||||||
reset_load_counters(bts);
|
reset_load_counters(bts);
|
||||||
|
|
||||||
/* re-schedule the timer */
|
/* re-schedule the timer */
|
||||||
@@ -93,3 +99,8 @@ void load_timer_stop(struct gsm_bts *bts)
|
|||||||
{
|
{
|
||||||
osmo_timer_del(&bts->load.ccch.timer);
|
osmo_timer_del(&bts->load.ccch.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool load_timer_is_running(const struct gsm_bts *bts)
|
||||||
|
{
|
||||||
|
return osmo_timer_pending(&bts->load.ccch.timer);
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ static struct log_info_cat bts_log_info_cat[] = {
|
|||||||
.name = "DRSL",
|
.name = "DRSL",
|
||||||
.description = "A-bis Radio Siganlling Link (RSL)",
|
.description = "A-bis Radio Siganlling Link (RSL)",
|
||||||
.color = "\033[1;35m",
|
.color = "\033[1;35m",
|
||||||
.enabled = 1, .loglevel = LOGL_INFO,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
[DOML] = {
|
[DOML] = {
|
||||||
.name = "DOML",
|
.name = "DOML",
|
||||||
.description = "A-bis Network Management / O&M (NM/OML)",
|
.description = "A-bis Network Management / O&M (NM/OML)",
|
||||||
.color = "\033[1;36m",
|
.color = "\033[1;36m",
|
||||||
.enabled = 1, .loglevel = LOGL_INFO,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
[DRLL] = {
|
[DRLL] = {
|
||||||
.name = "DRLL",
|
.name = "DRLL",
|
||||||
@@ -64,34 +64,23 @@ static struct log_info_cat bts_log_info_cat[] = {
|
|||||||
.name = "DPAG",
|
.name = "DPAG",
|
||||||
.description = "Paging Subsystem",
|
.description = "Paging Subsystem",
|
||||||
.color = "\033[1;38m",
|
.color = "\033[1;38m",
|
||||||
.enabled = 1, .loglevel = LOGL_INFO,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
[DL1C] = {
|
[DL1C] = {
|
||||||
.name = "DL1C",
|
.name = "DL1C",
|
||||||
.description = "Layer 1 Control (MPH)",
|
.description = "Layer 1 Control (MPH)",
|
||||||
.loglevel = LOGL_INFO,
|
.loglevel = LOGL_NOTICE,
|
||||||
.enabled = 1,
|
.enabled = 1,
|
||||||
},
|
},
|
||||||
[DL1P] = {
|
[DL1P] = {
|
||||||
.name = "DL1P",
|
.name = "DL1P",
|
||||||
.description = "Layer 1 Primitives (PH)",
|
.description = "Layer 1 Primitives (PH)",
|
||||||
.loglevel = LOGL_INFO,
|
.loglevel = LOGL_NOTICE,
|
||||||
.enabled = 0,
|
.enabled = 0,
|
||||||
},
|
},
|
||||||
[DDSP] = {
|
[DDSP] = {
|
||||||
.name = "DDSP",
|
.name = "DDSP",
|
||||||
.description = "DSP Trace Messages",
|
.description = "DSP Trace Messages",
|
||||||
.loglevel = LOGL_DEBUG,
|
|
||||||
.enabled = 1,
|
|
||||||
},
|
|
||||||
[DABIS] = {
|
|
||||||
.name = "DABIS",
|
|
||||||
.description = "A-bis Intput Subsystem",
|
|
||||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
|
||||||
},
|
|
||||||
[DRTP] = {
|
|
||||||
.name = "DRTP",
|
|
||||||
.description = "Realtime Transfer Protocol",
|
|
||||||
.loglevel = LOGL_NOTICE,
|
.loglevel = LOGL_NOTICE,
|
||||||
.enabled = 1,
|
.enabled = 1,
|
||||||
},
|
},
|
||||||
@@ -116,29 +105,23 @@ static struct log_info_cat bts_log_info_cat[] = {
|
|||||||
[DLOOP] = {
|
[DLOOP] = {
|
||||||
.name = "DLOOP",
|
.name = "DLOOP",
|
||||||
.description = "Control loops",
|
.description = "Control loops",
|
||||||
.color = "\033[0;34m",
|
.color = "\033[0;94m",
|
||||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
#if 0
|
[DABIS] = {
|
||||||
[DNS] = {
|
.name = "DABIS",
|
||||||
.name = "DNS",
|
.description = "A-bis Intput Subsystem",
|
||||||
.description = "GPRS Network Service (NS)",
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
.enabled = 1, .loglevel = LOGL_INFO,
|
|
||||||
},
|
},
|
||||||
[DBSSGP] = {
|
[DRTP] = {
|
||||||
.name = "DBSSGP",
|
.name = "DRTP",
|
||||||
.description = "GPRS BSS Gateway Protocol (BSSGP)",
|
.description = "Realtime Transfer Protocol",
|
||||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
.loglevel = LOGL_NOTICE,
|
||||||
|
.enabled = 1,
|
||||||
},
|
},
|
||||||
[DLLC] = {
|
[DOSMUX] = {
|
||||||
.name = "DLLC",
|
.name = "DOSMUX",
|
||||||
.description = "GPRS Logical Link Control Protocol (LLC)",
|
.description = "Osmux (Osmocom RTP multiplexing)",
|
||||||
.enabled = 1, .loglevel = LOGL_DEBUG,
|
|
||||||
},
|
|
||||||
#endif
|
|
||||||
[DSUM] = {
|
|
||||||
.name = "DSUM",
|
|
||||||
.description = "DSUM",
|
|
||||||
.loglevel = LOGL_NOTICE,
|
.loglevel = LOGL_NOTICE,
|
||||||
.enabled = 1,
|
.enabled = 1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -38,6 +38,9 @@
|
|||||||
#include <osmocom/core/application.h>
|
#include <osmocom/core/application.h>
|
||||||
#include <osmocom/vty/telnet_interface.h>
|
#include <osmocom/vty/telnet_interface.h>
|
||||||
#include <osmocom/vty/logging.h>
|
#include <osmocom/vty/logging.h>
|
||||||
|
#include <osmocom/vty/stats.h>
|
||||||
|
#include <osmocom/vty/misc.h>
|
||||||
|
#include <osmocom/vty/cpu_sched_vty.h>
|
||||||
#include <osmocom/core/gsmtap_util.h>
|
#include <osmocom/core/gsmtap_util.h>
|
||||||
#include <osmocom/core/gsmtap.h>
|
#include <osmocom/core/gsmtap.h>
|
||||||
|
|
||||||
@@ -56,30 +59,62 @@
|
|||||||
#include <osmocom/ctrl/control_vty.h>
|
#include <osmocom/ctrl/control_vty.h>
|
||||||
#include <osmo-bts/oml.h>
|
#include <osmo-bts/oml.h>
|
||||||
|
|
||||||
int quit = 0;
|
static int quit = 0;
|
||||||
static const char *config_file = "osmo-bts.cfg";
|
static const char *config_file = "osmo-bts.cfg";
|
||||||
static int daemonize = 0;
|
static int daemonize = 0;
|
||||||
static int rt_prio = -1;
|
static int rt_prio = -1;
|
||||||
static char *gsmtap_ip = 0;
|
static char *gsmtap_ip = 0;
|
||||||
extern int g_vty_port_num;
|
extern int g_vty_port_num;
|
||||||
|
static bool vty_test_mode = false;
|
||||||
|
|
||||||
static void print_help()
|
static void print_help()
|
||||||
{
|
{
|
||||||
printf( "Some useful options:\n"
|
printf( "Some useful options:\n"
|
||||||
" -h --help this text\n"
|
" -h --help this text\n"
|
||||||
" -d --debug MASK Enable debugging (e.g. -d DRSL:DOML:DLAPDM)\n"
|
" -d --debug MASK Enable debugging (e.g. -d DRSL:DOML:DLAPDM)\n"
|
||||||
" -D --daemonize For the process into a background daemon\n"
|
" -D --daemonize For the process into a background daemon\n"
|
||||||
" -c --config-file Specify the filename of the config file\n"
|
" -c --config-file Specify the filename of the config file\n"
|
||||||
" -s --disable-color Don't use colors in stderr log output\n"
|
" -s --disable-color Don't use colors in stderr log output\n"
|
||||||
" -T --timestamp Prefix every log line with a timestamp\n"
|
" -T --timestamp Prefix every log line with a timestamp\n"
|
||||||
" -V --version Print version information and exit\n"
|
" -V --version Print version information and exit\n"
|
||||||
" -e --log-level Set a global log-level\n"
|
" -e --log-level Set a global log-level\n"
|
||||||
" -r --realtime PRIO Use SCHED_RR with the specified priority\n"
|
"\nVTY reference generation:\n"
|
||||||
" -i --gsmtap-ip The destination IP used for GSMTAP.\n"
|
" --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n"
|
||||||
|
" --vty-ref-xml Generate the VTY reference XML output and exit.\n"
|
||||||
|
"\nRegression testing:\n"
|
||||||
|
" --vty-test VTY test mode. Do not connect to BSC, do not exit.\n"
|
||||||
);
|
);
|
||||||
bts_model_print_help();
|
bts_model_print_help();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_long_options(const char *prog_name, const int long_option)
|
||||||
|
{
|
||||||
|
static int vty_ref_mode = VTY_REF_GEN_MODE_DEFAULT;
|
||||||
|
|
||||||
|
switch (long_option) {
|
||||||
|
case 1:
|
||||||
|
vty_ref_mode = get_string_value(vty_ref_gen_mode_names, optarg);
|
||||||
|
if (vty_ref_mode < 0) {
|
||||||
|
fprintf(stderr, "%s: Unknown VTY reference generation "
|
||||||
|
"mode '%s'\n", prog_name, optarg);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fprintf(stderr, "Generating the VTY reference in mode '%s' (%s)\n",
|
||||||
|
get_value_string(vty_ref_gen_mode_names, vty_ref_mode),
|
||||||
|
get_value_string(vty_ref_gen_mode_desc, vty_ref_mode));
|
||||||
|
vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode);
|
||||||
|
exit(0);
|
||||||
|
case 3:
|
||||||
|
vty_test_mode = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "%s: error parsing cmdline options\n", prog_name);
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: finally get some option parsing code into libosmocore */
|
/* FIXME: finally get some option parsing code into libosmocore */
|
||||||
static void handle_options(int argc, char **argv)
|
static void handle_options(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -94,6 +129,7 @@ static void handle_options(int argc, char **argv)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int option_idx = 0, c;
|
int option_idx = 0, c;
|
||||||
|
static int long_option = 0;
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
/* FIXME: all those are generic Osmocom app options */
|
/* FIXME: all those are generic Osmocom app options */
|
||||||
{ "help", 0, 0, 'h' },
|
{ "help", 0, 0, 'h' },
|
||||||
@@ -108,6 +144,9 @@ static void handle_options(int argc, char **argv)
|
|||||||
{ "gsmtap-ip", 1, 0, 'i' },
|
{ "gsmtap-ip", 1, 0, 'i' },
|
||||||
{ "trx-num", 1, 0, 't' },
|
{ "trx-num", 1, 0, 't' },
|
||||||
{ "realtime", 1, 0, 'r' },
|
{ "realtime", 1, 0, 'r' },
|
||||||
|
{ "vty-ref-mode", 1, &long_option, 1 },
|
||||||
|
{ "vty-ref-xml", 0, &long_option, 2 },
|
||||||
|
{ "vty-test", 0, &long_option, 3 },
|
||||||
{ 0, 0, 0, 0 }
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -121,6 +160,9 @@ static void handle_options(int argc, char **argv)
|
|||||||
print_help();
|
print_help();
|
||||||
exit(0);
|
exit(0);
|
||||||
break;
|
break;
|
||||||
|
case 0:
|
||||||
|
handle_long_options(argv[0], long_option);
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
log_set_use_color(osmo_stderr_target, 0);
|
log_set_use_color(osmo_stderr_target, 0);
|
||||||
break;
|
break;
|
||||||
@@ -145,13 +187,17 @@ static void handle_options(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
rt_prio = atoi(optarg);
|
rt_prio = atoi(optarg);
|
||||||
|
fprintf(stderr, "Command line argument '-r' is deprecated, use VTY "
|
||||||
|
"cpu-sched node setting 'policy rr %d' instead.\n", rt_prio);
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
gsmtap_ip = optarg;
|
gsmtap_ip = optarg;
|
||||||
|
fprintf(stderr, "Command line argument '-i' is deprecated, use VTY "
|
||||||
|
"parameter 'gsmtap-remote-host %s' instead.\n", gsmtap_ip);
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
fprintf(stderr, "Parameter -t is deprecated and does nothing, "
|
fprintf(stderr, "Command line argument '-t' is deprecated and does nothing, "
|
||||||
"TRX num is calculated from VTY\n");
|
"TRX number is calculated from the VTY automatically.\n");
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
case 1:
|
case 1:
|
||||||
@@ -173,24 +219,35 @@ static void handle_options(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct gsm_bts *bts;
|
/* FIXME: remove this once we add multi-BTS support */
|
||||||
|
struct gsm_bts *g_bts = NULL;
|
||||||
|
|
||||||
static void signal_handler(int signal)
|
static void signal_handler(int signum)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "signal %u received\n", signal);
|
fprintf(stderr, "signal %u received\n", signum);
|
||||||
|
|
||||||
switch (signal) {
|
switch (signum) {
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
if (!quit) {
|
if (!quit) {
|
||||||
oml_tx_failure_event_rep(&bts->mo,
|
oml_tx_failure_event_rep(&g_bts->mo,
|
||||||
NM_SEVER_CRITICAL, OSMO_EVT_CRIT_PROC_STOP,
|
NM_SEVER_CRITICAL, OSMO_EVT_CRIT_PROC_STOP,
|
||||||
"BTS: SIGINT received -> shutdown");
|
"BTS: SIGINT received -> shutdown");
|
||||||
bts_shutdown(bts, "SIGINT");
|
bts_shutdown_ext(g_bts, "SIGINT", true, false);
|
||||||
}
|
}
|
||||||
quit++;
|
quit++;
|
||||||
break;
|
break;
|
||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
|
/* in case of abort, we want to obtain a talloc report and
|
||||||
|
* then run default SIGABRT handler, who will generate coredump
|
||||||
|
* and abort the process. abort() should do this for us after we
|
||||||
|
* return, but program wouldn't exit if an external SIGABRT is
|
||||||
|
* received.
|
||||||
|
*/
|
||||||
|
talloc_report_full(tall_bts_ctx, stderr);
|
||||||
|
signal(SIGABRT, SIG_DFL);
|
||||||
|
raise(SIGABRT);
|
||||||
|
break;
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
case SIGUSR2:
|
case SIGUSR2:
|
||||||
talloc_report_full(tall_bts_ctx, stderr);
|
talloc_report_full(tall_bts_ctx, stderr);
|
||||||
@@ -200,33 +257,11 @@ static void signal_handler(int signal)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int write_pid_file(char *procname)
|
|
||||||
{
|
|
||||||
FILE *outf;
|
|
||||||
char tmp[PATH_MAX+1];
|
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp)-1, "/var/run/%s.pid", procname);
|
|
||||||
tmp[PATH_MAX-1] = '\0';
|
|
||||||
|
|
||||||
outf = fopen(tmp, "w");
|
|
||||||
if (!outf)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
fprintf(outf, "%d\n", getpid());
|
|
||||||
|
|
||||||
fclose(outf);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bts_main(int argc, char **argv)
|
int bts_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct gsm_bts_trx *trx;
|
struct gsm_bts_trx *trx;
|
||||||
struct e1inp_line *line;
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
printf("((*))\n |\n / \\ OsmoBTS\n");
|
|
||||||
|
|
||||||
/* Track the use of talloc NULL memory contexts */
|
/* Track the use of talloc NULL memory contexts */
|
||||||
talloc_enable_null_tracking();
|
talloc_enable_null_tracking();
|
||||||
|
|
||||||
@@ -238,19 +273,31 @@ int bts_main(int argc, char **argv)
|
|||||||
osmo_stats_init(tall_bts_ctx);
|
osmo_stats_init(tall_bts_ctx);
|
||||||
vty_init(&bts_vty_info);
|
vty_init(&bts_vty_info);
|
||||||
ctrl_vty_init(tall_bts_ctx);
|
ctrl_vty_init(tall_bts_ctx);
|
||||||
|
osmo_cpu_sched_vty_init(tall_bts_ctx);
|
||||||
rate_ctr_init(tall_bts_ctx);
|
rate_ctr_init(tall_bts_ctx);
|
||||||
|
|
||||||
|
logging_vty_add_cmds();
|
||||||
|
osmo_talloc_vty_add_cmds();
|
||||||
|
osmo_stats_vty_add_cmds();
|
||||||
|
osmo_fsm_vty_add_cmds();
|
||||||
|
|
||||||
|
bts_vty_init(tall_bts_ctx);
|
||||||
|
e1inp_vty_init();
|
||||||
|
|
||||||
|
logging_vty_add_deprecated_subsys(tall_bts_ctx, "sum");
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
bts = gsm_bts_alloc(tall_bts_ctx, 0);
|
fprintf(stderr, "((*))\n |\n / \\ OsmoBTS\n");
|
||||||
if (!bts) {
|
if (vty_test_mode)
|
||||||
|
fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
|
||||||
|
|
||||||
|
g_bts = gsm_bts_alloc(tall_bts_ctx, 0);
|
||||||
|
if (!g_bts) {
|
||||||
fprintf(stderr, "Failed to create BTS structure\n");
|
fprintf(stderr, "Failed to create BTS structure\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
e1inp_vty_init();
|
|
||||||
bts_vty_init(bts);
|
|
||||||
|
|
||||||
/* enable realtime priority for us */
|
/* enable realtime priority for us */
|
||||||
if (rt_prio != -1) {
|
if (rt_prio != -1) {
|
||||||
struct sched_param param;
|
struct sched_param param;
|
||||||
@@ -265,21 +312,12 @@ int bts_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gsmtap_ip) {
|
if (bts_init(g_bts) < 0) {
|
||||||
gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 1);
|
|
||||||
if (!gsmtap) {
|
|
||||||
fprintf(stderr, "Failed during gsmtap_init()\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
gsmtap_source_add_sink(gsmtap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bts_init(bts) < 0) {
|
|
||||||
fprintf(stderr, "unable to open bts\n");
|
fprintf(stderr, "unable to open bts\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
abis_init(bts);
|
abis_init(g_bts);
|
||||||
|
|
||||||
rc = vty_read_config_file(config_file, NULL);
|
rc = vty_read_config_file(config_file, NULL);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
@@ -293,17 +331,41 @@ int bts_main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
llist_for_each_entry(trx, &g_bts->trx_list, list) {
|
||||||
if (!trx->role_bts.l1h) {
|
if (!trx->pinst) {
|
||||||
fprintf(stderr, "TRX %u has no associated PHY instance\n",
|
fprintf(stderr, "TRX %u has no associated PHY instance\n",
|
||||||
trx->nr);
|
trx->nr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_pid_file("osmo-bts");
|
/* Accept a GSMTAP host from VTY config, but a commandline option overrides that. */
|
||||||
|
if (gsmtap_ip != NULL) {
|
||||||
|
if (g_bts->gsmtap.remote_host != NULL) {
|
||||||
|
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||||
|
"Command line argument '-i %s' overrides "
|
||||||
|
"'gsmtap-remote-host %s' from the config file\n",
|
||||||
|
gsmtap_ip, g_bts->gsmtap.remote_host);
|
||||||
|
talloc_free(g_bts->gsmtap.remote_host);
|
||||||
|
}
|
||||||
|
g_bts->gsmtap.remote_host = talloc_strdup(g_bts, gsmtap_ip);
|
||||||
|
}
|
||||||
|
|
||||||
bts_controlif_setup(bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
|
/* TODO: move this to gsm_bts_alloc() */
|
||||||
|
if (g_bts->gsmtap.remote_host != NULL) {
|
||||||
|
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||||
|
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
|
||||||
|
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||||
|
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
|
||||||
|
GSMTAP_UDP_PORT, 1);
|
||||||
|
if (g_bts->gsmtap.inst == NULL) {
|
||||||
|
fprintf(stderr, "Failed during gsmtap_source_init()\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
|
||||||
|
|
||||||
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
|
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
|
||||||
g_vty_port_num);
|
g_vty_port_num);
|
||||||
@@ -312,29 +374,36 @@ int bts_main(int argc, char **argv)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcu_sock_init(bts->pcu.sock_path)) {
|
if (pcu_sock_init(g_bts->pcu.sock_path)) {
|
||||||
fprintf(stderr, "PCU L1 socket failed\n");
|
fprintf(stderr, "PCU L1 socket failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGINT, &signal_handler);
|
signal(SIGINT, &signal_handler);
|
||||||
signal(SIGTERM, &signal_handler);
|
signal(SIGTERM, &signal_handler);
|
||||||
//signal(SIGABRT, &signal_handler);
|
signal(SIGABRT, &signal_handler);
|
||||||
signal(SIGUSR1, &signal_handler);
|
signal(SIGUSR1, &signal_handler);
|
||||||
signal(SIGUSR2, &signal_handler);
|
signal(SIGUSR2, &signal_handler);
|
||||||
osmo_init_ignore_signals();
|
osmo_init_ignore_signals();
|
||||||
|
|
||||||
if (!bts->bsc_oml_host) {
|
if (bts_osmux_open(g_bts) < 0) {
|
||||||
fprintf(stderr, "Cannot start BTS without knowing BSC OML IP\n");
|
fprintf(stderr, "Osmux setup failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
line = abis_open(bts, bts->bsc_oml_host, "sysmoBTS");
|
if (vty_test_mode) {
|
||||||
if (!line) {
|
/* Just select-loop without connecting to the BSC, don't exit. This allows running tests on the VTY
|
||||||
fprintf(stderr, "unable to connect to BSC\n");
|
* telnet port. */
|
||||||
exit(2);
|
while (!quit) {
|
||||||
|
log_reset_context();
|
||||||
|
osmo_select_main(0);
|
||||||
|
}
|
||||||
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abis_open(g_bts, "osmo-bts") != 0)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
rc = phy_links_open();
|
rc = phy_links_open();
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "unable to open PHY link(s)\n");
|
fprintf(stderr, "unable to open PHY link(s)\n");
|
||||||
|
|||||||
@@ -2,20 +2,31 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <osmocom/gsm/gsm_utils.h>
|
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/core/endian.h>
|
||||||
|
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_44_004.h>
|
||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/measurement.h>
|
#include <osmo-bts/measurement.h>
|
||||||
#include <osmo-bts/scheduler.h>
|
#include <osmo-bts/scheduler.h>
|
||||||
#include <osmo-bts/rsl.h>
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/power_control.h>
|
||||||
#include <osmo-bts/ta_control.h>
|
#include <osmo-bts/ta_control.h>
|
||||||
|
|
||||||
/* Tables as per TS 45.008 Section 8.3 */
|
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
|
||||||
static const uint8_t ts45008_83_tch_f[] = { 52, 53, 54, 55, 56, 57, 58, 59 };
|
* This mapping is used to determine if a L2 block starting at the given TDMA FN
|
||||||
static const uint8_t ts45008_83_tch_hs0[] = { 0, 2, 4, 6, 52, 54, 56, 58 };
|
* belongs to the SUB set and thus shall always be transmitted in DTX mode. */
|
||||||
static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
|
static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
|
||||||
|
/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
|
||||||
|
[0] = 1, /* block { 0, 2, 4, 6} */
|
||||||
|
[52] = 1, /* block {52, 54, 56, 58} */
|
||||||
|
/* TCH/H(1): 14, 16, 18, 20, 66, 68, 70, 72 */
|
||||||
|
[14] = 1, /* block {14, 16, 18, 20} */
|
||||||
|
[66] = 1, /* block {66, 68, 70, 72} */
|
||||||
|
};
|
||||||
|
|
||||||
/* In cases where we less measurements than we expect we must assume that we
|
/* In cases where we less measurements than we expect we must assume that we
|
||||||
* just did not receive the block because it was lost due to bad channel
|
* just did not receive the block because it was lost due to bad channel
|
||||||
@@ -24,51 +35,43 @@ static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
|
|||||||
* the missing measurements */
|
* the missing measurements */
|
||||||
#define MEASUREMENT_DUMMY_BER 10000 /* 100% BER */
|
#define MEASUREMENT_DUMMY_BER 10000 /* 100% BER */
|
||||||
#define MEASUREMENT_DUMMY_IRSSI 109 /* noise floor in -dBm */
|
#define MEASUREMENT_DUMMY_IRSSI 109 /* noise floor in -dBm */
|
||||||
static const struct bts_ul_meas measurement_dummy = (struct bts_ul_meas) {
|
static const struct bts_ul_meas measurement_dummy = {
|
||||||
.ber10k = MEASUREMENT_DUMMY_BER,
|
.ber10k = MEASUREMENT_DUMMY_BER,
|
||||||
.ta_offs_256bits = 0,
|
.ta_offs_256bits = 0,
|
||||||
.c_i = 0,
|
.ci_cb = 0,
|
||||||
.is_sub = 0,
|
.is_sub = 0,
|
||||||
.inv_rssi = MEASUREMENT_DUMMY_IRSSI
|
.inv_rssi = MEASUREMENT_DUMMY_IRSSI
|
||||||
};
|
};
|
||||||
|
|
||||||
/* find out if an array contains a given key as element */
|
|
||||||
#define ARRAY_CONTAINS(arr, val) array_contains(arr, ARRAY_SIZE(arr), val)
|
|
||||||
static bool array_contains(const uint8_t *arr, unsigned int len, uint8_t val) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
if (arr[i] == val)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false)
|
/* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false)
|
||||||
* (this function is only used internally, it is public to call it from unit-tests) */
|
* (this function is only used internally, it is public to call it from unit-tests) */
|
||||||
bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_update)
|
bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
||||||
{
|
{
|
||||||
uint32_t fn104 = fn % 104;
|
uint32_t fn104 = fn % 104;
|
||||||
|
|
||||||
/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
|
/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
|
||||||
* implemented here. We only implement the logic for Voice, not CSD */
|
* implemented here. We only implement the logic for Voice, not CSD */
|
||||||
|
|
||||||
|
/* AMR is special, SID frames may be scheduled dynamically at any time */
|
||||||
|
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
|
||||||
|
return false;
|
||||||
|
|
||||||
switch (lchan->type) {
|
switch (lchan->type) {
|
||||||
case GSM_LCHAN_TCH_F:
|
case GSM_LCHAN_TCH_F:
|
||||||
switch (lchan->tch_mode) {
|
switch (lchan->tch_mode) {
|
||||||
case GSM48_CMODE_SIGN:
|
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
case GSM48_CMODE_SPEECH_V1:
|
||||||
case GSM48_CMODE_SPEECH_EFR:
|
case GSM48_CMODE_SPEECH_EFR:
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
|
||||||
return true;
|
* There is only one *complete* block in this subset starting at FN=52.
|
||||||
if (ARRAY_CONTAINS(ts45008_83_tch_f, fn104))
|
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
|
||||||
return true;
|
* contain only 50% of the useful bits (partial SID) and thus ~50% BER. */
|
||||||
break;
|
if (fn104 == 52)
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
|
||||||
return true;
|
|
||||||
if (is_amr_sid_update)
|
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
|
case GSM48_CMODE_SIGN:
|
||||||
|
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
||||||
|
* SUB */
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
|
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
|
||||||
gsm_lchan_name(lchan), lchan->tch_mode);
|
gsm_lchan_name(lchan), lchan->tch_mode);
|
||||||
@@ -78,25 +81,7 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_upd
|
|||||||
case GSM_LCHAN_TCH_H:
|
case GSM_LCHAN_TCH_H:
|
||||||
switch (lchan->tch_mode) {
|
switch (lchan->tch_mode) {
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
case GSM48_CMODE_SPEECH_V1:
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
if (ts45008_dtx_tchh_fn_map[fn104])
|
||||||
return true;
|
|
||||||
switch (lchan->nr) {
|
|
||||||
case 0:
|
|
||||||
if (ARRAY_CONTAINS(ts45008_83_tch_hs0, fn104))
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (ARRAY_CONTAINS(ts45008_83_tch_hs1, fn104))
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
OSMO_ASSERT(0);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
|
||||||
return true;
|
|
||||||
if (is_amr_sid_update)
|
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SIGN:
|
case GSM48_CMODE_SIGN:
|
||||||
@@ -251,11 +236,6 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
|
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
|
||||||
|
|
||||||
if (lchan->ts->nr >= 8)
|
|
||||||
return -EINVAL;
|
|
||||||
if (pchan >= _GSM_PCHAN_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
switch (pchan) {
|
switch (pchan) {
|
||||||
case GSM_PCHAN_TCH_F:
|
case GSM_PCHAN_TCH_F:
|
||||||
fn_mod = translate_tch_meas_rep_fn104(fn % 104);
|
fn_mod = translate_tch_meas_rep_fn104(fn % 104);
|
||||||
@@ -306,25 +286,25 @@ static uint8_t modulus_by_lchan(struct gsm_lchan *lchan)
|
|||||||
case GSM_PCHAN_TCH_F:
|
case GSM_PCHAN_TCH_F:
|
||||||
case GSM_PCHAN_TCH_H:
|
case GSM_PCHAN_TCH_H:
|
||||||
return 104;
|
return 104;
|
||||||
break;
|
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
case GSM_PCHAN_CCCH_SDCCH4:
|
case GSM_PCHAN_CCCH_SDCCH4:
|
||||||
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
|
||||||
return 102;
|
return 102;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
/* Invalid */
|
/* Invalid */
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* receive a L1 uplink measurement from L1 (this function is only used
|
/* receive a L1 uplink measurement from L1 (this function is only used
|
||||||
* internally, it is public to call it from unit-tests) */
|
* internally, it is public to call it from unit-tests) */
|
||||||
int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn)
|
int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
||||||
|
const struct bts_ul_meas *ulm,
|
||||||
|
uint32_t fn)
|
||||||
{
|
{
|
||||||
uint32_t fn_mod = fn % modulus_by_lchan(lchan);
|
uint32_t fn_mod = fn % modulus_by_lchan(lchan);
|
||||||
|
struct bts_ul_meas *dest;
|
||||||
|
|
||||||
if (lchan->state != LCHAN_S_ACTIVE) {
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||||
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
||||||
@@ -340,16 +320,19 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t
|
|||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dest = &lchan->meas.uplink[lchan->meas.num_ul_meas++];
|
||||||
|
memcpy(dest, ulm, sizeof(*ulm));
|
||||||
|
|
||||||
/* We expect the lower layers to mark AMR SID_UPDATE frames already as such.
|
/* We expect the lower layers to mark AMR SID_UPDATE frames already as such.
|
||||||
* In this function, we only deal with the common logic as per the TS 45.008 tables */
|
* In this function, we only deal with the common logic as per the TS 45.008 tables */
|
||||||
if (!ulm->is_sub)
|
if (!ulm->is_sub)
|
||||||
ulm->is_sub = ts45008_83_is_sub(lchan, fn, false);
|
dest->is_sub = ts45008_83_is_sub(lchan, fn);
|
||||||
|
|
||||||
DEBUGPFN(DMEAS, fn, "%s adding measurement (is_sub=%u), num_ul_meas=%d, fn_mod=%u\n",
|
DEBUGPFN(DMEAS, fn, "%s adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
|
||||||
gsm_lchan_name(lchan), ulm->is_sub, lchan->meas.num_ul_meas, fn_mod);
|
gsm_lchan_name(lchan),
|
||||||
|
dest->is_sub ? "SUB" : "FULL",
|
||||||
memcpy(&lchan->meas.uplink[lchan->meas.num_ul_meas++], ulm,
|
ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
||||||
sizeof(*ulm));
|
lchan->meas.num_ul_meas, fn_mod);
|
||||||
|
|
||||||
lchan->meas.last_fn = fn;
|
lchan->meas.last_fn = fn;
|
||||||
|
|
||||||
@@ -399,11 +382,16 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)
|
|||||||
|
|
||||||
switch (pchan) {
|
switch (pchan) {
|
||||||
case GSM_PCHAN_TCH_F:
|
case GSM_PCHAN_TCH_F:
|
||||||
/* 24 for TCH + 1 for SACCH */
|
/* 24 blocks for TCH + 1 for SACCH */
|
||||||
return 25;
|
return 25;
|
||||||
case GSM_PCHAN_TCH_H:
|
case GSM_PCHAN_TCH_H:
|
||||||
/* 24 half-blocks for TCH + 1 for SACCH */
|
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
||||||
return 25;
|
/* 12 blocks for TCH + 1 for SACCH */
|
||||||
|
return 13;
|
||||||
|
} else {
|
||||||
|
/* 24 blocks for TCH + 1 for SACCH */
|
||||||
|
return 25;
|
||||||
|
}
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
/* 2 for SDCCH + 1 for SACCH */
|
/* 2 for SDCCH + 1 for SACCH */
|
||||||
@@ -426,15 +414,25 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
|
|||||||
/* AMR is using a more elaborated model with a dymanic amount of
|
/* AMR is using a more elaborated model with a dymanic amount of
|
||||||
* DTX blocks so this function is not applicable to determine the
|
* DTX blocks so this function is not applicable to determine the
|
||||||
* amount of expected SUB Measurements when AMR is used */
|
* amount of expected SUB Measurements when AMR is used */
|
||||||
OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
|
OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR);
|
||||||
|
|
||||||
switch (pchan) {
|
switch (pchan) {
|
||||||
case GSM_PCHAN_TCH_F:
|
case GSM_PCHAN_TCH_F:
|
||||||
/* 1 block SDCCH, 2 blocks TCH */
|
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
||||||
return 3;
|
/* 1 block SACCH, 24 blocks TCH (see note 1) */
|
||||||
|
return 25;
|
||||||
|
} else {
|
||||||
|
/* 1 block SACCH, 1 block TCH */
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
case GSM_PCHAN_TCH_H:
|
case GSM_PCHAN_TCH_H:
|
||||||
/* 1 block SDCCH, 4 half-blocks TCH */
|
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
||||||
return 5;
|
/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
|
||||||
|
return 13;
|
||||||
|
} else {
|
||||||
|
/* 1 block SACCH, 2 blocks TCH */
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
/* no DTX here, all blocks must be present! */
|
/* no DTX here, all blocks must be present! */
|
||||||
@@ -446,6 +444,8 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
|
|||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note 1: In signalling mode all blocks count as SUB blocks. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we clip the TOA value to 12 bits, i.e. toa256=3200,
|
/* if we clip the TOA value to 12 bits, i.e. toa256=3200,
|
||||||
@@ -472,7 +472,7 @@ static void lchan_meas_compute_extended(struct gsm_lchan *lchan)
|
|||||||
|
|
||||||
/* each measurement is an int32_t, so the squared difference value must fit in 32bits */
|
/* each measurement is an int32_t, so the squared difference value must fit in 32bits */
|
||||||
/* the sum of the squared values (each up to 32bit) can very easily exceed 32 bits */
|
/* the sum of the squared values (each up to 32bit) can very easily exceed 32 bits */
|
||||||
u_int64_t sq_diff_sum = 0;
|
uint64_t sq_diff_sum = 0;
|
||||||
|
|
||||||
/* In case we do not have any measurement values collected there is no
|
/* In case we do not have any measurement values collected there is no
|
||||||
* computation possible. We just skip the whole computation here, the
|
* computation possible. We just skip the whole computation here, the
|
||||||
@@ -543,8 +543,10 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
struct gsm_meas_rep_unidir *mru;
|
struct gsm_meas_rep_unidir *mru;
|
||||||
uint32_t ber_full_sum = 0;
|
uint32_t ber_full_sum = 0;
|
||||||
uint32_t irssi_full_sum = 0;
|
uint32_t irssi_full_sum = 0;
|
||||||
|
int32_t ci_full_sum = 0;
|
||||||
uint32_t ber_sub_sum = 0;
|
uint32_t ber_sub_sum = 0;
|
||||||
uint32_t irssi_sub_sum = 0;
|
uint32_t irssi_sub_sum = 0;
|
||||||
|
int32_t ci_sub_sum = 0;
|
||||||
int32_t ta256b_sum = 0;
|
int32_t ta256b_sum = 0;
|
||||||
unsigned int num_meas_sub = 0;
|
unsigned int num_meas_sub = 0;
|
||||||
unsigned int num_meas_sub_actual = 0;
|
unsigned int num_meas_sub_actual = 0;
|
||||||
@@ -561,8 +563,8 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
if (!is_meas_complete(lchan, fn))
|
if (!is_meas_complete(lchan, fn))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
LOGP(DMEAS, LOGL_DEBUG, "%s Calculating measurement results for physical channel:%s\n",
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Calculating measurement results "
|
||||||
gsm_lchan_name(lchan), gsm_pchan_name(ts_pchan(lchan->ts)));
|
"for physical channel: %s\n", gsm_pchan_name(ts_pchan(lchan->ts)));
|
||||||
|
|
||||||
/* Note: Some phys will send no measurement indication at all
|
/* Note: Some phys will send no measurement indication at all
|
||||||
* when a block is lost. Also in DTX mode blocks are left out
|
* when a block is lost. Also in DTX mode blocks are left out
|
||||||
@@ -573,21 +575,22 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
|
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
|
||||||
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
|
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
|
||||||
else {
|
else {
|
||||||
/* FIXME: the amount of SUB Measurements is a dynamic parameter
|
/* When AMR is used, we expect at least one SUB frame, since
|
||||||
* in AMR and can not be determined by using a lookup table.
|
* the SACCH will always be SUB frame. There may occur more
|
||||||
* See also: OS#2978 */
|
* SUB frames but since DTX periods in AMR are dynamic, we
|
||||||
num_meas_sub_expect = 0;
|
* can not know how many exactly. */
|
||||||
|
num_meas_sub_expect = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lchan->meas.num_ul_meas > num_ul_meas_expect)
|
if (lchan->meas.num_ul_meas > num_ul_meas_expect)
|
||||||
num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;
|
num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect;
|
||||||
num_ul_meas = num_ul_meas_expect;
|
num_ul_meas = num_ul_meas_expect;
|
||||||
|
|
||||||
LOGP(DMEAS, LOGL_DEBUG, "%s received %u UL measurements, expected %u\n", gsm_lchan_name(lchan),
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Received %u UL measurements, expected %u\n",
|
||||||
lchan->meas.num_ul_meas, num_ul_meas_expect);
|
lchan->meas.num_ul_meas, num_ul_meas_expect);
|
||||||
if (num_ul_meas_excess)
|
if (num_ul_meas_excess)
|
||||||
LOGP(DMEAS, LOGL_DEBUG, "%s received %u excess UL measurements\n", gsm_lchan_name(lchan),
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Received %u excess UL measurements\n",
|
||||||
num_ul_meas_excess);
|
num_ul_meas_excess);
|
||||||
|
|
||||||
/* Measurement computation step 1: add up */
|
/* Measurement computation step 1: add up */
|
||||||
for (i = 0; i < num_ul_meas; i++) {
|
for (i = 0; i < num_ul_meas; i++) {
|
||||||
@@ -611,18 +614,27 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
m = &lchan->meas.uplink[i + num_ul_meas_excess];
|
m = &lchan->meas.uplink[i + num_ul_meas_excess];
|
||||||
if (m->is_sub) {
|
if (m->is_sub) {
|
||||||
irssi_sub_sum += m->inv_rssi;
|
irssi_sub_sum += m->inv_rssi;
|
||||||
|
ci_sub_sum += m->ci_cb;
|
||||||
num_meas_sub_actual++;
|
num_meas_sub_actual++;
|
||||||
is_sub = true;
|
is_sub = true;
|
||||||
}
|
}
|
||||||
irssi_full_sum += m->inv_rssi;
|
irssi_full_sum += m->inv_rssi;
|
||||||
ta256b_sum += m->ta_offs_256bits;
|
ta256b_sum += m->ta_offs_256bits;
|
||||||
|
ci_full_sum += m->ci_cb;
|
||||||
|
|
||||||
num_ul_meas_actual++;
|
num_ul_meas_actual++;
|
||||||
} else {
|
} else {
|
||||||
m = &measurement_dummy;
|
m = &measurement_dummy;
|
||||||
if (num_ul_meas_expect - i <= num_meas_sub_expect - num_meas_sub) {
|
|
||||||
num_meas_sub_subst++;
|
/* For AMR the amount of SUB frames is defined by the
|
||||||
is_sub = true;
|
* the occurrence of DTX periods, which are dynamically
|
||||||
|
* negotiated in AMR, so we can not know if and how many
|
||||||
|
* SUB frames are missing. */
|
||||||
|
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||||
|
if (num_meas_sub <= i) {
|
||||||
|
num_meas_sub_subst++;
|
||||||
|
is_sub = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
num_ul_meas_subst++;
|
num_ul_meas_subst++;
|
||||||
@@ -635,21 +647,38 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGP(DMEAS, LOGL_DEBUG, "%s received UL measurements contain %u SUB measurements, expected %u\n",
|
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||||
gsm_lchan_name(lchan), num_meas_sub_actual, num_meas_sub_expect);
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
|
||||||
LOGP(DMEAS, LOGL_DEBUG, "%s replaced %u measurements with dummy values, from which %u were SUB measurements\n",
|
"Received UL measurements contain %u SUB measurements, expected %u\n",
|
||||||
gsm_lchan_name(lchan), num_ul_meas_subst, num_meas_sub_subst);
|
num_meas_sub_actual, num_meas_sub_expect);
|
||||||
|
} else {
|
||||||
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
|
||||||
|
"Received UL measurements contain %u SUB measurements, expected at least %u\n",
|
||||||
|
num_meas_sub_actual, num_meas_sub_expect);
|
||||||
|
}
|
||||||
|
|
||||||
if (num_meas_sub != num_meas_sub_expect) {
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, "
|
||||||
LOGP(DMEAS, LOGL_ERROR, "%s Incorrect number of SUB measurements detected! (%u vs exp %u)\n",
|
"from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst);
|
||||||
gsm_lchan_name(lchan), num_meas_sub, num_meas_sub_expect);
|
|
||||||
/* Normally the logic above should make sure that there is
|
/* Normally the logic above should make sure that there is
|
||||||
* always the exact amount of SUB measurements taken into
|
* always the exact amount of SUB measurements taken into
|
||||||
* account. If not then the logic that decides tags the received
|
* account. If not then the logic that decides tags the received
|
||||||
* measurements as is_sub works incorrectly. Since the logic
|
* measurements as is_sub works incorrectly. Since the logic
|
||||||
* above only adds missing measurements during the calculation
|
* above only adds missing measurements during the calculation
|
||||||
* it can not remove excess SUB measurements or add missing SUB
|
* it can not remove excess SUB measurements or add missing SUB
|
||||||
* measurements when there is no more room in the interval. */
|
* measurements when there is no more room in the interval. */
|
||||||
|
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||||
|
if (num_meas_sub != num_meas_sub_expect) {
|
||||||
|
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
||||||
|
"Incorrect number of SUB measurements detected! "
|
||||||
|
"(%u vs exp %u)\n", num_meas_sub, num_meas_sub_expect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (num_meas_sub < num_meas_sub_expect) {
|
||||||
|
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
||||||
|
"Incorrect number of SUB measurements detected! "
|
||||||
|
"(%u vs exp >=%u)\n", num_meas_sub, num_meas_sub_expect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Measurement computation step 2: divide */
|
/* Measurement computation step 2: divide */
|
||||||
@@ -660,25 +689,32 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
else
|
else
|
||||||
irssi_full_sum = irssi_full_sum / num_ul_meas_actual;
|
irssi_full_sum = irssi_full_sum / num_ul_meas_actual;
|
||||||
|
|
||||||
if (!num_ul_meas_actual)
|
if (!num_ul_meas_actual) {
|
||||||
ta256b_sum = lchan->meas.ms_toa256;
|
ta256b_sum = lchan->meas.ms_toa256;
|
||||||
else
|
ci_full_sum = lchan->meas.ul_ci_cb_full;
|
||||||
|
} else {
|
||||||
ta256b_sum = ta256b_sum / (signed)num_ul_meas_actual;
|
ta256b_sum = ta256b_sum / (signed)num_ul_meas_actual;
|
||||||
|
ci_full_sum = ci_full_sum / (signed)num_ul_meas_actual;
|
||||||
|
}
|
||||||
|
|
||||||
if (!num_meas_sub)
|
if (!num_meas_sub)
|
||||||
ber_sub_sum = MEASUREMENT_DUMMY_BER;
|
ber_sub_sum = MEASUREMENT_DUMMY_BER;
|
||||||
else
|
else
|
||||||
ber_sub_sum = ber_sub_sum / num_meas_sub;
|
ber_sub_sum = ber_sub_sum / num_meas_sub;
|
||||||
|
|
||||||
if (!num_meas_sub_actual)
|
if (!num_meas_sub_actual) {
|
||||||
irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI;
|
irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI;
|
||||||
else
|
ci_sub_sum = lchan->meas.ul_ci_cb_sub;
|
||||||
|
} else {
|
||||||
irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual;
|
irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual;
|
||||||
|
ci_sub_sum = ci_sub_sum / (signed)num_meas_sub_actual;
|
||||||
|
}
|
||||||
|
|
||||||
LOGP(DMEAS, LOGL_INFO, "%s Computed TA256(% 4d) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), "
|
LOGPLCHAN(lchan, DMEAS, LOGL_INFO,
|
||||||
"BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", gsm_lchan_name(lchan),
|
"Computed TA256(% 4d), BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), C/I-FULL(% 4d cB), "
|
||||||
ta256b_sum, ber_full_sum / 100,
|
"BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm), C/I-SUB(% 4d cB)\n",
|
||||||
ber_full_sum % 100, irssi_full_sum, ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum);
|
ta256b_sum, ber_full_sum / 100, ber_full_sum % 100, irssi_full_sum, ci_full_sum,
|
||||||
|
ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum, ci_sub_sum);
|
||||||
|
|
||||||
/* store results */
|
/* store results */
|
||||||
mru = &lchan->meas.ul_res;
|
mru = &lchan->meas.ul_res;
|
||||||
@@ -687,21 +723,20 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);
|
mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum);
|
||||||
mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum);
|
mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum);
|
||||||
lchan->meas.ms_toa256 = ta256b_sum;
|
lchan->meas.ms_toa256 = ta256b_sum;
|
||||||
|
lchan->meas.ul_ci_cb_full = ci_full_sum;
|
||||||
|
lchan->meas.ul_ci_cb_sub = ci_sub_sum;
|
||||||
|
|
||||||
LOGP(DMEAS, LOGL_INFO, "%s UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u),"
|
LOGPLCHAN(lchan, DMEAS, LOGL_INFO,
|
||||||
"RXQUAL_FULL(%u), RXQUAL_SUB(%u), num_meas_sub(%u), num_ul_meas(%u) \n",
|
"UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u), RXQUAL_FULL(%u), RXQUAL_SUB(%u), "
|
||||||
gsm_lchan_name(lchan),
|
"num_meas_sub(%u), num_ul_meas(%u)\n",
|
||||||
mru->full.rx_lev, mru->sub.rx_lev, mru->full.rx_qual, mru->sub.rx_qual, num_meas_sub, num_ul_meas_expect);
|
mru->full.rx_lev, mru->sub.rx_lev,
|
||||||
|
mru->full.rx_qual, mru->sub.rx_qual,
|
||||||
|
num_meas_sub, num_ul_meas_expect);
|
||||||
|
|
||||||
lchan->meas.flags |= LC_UL_M_F_RES_VALID;
|
lchan->meas.flags |= LC_UL_M_F_RES_VALID;
|
||||||
|
|
||||||
lchan_meas_compute_extended(lchan);
|
lchan_meas_compute_extended(lchan);
|
||||||
|
|
||||||
/* Compute new ta_req value. This has to be done here since the value
|
|
||||||
* in lchan->meas.num_ul_meas together with lchan->meas.ms_toa256
|
|
||||||
* is needed for the computation. */
|
|
||||||
lchan_ms_ta_ctrl(lchan);
|
|
||||||
|
|
||||||
lchan->meas.num_ul_meas = 0;
|
lchan->meas.num_ul_meas = 0;
|
||||||
|
|
||||||
/* return 1 to indicate that the computation has been done and the next
|
/* return 1 to indicate that the computation has been done and the next
|
||||||
@@ -713,7 +748,9 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
* l1sap.c every time a measurement indication is received. It collects the
|
* l1sap.c every time a measurement indication is received. It collects the
|
||||||
* measurement samples and automatically detects the end of the measurement
|
* measurement samples and automatically detects the end of the measurement
|
||||||
* interval. */
|
* interval. */
|
||||||
int lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn)
|
int lchan_meas_process_measurement(struct gsm_lchan *lchan,
|
||||||
|
const struct bts_ul_meas *ulm,
|
||||||
|
uint32_t fn)
|
||||||
{
|
{
|
||||||
lchan_new_ul_meas(lchan, ulm, fn);
|
lchan_new_ul_meas(lchan, ulm, fn);
|
||||||
return lchan_meas_check_compute(lchan, fn);
|
return lchan_meas_check_compute(lchan, fn);
|
||||||
@@ -727,3 +764,230 @@ void lchan_meas_reset(struct gsm_lchan *lchan)
|
|||||||
memset(&lchan->meas, 0, sizeof(lchan->meas));
|
memset(&lchan->meas, 0, sizeof(lchan->meas));
|
||||||
lchan->meas.last_fn = LCHAN_FN_DUMMY;
|
lchan->meas.last_fn = LCHAN_FN_DUMMY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, uint8_t ta)
|
||||||
|
{
|
||||||
|
return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - ta);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool ms_to_valid(const struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Decide if repeated FACCH should be applied or not. If RXQUAL level, that the
|
||||||
|
* MS reports is high enough, FACCH repetition is not needed. */
|
||||||
|
static void repeated_dl_facch_active_decision(struct gsm_lchan *lchan,
|
||||||
|
const struct gsm48_meas_res *meas_res)
|
||||||
|
{
|
||||||
|
uint8_t upper;
|
||||||
|
uint8_t lower;
|
||||||
|
uint8_t rxqual;
|
||||||
|
bool prev_repeated_dl_facch_active = lchan->rep_acch.dl_facch_active;
|
||||||
|
|
||||||
|
/* This is an optimization so that we exit as quickly as possible if
|
||||||
|
* there are no FACCH repetition capabilities present. However If the
|
||||||
|
* repeated FACCH capabilities vanish for whatever reason, we must be
|
||||||
|
* sure that FACCH repetition is disabled. */
|
||||||
|
if (!lchan->rep_acch_cap.dl_facch_cmd
|
||||||
|
&& !lchan->rep_acch_cap.dl_facch_all) {
|
||||||
|
lchan->rep_acch.dl_facch_active = false;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Threshold disabled (always on) */
|
||||||
|
if (lchan->rep_acch_cap.rxqual == 0) {
|
||||||
|
lchan->rep_acch.dl_facch_active = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* When the MS sets the SRR bit in the UL-SACCH L1 header
|
||||||
|
* (repeated SACCH requested) then it makes sense to enable
|
||||||
|
* FACCH repetition too. */
|
||||||
|
if (lchan->meas.l1_info.srr_sro) {
|
||||||
|
lchan->rep_acch.dl_facch_active = true;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Parse MS measurement results */
|
||||||
|
if (meas_res == NULL)
|
||||||
|
goto out;
|
||||||
|
if (!gsm48_meas_res_is_valid(meas_res))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* If the RXQUAL level at the MS drops under a certain threshold
|
||||||
|
* we enable FACCH repetition. */
|
||||||
|
upper = lchan->rep_acch_cap.rxqual;
|
||||||
|
if (upper > 2)
|
||||||
|
lower = lchan->rep_acch_cap.rxqual - 2;
|
||||||
|
else
|
||||||
|
lower = 0;
|
||||||
|
|
||||||
|
/* When downlink DTX is applied, use RXQUAL-SUB, otherwise use
|
||||||
|
* RXQUAL-FULL. */
|
||||||
|
if (meas_res->dtx_used)
|
||||||
|
rxqual = meas_res->rxqual_sub;
|
||||||
|
else
|
||||||
|
rxqual = meas_res->rxqual_full;
|
||||||
|
|
||||||
|
if (rxqual >= upper)
|
||||||
|
lchan->rep_acch.dl_facch_active = true;
|
||||||
|
else if (rxqual <= lower)
|
||||||
|
lchan->rep_acch.dl_facch_active = false;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (lchan->rep_acch.dl_facch_active == prev_repeated_dl_facch_active)
|
||||||
|
return;
|
||||||
|
if (lchan->rep_acch.dl_facch_active)
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: inactive => active\n");
|
||||||
|
else
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: active => inactive\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void acch_overpower_active_decision(struct gsm_lchan *lchan,
|
||||||
|
const struct gsm48_meas_res *meas_res)
|
||||||
|
{
|
||||||
|
const bool old = lchan->top_acch_active;
|
||||||
|
uint8_t upper, lower, rxqual;
|
||||||
|
|
||||||
|
/* ACCH overpower is not allowed => nothing to do */
|
||||||
|
if (lchan->top_acch_cap.overpower_db == 0)
|
||||||
|
return;
|
||||||
|
/* RxQual threshold is disabled => overpower is always on */
|
||||||
|
if (lchan->top_acch_cap.rxqual == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If DTx is active on Downlink, use the '-SUB' */
|
||||||
|
if (meas_res->dtx_used)
|
||||||
|
rxqual = meas_res->rxqual_sub;
|
||||||
|
else /* ... otherwise use the '-FULL' */
|
||||||
|
rxqual = meas_res->rxqual_full;
|
||||||
|
|
||||||
|
upper = lchan->top_acch_cap.rxqual;
|
||||||
|
if (upper > 2)
|
||||||
|
lower = upper - 2;
|
||||||
|
else
|
||||||
|
lower = 0;
|
||||||
|
|
||||||
|
if (rxqual >= upper)
|
||||||
|
lchan->top_acch_active = true;
|
||||||
|
else if (rxqual <= lower)
|
||||||
|
lchan->top_acch_active = false;
|
||||||
|
|
||||||
|
if (lchan->top_acch_active != old) {
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Temporary ACCH overpower: %s\n",
|
||||||
|
lchan->top_acch_active ? "inactive => active"
|
||||||
|
: "active => inactive");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool data_is_rr_meas_rep(const uint8_t *data)
|
||||||
|
{
|
||||||
|
const struct gsm48_hdr *gh = (void *)(data + 5);
|
||||||
|
const uint8_t *lapdm_hdr = (void *)(data + 2);
|
||||||
|
|
||||||
|
/* LAPDm address field: SAPI=0, C/R=0, EA=1 */
|
||||||
|
if (lapdm_hdr[0] != 0x01)
|
||||||
|
return false;
|
||||||
|
/* LAPDm control field: U, func=UI */
|
||||||
|
if (lapdm_hdr[1] != 0x03)
|
||||||
|
return false;
|
||||||
|
/* Protocol discriminator: RR */
|
||||||
|
if (gh->proto_discr != GSM48_PDISC_RR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
switch (gh->msg_type) {
|
||||||
|
case GSM48_MT_RR_EXT_MEAS_REP:
|
||||||
|
case GSM48_MT_RR_MEAS_REP:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called every time a SACCH block is received from lower layers */
|
||||||
|
void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)
|
||||||
|
{
|
||||||
|
const struct gsm48_meas_res *mr = NULL;
|
||||||
|
const struct gsm48_hdr *gh = NULL;
|
||||||
|
int timing_offset, rc;
|
||||||
|
bool dtxu_used = true; /* safe default assumption */
|
||||||
|
uint8_t ms_pwr;
|
||||||
|
uint8_t ms_ta;
|
||||||
|
int8_t ul_rssi;
|
||||||
|
int16_t ul_ci_cb;
|
||||||
|
uint8_t *l3;
|
||||||
|
unsigned int l3_len;
|
||||||
|
|
||||||
|
if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) {
|
||||||
|
/* Some brilliant engineer decided that the ordering of
|
||||||
|
* fields on the Um interface is different from the
|
||||||
|
* order of fields in RSL. See 3GPP TS 44.004 (section 7.2)
|
||||||
|
* vs. 3GPP TS 48.058 (section 9.3.10). */
|
||||||
|
const struct gsm_sacch_l1_hdr *l1h = msgb_l2(msg);
|
||||||
|
lchan->meas.l1_info.ms_pwr = l1h->ms_pwr;
|
||||||
|
lchan->meas.l1_info.fpc_epc = l1h->fpc_epc;
|
||||||
|
lchan->meas.l1_info.srr_sro = l1h->srr_sro;
|
||||||
|
lchan->meas.l1_info.ta = l1h->ta;
|
||||||
|
lchan->meas.flags |= LC_UL_M_F_L1_VALID;
|
||||||
|
|
||||||
|
/* Check if this is a Measurement Report */
|
||||||
|
if (data_is_rr_meas_rep(msgb_l2(msg))) {
|
||||||
|
/* Skip both L1 SACCH and LAPDm headers */
|
||||||
|
msg->l3h = (void *)(msg->l2h + 2 + 3);
|
||||||
|
gh = msgb_l3(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ms_pwr = lchan->meas.l1_info.ms_pwr;
|
||||||
|
ms_ta = lchan->meas.l1_info.ta;
|
||||||
|
} else {
|
||||||
|
lchan->meas.flags &= ~LC_UL_M_F_L1_VALID;
|
||||||
|
ms_pwr = lchan->ms_power_ctrl.current;
|
||||||
|
ms_ta = lchan->ta_ctrl.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, ms_ta) : -1;
|
||||||
|
l3 = msgb_l3(msg);
|
||||||
|
l3_len = l3 ? msgb_l3len(msg) : 0;
|
||||||
|
rc = rsl_tx_meas_res(lchan, l3, l3_len, timing_offset);
|
||||||
|
if (rc == 0) /* Count successful transmissions */
|
||||||
|
lchan->meas.res_nr++;
|
||||||
|
|
||||||
|
/* Run control loops now that we have all the information: */
|
||||||
|
/* 3GPP TS 45.008 sec 4.2: UL L1 SACCH Header contains TA and
|
||||||
|
* MS_PWR used "for the last burst of the previous SACCH
|
||||||
|
* period". Since MS must use the values provided in DL SACCH
|
||||||
|
* starting at next meas period, the value of the "last burst"
|
||||||
|
* is actually the value used in the entire meas period. Since
|
||||||
|
* it contains info about the previous meas period, we want to
|
||||||
|
* feed the Control Loop with the measurements for the same
|
||||||
|
* period (the previous one), which is stored in lchan->meas(.ul_res):
|
||||||
|
*/
|
||||||
|
if (gh && gh->msg_type == GSM48_MT_RR_MEAS_REP) {
|
||||||
|
mr = (const struct gsm48_meas_res *)gh->data;
|
||||||
|
if (gsm48_meas_res_is_valid(mr))
|
||||||
|
dtxu_used = mr->dtx_used;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dtxu_used) {
|
||||||
|
ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev);
|
||||||
|
ul_ci_cb = lchan->meas.ul_ci_cb_sub;
|
||||||
|
} else {
|
||||||
|
ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev);
|
||||||
|
ul_ci_cb = lchan->meas.ul_ci_cb_full;
|
||||||
|
}
|
||||||
|
lchan_ms_ta_ctrl(lchan, ms_ta, lchan->meas.ms_toa256);
|
||||||
|
lchan_ms_pwr_ctrl(lchan, ms_pwr, ul_rssi, ul_ci_cb);
|
||||||
|
if (mr && gsm48_meas_res_is_valid(mr)) {
|
||||||
|
lchan_bs_pwr_ctrl(lchan, mr);
|
||||||
|
acch_overpower_active_decision(lchan, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
repeated_dl_facch_active_decision(lchan, mr);
|
||||||
|
|
||||||
|
/* Reset state for next iteration */
|
||||||
|
lchan->tch.dtx.dl_active = false;
|
||||||
|
lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID;
|
||||||
|
lchan->ms_t_offs = -1;
|
||||||
|
lchan->p_offs = -1;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <osmo-bts/oml.h>
|
#include <osmo-bts/oml.h>
|
||||||
#include <osmo-bts/amr.h>
|
#include <osmo-bts/amr.h>
|
||||||
#include <osmo-bts/rsl.h>
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
|
||||||
#include <osmocom/gsm/protocol/ipaccess.h>
|
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||||
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
@@ -320,17 +321,17 @@ static inline bool dtx_amr_sid_optional(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
already: we rely here on the order of RTS arrival from L1 - we
|
already: we rely here on the order of RTS arrival from L1 - we
|
||||||
expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the
|
expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the
|
||||||
same FN */
|
same FN */
|
||||||
if(lchan->type == GSM_LCHAN_TCH_H) {
|
if (lchan->type == GSM_LCHAN_TCH_H) {
|
||||||
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY &&
|
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY &&
|
||||||
lchan->tch.dtx.fn != LCHAN_FN_WAIT) {
|
lchan->tch.dtx.fn != LCHAN_FN_WAIT) {
|
||||||
/* FACCH interruption is over */
|
/* FACCH interruption is over */
|
||||||
dtx_dispatch(lchan, E_COMPL);
|
dtx_dispatch(lchan, E_COMPL);
|
||||||
return false;
|
return false;
|
||||||
} else if(lchan->tch.dtx.fn == LCHAN_FN_DUMMY) {
|
} else if (lchan->tch.dtx.fn == LCHAN_FN_DUMMY) {
|
||||||
lchan->tch.dtx.fn = LCHAN_FN_WAIT;
|
lchan->tch.dtx.fn = LCHAN_FN_WAIT;
|
||||||
} else
|
} else
|
||||||
lchan->tch.dtx.fn = fn;
|
lchan->tch.dtx.fn = fn;
|
||||||
} else if(lchan->type == GSM_LCHAN_TCH_F) {
|
} else if (lchan->type == GSM_LCHAN_TCH_F) {
|
||||||
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
|
if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
|
||||||
/* FACCH interruption is over */
|
/* FACCH interruption is over */
|
||||||
dtx_dispatch(lchan, E_COMPL);
|
dtx_dispatch(lchan, E_COMPL);
|
||||||
|
|||||||
292
src/common/nm_bb_transc_fsm.c
Normal file
292
src/common/nm_bb_transc_fsm.c
Normal file
@@ -0,0 +1,292 @@
|
|||||||
|
/* NM Radio Carrier FSM */
|
||||||
|
|
||||||
|
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
#include <osmocom/core/tdef.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
#include <osmo-bts/phy_link.h>
|
||||||
|
|
||||||
|
#define X(s) (1 << (s))
|
||||||
|
|
||||||
|
#define nm_bb_transc_fsm_state_chg(fi, NEXT_STATE) \
|
||||||
|
osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0)
|
||||||
|
|
||||||
|
static void ev_dispatch_children(struct gsm_bts_bb_trx *bb_transc, uint32_t event)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||||
|
uint8_t tn;
|
||||||
|
|
||||||
|
for (tn = 0; tn < TRX_NR_TS; tn++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
|
osmo_fsm_inst_dispatch(ts->mo.fi, event, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// FSM STATE ACTIONS
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
/* Reset state: */
|
||||||
|
TALLOC_FREE(bb_transc->mo.nm_attr);
|
||||||
|
|
||||||
|
bb_transc->mo.setattr_success = false;
|
||||||
|
bb_transc->mo.opstart_success = false;
|
||||||
|
oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SW_ACT:
|
||||||
|
oml_mo_tx_sw_act_rep(&bb_transc->mo);
|
||||||
|
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
|
||||||
|
for (i = 0; i < TRX_NR_TS; i++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||||
|
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_INSTALLED, NULL);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case NM_EV_RSL_UP:
|
||||||
|
return;
|
||||||
|
case NM_EV_RSL_DOWN:
|
||||||
|
return;
|
||||||
|
case NM_EV_PHYLINK_UP:
|
||||||
|
return;
|
||||||
|
case NM_EV_PHYLINK_DOWN:
|
||||||
|
return;
|
||||||
|
case NM_EV_DISABLE:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bb_transc->mo.setattr_success = false;
|
||||||
|
bb_transc->mo.opstart_success = false;
|
||||||
|
oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1);
|
||||||
|
|
||||||
|
if (prev_state == NM_BBTRANSC_ST_OP_ENABLED) {
|
||||||
|
for (i = 0; i < TRX_NR_TS; i++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||||
|
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_DISABLED, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||||
|
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||||
|
bool phy_state_connected;
|
||||||
|
bool rsl_link_connected;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SETATTR_ACK:
|
||||||
|
case NM_EV_SETATTR_NACK:
|
||||||
|
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||||
|
bb_transc->mo.setattr_success = setattr_data->cause == 0;
|
||||||
|
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||||
|
break;
|
||||||
|
case NM_EV_OPSTART_ACK:
|
||||||
|
bb_transc->mo.opstart_success = true;
|
||||||
|
oml_mo_opstart_ack(&bb_transc->mo);
|
||||||
|
break; /* check statechg below */
|
||||||
|
case NM_EV_OPSTART_NACK:
|
||||||
|
bb_transc->mo.opstart_success = false;
|
||||||
|
oml_mo_opstart_nack(&bb_transc->mo, (int)(intptr_t)data);
|
||||||
|
return;
|
||||||
|
case NM_EV_RSL_UP:
|
||||||
|
break; /* check statechg below */
|
||||||
|
case NM_EV_RSL_DOWN:
|
||||||
|
return;
|
||||||
|
case NM_EV_PHYLINK_UP:
|
||||||
|
break; /* check statechg below */
|
||||||
|
case NM_EV_PHYLINK_DOWN:
|
||||||
|
return;
|
||||||
|
case NM_EV_DISABLE:
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
|
||||||
|
struct phy_instance *pinst = trx_phy_instance(trx);
|
||||||
|
phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
|
||||||
|
rsl_link_connected = !!trx->rsl_link;
|
||||||
|
} else {
|
||||||
|
phy_state_connected = true;
|
||||||
|
rsl_link_connected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We so far don't expect any SetAttributes for this NM object */
|
||||||
|
if (rsl_link_connected && phy_state_connected &&
|
||||||
|
bb_transc->mo.opstart_success) {
|
||||||
|
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_ENABLED);
|
||||||
|
} else {
|
||||||
|
LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s\n",
|
||||||
|
rsl_link_connected ? "" : " rsl",
|
||||||
|
phy_state_connected ? "" : " phy",
|
||||||
|
bb_transc->mo.opstart_success ? "" : " opstart");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||||
|
uint8_t tn;
|
||||||
|
|
||||||
|
oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1);
|
||||||
|
/* Mark Dependency TS as Offline (ready to be Opstarted) */
|
||||||
|
for (tn = 0; tn < TRX_NR_TS; tn++) {
|
||||||
|
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
|
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_ENABLED, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_RSL_DOWN:
|
||||||
|
break;
|
||||||
|
case NM_EV_PHYLINK_DOWN:
|
||||||
|
break;
|
||||||
|
case NM_EV_DISABLE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nm_bb_transc_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SHUTDOWN_START:
|
||||||
|
/* Announce we start shutting down */
|
||||||
|
oml_mo_state_chg(&bb_transc->mo, -1, -1, NM_STATE_SHUTDOWN);
|
||||||
|
|
||||||
|
/* Propagate event to children: */
|
||||||
|
ev_dispatch_children(bb_transc, event);
|
||||||
|
break;
|
||||||
|
case NM_EV_SHUTDOWN_FINISH:
|
||||||
|
/* Propagate event to children: */
|
||||||
|
ev_dispatch_children(bb_transc, event);
|
||||||
|
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
|
||||||
|
[NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(NM_EV_SW_ACT) |
|
||||||
|
X(NM_EV_RSL_UP) |
|
||||||
|
X(NM_EV_RSL_DOWN) |
|
||||||
|
X(NM_EV_PHYLINK_UP) |
|
||||||
|
X(NM_EV_PHYLINK_DOWN) |
|
||||||
|
X(NM_EV_DISABLE),
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) |
|
||||||
|
X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE),
|
||||||
|
.name = "DISABLED_NOTINSTALLED",
|
||||||
|
.onenter = st_op_disabled_notinstalled_on_enter,
|
||||||
|
.action = st_op_disabled_notinstalled,
|
||||||
|
},
|
||||||
|
[NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(NM_EV_SETATTR_ACK) |
|
||||||
|
X(NM_EV_SETATTR_NACK) |
|
||||||
|
X(NM_EV_OPSTART_ACK) |
|
||||||
|
X(NM_EV_OPSTART_NACK) |
|
||||||
|
X(NM_EV_RSL_UP) |
|
||||||
|
X(NM_EV_RSL_DOWN) |
|
||||||
|
X(NM_EV_PHYLINK_UP) |
|
||||||
|
X(NM_EV_PHYLINK_DOWN) |
|
||||||
|
X(NM_EV_DISABLE),
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) |
|
||||||
|
X(NM_BBTRANSC_ST_OP_ENABLED),
|
||||||
|
.name = "DISABLED_OFFLINE",
|
||||||
|
.onenter = st_op_disabled_offline_on_enter,
|
||||||
|
.action = st_op_disabled_offline,
|
||||||
|
},
|
||||||
|
[NM_BBTRANSC_ST_OP_ENABLED] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(NM_EV_RSL_DOWN) |
|
||||||
|
X(NM_EV_PHYLINK_DOWN) |
|
||||||
|
X(NM_EV_DISABLE),
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) |
|
||||||
|
X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE),
|
||||||
|
.name = "ENABLED",
|
||||||
|
.onenter = st_op_enabled_on_enter,
|
||||||
|
.action = st_op_enabled,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct osmo_fsm nm_bb_transc_fsm = {
|
||||||
|
.name = "NM_BBTRANSC_OP",
|
||||||
|
.states = nm_bb_transc_fsm_states,
|
||||||
|
.num_states = ARRAY_SIZE(nm_bb_transc_fsm_states),
|
||||||
|
.event_names = nm_fsm_event_names,
|
||||||
|
.allstate_action = nm_bb_transc_allstate,
|
||||||
|
.allstate_event_mask = X(NM_EV_SHUTDOWN_START) |
|
||||||
|
X(NM_EV_SHUTDOWN_FINISH),
|
||||||
|
.log_subsys = DOML,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void nm_bb_transc_fsm_init(void)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(osmo_fsm_register(&nm_bb_transc_fsm) == 0);
|
||||||
|
}
|
||||||
214
src/common/nm_bts_fsm.c
Normal file
214
src/common/nm_bts_fsm.c
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
/* NM BTS FSM */
|
||||||
|
|
||||||
|
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
#include <osmocom/core/tdef.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
#include <osmo-bts/phy_link.h>
|
||||||
|
#include <osmo-bts/cbch.h>
|
||||||
|
|
||||||
|
#define X(s) (1 << (s))
|
||||||
|
|
||||||
|
#define nm_bts_fsm_state_chg(fi, NEXT_STATE) \
|
||||||
|
osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0)
|
||||||
|
|
||||||
|
static void ev_dispatch_children(struct gsm_bts *bts, uint32_t event)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
osmo_fsm_inst_dispatch(trx->mo.fi, event, NULL);
|
||||||
|
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, event, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// FSM STATE ACTIONS
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
/* Reset state: */
|
||||||
|
bts->si_valid = 0;
|
||||||
|
TALLOC_FREE(bts->mo.nm_attr);
|
||||||
|
bts_cbch_reset(bts);
|
||||||
|
|
||||||
|
bts->mo.setattr_success = false;
|
||||||
|
bts->mo.opstart_success = false;
|
||||||
|
oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct gsm_bts_trx *trx;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SW_ACT:
|
||||||
|
oml_mo_tx_sw_act_rep(&bts->mo);
|
||||||
|
|
||||||
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
|
if (trx->bts->variant == BTS_OSMO_OMLDUMMY) /* In OMLDUMMY, phy=NULL */
|
||||||
|
continue;
|
||||||
|
/* During startup, phy_links are already opened, but if we are
|
||||||
|
* re-connecting, phy_link was closed when disconnected from
|
||||||
|
* previous BSC, so let's re-open it.
|
||||||
|
*/
|
||||||
|
struct phy_instance *pinst = trx_phy_instance(trx);
|
||||||
|
struct phy_link *plink = pinst->phy_link;
|
||||||
|
if (phy_link_state_get(plink) == PHY_LINK_SHUTDOWN)
|
||||||
|
bts_model_phy_link_open(plink);
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
bts->mo.setattr_success = false;
|
||||||
|
bts->mo.opstart_success = false;
|
||||||
|
oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SETATTR_ACK:
|
||||||
|
case NM_EV_SETATTR_NACK:
|
||||||
|
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||||
|
bts->mo.setattr_success = setattr_data->cause == 0;
|
||||||
|
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||||
|
break;
|
||||||
|
case NM_EV_OPSTART_ACK:
|
||||||
|
bts->mo.opstart_success = true;
|
||||||
|
oml_mo_opstart_ack(&bts->mo);
|
||||||
|
nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_ENABLED);
|
||||||
|
break; /* check statechg below */
|
||||||
|
case NM_EV_OPSTART_NACK:
|
||||||
|
bts->mo.opstart_success = false;
|
||||||
|
oml_mo_opstart_nack(&bts->mo, (int)(intptr_t)data);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
oml_mo_state_chg(&bts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nm_bts_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NM_EV_SHUTDOWN_START:
|
||||||
|
/* Announce we start shutting down */
|
||||||
|
oml_mo_state_chg(&bts->mo, -1, -1, NM_STATE_SHUTDOWN);
|
||||||
|
|
||||||
|
/* Propagate event to children: */
|
||||||
|
ev_dispatch_children(bts, event);
|
||||||
|
break;
|
||||||
|
case NM_EV_SHUTDOWN_FINISH:
|
||||||
|
/* Propagate event to children: */
|
||||||
|
ev_dispatch_children(bts, event);
|
||||||
|
nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_NOTINSTALLED);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
OSMO_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct osmo_fsm_state nm_bts_fsm_states[] = {
|
||||||
|
[NM_BTS_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(NM_EV_SW_ACT),
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) |
|
||||||
|
X(NM_BTS_ST_OP_DISABLED_OFFLINE),
|
||||||
|
.name = "DISABLED_NOTINSTALLED",
|
||||||
|
.onenter = st_op_disabled_notinstalled_on_enter,
|
||||||
|
.action = st_op_disabled_notinstalled,
|
||||||
|
},
|
||||||
|
[NM_BTS_ST_OP_DISABLED_OFFLINE] = {
|
||||||
|
.in_event_mask =
|
||||||
|
X(NM_EV_SETATTR_ACK) |
|
||||||
|
X(NM_EV_SETATTR_NACK) |
|
||||||
|
X(NM_EV_OPSTART_ACK) |
|
||||||
|
X(NM_EV_OPSTART_NACK),
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) |
|
||||||
|
X(NM_BTS_ST_OP_ENABLED),
|
||||||
|
.name = "DISABLED_OFFLINE",
|
||||||
|
.onenter = st_op_disabled_offline_on_enter,
|
||||||
|
.action = st_op_disabled_offline,
|
||||||
|
},
|
||||||
|
[NM_BTS_ST_OP_ENABLED] = {
|
||||||
|
.in_event_mask = 0,
|
||||||
|
.out_state_mask =
|
||||||
|
X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED),
|
||||||
|
.name = "ENABLED",
|
||||||
|
.onenter = st_op_enabled_on_enter,
|
||||||
|
.action = st_op_enabled,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
struct osmo_fsm nm_bts_fsm = {
|
||||||
|
.name = "NM_BTS_OP",
|
||||||
|
.states = nm_bts_fsm_states,
|
||||||
|
.num_states = ARRAY_SIZE(nm_bts_fsm_states),
|
||||||
|
.event_names = nm_fsm_event_names,
|
||||||
|
.allstate_action = nm_bts_allstate,
|
||||||
|
.allstate_event_mask = X(NM_EV_SHUTDOWN_START) |
|
||||||
|
X(NM_EV_SHUTDOWN_FINISH),
|
||||||
|
.log_subsys = DOML,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((constructor)) void nm_bts_fsm_init(void)
|
||||||
|
{
|
||||||
|
OSMO_ASSERT(osmo_fsm_register(&nm_bts_fsm) == 0);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user