mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-13 02:17:00 +00:00
Compare commits
450 Commits
1.4.0
...
jolly/test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
152d8e5b8a | ||
|
|
9c6c6b043b | ||
|
|
5076fef0ec | ||
|
|
e01cf27678 | ||
|
|
b7aa08f69b | ||
|
|
36e4fb63b8 | ||
|
|
076324446d | ||
|
|
18e5eb668e | ||
|
|
38dbebc48c | ||
|
|
65337b739a | ||
|
|
3c09964b11 | ||
|
|
798b28728b | ||
|
|
aec0422c8f | ||
|
|
3c133dc386 | ||
|
|
3af73977dd | ||
|
|
a7263b6474 | ||
|
|
82a2a8d9b4 | ||
|
|
e94553a547 | ||
|
|
088f4ffd57 | ||
|
|
950ed8bc4d | ||
|
|
59c641d20e | ||
|
|
1f755bcfee | ||
|
|
7786d9b673 | ||
|
|
f60f45e7ab | ||
|
|
722767a49d | ||
|
|
90f6ebcd3b | ||
|
|
17fe7d6841 | ||
|
|
1013ca3b8b | ||
|
|
647b8d0978 | ||
|
|
bc6cc67115 | ||
|
|
bc4ca18a31 | ||
|
|
4a6a2fdf7e | ||
|
|
28b8759465 | ||
|
|
25aae40e17 | ||
|
|
dc3b78da01 | ||
|
|
7c76630024 | ||
|
|
bcb9875176 | ||
|
|
863d4d933e | ||
|
|
791d121bd9 | ||
|
|
771e9f2838 | ||
|
|
e5d8a469d2 | ||
|
|
8fafc1a74c | ||
|
|
d88cc624ed | ||
|
|
bd777b0276 | ||
|
|
3bd97d839e | ||
|
|
6ed4a9a1eb | ||
|
|
d265ce68b2 | ||
|
|
586e897eea | ||
|
|
955b7dc637 | ||
|
|
695080745c | ||
|
|
fe005cb76e | ||
|
|
b960c7558a | ||
|
|
b8a185cc12 | ||
|
|
08f058789f | ||
|
|
8bff3b6898 | ||
|
|
aaa1f26e52 | ||
|
|
40ba43a2e8 | ||
|
|
c6211a8bec | ||
|
|
aa06f97326 | ||
|
|
188f76275a | ||
|
|
ddc15996dd | ||
|
|
f5c1cd3889 | ||
|
|
0978d1df71 | ||
|
|
852b2cbadc | ||
|
|
c4e836838d | ||
|
|
9aaaacc7aa | ||
|
|
9d9d9e2f27 | ||
|
|
fbd8aa8a77 | ||
|
|
e8518ae375 | ||
|
|
fd4654e1b8 | ||
|
|
e97834f2db | ||
|
|
8a1f740dfc | ||
|
|
1d53d231da | ||
|
|
d2d938c261 | ||
|
|
f20e13d160 | ||
|
|
55a21dc1c3 | ||
|
|
b33502a39b | ||
|
|
183c088864 | ||
|
|
37e639cb8f | ||
|
|
7e5a62e9f3 | ||
|
|
9171e37aff | ||
|
|
086b46a77f | ||
|
|
ff085f63c9 | ||
|
|
bbb3a1ed17 | ||
|
|
88de4d6789 | ||
|
|
66eae187b9 | ||
|
|
8ae829cabc | ||
|
|
007e72d5bc | ||
|
|
ca418643b3 | ||
|
|
d1f8f3429c | ||
|
|
97d3bd3e62 | ||
|
|
467d63e387 | ||
|
|
be93b87a64 | ||
|
|
ba5d2e4a5f | ||
|
|
0a2b0a20b3 | ||
|
|
290085787a | ||
|
|
6fa1dfce61 | ||
|
|
65c8f0de94 | ||
|
|
98e5d6f7c6 | ||
|
|
29fcae8632 | ||
|
|
fa90ff3e67 | ||
|
|
15330e2368 | ||
|
|
cdbd83affd | ||
|
|
2ae45aba3f | ||
|
|
6c83527e62 | ||
|
|
d04e3e708b | ||
|
|
4344f323f2 | ||
|
|
17087a08c7 | ||
|
|
f2c902c2af | ||
|
|
bb596dddc7 | ||
|
|
4bbfb904b8 | ||
|
|
deef79ffae | ||
|
|
95407f3f63 | ||
|
|
f3a63758d1 | ||
|
|
34077236f2 | ||
|
|
d53a084fd6 | ||
|
|
2bdb2201f6 | ||
|
|
84d220abc1 | ||
|
|
34838ee4e9 | ||
|
|
44c94fdeae | ||
|
|
f0510b6207 | ||
|
|
3480a2ab4c | ||
|
|
ad15414fd9 | ||
|
|
f98a55b713 | ||
|
|
1f5fdf8c8d | ||
|
|
d78968422f | ||
|
|
c860309aea | ||
|
|
5c1401d6f3 | ||
|
|
477fb3d9a4 | ||
|
|
e5c2bc346b | ||
|
|
c938a95e25 | ||
|
|
4c3b4e2868 | ||
|
|
676e9e5804 | ||
|
|
f0f91fc66c | ||
|
|
805340cb9c | ||
|
|
81ebfb34b4 | ||
|
|
07c3d86356 | ||
|
|
34ab6f1470 | ||
|
|
235d2bfbc4 | ||
|
|
fd544caae1 | ||
|
|
3f9e507d77 | ||
|
|
b2c6b68a10 | ||
|
|
c9a8eca543 | ||
|
|
9b5721b3fb | ||
|
|
194d1e8bc2 | ||
|
|
282c87ab2d | ||
|
|
785e731def | ||
|
|
592030eee7 | ||
|
|
3302d4adfe | ||
|
|
405368b697 | ||
|
|
1dd710944f | ||
|
|
a84b9a0261 | ||
|
|
d9de1a5b28 | ||
|
|
a0770250bc | ||
|
|
c18f9f256c | ||
|
|
44d47b2cdd | ||
|
|
4b945ec327 | ||
|
|
1160cabefb | ||
|
|
208127986e | ||
|
|
05b4629166 | ||
|
|
9cc85c1a6a | ||
|
|
2c511d5755 | ||
|
|
0eb90a0a98 | ||
|
|
7f03444d8b | ||
|
|
81cfbb10cb | ||
|
|
e38618f7cc | ||
|
|
5755946beb | ||
|
|
8b306b6f93 | ||
|
|
267c2606ad | ||
|
|
04a373cf6a | ||
|
|
3f5a343098 | ||
|
|
2a60cc3087 | ||
|
|
acaf6c563b | ||
|
|
dfd6224484 | ||
|
|
8b535ee77a | ||
|
|
cf8736e916 | ||
|
|
204cd4d7e3 | ||
|
|
1d7133e936 | ||
|
|
a4a9c28f15 | ||
|
|
f729ff970a | ||
|
|
bbdb10ee48 | ||
|
|
ac1eb71d78 | ||
|
|
11ec99d419 | ||
|
|
fad8986f06 | ||
|
|
b96d975f7d | ||
|
|
30601ccaf4 | ||
|
|
a1927f32f7 | ||
|
|
be18d2b275 | ||
|
|
cb0c0dfa15 | ||
|
|
8a21e7c27a | ||
|
|
4c56bed4d7 | ||
|
|
31c759165a | ||
|
|
38491d813b | ||
|
|
1dc9e3f2f8 | ||
|
|
b07e19d185 | ||
|
|
c3e059ce04 | ||
|
|
36ef885a6c | ||
|
|
7cd45a7cfe | ||
|
|
6be13437b7 | ||
|
|
3481dd40b3 | ||
|
|
66543fe422 | ||
|
|
c3d839be9e | ||
|
|
5b75e5dc8d | ||
|
|
9c4b472179 | ||
|
|
10d5499d03 | ||
|
|
d50d239914 | ||
|
|
989d99ca00 | ||
|
|
633bbf174a | ||
|
|
4190537d7d | ||
|
|
cea6c230ad | ||
|
|
92d1d1582b | ||
|
|
f4505f6caf | ||
|
|
91a1295a5a | ||
|
|
8894fe6f4c | ||
|
|
aebd2a21b5 | ||
|
|
8c397da917 | ||
|
|
c4a17d35ec | ||
|
|
c12bc93db8 | ||
|
|
7a646f963b | ||
|
|
914e55caf3 | ||
|
|
0350824203 | ||
|
|
4ff6888a81 | ||
|
|
5f556af232 | ||
|
|
909d943fe8 | ||
|
|
1266c068d7 | ||
|
|
61e7fdbb3f | ||
|
|
50710f4e8e | ||
|
|
acf0f0f0bb | ||
|
|
f06b959c7d | ||
|
|
2551882c1c | ||
|
|
96263aa908 | ||
|
|
362f2e50c2 | ||
|
|
3d2c107922 | ||
|
|
9584980ea2 | ||
|
|
80c605dd0b | ||
|
|
c29ca5eb7d | ||
|
|
32682c63f6 | ||
|
|
e1e204fae3 | ||
|
|
ac23ce2e03 | ||
|
|
c17697d337 | ||
|
|
bb3ed23e71 | ||
|
|
a563640f86 | ||
|
|
61b005193c | ||
|
|
d47d288630 | ||
|
|
e464ef6524 | ||
|
|
dbd70bca75 | ||
|
|
8fe6479358 | ||
|
|
8e04613e4f | ||
|
|
e7085d1699 | ||
|
|
ef9b27526c | ||
|
|
4bdc5a74cc | ||
|
|
767f690f05 | ||
|
|
48b00783f8 | ||
|
|
c88ed31d9e | ||
|
|
149de0c113 | ||
|
|
ca72961bbd | ||
|
|
50de553a1f | ||
|
|
c1909e7258 | ||
|
|
729037de0a | ||
|
|
33956215a7 | ||
|
|
f162fa9009 | ||
|
|
9b88fd8481 | ||
|
|
61933e6a7a | ||
|
|
a023df5c7f | ||
|
|
a21545e374 | ||
|
|
72f991f541 | ||
|
|
a981e28128 | ||
|
|
c48b4651a1 | ||
|
|
fa109255ac | ||
|
|
69bca44a84 | ||
|
|
54840a203b | ||
|
|
66bcdd839c | ||
|
|
cc13ea8b66 | ||
|
|
bdc438299b | ||
|
|
f19f533139 | ||
|
|
af9466159e | ||
|
|
633c09ee50 | ||
|
|
dfe96b786f | ||
|
|
d28ce3287f | ||
|
|
495cf39cb9 | ||
|
|
2f6e105956 | ||
|
|
c66b812c16 | ||
|
|
757180beba | ||
|
|
f1b7ee6a63 | ||
|
|
809879daae | ||
|
|
0701788724 | ||
|
|
0336b6e8e5 | ||
|
|
a743ae1c1e | ||
|
|
6a6a47f554 | ||
|
|
63baf960c6 | ||
|
|
7377344771 | ||
|
|
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 |
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
open_collective: osmocom
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -55,6 +55,7 @@ src/osmo-bts-oc2g/misc/.dirstamp
|
|||||||
tests/atconfig
|
tests/atconfig
|
||||||
tests/package.m4
|
tests/package.m4
|
||||||
tests/amr/amr_test
|
tests/amr/amr_test
|
||||||
|
tests/csd/csd_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
|
||||||
@@ -93,6 +94,7 @@ debian/tmp/
|
|||||||
doc/manuals/*.html
|
doc/manuals/*.html
|
||||||
doc/manuals/*.svg
|
doc/manuals/*.svg
|
||||||
doc/manuals/*.pdf
|
doc/manuals/*.pdf
|
||||||
|
doc/manuals/vty/*.pdf
|
||||||
doc/manuals/*__*.png
|
doc/manuals/*__*.png
|
||||||
doc/manuals/*.check
|
doc/manuals/*.check
|
||||||
doc/manuals/generated/
|
doc/manuals/generated/
|
||||||
@@ -104,3 +106,7 @@ doc/manuals/common
|
|||||||
doc/manuals/build
|
doc/manuals/build
|
||||||
|
|
||||||
contrib/osmo-bts.spec
|
contrib/osmo-bts.spec
|
||||||
|
contrib/ber/rtp_ber
|
||||||
|
contrib/ber/rtp_gen_map
|
||||||
|
|
||||||
|
arm-poky-linux-gnueabi-libtool
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ EXTRA_DIST = \
|
|||||||
.version \
|
.version \
|
||||||
README.md \
|
README.md \
|
||||||
contrib/dump_docs.py \
|
contrib/dump_docs.py \
|
||||||
contrib/osmo-bts.spec.in \
|
|
||||||
debian \
|
debian \
|
||||||
git-version-gen \
|
git-version-gen \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -27,16 +27,16 @@ 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 https://git.osmocom.org/osmo-bts/
|
There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-bts>
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
-------------
|
-------------
|
||||||
@@ -57,6 +57,13 @@ There also is an
|
|||||||
[Abis reference Manual](https://ftp.osmocom.org/docs/latest/osmobts-abis.pdf)
|
[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.
|
||||||
|
|
||||||
|
Forum
|
||||||
|
-----
|
||||||
|
|
||||||
|
We welcome any osmo-bts related discussions in the
|
||||||
|
[Cellular Network Infrastructure -> 2G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran)
|
||||||
|
section of the osmocom discourse (web based Forum).
|
||||||
|
|
||||||
Mailing List
|
Mailing List
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@@ -69,13 +76,20 @@ Please observe the [Osmocom Mailing List
|
|||||||
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||||
when posting.
|
when posting.
|
||||||
|
|
||||||
|
Issue Tracker
|
||||||
|
-------------
|
||||||
|
|
||||||
|
We use the [issue tracker of the osmo-bts project on osmocom.org](https://osmocom.org/projects/osmobts/issues) for
|
||||||
|
tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help
|
||||||
|
us out by resolving existing issues.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Our coding standards are described at
|
Our coding standards are described at
|
||||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
|
https://osmocom.org/projects/cellular-infrastructure/wiki/Coding_standards
|
||||||
|
|
||||||
We us a gerrit based patch submission/review process for managing
|
We use a Gerrit based patch submission/review process for managing
|
||||||
contributions. Please see
|
contributions. Please see
|
||||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
|
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
|
||||||
more details
|
more details
|
||||||
|
|||||||
15
TODO-RELEASE
15
TODO-RELEASE
@@ -1,2 +1,13 @@
|
|||||||
# When cleaning up this file: bump API version(s) in the following files:
|
# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install
|
||||||
# configure.ac, debian/control, and contrib/osmo-bts.spec.in.
|
# 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
|
||||||
|
libosmogsm >1.9.0 added new PRIM_INFO to include/osmocom/gsm/l1sap.h
|
||||||
|
libosmogsm >1.9.0 use of RLP code in libosmogsm
|
||||||
|
libosmogsm >1.9.0 BTS feature & RSL defs for ThemWi RTP extensions
|
||||||
|
libosmoctrl >1.9.0 use ctrl_cmd_send2()
|
||||||
|
|||||||
22
configure.ac
22
configure.ac
@@ -69,14 +69,15 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl checks for libraries
|
dnl checks for libraries
|
||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.6.0)
|
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.9.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.2.0)
|
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.2.0)
|
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.5.0)
|
||||||
|
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.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,
|
||||||
@@ -360,7 +361,7 @@ if test "x$enable_ext_tests" = "xyes" ; then
|
|||||||
fi
|
fi
|
||||||
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes)
|
||||||
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then
|
||||||
AC_MSG_ERROR([Please install git://osmocom.org/python/osmo-python-tests to run the VTY/CTRL tests.])
|
AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.])
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
AC_MSG_CHECKING([whether to enable VTY/CTRL tests])
|
||||||
@@ -444,10 +445,11 @@ AC_OUTPUT(
|
|||||||
tests/power/Makefile
|
tests/power/Makefile
|
||||||
tests/meas/Makefile
|
tests/meas/Makefile
|
||||||
tests/amr/Makefile
|
tests/amr/Makefile
|
||||||
|
tests/csd/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
doc/examples/Makefile
|
doc/examples/Makefile
|
||||||
doc/manuals/Makefile
|
doc/manuals/Makefile
|
||||||
contrib/Makefile
|
contrib/Makefile
|
||||||
|
contrib/ber/Makefile
|
||||||
contrib/systemd/Makefile
|
contrib/systemd/Makefile
|
||||||
contrib/osmo-bts.spec
|
|
||||||
Makefile)
|
Makefile)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
SUBDIRS = systemd
|
SUBDIRS = systemd ber
|
||||||
|
|||||||
28
contrib/ber/Makefile.am
Normal file
28
contrib/ber/Makefile.am
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
AM_CPPFLAGS = \
|
||||||
|
$(all_includes) \
|
||||||
|
-I$(top_srcdir)/include \
|
||||||
|
-I$(top_builddir)/include \
|
||||||
|
-I$(builddir) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
AM_CFLAGS = \
|
||||||
|
-Wall \
|
||||||
|
$(LIBOSMOCORE_CFLAGS) \
|
||||||
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
|
$(LIBOSMOCODEC_CFLAGS) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
LDADD = \
|
||||||
|
$(LIBOSMOCORE_LIBS) \
|
||||||
|
$(LIBOSMOTRAU_LIBS) \
|
||||||
|
$(LIBOSMOCODEC_LIBS) \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
noinst_PROGRAMS = rtp_ber rtp_gen_map
|
||||||
|
|
||||||
|
rtp_ber_SOURCES = rtp_ber.c codec_bit_class.h
|
||||||
|
|
||||||
|
rtp_gen_map_SOURCES = rtp_gen_map.c
|
||||||
|
|
||||||
|
update_codec_bit_class_h: rtp_gen_map
|
||||||
|
$(AM_V_GEN)./$< > $(top_srcdir)/contrib/ber/codec_bit_class.h
|
||||||
26
contrib/ber/README
Normal file
26
contrib/ber/README
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
BER testing tool
|
||||||
|
----------------
|
||||||
|
|
||||||
|
* Check all configs (MSC/BSC/BTS) for proper codec support
|
||||||
|
- FR enabled
|
||||||
|
- EFR enabled
|
||||||
|
- AMR 12.2 enabled (and all other modes disabled !)
|
||||||
|
- Use `amr-payload octet-aligned` in BSC config
|
||||||
|
|
||||||
|
* Check BTS config
|
||||||
|
- Disable jitter buffer : `bts N / rtp jitter-buffer 0`
|
||||||
|
|
||||||
|
* Check BSC config
|
||||||
|
- Disable radio timeout : `network / bts n / radio-link-timeout infinite`
|
||||||
|
|
||||||
|
* Start BER testing tool
|
||||||
|
- `./rtp_ber 4000`
|
||||||
|
|
||||||
|
* On the MSC CLI, start a silent-call, then request GSM to test loop
|
||||||
|
- `subscriber imsi <XXX> silent-call start tch/f speech-amr`
|
||||||
|
- `subscriber imsi <XXX> ms-test close-loop b`
|
||||||
|
|
||||||
|
Don't forget to terminate the loop and terminate the silent call !
|
||||||
|
|
||||||
|
- `subscriber imsi <XXX> ms-test open-loop`
|
||||||
|
- `subscriber imsi <XXX> silent-call stop`
|
||||||
59
contrib/ber/codec_bit_class.h
Normal file
59
contrib/ber/codec_bit_class.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
static const int gsm_fr_bitclass[] = {
|
||||||
|
-1, -1, -1, -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 2,
|
||||||
|
0, 0, 1, 2, 2, 0, 0, 1, 2, 2, 0, 1, 1, 2, 0, 1,
|
||||||
|
2, 2, 0, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||||
|
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||||
|
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
|
||||||
|
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||||
|
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||||
|
1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||||
|
1, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||||
|
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||||
|
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
|
||||||
|
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||||
|
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2,
|
||||||
|
1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1,
|
||||||
|
2, 2, 1, 2, 2, 1, 2, 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int gsm_efr_bitclass[] = {
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||||
|
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
|
||||||
|
1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
|
||||||
|
1, 1, 1, 1, 2, 2, 1, 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int gsm_amr_12_2_bitclass[] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, -1, -1, -1, -1,
|
||||||
|
};
|
||||||
|
|
||||||
483
contrib/ber/rtp_ber.c
Normal file
483
contrib/ber/rtp_ber.c
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
/* RTP based GSM BER testing for osmo-bts, implementing ideas described in
|
||||||
|
* https://osmocom.org/projects/osmobts/wiki/BER_Testing
|
||||||
|
*
|
||||||
|
* In short: The command transmits a PRBS sequence encapsulated in RTP frames, which are sent
|
||||||
|
* to the BTS, which transmits that data in the (unimpaired) downlink. The mobile station
|
||||||
|
* receives the data and is instructed to loop it back in the (possibly impaired) uplink.
|
||||||
|
* The BTS receives that uplink, puts in in RTP frames which end up being received back by this
|
||||||
|
* very tool. By correlating the received RTP with the PRBS sequence, this tool can compute
|
||||||
|
* the BER (Bit Error Rate) of the (possibly impaired) uplink. Doing this with different
|
||||||
|
* RF channel model simulators in the uplink allows to establish BER at different levels and
|
||||||
|
* channel conditions. */
|
||||||
|
|
||||||
|
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
|
#include <osmocom/codec/codec.h>
|
||||||
|
#include <osmocom/core/logging.h>
|
||||||
|
#include <osmocom/core/prbs.h>
|
||||||
|
#include <osmocom/core/timer.h>
|
||||||
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/trau/osmo_ortp.h>
|
||||||
|
|
||||||
|
#include <codec_bit_class.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct app_state {
|
||||||
|
struct osmo_rtp_socket *rs;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WAIT_CONN = 0, /* Wait for incoming connection */
|
||||||
|
WAIT_LOOP, /* Wait for a somewhat valid packet to start measuring */
|
||||||
|
RUNNING, /* Main state */
|
||||||
|
} state;
|
||||||
|
|
||||||
|
int pt;
|
||||||
|
|
||||||
|
int ref_len;
|
||||||
|
uint8_t ref_bytes[GSM_FR_BYTES]; /* FR is the largest possible one */
|
||||||
|
ubit_t ref_bits[8*GSM_FR_BYTES];
|
||||||
|
|
||||||
|
struct osmo_timer_list rtp_timer;
|
||||||
|
|
||||||
|
uint16_t rx_last_seq;
|
||||||
|
uint32_t rx_last_ts;
|
||||||
|
uint32_t rx_idx;
|
||||||
|
uint32_t tx_idx;
|
||||||
|
|
||||||
|
const int *err_tbl; /* Classification table */
|
||||||
|
int err_frames; /* Number of accumulated frames */
|
||||||
|
int err_cnt[3]; /* Bit error counter */
|
||||||
|
int err_tot[3]; /* Total # bits in that class */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FLOW_REG_TX_MAX_ADVANCE 200
|
||||||
|
#define FLOW_REG_TX_MIN_ADVANCE 50
|
||||||
|
|
||||||
|
|
||||||
|
const struct log_info log_info;
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t amr_size_by_ft[] = {
|
||||||
|
[0] = 12, /* 4.75 */
|
||||||
|
[1] = 13, /* 5.15 */
|
||||||
|
[2] = 15, /* 5.9 */
|
||||||
|
[3] = 17, /* 6.7 */
|
||||||
|
[4] = 19, /* 7.4 */
|
||||||
|
[5] = 20, /* 7.95 */
|
||||||
|
[6] = 26, /* 10.2 */
|
||||||
|
[7] = 31, /* 12.2 */
|
||||||
|
[8] = 5, /* SID */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char * const amr_rate_by_ft[] = {
|
||||||
|
[0] = "4.75",
|
||||||
|
[1] = "5.15",
|
||||||
|
[2] = "5.9",
|
||||||
|
[3] = "6.7",
|
||||||
|
[4] = "7.4",
|
||||||
|
[5] = "7.95",
|
||||||
|
[6] = "10.2",
|
||||||
|
[7] = "12.2",
|
||||||
|
[8] = "SID",
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gsm_fr_gen_ref(struct app_state *as)
|
||||||
|
{
|
||||||
|
struct osmo_prbs_state pn9;
|
||||||
|
|
||||||
|
/* Length */
|
||||||
|
as->ref_len = GSM_FR_BYTES;
|
||||||
|
|
||||||
|
/* Marker */
|
||||||
|
as->ref_bits[0] = 1;
|
||||||
|
as->ref_bits[1] = 1;
|
||||||
|
as->ref_bits[2] = 0;
|
||||||
|
as->ref_bits[3] = 1;
|
||||||
|
|
||||||
|
/* PN */
|
||||||
|
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||||
|
pn9.state = 31;
|
||||||
|
osmo_prbs_get_ubits(&as->ref_bits[4], 260, &pn9);
|
||||||
|
|
||||||
|
/* Convert to bytes */
|
||||||
|
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_FR_BYTES, 0);
|
||||||
|
|
||||||
|
/* Init error classes */
|
||||||
|
as->err_tot[0] = 50;
|
||||||
|
as->err_tot[1] = 132;
|
||||||
|
as->err_tot[2] = 78;
|
||||||
|
as->err_tbl = gsm_fr_bitclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gsm_efr_gen_ref(struct app_state *as)
|
||||||
|
{
|
||||||
|
struct osmo_prbs_state pn9;
|
||||||
|
|
||||||
|
/* Length */
|
||||||
|
as->ref_len = GSM_EFR_BYTES;
|
||||||
|
|
||||||
|
/* Marker */
|
||||||
|
as->ref_bits[0] = 1;
|
||||||
|
as->ref_bits[1] = 1;
|
||||||
|
as->ref_bits[2] = 0;
|
||||||
|
as->ref_bits[3] = 0;
|
||||||
|
|
||||||
|
/* PN */
|
||||||
|
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||||
|
pn9.state = 31;
|
||||||
|
osmo_prbs_get_ubits(&as->ref_bits[4], 244, &pn9);
|
||||||
|
|
||||||
|
/* Convert to bytes */
|
||||||
|
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_EFR_BYTES, 0);
|
||||||
|
|
||||||
|
/* Init error classes */
|
||||||
|
as->err_tot[0] = 50;
|
||||||
|
as->err_tot[1] = 125;
|
||||||
|
as->err_tot[2] = 73;
|
||||||
|
as->err_tbl = gsm_efr_bitclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gsm_amr_gen_ref(struct app_state *as)
|
||||||
|
{
|
||||||
|
struct osmo_prbs_state pn9;
|
||||||
|
uint8_t hdr[2];
|
||||||
|
|
||||||
|
/* Length */
|
||||||
|
as->ref_len = 33;
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
hdr[0] = 0x70;
|
||||||
|
hdr[1] = 0x3c;
|
||||||
|
osmo_pbit2ubit_ext(as->ref_bits, 0, hdr, 0, 16, 0);
|
||||||
|
|
||||||
|
/* PN */
|
||||||
|
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||||
|
pn9.state = 31;
|
||||||
|
osmo_prbs_get_ubits(&as->ref_bits[16], 244, &pn9);
|
||||||
|
|
||||||
|
/* Unused bits */
|
||||||
|
as->ref_bits[260] = 0;
|
||||||
|
as->ref_bits[261] = 0;
|
||||||
|
as->ref_bits[262] = 0;
|
||||||
|
as->ref_bits[263] = 0;
|
||||||
|
|
||||||
|
/* Convert to bytes */
|
||||||
|
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 264, 0);
|
||||||
|
|
||||||
|
/* Init error classes */
|
||||||
|
as->err_tot[0] = 81;
|
||||||
|
as->err_tot[1] = 163;
|
||||||
|
as->err_tot[2] = -1;
|
||||||
|
as->err_tbl = gsm_amr_12_2_bitclass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_gsm_gen_ref(struct app_state *as)
|
||||||
|
{
|
||||||
|
switch (as->pt) {
|
||||||
|
case RTP_PT_GSM_FULL:
|
||||||
|
_gsm_fr_gen_ref(as);
|
||||||
|
break;
|
||||||
|
case RTP_PT_GSM_EFR:
|
||||||
|
_gsm_efr_gen_ref(as);
|
||||||
|
break;
|
||||||
|
case RTP_PT_AMR:
|
||||||
|
_gsm_amr_gen_ref(as);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "[!] Unsupported payload type for BER measurement\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_gsm_ber(struct app_state *as, const uint8_t *payload, unsigned int payload_len)
|
||||||
|
{
|
||||||
|
ubit_t rx_bits[8*33];
|
||||||
|
int err[3]; /* Class 1a, 1b, 2 */
|
||||||
|
int ones;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
if (payload) {
|
||||||
|
/* Process real-payload */
|
||||||
|
osmo_pbit2ubit_ext(rx_bits, 0, payload, 0, 8*payload_len, 0);
|
||||||
|
|
||||||
|
err[0] = err[1] = err[2] = 0;
|
||||||
|
ones = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < 8 * payload_len; i++) {
|
||||||
|
j = as->err_tbl[i];
|
||||||
|
if (j >= 0) {
|
||||||
|
err[j] += rx_bits[i] ^ as->ref_bits[i];
|
||||||
|
ones += rx_bits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ones < 32) { // This frames is probably us underrunning Tx, don't use it
|
||||||
|
fprintf(stderr, "[w] Frame ignored as probably TX underrun %d %d\n", as->tx_idx, as->rx_idx);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* No payload -> Lost frame completely */
|
||||||
|
err[0] = as->err_tot[0] / 2;
|
||||||
|
err[1] = as->err_tot[1] / 2;
|
||||||
|
err[2] = as->err_tot[2] / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (as->state == RUNNING) {
|
||||||
|
/* Update records */
|
||||||
|
if (err[0] != 0) {
|
||||||
|
/* Class 1a bits bad -> Frame error */
|
||||||
|
as->err_cnt[0]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
as->err_cnt[1] += err[1]; /* Class 1b */
|
||||||
|
as->err_cnt[2] += err[2]; /* class 2 */
|
||||||
|
|
||||||
|
as->err_frames++;
|
||||||
|
|
||||||
|
/* Enough for a read-out ? */
|
||||||
|
if (as->err_frames == 200) {
|
||||||
|
printf("FBER: %4.2f C1b RBER: %5.3f C2 RBER: %5.3f\n",
|
||||||
|
100.0f * as->err_cnt[0] / as->err_frames,
|
||||||
|
100.0f * as->err_cnt[1] / (as->err_tot[1] * as->err_frames),
|
||||||
|
100.0f * as->err_cnt[2] / (as->err_tot[2] * as->err_frames)
|
||||||
|
);
|
||||||
|
memset(as->err_cnt, 0, sizeof(as->err_cnt));
|
||||||
|
as->err_frames = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err[0] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_rtp_check_payload_type(const uint8_t *payload, unsigned int payload_len)
|
||||||
|
{
|
||||||
|
uint8_t ft;
|
||||||
|
int pt = -1;
|
||||||
|
|
||||||
|
switch (payload_len) {
|
||||||
|
case GSM_FR_BYTES: /* FR or AMR 12.2k */
|
||||||
|
/* Check for AMR */
|
||||||
|
ft = (payload[1] >> 3) & 0xf;
|
||||||
|
if (ft == 7)
|
||||||
|
pt = RTP_PT_AMR;
|
||||||
|
|
||||||
|
/* Check for FR */
|
||||||
|
else if ((payload[0] & 0xF0) == 0xD0)
|
||||||
|
pt = RTP_PT_GSM_FULL;
|
||||||
|
|
||||||
|
/* None of the above */
|
||||||
|
else
|
||||||
|
fprintf(stderr, "[!] FR without 0xD0 signature or AMR with unknwon Frame Type ?!?\n");
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GSM_EFR_BYTES: /* EFR */
|
||||||
|
if ((payload[0] & 0xF0) != 0xC0)
|
||||||
|
fprintf(stderr, "[!] EFR without 0xC0 signature ?!?\n");
|
||||||
|
pt = RTP_PT_GSM_EFR;
|
||||||
|
break;
|
||||||
|
case GSM_HR_BYTES: /* HR */
|
||||||
|
pt = RTP_PT_GSM_HALF;
|
||||||
|
break;
|
||||||
|
default: /* AMR */
|
||||||
|
{
|
||||||
|
uint8_t cmr, cmi, sti;
|
||||||
|
cmr = payload[0] >> 4;
|
||||||
|
ft = (payload[1] >> 3) & 0xf;
|
||||||
|
|
||||||
|
if (payload_len != amr_size_by_ft[ft]+2)
|
||||||
|
fprintf(stderr, "AMR FT %u(%s) but size %u\n",
|
||||||
|
ft, amr_rate_by_ft[ft], payload_len);
|
||||||
|
|
||||||
|
switch (ft) {
|
||||||
|
case 0: case 1: case 2: case 3:
|
||||||
|
case 4: case 5: case 6: case 7:
|
||||||
|
cmi = ft;
|
||||||
|
printf("AMR SPEECH with FT/CMI %u(%s), "
|
||||||
|
"CMR %u\n",
|
||||||
|
cmi, amr_rate_by_ft[cmi],
|
||||||
|
cmr);
|
||||||
|
break;
|
||||||
|
case 8: /* SID */
|
||||||
|
cmi = (payload[2+4] >> 1) & 0x7;
|
||||||
|
sti = payload[2+4] & 0x10;
|
||||||
|
printf("AMR SID %s with CMI %u(%s), CMR %u(%s)\n",
|
||||||
|
sti ? "UPDATE" : "FIRST",
|
||||||
|
cmi, amr_rate_by_ft[cmi],
|
||||||
|
cmr, amr_rate_by_ft[cmr]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtp_timer_cb(void *priv)
|
||||||
|
{
|
||||||
|
struct app_state *as = (struct app_state *)priv;
|
||||||
|
|
||||||
|
/* Send at least one frame if we're not too far ahead */
|
||||||
|
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MAX_ADVANCE)) {
|
||||||
|
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
|
||||||
|
as->tx_idx++;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, "Skipped\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then maybe a second one to try and catch up to RX */
|
||||||
|
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MIN_ADVANCE)) {
|
||||||
|
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
|
||||||
|
as->tx_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Re-schedule */
|
||||||
|
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rtp_seq_num_diff(uint16_t new, uint16_t old)
|
||||||
|
{
|
||||||
|
int d = (int)new - (int)old;
|
||||||
|
while (d > 49152)
|
||||||
|
d -= 65536;
|
||||||
|
while (d < -49152)
|
||||||
|
d += 65536;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtp_rx_cb(struct osmo_rtp_socket *rs,
|
||||||
|
const uint8_t *payload, unsigned int payload_len,
|
||||||
|
uint16_t seq_number, uint32_t timestamp, bool marker)
|
||||||
|
{
|
||||||
|
struct app_state *as = (struct app_state *)rs->priv;
|
||||||
|
int pt, rc, d;
|
||||||
|
|
||||||
|
// printf("Rx(%u, %d, %d, %d): %s\n", payload_len, seq_number, timestamp, marker, osmo_hexdump(payload, payload_len));
|
||||||
|
|
||||||
|
/* Identify payload */
|
||||||
|
pt = _rtp_check_payload_type(payload, payload_len);
|
||||||
|
|
||||||
|
/* First packet ? */
|
||||||
|
if (as->state == WAIT_CONN) {
|
||||||
|
/* Setup for this payload type */
|
||||||
|
as->pt = pt;
|
||||||
|
osmo_rtp_socket_set_pt(as->rs, pt);
|
||||||
|
_gsm_gen_ref(as);
|
||||||
|
|
||||||
|
/* Timer every 20 ms */
|
||||||
|
osmo_timer_setup(&as->rtp_timer, rtp_timer_cb, as);
|
||||||
|
osmo_timer_add(&as->rtp_timer);
|
||||||
|
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
|
||||||
|
|
||||||
|
/* Init our time tracking */
|
||||||
|
as->rx_last_seq = seq_number;
|
||||||
|
as->rx_last_ts = timestamp;
|
||||||
|
|
||||||
|
/* Now we wait for a loop */
|
||||||
|
as->state = WAIT_LOOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RX sequence & timstamp tracking */
|
||||||
|
if (rtp_seq_num_diff(seq_number, as->rx_last_seq) > 1)
|
||||||
|
fprintf(stderr, "[!] RTP sequence number discontinuity (%d -> %d)\n", as->rx_last_seq, seq_number);
|
||||||
|
|
||||||
|
d = (timestamp - as->rx_last_ts) / GSM_RTP_DURATION;
|
||||||
|
|
||||||
|
as->rx_idx += d;
|
||||||
|
as->rx_last_seq = seq_number;
|
||||||
|
as->rx_last_ts = timestamp;
|
||||||
|
|
||||||
|
/* Account for missing frames in BER tracking */
|
||||||
|
if (d > 1) {
|
||||||
|
fprintf(stderr, "[!] RTP %d missing frames assumed lost @%d\n", d-1, seq_number);
|
||||||
|
while (--d)
|
||||||
|
_gsm_ber(as, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BER analysis */
|
||||||
|
rc = _gsm_ber(as, payload, payload_len);
|
||||||
|
|
||||||
|
if ((as->state == WAIT_LOOP) && (rc == 0))
|
||||||
|
as->state = RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct app_state _as, *as = &_as;
|
||||||
|
int rc, port;
|
||||||
|
|
||||||
|
/* Args */
|
||||||
|
if (argc < 2)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
port = atoi(argv[1]);
|
||||||
|
|
||||||
|
/* App init */
|
||||||
|
memset(as, 0x00, sizeof(struct app_state));
|
||||||
|
|
||||||
|
log_init(&log_info, NULL);
|
||||||
|
osmo_rtp_init(NULL);
|
||||||
|
|
||||||
|
/* Start auto-connect RTP socket */
|
||||||
|
as->rs = osmo_rtp_socket_create(NULL, 0);
|
||||||
|
|
||||||
|
as->rs->priv = as;
|
||||||
|
as->rs->rx_cb = rtp_rx_cb;
|
||||||
|
|
||||||
|
/* Jitter buffer gets in the way, we want the raw traffic */
|
||||||
|
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JIT_ADAP, 0);
|
||||||
|
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JITBUF, 0);
|
||||||
|
|
||||||
|
/* Bind to requested port */
|
||||||
|
fprintf(stderr, "[+] Binding RTP socket on port %u...\n", port);
|
||||||
|
rc = osmo_rtp_socket_bind(as->rs, "0.0.0.0", port);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "[!] error binding RTP socket: %d\n", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We 'connect' to the first source we hear from */
|
||||||
|
osmo_rtp_socket_autoconnect(as->rs);
|
||||||
|
|
||||||
|
/* Main loop */
|
||||||
|
while (1)
|
||||||
|
osmo_select_main(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
145
contrib/ber/rtp_gen_map.c
Normal file
145
contrib/ber/rtp_gen_map.c
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/* utility to generate codec_bit_class.h, a file with structures
|
||||||
|
* describing which [protection] class each bit of a given codec frame belongs to */
|
||||||
|
|
||||||
|
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <osmocom/codec/codec.h>
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_table_fr(int *tbl)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < 260; i++) {
|
||||||
|
j = 4 + gsm610_bitorder[i];
|
||||||
|
if (i < 50)
|
||||||
|
tbl[j] = 0; /* Class 1a */
|
||||||
|
else if (i < 182)
|
||||||
|
tbl[j] = 1; /* Class 1b */
|
||||||
|
else
|
||||||
|
tbl[j] = 2; /* Class 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
return GSM_FR_BYTES * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_table_efr(int *tbl)
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
|
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < 260; i++) {
|
||||||
|
j = gsm660_bitorder[i];
|
||||||
|
|
||||||
|
if (j < 71)
|
||||||
|
k = j;
|
||||||
|
else if (j < 73)
|
||||||
|
k = 71;
|
||||||
|
else if (j < 123)
|
||||||
|
k = j - 2;
|
||||||
|
else if (j < 125)
|
||||||
|
k = 119;
|
||||||
|
else if (j < 178)
|
||||||
|
k = j - 4;
|
||||||
|
else if (j < 180)
|
||||||
|
k = 172;
|
||||||
|
else if (j < 230)
|
||||||
|
k = j - 6;
|
||||||
|
else if (j < 232)
|
||||||
|
k = 222;
|
||||||
|
else if (j < 252)
|
||||||
|
k = j - 8;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (i < 50)
|
||||||
|
tbl[k] = 0; /* Class 1a */
|
||||||
|
else if (i < 182)
|
||||||
|
tbl[k] = 1; /* Class 1b */
|
||||||
|
else
|
||||||
|
tbl[k] = 2; /* Class 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
return GSM_EFR_BYTES * 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
gen_table_amr_12_2(int *tbl)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
tbl[i] = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < 244; i++)
|
||||||
|
tbl[i+16] = i < 81 ? 0 : 1;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++)
|
||||||
|
tbl[i+16+244] = -1;
|
||||||
|
|
||||||
|
return 8 * 33;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_table(const char *name, int *tbl, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("static const int %s[] = {\n", name);
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
if ((i & 15) == 0)
|
||||||
|
printf("\t");
|
||||||
|
|
||||||
|
printf("%2d", tbl[i]);
|
||||||
|
|
||||||
|
if (((i & 15) == 15) || (i == len-1))
|
||||||
|
printf(",\n");
|
||||||
|
else
|
||||||
|
printf(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int tbl[33*8];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = gen_table_fr(tbl);
|
||||||
|
print_table("gsm_fr_bitclass", tbl, rv);
|
||||||
|
|
||||||
|
rv = gen_table_efr(tbl);
|
||||||
|
print_table("gsm_efr_bitclass", tbl, rv);
|
||||||
|
|
||||||
|
rv = gen_table_amr_12_2(tbl);
|
||||||
|
print_table("gsm_amr_12_2_bitclass", tbl, rv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -9,7 +9,8 @@ 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 "" --disable-dahdi
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
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 "" --disable-dahdi
|
||||||
|
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"
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
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 "" --disable-dahdi
|
||||||
|
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"
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
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 "" --disable-dahdi
|
||||||
|
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"
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ 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 "" --disable-dahdi
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
|||||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
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 "" --disable-dahdi
|
||||||
|
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"
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
#
|
|
||||||
# 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.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmocoding) >= 1.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmocore) >= 1.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmogsm) >= 1.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmovty) >= 1.6.0
|
|
||||||
BuildRequires: pkgconfig(libosmoabis) >= 1.2.0
|
|
||||||
BuildRequires: pkgconfig(libosmotrau) >= 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
|
|
||||||
@@ -2,11 +2,15 @@
|
|||||||
Description=osmo-bts manager for LC15 / sysmoBTS 2100
|
Description=osmo-bts manager for LC15 / sysmoBTS 2100
|
||||||
After=lc15-sysdev-remap.service
|
After=lc15-sysdev-remap.service
|
||||||
Wants=lc15-sysdev-remap.service
|
Wants=lc15-sysdev-remap.service
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[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
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,15 @@
|
|||||||
Description=osmo-bts manager for OC-2G
|
Description=osmo-bts manager for OC-2G
|
||||||
After=oc2g-sysdev-remap.service
|
After=oc2g-sysdev-remap.service
|
||||||
Wants=oc2g-sysdev-remap.service
|
Wants=oc2g-sysdev-remap.service
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[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
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=osmo-bts for LC15 / sysmoBTS 2100
|
Description=osmo-bts for LC15 / sysmoBTS 2100
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=osmo-bts for OC-2G
|
Description=osmo-bts for OC-2G
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[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
|
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=osmo-bts for sysmocom sysmoBTS
|
Description=osmo-bts for sysmocom sysmoBTS
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
@@ -7,13 +9,16 @@ 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
|
|
||||||
|
|
||||||
# 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=20
|
||||||
|
# See sched(7) for further details on real-time policies and priorities
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Osmocom osmo-bts for osmo-trx
|
Description=Osmocom osmo-bts for osmo-trx
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[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
|
||||||
|
User=osmocom
|
||||||
|
Group=osmocom
|
||||||
|
AmbientCapabilities=CAP_SYS_NICE
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
|
Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[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
|
||||||
|
User=osmocom
|
||||||
|
Group=osmocom
|
||||||
|
AmbientCapabilities=CAP_SYS_NICE
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=osmo-bts manager for sysmoBTS
|
Description=osmo-bts manager for sysmoBTS
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
[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
|
||||||
|
|
||||||
|
|||||||
441
debian/changelog
vendored
441
debian/changelog
vendored
@@ -1,3 +1,444 @@
|
|||||||
|
osmo-bts (1.7.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ arehbein ]
|
||||||
|
* common: Fix memleak in get_smscb_block()
|
||||||
|
* doc: Adapt to use of 'telnet_init_default'
|
||||||
|
* common: Remove redundant checks
|
||||||
|
* common: Remove unused function gsm_objclass2nmstate()
|
||||||
|
* gsm_objclass2mo(): Change signature/set NACK cause
|
||||||
|
* gsm_objclass2obj(): Change signature/set NACK cause
|
||||||
|
* PCU interface: Log version when starting listener
|
||||||
|
* common: Have PCU socket connection use osmo_wqueue
|
||||||
|
* common: Make socket queue max. length configurable
|
||||||
|
|
||||||
|
[ Max ]
|
||||||
|
* bts-virtual: fix segfault
|
||||||
|
* osmo-bts-trx: log TRXC/TRXD connection address
|
||||||
|
* osmo-bts-trx: use bool for true/false flags
|
||||||
|
* GSMTAP: allow configuring local address
|
||||||
|
* license: fix typos
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* paging_add_imm_ass(): remove meaningless from_pcu argument
|
||||||
|
* osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down()
|
||||||
|
* osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down()
|
||||||
|
* osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down()
|
||||||
|
* GSMTAP: print 'gsmtap-local-host' if not NULL
|
||||||
|
* osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC
|
||||||
|
* rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack()
|
||||||
|
* rsl: reduce logging verbosity on some messages
|
||||||
|
* tests: use -no-install libtool flag to avoid ./lt-* scripts
|
||||||
|
* scheduler: log pchan value in trx_sched_set_pchan()
|
||||||
|
* osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts()
|
||||||
|
* contrib/osmo-bts.spec.in: do not depend on libosmogb
|
||||||
|
* osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
|
||||||
|
* rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values
|
||||||
|
* osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req()
|
||||||
|
* tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual
|
||||||
|
* osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH
|
||||||
|
* flags: add missing entries to bts_impl_flag_desc[]
|
||||||
|
* flags: group BTS_INTERNAL_FLAG_* into an enum
|
||||||
|
* flags: ensure completeness of bts_impl_flag_desc[]
|
||||||
|
* fixup: common: Remove unused function gsm_objclass2nmstate()
|
||||||
|
* oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately
|
||||||
|
* oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class
|
||||||
|
* oml: reset BCCH carrier power reduction mode (if enabled)
|
||||||
|
* copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
|
||||||
|
* osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()
|
||||||
|
* osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts
|
||||||
|
* osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames
|
||||||
|
* osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len()
|
||||||
|
* osmo-bts-trx: fix recent regression in Tx lchan handlers
|
||||||
|
* osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind
|
||||||
|
* l1sap: use gsm0502_fn2ccch_block() from libosmogsm
|
||||||
|
* scheduler: fix wrong union field in _sched_compose_tch_ind()
|
||||||
|
* scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind()
|
||||||
|
* scheduler: unify argument names/order for _sched_compose_*_ind()
|
||||||
|
* scheduler: constify *data pointer in _sched_compose_*_ind()
|
||||||
|
* scheduler: use size_t for data_len in _sched_compose_*_ind()
|
||||||
|
* fix bts_supports_cm(): properly check feature flags for VGCS/VBS
|
||||||
|
* measurement: suppress unsupported tch_mode warnings for CSD
|
||||||
|
* osmo-bts-trx: pull the AMR header in tch_dl_dequeue()
|
||||||
|
* osmo-bts-trx: implement CSD scheduling support
|
||||||
|
* osmo-bts-trx: implement FACCH/[FH] support for CSD
|
||||||
|
* osmo-bts-trx: implement TCH/F2.4 support for CSD
|
||||||
|
* osmo-bts-trx: visualize rx_tch[fh]_fn() functions
|
||||||
|
* osmo-bts-trx: unify and enrich 'Received bad data' logging
|
||||||
|
* osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above
|
||||||
|
* osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs
|
||||||
|
* osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG
|
||||||
|
* osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference
|
||||||
|
* osmo-bts-trx: document/clarify the meaning of BUFMAX=24
|
||||||
|
* l1sap: proper rate adaptation for CSD (RFC4040 'clearmode')
|
||||||
|
* csd_v110_rtp_encode(): properly set E1/E2/E3 bits
|
||||||
|
* osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes
|
||||||
|
* rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode
|
||||||
|
* rsl: rsl_handle_chan_mod_ie(): do not use legacy defines
|
||||||
|
* csd_v110: fix comments in csd_v110_rtp_{en,de}code()
|
||||||
|
* csd_v110: properly set E1/E2/E3 for non-transparent data
|
||||||
|
* csd_v110: handle empty/incomplete Uplink frames gracefully
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* pcu_sock: rename rc to fd
|
||||||
|
* pcu_sock: cosmetic: remove whitespace after type cast
|
||||||
|
* pcu_sock: cosmetic: remove unnecessary line breaks
|
||||||
|
* pcu_sock: do not mess with the osmo fd flags directly
|
||||||
|
* sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant
|
||||||
|
* l1sap: fix wording in comment
|
||||||
|
* pcu_sock: don not continue when running out of TRX space
|
||||||
|
* paging: cosmetic: rename all IMM.ASS references to MAC block
|
||||||
|
* paging: parse PCUIF data indication outside of paging.c
|
||||||
|
* paging: do not confirm PAGING COMMAND messages
|
||||||
|
* pcu_sock: move variable declaration of imsi[4] into related scope
|
||||||
|
* l1sap: cosmetic: rename payload_len to rtp_pl_len
|
||||||
|
* pcu_sock: use PCUIF version 11 (direct TLLI)
|
||||||
|
* paging: also accept zero length IMSI strings 3
|
||||||
|
* pcuif_proto: rename tlli to msg_id
|
||||||
|
* pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf
|
||||||
|
* pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
|
||||||
|
* pcuif_proto: get rid of _DT, _dt (Direct TLLI)
|
||||||
|
* bts: make bts_agch_dequeue static
|
||||||
|
* pcuif_proto: use confirm flag in struct gsm_pcu_if_pch
|
||||||
|
* pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
|
||||||
|
* pcu_sock: print SAPI and msg_id when sending confirmation
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked
|
||||||
|
* pcu_sock: Submit all DATA.ind regardless of link quality
|
||||||
|
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
|
||||||
|
* Rewrite pcu_sock_write()
|
||||||
|
* lchan: Improve error path logging in gsm_pchan2chan_nr()
|
||||||
|
* cosmetic: gsm_pchan2chan_nr(): Update spec documentation
|
||||||
|
* cosmetic: bts_trx.h: Fix whitespace
|
||||||
|
* Avoid tx RF Resource Ind for disabled TRX
|
||||||
|
* bts-trx: Avoid pushing interf_meas for disabled TRX
|
||||||
|
* contrib/ber: Avoid regenerating codec_bit_class.h every build
|
||||||
|
* bts-trx: Drop unused param to internal function
|
||||||
|
* Clarify configuration of TSC on each timeslot
|
||||||
|
* bts_model_apply_oml(): Drop unneded code
|
||||||
|
* oml.c: Remove dot character at the end of log lines
|
||||||
|
* nm: Apply BTS/TRX/TS OML Attributes through NM FSMs
|
||||||
|
* nm: Drop NM_EV_SETATTR_{ACK/NACK}
|
||||||
|
* oml: Get rid of unused tlv_parsed param in bts_model_apply_oml()
|
||||||
|
* bts_model_apply_oml(): Improve definition of parameter
|
||||||
|
* lc15,oc2g,sysmo: Update GPRS NM object state at the right time
|
||||||
|
* Simplify implementation of bts_model_opstart() in all bts types
|
||||||
|
* nm: Apply OPSTART through NM FSMs
|
||||||
|
* NM: NACK received OML OPSTART if no attributes were set beforehand
|
||||||
|
* Introduce NM FSM for GPRS NSE object
|
||||||
|
* Fix octet 2 of NM GPRS Cell
|
||||||
|
* Introduce NM FSM for GPRS Cell object
|
||||||
|
* Rearrange declaration of struct gsm_bts_gprs_nsvc
|
||||||
|
* Move NSVC structs to be part of NSE
|
||||||
|
* bts: Simplify lifecycle of BTS inside bts_list
|
||||||
|
* Introduce NM FSM for GPRS NSVC object
|
||||||
|
* nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children
|
||||||
|
* Merge gsm_network into gsm_bts_sm and place gsm_bts under it
|
||||||
|
* Move GPRS NSE under BTS SiteMgr
|
||||||
|
* Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT
|
||||||
|
* nm: Document current state of SW_ACT in TRX related objects
|
||||||
|
* Properly report all states through NM FSM upon OML link up
|
||||||
|
* Update g_bts_sm->num_bts when bts is added/removed from bts list
|
||||||
|
* Move pcu_sock_state to gprs section of bts_sm
|
||||||
|
* pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context
|
||||||
|
* pcu_sock: Drop bts_sm pointer
|
||||||
|
* oml: Fix potential null ptr access on trx object
|
||||||
|
* bts-sysmo: Fix pinst->version filled too early
|
||||||
|
* bts-sysmo: Delay marking phy_link as connected until L1 reset + got info
|
||||||
|
* vty.c: Use already available tpp pointer
|
||||||
|
* octphy: Fix clearly wrong noop assignment
|
||||||
|
* bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART
|
||||||
|
* Increase PCUIF wqueue size
|
||||||
|
* bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC
|
||||||
|
* rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* gitignore: add vty pdf
|
||||||
|
* doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT
|
||||||
|
* rsl_rx_ipac_XXcx: parse csd_fmt_d/ir
|
||||||
|
* debian: set compat level to 10
|
||||||
|
* systemd: depend on networking-online.target
|
||||||
|
* gitignore: add arm-poky-linux-gnueabi-libtool
|
||||||
|
* osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status
|
||||||
|
* osmo-bts-sysmo: activate_rf: no dispatch on fail
|
||||||
|
* osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up
|
||||||
|
* osmo-bts-sysmo: mute PHY until OML is ready
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET
|
||||||
|
* cosmetic: Replace %i with %d
|
||||||
|
* Introduce LOGPLCFN() for logging lchan-name + frame number
|
||||||
|
* bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1
|
||||||
|
* common/vty: Print AMR MultiRate Configuration in "show lchan"
|
||||||
|
* bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req
|
||||||
|
* cosmetic: use __func__ instead of __FUNCTION__
|
||||||
|
* lc15: fix compiler warning about wrong indent
|
||||||
|
* lc15: Remove unused warning
|
||||||
|
* lc15/oc2g: remove unused variables
|
||||||
|
* oc2g: Fix 'unused variable' compiler warning
|
||||||
|
* cosmetic: Remove "FIXME?" from Odd AMR CMI phase
|
||||||
|
* lc15: fix compiler warning about unused variable cell_size
|
||||||
|
* Replace explicit gsm_lchan_name() calls with LOGPLCHAN
|
||||||
|
* logging: Introduce LOGPLCGT()
|
||||||
|
* cosmetic: Change LOGPLCFN argument order
|
||||||
|
* paging: Add support for generating NLN/NLN-Status in P1 Rest Octets
|
||||||
|
* Add ASCI (advanced speech call items) log sub-system
|
||||||
|
* ASCI: NCH / NOTIFICATION support
|
||||||
|
* validate RSL "channel rate and type" against VGCS/VBS flags
|
||||||
|
* Store "Channel rate and type" from RSL Channel Mode IE in BTS
|
||||||
|
* ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT
|
||||||
|
* sysmo: Enable VGSCS + VBS feature flags
|
||||||
|
* omldummy: Claim to support VBS + VGCS towards BSC
|
||||||
|
|
||||||
|
[ Mychaela N. Falconia ]
|
||||||
|
* trx: detect UL SID in EFR just like in FR
|
||||||
|
* sysmo: fix handling of SID in EFR
|
||||||
|
* common: implement rtp continuous-streaming mode
|
||||||
|
* rtp continuous-streaming: fix BFI in the quality-suppressed case
|
||||||
|
* sysmo: emit empty RTP ticks during FACCH stealing on TCH/F
|
||||||
|
* bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid()
|
||||||
|
* RTP input, FR & EFR: preen incoming payloads for SID errors
|
||||||
|
* lc15,oc2g: fix handling of SID in EFR
|
||||||
|
* all models, FR/EFR UL: change SID check to _is_any_sid()
|
||||||
|
* trx: remove model-specific BFI packet formats
|
||||||
|
* refactor: replace rtppayload_is_valid() with preening before enqueue
|
||||||
|
* all models, HR1 codec: accept both TS101318 and RFC5993 formats
|
||||||
|
* trx: fix HR1 codec breakage from format change
|
||||||
|
* trx, HR1 codec: change UL PHY output format to TS 101 318
|
||||||
|
* all models, HR1 codec: select RTP output format via vty option
|
||||||
|
* FR/HR/EFR TCH DL: implement DTX rules
|
||||||
|
* HR1 codec: validate ToC header in RFC5993 RTP input
|
||||||
|
* HR1 codec: act on SID indication in RFC5993 RTP input
|
||||||
|
* trx TCH DL: transmit invalid speech blocks instead of dummy FACCH
|
||||||
|
* ECU in UL path: make it optional per vty config
|
||||||
|
* ECU in UL path: move state alloc/free to l1sap
|
||||||
|
* ECU in UL path: move it from trx model to l1sap
|
||||||
|
|
||||||
|
[ Sylvain Munaut ]
|
||||||
|
* contrib: Add BER testing tool
|
||||||
|
|
||||||
|
[ Andreas Eversberg ]
|
||||||
|
* Change return value of bts_supports_cm() from int to bool
|
||||||
|
* ASCI: Add function to reactivate channel
|
||||||
|
* ASCI: Retrieve NCH position from System Information 1
|
||||||
|
* ASCI: Add Notification CHannel (NCH) support
|
||||||
|
* ASCI: Add support for rest octets in Paging request type 2 and 3
|
||||||
|
* ASCI: Send only NLN on Paging request type 1 rest octets
|
||||||
|
* ASCI: Add Notification/FACCH support
|
||||||
|
* ASCI: Repeat UPLINK FREE message until uplink becomes busy
|
||||||
|
* Add test cases for rest octets of Paging Requests
|
||||||
|
* ASCI: Enable UPLINK ACCESS on various BTS models
|
||||||
|
|
||||||
|
[ Keith ]
|
||||||
|
* Fix incorrect order of params passed to logging macro
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:05:30 +0200
|
||||||
|
|
||||||
|
osmo-bts (1.6.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* osmo-bts-trx: call osmo_timer_del() unconditionally
|
||||||
|
* osmo-bts-trx: amr_loop: trigger the loop unconditionally
|
||||||
|
* osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY
|
||||||
|
* osmo-bts-trx: rx_rach_fn(): properly detect handover RACH
|
||||||
|
* osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst
|
||||||
|
* osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink
|
||||||
|
* osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi()
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* rsl: rx ipac crcx/mdcx: Log payload_type2
|
||||||
|
* logging: Move category descriptions to be in order with enum
|
||||||
|
* Clean up osmo-bts-*/Makefile.am
|
||||||
|
* Split out lchan rtp socket creation from rsl handling code
|
||||||
|
* Avoid counting lchan->dl_tch_queue length every time a msg is enqueued
|
||||||
|
* Use libosmocore API msgb_queue_free() to free lists
|
||||||
|
* rsl: Reduce scope of variable
|
||||||
|
* Move lchan_dl_tch_queue_enqueue to lchan.c and make it public
|
||||||
|
* cosmetic: Fix formatting of if-else block brackets
|
||||||
|
* Depend on libosmo-netif
|
||||||
|
* Clarify RTP AMR header offset in TCH enc/dec
|
||||||
|
* tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS
|
||||||
|
* tests/*/Makefile.am: Add missing libosmo-netif cflags
|
||||||
|
* oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS
|
||||||
|
* Introduce Osmux support
|
||||||
|
* abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down
|
||||||
|
* osmux: Log sendto() error
|
||||||
|
* lchan: Reset Abis RTP/Osmux config during lchan release
|
||||||
|
* vty: Fix SPEECH_MODE printed with hex prefix but dec value
|
||||||
|
* vty: Print Osmux CID on lchans using Osmux
|
||||||
|
* Allocate struct osmux_in_handle through new libosmo-netif APIs
|
||||||
|
* osmux: Drop logging of osmux internal counters
|
||||||
|
* osmux: Match remote address in osmux_lchan_find()
|
||||||
|
* osmux: Log remote address upon rx of osmux pkt
|
||||||
|
* osmux: Lower log level when osmux batch received for unknown CID
|
||||||
|
* osmux: nullify osmux.rtpst after freeing it
|
||||||
|
* osmux: Skip lchans in lookup which still have no remote associated
|
||||||
|
* osmux: Close osmux socket when bts is freed
|
||||||
|
* osmux: Fix null ptr dereference sending UL data before the remote is configured
|
||||||
|
* osmux: Rotate over available Osmux CID when allocating a new one
|
||||||
|
* osmux: Use new osmux_xfrm_input API to set name on each link
|
||||||
|
* vty: Fix typo in write-config: osmux / local-port
|
||||||
|
* vty: Fix typo in symbol name
|
||||||
|
|
||||||
|
[ Max ]
|
||||||
|
* Set working directory in systemd service file
|
||||||
|
* Don't manually create pid file
|
||||||
|
* Document realtime options in .service units
|
||||||
|
* Update realtime scheduling priority in service file
|
||||||
|
* ctrl: take both address and port from vty config
|
||||||
|
* Add SI10 support
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* pcu_sock: fix sourcecode formatting
|
||||||
|
* measurement: do not call msgb_l3len without checking
|
||||||
|
* l1sap: do not call msgb_l2hlen without checking
|
||||||
|
* rsl: use unsigned int
|
||||||
|
* pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers
|
||||||
|
* sched_lchan_tchf: replace numeric constant with define constant
|
||||||
|
* l1sap: remove unused pointer variable
|
||||||
|
* pcuif_proto: use define constant to specify nax number of trx
|
||||||
|
* pcu_sock: use ARRAY_SIZE rather then magic number
|
||||||
|
|
||||||
|
[ Keith ]
|
||||||
|
* osmo-bts-trx: respond to tx-attenuation config in real time.
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* update outdated vty copyright statement
|
||||||
|
|
||||||
|
[ Daniel Willmann ]
|
||||||
|
* shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C
|
||||||
|
* shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
|
||||||
|
|
||||||
|
[ daniel ]
|
||||||
|
* Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C"
|
||||||
|
|
||||||
|
[ Alexander Couzens ]
|
||||||
|
* OML: NSVC[1] MO should have the same initial state as NVSC[0]
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* oc2gbts_mgr_calib: fix build against gpsd >= 3.20
|
||||||
|
* contrib/jenkins: build libosmo-abis without dahdi
|
||||||
|
|
||||||
|
[ arehbein ]
|
||||||
|
* osmo-bts: Transition to use of 'telnet_init_default'
|
||||||
|
|
||||||
|
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:15:52 +0100
|
||||||
|
|
||||||
|
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
|
osmo-bts (1.4.0) unstable; urgency=medium
|
||||||
|
|
||||||
[ Philipp Maier ]
|
[ Philipp Maier ]
|
||||||
|
|||||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
|||||||
9
|
10
|
||||||
|
|||||||
32
debian/control
vendored
32
debian/control
vendored
@@ -2,24 +2,41 @@ Source: osmo-bts
|
|||||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||||
Section: net
|
Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Build-Depends: debhelper (>= 9),
|
Build-Depends: debhelper (>= 10),
|
||||||
pkg-config,
|
pkg-config,
|
||||||
dh-autoreconf,
|
dh-autoreconf,
|
||||||
autotools-dev,
|
autotools-dev,
|
||||||
pkg-config,
|
pkg-config,
|
||||||
libosmocore-dev (>= 1.6.0),
|
libosmocore-dev (>= 1.9.0),
|
||||||
libosmo-abis-dev (>= 1.2.0),
|
libosmo-abis-dev (>= 1.5.0),
|
||||||
|
libosmo-netif-dev (>= 1.4.0),
|
||||||
libgps-dev,
|
libgps-dev,
|
||||||
txt2man,
|
txt2man,
|
||||||
osmo-gsm-manuals-dev (>= 1.2.0)
|
osmo-gsm-manuals-dev (>= 1.5.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
|
||||||
@@ -34,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
|
||||||
|
|||||||
39
debian/osmo-bts-trx.postinst
vendored
Executable file
39
debian/osmo-bts-trx.postinst
vendored
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
# Create the osmocom group and user (if it doesn't exist yet)
|
||||||
|
if ! getent group osmocom >/dev/null; then
|
||||||
|
groupadd --system osmocom
|
||||||
|
fi
|
||||||
|
if ! getent passwd osmocom >/dev/null; then
|
||||||
|
useradd \
|
||||||
|
--system \
|
||||||
|
--gid osmocom \
|
||||||
|
--home-dir /var/lib/osmocom \
|
||||||
|
--shell /sbin/nologin \
|
||||||
|
--comment "Open Source Mobile Communications" \
|
||||||
|
osmocom
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fix permissions of previous (root-owned) install (OS#4107)
|
||||||
|
if dpkg --compare-versions "$2" le "1.13.0"; then
|
||||||
|
if [ -e /etc/osmocom/osmo-bts-trx.cfg ]; then
|
||||||
|
chown -v osmocom:osmocom /etc/osmocom/osmo-bts-trx.cfg
|
||||||
|
chmod -v 0660 /etc/osmocom/osmo-bts-trx.cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/osmocom ]; then
|
||||||
|
chown -v root:osmocom /etc/osmocom
|
||||||
|
chmod -v 2775 /etc/osmocom
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /var/lib/osmocom
|
||||||
|
chown -R -v osmocom:osmocom /var/lib/osmocom
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb(1) will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
39
debian/osmo-bts-virtual.postinst
vendored
Executable file
39
debian/osmo-bts-virtual.postinst
vendored
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/sh -e
|
||||||
|
case "$1" in
|
||||||
|
configure)
|
||||||
|
# Create the osmocom group and user (if it doesn't exist yet)
|
||||||
|
if ! getent group osmocom >/dev/null; then
|
||||||
|
groupadd --system osmocom
|
||||||
|
fi
|
||||||
|
if ! getent passwd osmocom >/dev/null; then
|
||||||
|
useradd \
|
||||||
|
--system \
|
||||||
|
--gid osmocom \
|
||||||
|
--home-dir /var/lib/osmocom \
|
||||||
|
--shell /sbin/nologin \
|
||||||
|
--comment "Open Source Mobile Communications" \
|
||||||
|
osmocom
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fix permissions of previous (root-owned) install (OS#4107)
|
||||||
|
if dpkg --compare-versions "$2" le "1.13.0"; then
|
||||||
|
if [ -e /etc/osmocom/osmo-bts-virtual.cfg ]; then
|
||||||
|
chown -v osmocom:osmocom /etc/osmocom/osmo-bts-virtual.cfg
|
||||||
|
chmod -v 0660 /etc/osmocom/osmo-bts-virtual.cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d /etc/osmocom ]; then
|
||||||
|
chown -v root:osmocom /etc/osmocom
|
||||||
|
chmod -v 2775 /etc/osmocom
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p /var/lib/osmocom
|
||||||
|
chown -R -v osmocom:osmocom /var/lib/osmocom
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# dh_installdeb(1) will replace this with shell code automatically
|
||||||
|
# generated by other debhelper scripts.
|
||||||
|
#DEBHELPER#
|
||||||
|
|
||||||
@@ -1,16 +1,29 @@
|
|||||||
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
|
# all config examples must be listed here unconditionally, so that
|
||||||
|
# all of them end up in the release tarball (see OS#6349)
|
||||||
|
EXTRA_DIST = \
|
||||||
|
trx/osmo-bts-trx.cfg \
|
||||||
|
trx/osmo-bts-trx-calypso.cfg \
|
||||||
|
octphy/osmo-bts-trx2dsp1.cfg \
|
||||||
|
octphy/osmo-bts-octphy.cfg \
|
||||||
|
oc2g/osmo-bts-oc2g.cfg \
|
||||||
|
oc2g/oc2gbts-mgr.cfg \
|
||||||
|
sysmo/sysmobts-mgr.cfg \
|
||||||
|
sysmo/osmo-bts-sysmo.cfg \
|
||||||
|
litecell15/osmo-bts-lc15.cfg \
|
||||||
|
litecell15/lc15bts-mgr.cfg \
|
||||||
|
virtual/osmo-bts-virtual.cfg \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
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
|
||||||
EXTRA_DIST = $(doc_virtual_DATA)
|
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
|
||||||
|
|
||||||
if ENABLE_SYSMOBTS
|
if ENABLE_SYSMOBTS
|
||||||
doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo
|
doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo
|
||||||
doc_sysmo_DATA = \
|
doc_sysmo_DATA = \
|
||||||
sysmo/osmo-bts-sysmo.cfg \
|
sysmo/osmo-bts-sysmo.cfg \
|
||||||
sysmo/sysmobts-mgr.cfg
|
sysmo/sysmobts-mgr.cfg
|
||||||
EXTRA_DIST += $(doc_sysmo_DATA)
|
|
||||||
OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg
|
OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -19,7 +32,6 @@ doc_trxdir = $(docdir)/examples/osmo-bts-trx
|
|||||||
doc_trx_DATA = \
|
doc_trx_DATA = \
|
||||||
trx/osmo-bts-trx.cfg \
|
trx/osmo-bts-trx.cfg \
|
||||||
trx/osmo-bts-trx-calypso.cfg
|
trx/osmo-bts-trx-calypso.cfg
|
||||||
EXTRA_DIST += $(doc_trx_DATA)
|
|
||||||
OSMOCONF_FILES += trx/osmo-bts-trx.cfg
|
OSMOCONF_FILES += trx/osmo-bts-trx.cfg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -28,7 +40,6 @@ doc_octphydir = $(docdir)/examples/osmo-bts-octphy
|
|||||||
doc_octphy_DATA = \
|
doc_octphy_DATA = \
|
||||||
octphy/osmo-bts-trx2dsp1.cfg \
|
octphy/osmo-bts-trx2dsp1.cfg \
|
||||||
octphy/osmo-bts-octphy.cfg
|
octphy/osmo-bts-octphy.cfg
|
||||||
EXTRA_DIST += $(doc_octphy_DATA)
|
|
||||||
OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg
|
OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -37,7 +48,6 @@ doc_lc15dir = $(docdir)/examples/osmo-bts-lc15
|
|||||||
doc_lc15_DATA = \
|
doc_lc15_DATA = \
|
||||||
litecell15/osmo-bts-lc15.cfg \
|
litecell15/osmo-bts-lc15.cfg \
|
||||||
litecell15/lc15bts-mgr.cfg
|
litecell15/lc15bts-mgr.cfg
|
||||||
EXTRA_DIST += $(doc_lc15_DATA)
|
|
||||||
OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg
|
OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@@ -46,7 +56,6 @@ doc_oc2gdir = $(docdir)/examples/osmo-bts-oc2g
|
|||||||
doc_oc2g_DATA = \
|
doc_oc2g_DATA = \
|
||||||
oc2g/osmo-bts-oc2g.cfg \
|
oc2g/osmo-bts-oc2g.cfg \
|
||||||
oc2g/oc2gbts-mgr.cfg
|
oc2g/oc2gbts-mgr.cfg
|
||||||
EXTRA_DIST += $(doc_oc2g_DATA)
|
|
||||||
OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg
|
OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging filter all 1
|
|
||||||
logging color 1
|
logging color 1
|
||||||
logging print category 0
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level temp info
|
logging level temp info
|
||||||
logging level fw info
|
logging level fw info
|
||||||
logging level find info
|
logging level find info
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging filter all 1
|
|
||||||
logging color 1
|
logging color 1
|
||||||
logging print category 0
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level temp info
|
logging level temp info
|
||||||
logging level fw info
|
logging level fw info
|
||||||
logging level find info
|
logging level find info
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -3,9 +3,12 @@
|
|||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging filter all 1
|
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level temp info
|
logging level temp info
|
||||||
logging level fw info
|
logging level fw info
|
||||||
logging level find info
|
logging level find info
|
||||||
|
|||||||
@@ -5,7 +5,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl notice
|
logging level rsl notice
|
||||||
logging level oml notice
|
logging level oml notice
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging color 1
|
logging color 1
|
||||||
|
logging print category-hex 0
|
||||||
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl notice
|
logging level rsl notice
|
||||||
logging level oml notice
|
logging level oml notice
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -3,10 +3,12 @@
|
|||||||
!!
|
!!
|
||||||
!
|
!
|
||||||
log stderr
|
log stderr
|
||||||
logging filter all 1
|
logging color 1
|
||||||
logging color 0
|
logging print category-hex 0
|
||||||
logging print category 1
|
logging print category 1
|
||||||
logging timestamp 0
|
logging timestamp 0
|
||||||
|
logging print file basename last
|
||||||
|
logging print level 1
|
||||||
logging level rsl info
|
logging level rsl info
|
||||||
logging level oml info
|
logging level oml info
|
||||||
logging level rll notice
|
logging level rll notice
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ Conforms to 3GPP TS 48.058 § 8.4.20, with these exceptions:
|
|||||||
| 0x06 | RSL_SYSTEM_INFO_6
|
| 0x06 | RSL_SYSTEM_INFO_6
|
||||||
| 0x0d | RSL_SYSTEM_INFO_5bis
|
| 0x0d | RSL_SYSTEM_INFO_5bis
|
||||||
| 0x0e | RSL_SYSTEM_INFO_5ter
|
| 0x0e | RSL_SYSTEM_INFO_5ter
|
||||||
|
| 0x0f | RSL_SYSTEM_INFO_10
|
||||||
| 0x47 | RSL_EXT_MEAS_ORDER
|
| 0x47 | RSL_EXT_MEAS_ORDER
|
||||||
| 0x48 | RSL_MEAS_INFO
|
| 0x48 | RSL_MEAS_INFO
|
||||||
|===
|
|===
|
||||||
@@ -516,6 +517,7 @@ number*.
|
|||||||
| 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
|
||||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||||
|
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_crcx_msg_ack]]
|
[[rsl_crcx_msg_ack]]
|
||||||
@@ -576,6 +578,7 @@ properties of a user-plane RTP connection.
|
|||||||
| 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
|
||||||
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
| RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2
|
||||||
|
| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2
|
||||||
|===
|
|===
|
||||||
|
|
||||||
[[rsl_mdcx_msg_ack]]
|
[[rsl_mdcx_msg_ack]]
|
||||||
@@ -864,6 +867,8 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
|
|||||||
| 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>>
|
| 0x60 | RSL_IE_OSMO_REP_ACCH_CAP | <<RSL_IE_OSMO_REP_ACCH_CAP>>
|
||||||
| 0x61 | RSL_IE_OSMO_TRAINING_SEQUENCE | <<RSL_IE_OSMO_TRAINING_SEQUENCE>>
|
| 0x61 | RSL_IE_OSMO_TRAINING_SEQUENCE | <<RSL_IE_OSMO_TRAINING_SEQUENCE>>
|
||||||
|
| 0x62 | RSL_IE_OSMO_TEMP_OVP_ACCH_CAP | <<RSL_IE_OSMO_TEMP_OVP_ACCH_CAP>>
|
||||||
|
| 0x63 | RSL_IE_OSMO_OSMUX_CID | <<RSL_IE_OSMO_OSMUX_CID>>
|
||||||
| 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>>
|
||||||
@@ -871,6 +876,7 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3:
|
|||||||
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
|
| 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>>
|
||||||
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
||||||
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
|
| 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>>
|
||||||
|
| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>>
|
||||||
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|
| 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>>
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -953,8 +959,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%"]
|
||||||
@@ -1085,6 +1091,49 @@ for future use.
|
|||||||
| 8..255 | reserved values
|
| 8..255 | reserved values
|
||||||
|===
|
|===
|
||||||
|
|
||||||
|
[[RSL_IE_OSMO_TEMP_OVP_ACCH_CAP]]
|
||||||
|
==== RSL_IE_OSMO_TEMP_OVP_ACCH_CAP
|
||||||
|
|
||||||
|
FIXME: this IE has been defined, but remains to be documented.
|
||||||
|
|
||||||
|
[[RSL_IE_OSMO_OSMUX_CID]]
|
||||||
|
==== RSL_IE_OSMO_OSMUX_CID
|
||||||
|
|
||||||
|
FIXME: this IE has been defined, but remains to be documented.
|
||||||
|
|
||||||
|
[[RSL_IE_IPAC_RTP_CSD_FORMAT]]
|
||||||
|
==== RSL_IE_IPAC_RTP_CSD_FORMAT
|
||||||
|
|
||||||
|
This information element contains the RTP Circuit Switched Data format.
|
||||||
|
|
||||||
|
.A-bis/IP RTP CSD Format
|
||||||
|
[options="header",width="60%",cols="15%,15%,70%"]
|
||||||
|
|===
|
||||||
|
| Offset | Size | Description
|
||||||
|
| 0 | 4 | RTP CSD Format D
|
||||||
|
| 4 | 4 | RTP CSD Format IR
|
||||||
|
|===
|
||||||
|
|
||||||
|
.A-bis/IP RTP CSD Format D Values
|
||||||
|
[options="header",width="40%",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| Value | Description
|
||||||
|
| 0 | External TRAU format
|
||||||
|
| 1 | Non-TRAU Packed format
|
||||||
|
| 2 | TRAU within the BTS
|
||||||
|
| 3 | IWF-Free BTS-BTS Data
|
||||||
|
|===
|
||||||
|
|
||||||
|
.A-bis/IP RTP CSD Format IR Values
|
||||||
|
[options="header",width="40%",cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
| Value | Description
|
||||||
|
| 0 | 8 kb/s
|
||||||
|
| 1 | 16 kb/s
|
||||||
|
| 2 | 32 kb/s
|
||||||
|
| 3 | 48 kb/s
|
||||||
|
|===
|
||||||
|
|
||||||
=== 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
|
||||||
|
|||||||
@@ -82,14 +82,13 @@ order to specify which PHY instance is allocated to this specific TRX.
|
|||||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
||||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||||
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
|
| bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands
|
||||||
| common | telnet_init() | Initialization of telnet interface
|
| common | telnet_init_default() | Initialization of telnet interface
|
||||||
| common | pcu_sock_init() | Initialization of PCU socket
|
| common | pcu_sock_init() | Initialization of PCU socket
|
||||||
| common | main() | Installation of signal handlers
|
| common | main() | Installation of signal handlers
|
||||||
| 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
|
||||||
| bts-specific | bts_model_phy_link_close() | Close each of the configured PHY links
|
| bts-specific | bts_model_phy_link_close() | Close 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
|
||||||
|===
|
|===
|
||||||
|
|||||||
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.
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
:gfdl-enabled:
|
:gfdl-enabled:
|
||||||
|
:program-name: OsmoBTS
|
||||||
|
|
||||||
OsmoBTS User Manual
|
OsmoBTS User Manual
|
||||||
===================
|
===================
|
||||||
@@ -30,6 +31,8 @@ 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/qos-dscp-pcp.adoc[]
|
||||||
|
|
||||||
include::./common/chapters/vty_cpu_sched.adoc[]
|
include::./common/chapters/vty_cpu_sched.adoc[]
|
||||||
|
|||||||
@@ -21,13 +21,12 @@ The start-up procedure of OsmoBTS can be described as follows:
|
|||||||
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
| bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created
|
||||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||||
| bts-specific | bts_model_ctrl_cmds_install()
|
| bts-specific | bts_model_ctrl_cmds_install()
|
||||||
| common | telnet_init() | Initialization of telnet interface
|
| common | telnet_init_default() | Initialization of telnet interface
|
||||||
| common | pcu_sock_init() | Initialization of PCU socket
|
| common | pcu_sock_init() | Initialization of PCU socket
|
||||||
| common | main() | Installation of signal handlers
|
| common | main() | Installation of signal handlers
|
||||||
| 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
|
||||||
|
|||||||
98
doc/trx_sched_tch.txt
Normal file
98
doc/trx_sched_tch.txt
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
== rx_tchf_fn(): TCH/FS, TCH/EFS, TCH/AFS, TCH/F2.4, and FACCH/F
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4
|
||||||
|
|
|
||||||
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
|
||||||
|
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
|
||||||
|
@ decoding from here
|
||||||
|
|
||||||
|
|
||||||
|
== rx_tchf_fn(): TCH/F14.4, TCH/F9.6, TCH/F4.8
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | Rx bid={0,1,2,3}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4
|
||||||
|
|
|
||||||
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
|
||||||
|
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
|
||||||
|
@ decoding from here
|
||||||
|
|
||||||
|
|
||||||
|
== rx_tchh_fn(): TCH/HS, TCH/AHS
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
|
|
||||||
|
|<~~~~~~~~~~~~~>| frame A
|
||||||
|
| |<~~~~~~~~~~~~~>| frame B
|
||||||
|
@ decoding from here
|
||||||
|
|
||||||
|
|
||||||
|
== rx_tchh_fn(): FACCH/H
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
|
||||||
|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2
|
||||||
|
|
|
||||||
|
|<~~~~~~~~~~~~~~~~~~~~~>| frame A
|
||||||
|
| |<~~~~~~~~~~~~~~~~~~~~~>| frame B
|
||||||
|
@ decoding from here
|
||||||
|
|
||||||
|
|
||||||
|
== rx_tchh_fn(): TCH/H4.8, TCH/H2.4
|
||||||
|
|
||||||
|
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | | | Rx bid={0,1}
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | | | Rx bid={0,1}
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | | | Rx bid={0,1}
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | | | Rx bid={0,1}
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | | | Rx bid={0,1}, decode
|
||||||
|
|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2
|
||||||
|
|
|
||||||
|
|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A
|
||||||
|
| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B
|
||||||
|
@ decoding from here
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
abis.h \
|
abis.h \
|
||||||
abis_osmo.h \
|
abis_osmo.h \
|
||||||
|
asci.h \
|
||||||
bts.h \
|
bts.h \
|
||||||
bts_model.h \
|
bts_model.h \
|
||||||
bts_shutdown_fsm.h \
|
bts_shutdown_fsm.h \
|
||||||
|
bts_sm.h \
|
||||||
bts_trx.h \
|
bts_trx.h \
|
||||||
gsm_data.h \
|
gsm_data.h \
|
||||||
logging.h \
|
logging.h \
|
||||||
@@ -11,6 +13,7 @@ noinst_HEADERS = \
|
|||||||
oml.h \
|
oml.h \
|
||||||
paging.h \
|
paging.h \
|
||||||
rsl.h \
|
rsl.h \
|
||||||
|
rtp_input_preen.h \
|
||||||
signal.h \
|
signal.h \
|
||||||
vty.h \
|
vty.h \
|
||||||
amr.h \
|
amr.h \
|
||||||
@@ -21,6 +24,7 @@ noinst_HEADERS = \
|
|||||||
tx_power.h \
|
tx_power.h \
|
||||||
control_if.h \
|
control_if.h \
|
||||||
cbch.h \
|
cbch.h \
|
||||||
|
csd_v110.h \
|
||||||
l1sap.h \
|
l1sap.h \
|
||||||
lchan.h \
|
lchan.h \
|
||||||
power_control.h \
|
power_control.h \
|
||||||
@@ -30,4 +34,6 @@ noinst_HEADERS = \
|
|||||||
dtx_dl_amr_fsm.h \
|
dtx_dl_amr_fsm.h \
|
||||||
ta_control.h \
|
ta_control.h \
|
||||||
nm_common_fsm.h \
|
nm_common_fsm.h \
|
||||||
|
notification.h \
|
||||||
|
osmux.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
43
include/osmo-bts/asci.h
Normal file
43
include/osmo-bts/asci.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
VGCS_TALKER_NONE = 0,
|
||||||
|
VGCS_TALKER_WAIT_FRAME,
|
||||||
|
VGCS_TALKER_ACTIVE,
|
||||||
|
};
|
||||||
|
|
||||||
|
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn);
|
||||||
|
|
||||||
|
void vgcs_lchan_activate(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
void vgcs_lchan_react(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
void vgcs_talker_frame(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access);
|
||||||
|
|
||||||
|
void vgcs_listener_reset(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
|
static inline bool vgcs_is_uplink_free(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
return lchan->asci.uplink_free;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vgcs_uplink_free_get(struct gsm_lchan *lchan, uint8_t *msg)
|
||||||
|
{
|
||||||
|
memcpy(msg, lchan->asci.uplink_free_msg, GSM_MACBLOCK_LEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vgcs_uplink_free_set(struct gsm_lchan *lchan, uint8_t *msg)
|
||||||
|
{
|
||||||
|
memcpy(lchan->asci.uplink_free_msg, msg, GSM_MACBLOCK_LEN);
|
||||||
|
lchan->asci.uplink_free = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void vgcs_uplink_free_reset(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
lchan->asci.uplink_free = false;
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <osmocom/core/socket.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/bts_trx.h>
|
||||||
|
#include <osmo-bts/osmux.h>
|
||||||
|
|
||||||
|
|
||||||
struct gsm_bts_trx;
|
struct gsm_bts_trx;
|
||||||
@@ -24,11 +25,21 @@ enum {
|
|||||||
BTS_CTR_RACH_RCVD,
|
BTS_CTR_RACH_RCVD,
|
||||||
BTS_CTR_RACH_DROP,
|
BTS_CTR_RACH_DROP,
|
||||||
BTS_CTR_RACH_HO,
|
BTS_CTR_RACH_HO,
|
||||||
|
BTS_CTR_RACH_VGCS,
|
||||||
BTS_CTR_RACH_CS,
|
BTS_CTR_RACH_CS,
|
||||||
BTS_CTR_RACH_PS,
|
BTS_CTR_RACH_PS,
|
||||||
BTS_CTR_AGCH_RCVD,
|
BTS_CTR_AGCH_RCVD,
|
||||||
BTS_CTR_AGCH_SENT,
|
BTS_CTR_AGCH_SENT,
|
||||||
BTS_CTR_AGCH_DELETED,
|
BTS_CTR_AGCH_DELETED,
|
||||||
|
|
||||||
|
BTS_CTR_RTP_RX_TOTAL,
|
||||||
|
BTS_CTR_RTP_RX_MARKER,
|
||||||
|
BTS_CTR_RTP_RX_DROP_PREEN,
|
||||||
|
BTS_CTR_RTP_RX_DROP_LOOPBACK,
|
||||||
|
BTS_CTR_RTP_RX_DROP_OVERFLOW,
|
||||||
|
BTS_CTR_RTP_RX_DROP_V110_DEC,
|
||||||
|
BTS_CTR_RTP_TX_TOTAL,
|
||||||
|
BTS_CTR_RTP_TX_MARKER,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used by OML layer for BTS Attribute reporting */
|
/* Used by OML layer for BTS Attribute reporting */
|
||||||
@@ -52,36 +63,28 @@ enum gsm_bts_type_variant {
|
|||||||
};
|
};
|
||||||
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
||||||
|
|
||||||
|
enum bts_impl_flag {
|
||||||
/* TODO: add a brief description of this flag */
|
/* TODO: add a brief description of this flag */
|
||||||
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
|
BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,
|
||||||
/* When this flag is set then the measurement data is included in
|
/* When this flag is set then the measurement data is included in
|
||||||
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
||||||
* measurement data is passed using a separate MPH INFO MEAS IND.
|
* measurement data is passed using a separate MPH INFO MEAS IND.
|
||||||
* (See also ticket: OS#2977) */
|
* (See also ticket: OS#2977) */
|
||||||
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
|
BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,
|
||||||
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
||||||
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
||||||
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2)
|
BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER,
|
||||||
/* Whether the BTS model reports interference measurements to L1SAP. */
|
/* Whether the BTS model reports interference measurements to L1SAP. */
|
||||||
#define BTS_INTERNAL_FLAG_INTERF_MEAS (1 << 3)
|
BTS_INTERNAL_FLAG_INTERF_MEAS,
|
||||||
|
|
||||||
|
_BTS_INTERNAL_FLAG_NUM, /* must be at the end */
|
||||||
|
};
|
||||||
|
|
||||||
/* BTS implementation flags (internal use, not exposed via OML) */
|
/* BTS implementation flags (internal use, not exposed via OML) */
|
||||||
#define bts_internal_flag_get(bts, flag) \
|
#define bts_internal_flag_get(bts, flag) \
|
||||||
((bts->flags & (typeof(bts->flags)) flag) != 0)
|
((bts->flags & (typeof(bts->flags))(1 << flag)) != 0)
|
||||||
#define bts_internal_flag_set(bts, flag) \
|
#define bts_internal_flag_set(bts, flag) \
|
||||||
bts->flags |= (typeof(bts->flags)) flag
|
bts->flags |= (typeof(bts->flags))(1 << 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 {
|
struct gprs_rlc_cfg {
|
||||||
uint16_t parameter[_NUM_RLC_PAR];
|
uint16_t parameter[_NUM_RLC_PAR];
|
||||||
@@ -130,9 +133,15 @@ struct bts_power_ctrl_params {
|
|||||||
} pf;
|
} pf;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* BTS Site Manager */
|
/* GPRS CELL; ip.access specific NM Object */
|
||||||
struct gsm_bts_sm {
|
struct gsm_gprs_cell {
|
||||||
struct gsm_abis_mo mo;
|
struct gsm_abis_mo mo;
|
||||||
|
uint16_t bvci;
|
||||||
|
uint8_t timer[11];
|
||||||
|
struct gprs_rlc_cfg rlc_cfg;
|
||||||
|
struct {
|
||||||
|
uint32_t gprs_codings; /* see NM_IPAC_F_GPRS_CODING_* flags */
|
||||||
|
} support;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Struct that holds one OML-Address (Address of the BSC) */
|
/* Struct that holds one OML-Address (Address of the BSC) */
|
||||||
@@ -141,9 +150,11 @@ struct bsc_oml_host {
|
|||||||
char *addr;
|
char *addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
|
||||||
|
|
||||||
/* One BTS */
|
/* One BTS */
|
||||||
struct gsm_bts {
|
struct gsm_bts {
|
||||||
/* list header in net->bts_list */
|
/* list header in g_bts_sm->bts_list */
|
||||||
struct llist_head list;
|
struct llist_head list;
|
||||||
|
|
||||||
/* number of the BTS in network */
|
/* number of the BTS in network */
|
||||||
@@ -157,6 +168,7 @@ struct gsm_bts {
|
|||||||
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
||||||
* which is used as TSC for the CCCH */
|
* which is used as TSC for the CCCH */
|
||||||
uint8_t bsic;
|
uint8_t bsic;
|
||||||
|
bool bsic_configured;
|
||||||
/* type of BTS */
|
/* type of BTS */
|
||||||
enum gsm_bts_type_variant variant;
|
enum gsm_bts_type_variant variant;
|
||||||
enum gsm_band band;
|
enum gsm_band band;
|
||||||
@@ -192,7 +204,7 @@ struct gsm_bts {
|
|||||||
/* CCCH is on C0 */
|
/* CCCH is on C0 */
|
||||||
struct gsm_bts_trx *c0;
|
struct gsm_bts_trx *c0;
|
||||||
|
|
||||||
struct gsm_bts_sm site_mgr;
|
struct gsm_bts_sm *site_mgr;
|
||||||
|
|
||||||
/* bitmask of all SI that are present/valid in si_buf */
|
/* bitmask of all SI that are present/valid in si_buf */
|
||||||
uint32_t si_valid;
|
uint32_t si_valid;
|
||||||
@@ -222,18 +234,7 @@ struct gsm_bts {
|
|||||||
|
|
||||||
/* Not entirely sure how ip.access specific this is */
|
/* Not entirely sure how ip.access specific this is */
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct gsm_gprs_cell cell;
|
||||||
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 rac;
|
||||||
} gprs;
|
} gprs;
|
||||||
|
|
||||||
@@ -249,8 +250,9 @@ struct gsm_bts {
|
|||||||
int16_t boundary[6];
|
int16_t boundary[6];
|
||||||
uint8_t intave;
|
uint8_t intave;
|
||||||
} interference;
|
} interference;
|
||||||
unsigned int t200_ms[7];
|
uint32_t t200_fn[7];
|
||||||
unsigned int t3105_ms;
|
unsigned int t3105_ms;
|
||||||
|
unsigned int t3115_ms; /* VGCS UPLINK GRANT repeat timer */
|
||||||
struct {
|
struct {
|
||||||
uint8_t overload_period;
|
uint8_t overload_period;
|
||||||
struct {
|
struct {
|
||||||
@@ -273,6 +275,7 @@ struct gsm_bts {
|
|||||||
} rach;
|
} rach;
|
||||||
} load;
|
} load;
|
||||||
uint8_t ny1;
|
uint8_t ny1;
|
||||||
|
uint8_t ny2; /* maximum number of repetitions for the VGCS UPLINK GRANT */
|
||||||
uint8_t max_ta;
|
uint8_t max_ta;
|
||||||
|
|
||||||
/* AGCH queuing */
|
/* AGCH queuing */
|
||||||
@@ -302,6 +305,15 @@ struct gsm_bts {
|
|||||||
bool pni; /* Primary Notification Identifier */
|
bool pni; /* Primary Notification Identifier */
|
||||||
} etws;
|
} etws;
|
||||||
|
|
||||||
|
/* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */
|
||||||
|
struct {
|
||||||
|
int pos_nch; /* position of the NCH or < 0, if not available */
|
||||||
|
uint8_t nln, nln_status; /* current notification list number and status */
|
||||||
|
struct llist_head notifications;
|
||||||
|
int notification_entries; /* current number of entries in the list */
|
||||||
|
int notification_count; /* counter to count all entries */
|
||||||
|
} asci;
|
||||||
|
|
||||||
struct paging_state *paging_state;
|
struct paging_state *paging_state;
|
||||||
struct llist_head bsc_oml_hosts;
|
struct llist_head bsc_oml_hosts;
|
||||||
unsigned int rtp_jitter_buf_ms;
|
unsigned int rtp_jitter_buf_ms;
|
||||||
@@ -313,8 +325,13 @@ struct gsm_bts {
|
|||||||
int rtp_ip_dscp;
|
int rtp_ip_dscp;
|
||||||
int rtp_priority;
|
int rtp_priority;
|
||||||
|
|
||||||
|
bool rtp_nogaps_mode; /* emit RTP stream without any gaps */
|
||||||
|
bool use_ul_ecu; /* "rtp internal-uplink-ecu" option */
|
||||||
|
bool emit_hr_rfc5993;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
||||||
|
uint8_t max_ta; /* maximum timing advance */
|
||||||
} support;
|
} support;
|
||||||
struct {
|
struct {
|
||||||
uint8_t tc4_ctr;
|
uint8_t tc4_ctr;
|
||||||
@@ -359,18 +376,25 @@ struct gsm_bts {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
char *sock_path;
|
char *sock_path;
|
||||||
|
unsigned int sock_wqueue_len_max;
|
||||||
} pcu;
|
} pcu;
|
||||||
|
|
||||||
/* GSMTAP Um logging (disabled by default) */
|
/* GSMTAP Um logging (disabled by default) */
|
||||||
struct {
|
struct {
|
||||||
struct gsmtap_inst *inst;
|
struct gsmtap_inst *inst;
|
||||||
char *remote_host;
|
char *remote_host;
|
||||||
|
char *local_host;
|
||||||
uint32_t sapi_mask;
|
uint32_t sapi_mask;
|
||||||
uint8_t sapi_acch;
|
uint8_t sapi_acch;
|
||||||
|
bool rlp;
|
||||||
|
bool rlp_skip_null;
|
||||||
} gsmtap;
|
} gsmtap;
|
||||||
|
|
||||||
|
struct osmux_state osmux;
|
||||||
|
|
||||||
struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
|
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_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_fsm_inst *abis_link_fi; /* FSM instance to manage abis connection during process startup and link failure */
|
||||||
struct osmo_tdef *T_defs; /* Timer defines */
|
struct osmo_tdef *T_defs; /* Timer defines */
|
||||||
|
|
||||||
@@ -384,24 +408,30 @@ extern void *tall_bts_ctx;
|
|||||||
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << 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_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) {
|
static inline struct gsm_bts *gsm_gprs_cell_get_bts(struct gsm_gprs_cell *cell)
|
||||||
return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
|
{
|
||||||
|
return (struct gsm_bts *)container_of(cell, struct gsm_bts, gprs.cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num);
|
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num);
|
||||||
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num);
|
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num);
|
||||||
|
|
||||||
int bts_init(struct gsm_bts *bts);
|
int bts_init(struct gsm_bts *bts);
|
||||||
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);
|
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 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);
|
|
||||||
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 is_ag_res);
|
enum ccch_msgt {
|
||||||
|
CCCH_MSGT_AGCH,
|
||||||
|
CCCH_MSGT_PCH,
|
||||||
|
CCCH_MSGT_NCH,
|
||||||
|
};
|
||||||
|
|
||||||
|
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch);
|
||||||
int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher);
|
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);
|
||||||
@@ -417,7 +447,7 @@ 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(const struct gsm_bts *bts,
|
bool bts_supports_cm(const struct gsm_bts *bts,
|
||||||
const struct rsl_ie_chan_mode *cm);
|
const struct rsl_ie_chan_mode *cm);
|
||||||
|
|
||||||
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
|
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
|
||||||
@@ -427,4 +457,11 @@ 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);
|
int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red);
|
||||||
|
|
||||||
|
/* Context information to be put in the control buffer (db) of the AGCH msg
|
||||||
|
* buffer */
|
||||||
|
struct bts_agch_msg_cb {
|
||||||
|
uint32_t msg_id;
|
||||||
|
bool confirm;
|
||||||
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
#endif /* _BTS_H */
|
#endif /* _BTS_H */
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <osmocom/gsm/tlv.h>
|
#include <osmocom/gsm/tlv.h>
|
||||||
#include <osmocom/gsm/gsm_utils.h>
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_12_21.h>
|
||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
@@ -20,8 +21,8 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type,
|
|||||||
struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
|
struct tlv_parsed *old_attr, struct tlv_parsed *new_attr,
|
||||||
void *obj);
|
void *obj);
|
||||||
|
|
||||||
int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
|
int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg,
|
||||||
struct tlv_parsed *new_attr, int obj_kind, void *obj);
|
struct gsm_abis_mo *mo, void *obj);
|
||||||
|
|
||||||
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
|
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
|
||||||
void *obj);
|
void *obj);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* BTS shutdown FSM */
|
/* BTS shutdown FSM */
|
||||||
|
|
||||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
#include <osmocom/core/fsm.h>
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */
|
|
||||||
enum bts_shutdown_fsm_states {
|
enum bts_shutdown_fsm_states {
|
||||||
BTS_SHUTDOWN_ST_NONE,
|
BTS_SHUTDOWN_ST_NONE,
|
||||||
BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL,
|
BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL,
|
||||||
|
|||||||
48
include/osmo-bts/bts_sm.h
Normal file
48
include/osmo-bts/bts_sm.h
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
#include <osmocom/core/socket.h>
|
||||||
|
#include <osmocom/gsm/gsm23003.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/oml.h>
|
||||||
|
|
||||||
|
struct pcu_sock_state;
|
||||||
|
|
||||||
|
/* GPRS NSVC; ip.access specific NM Object */
|
||||||
|
struct gsm_gprs_nse;
|
||||||
|
struct gsm_gprs_nsvc {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
struct gsm_gprs_nse *nse;
|
||||||
|
/* 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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* GPRS NSE; ip.access specific NM Object */
|
||||||
|
struct gsm_gprs_nse {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
uint16_t nsei;
|
||||||
|
uint8_t timer[7];
|
||||||
|
struct gsm_gprs_nsvc nsvc[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse);
|
||||||
|
|
||||||
|
/* BTS Site Manager */
|
||||||
|
struct gsm_bts_sm {
|
||||||
|
struct gsm_abis_mo mo;
|
||||||
|
struct llist_head bts_list;
|
||||||
|
unsigned int num_bts;
|
||||||
|
struct osmo_plmn_id plmn;
|
||||||
|
struct {
|
||||||
|
struct pcu_sock_state *pcu_state;
|
||||||
|
struct gsm_gprs_nse nse;
|
||||||
|
} gprs;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct gsm_bts_sm *g_bts_sm;
|
||||||
|
|
||||||
|
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx);
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <osmocom/core/sockaddr_str.h>
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
struct gsm_bts_bb_trx {
|
struct gsm_bts_bb_trx {
|
||||||
struct gsm_abis_mo mo;
|
struct gsm_abis_mo mo;
|
||||||
|
/* how do we talk RSL with this TRX? */
|
||||||
|
struct {
|
||||||
|
struct osmo_sockaddr_str rem_addrstr;
|
||||||
|
uint8_t tei;
|
||||||
|
struct e1inp_sign_link *link;
|
||||||
|
} rsl;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* One TRX in a BTS */
|
/* One TRX in a BTS */
|
||||||
@@ -16,9 +23,6 @@ struct gsm_bts_trx {
|
|||||||
uint8_t nr;
|
uint8_t nr;
|
||||||
/* human readable name / description */
|
/* human readable name / description */
|
||||||
char *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 */
|
/* NM Radio Carrier and Baseband Transciever */
|
||||||
struct gsm_abis_mo mo;
|
struct gsm_abis_mo mo;
|
||||||
@@ -40,6 +44,12 @@ struct gsm_bts_trx {
|
|||||||
/* The associated PHY instance */
|
/* The associated PHY instance */
|
||||||
struct phy_instance *pinst;
|
struct phy_instance *pinst;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint32_t freq_bands; /* see NM_IPAC_F_FREQ_BAND_* flags */
|
||||||
|
uint32_t chan_types; /* see NM_IPAC_F_CHANT_* flags */
|
||||||
|
uint32_t chan_modes; /* see NM_IPAC_F_CHANM_* flags */
|
||||||
|
} support;
|
||||||
|
|
||||||
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
struct gsm_bts_trx_ts ts[TRX_NR_TS];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,6 +68,7 @@ int trx_link_estab(struct gsm_bts_trx *trx);
|
|||||||
void trx_operability_update(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);
|
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
|
||||||
|
int pos_nch(const struct gsm_bts_trx *trx, const char *arg);
|
||||||
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx);
|
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)
|
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
int bts_ctrl_cmds_install(struct gsm_bts *bts);
|
int bts_ctrl_cmds_install(struct gsm_bts *bts);
|
||||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port);
|
||||||
const char *bind_addr, uint16_t port);
|
|
||||||
|
|||||||
23
include/osmo-bts/csd_v110.h
Normal file
23
include/osmo-bts/csd_v110.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* RFC4040 "clearmode" RTP payload length */
|
||||||
|
#define RFC4040_RTP_PLEN 160
|
||||||
|
|
||||||
|
struct gsm_lchan;
|
||||||
|
|
||||||
|
struct csd_v110_frame_desc {
|
||||||
|
uint16_t num_blocks;
|
||||||
|
uint16_t num_bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct csd_v110_lchan_desc {
|
||||||
|
struct csd_v110_frame_desc fr;
|
||||||
|
struct csd_v110_frame_desc hr;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256];
|
||||||
|
|
||||||
|
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
|
||||||
|
const uint8_t *data, size_t data_len);
|
||||||
|
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||||
|
const uint8_t *rtp, size_t rtp_len);
|
||||||
@@ -41,12 +41,6 @@
|
|||||||
#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
|
||||||
|
|
||||||
struct gsm_network {
|
|
||||||
struct llist_head bts_list;
|
|
||||||
unsigned int num_bts;
|
|
||||||
struct osmo_plmn_id plmn;
|
|
||||||
struct pcu_sock_state *pcu_state;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1:
|
/* 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) */
|
4-bit index is used (2#1111 = 10#15) */
|
||||||
@@ -58,12 +52,59 @@ struct gsm_network {
|
|||||||
/* lchans 0..3 are SDCCH in combined channel configuration,
|
/* lchans 0..3 are SDCCH in combined channel configuration,
|
||||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||||
#define CCCH_LCHAN 4
|
#define CCCH_LCHAN 4
|
||||||
|
#define CBCH_LCHAN 2
|
||||||
|
|
||||||
#define TRX_NR_TS 8
|
#define TRX_NR_TS 8
|
||||||
#define TS_MAX_LCHAN 8
|
#define TS_MAX_LCHAN 8
|
||||||
|
|
||||||
#define MAX_VERSION_LENGTH 64
|
#define MAX_VERSION_LENGTH 64
|
||||||
|
|
||||||
|
/* NM_IPAC_F_CHANT_* mask for NM_IPAC_EIE_CHAN_TYPES (common) */
|
||||||
|
#define NM_IPAC_MASK_CHANT_COMMON \
|
||||||
|
(NM_IPAC_F_CHANT_TCHF | \
|
||||||
|
NM_IPAC_F_CHANT_TCHH | \
|
||||||
|
NM_IPAC_F_CHANT_SDCCH8 | \
|
||||||
|
NM_IPAC_F_CHANT_BCCH | \
|
||||||
|
NM_IPAC_F_CHANT_BCCH_SDCCH4)
|
||||||
|
/* NM_IPAC_F_CHANM_SPEECH_* mask for NM_IPAC_EIE_CHAN_MODES */
|
||||||
|
#define NM_IPAC_MASK_CHANM_SPEECH \
|
||||||
|
(NM_IPAC_F_CHANM_SPEECH_FS | \
|
||||||
|
NM_IPAC_F_CHANM_SPEECH_EFS | \
|
||||||
|
NM_IPAC_F_CHANM_SPEECH_AFS | \
|
||||||
|
NM_IPAC_F_CHANM_SPEECH_HS | \
|
||||||
|
NM_IPAC_F_CHANM_SPEECH_AHS)
|
||||||
|
/* NM_IPAC_F_CHANM_CSD_NT_* mask for NM_IPAC_EIE_CHAN_MODES */
|
||||||
|
#define NM_IPAC_MASK_CHANM_CSD_NT \
|
||||||
|
(NM_IPAC_F_CHANM_CSD_NT_4k8 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_NT_9k6 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_NT_14k4)
|
||||||
|
/* NM_IPAC_F_CHANM_CSD_T_* mask for NM_IPAC_EIE_CHAN_MODES */
|
||||||
|
#define NM_IPAC_MASK_CHANM_CSD_T \
|
||||||
|
(NM_IPAC_F_CHANM_CSD_T_1200_75 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_600 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_1k2 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_2k4 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_4k8 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_9k6 | \
|
||||||
|
NM_IPAC_F_CHANM_CSD_T_14k4)
|
||||||
|
/* NM_IPAC_F_GPRS_CODING_CS[1-4] mask for NM_IPAC_EIE_GPRS_CODING */
|
||||||
|
#define NM_IPAC_MASK_GPRS_CODING_CS \
|
||||||
|
(NM_IPAC_F_GPRS_CODING_CS1 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_CS2 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_CS3 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_CS4)
|
||||||
|
/* NM_IPAC_F_GPRS_CODING_MCS[1-9] mask for NM_IPAC_EIE_GPRS_CODING */
|
||||||
|
#define NM_IPAC_MASK_GPRS_CODING_MCS \
|
||||||
|
(NM_IPAC_F_GPRS_CODING_MCS1 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS2 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS3 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS4 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS5 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS6 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS7 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS8 | \
|
||||||
|
NM_IPAC_F_GPRS_CODING_MCS9)
|
||||||
|
|
||||||
enum gsm_bts_trx_ts_flags {
|
enum gsm_bts_trx_ts_flags {
|
||||||
TS_F_PDCH_ACTIVE = 0x1000,
|
TS_F_PDCH_ACTIVE = 0x1000,
|
||||||
TS_F_PDCH_ACT_PENDING = 0x2000,
|
TS_F_PDCH_ACT_PENDING = 0x2000,
|
||||||
@@ -90,7 +131,10 @@ struct gsm_bts_trx_ts {
|
|||||||
|
|
||||||
/* Training Sequence Code (range 0..7) */
|
/* Training Sequence Code (range 0..7) */
|
||||||
uint8_t tsc_oml; /* configured via OML */
|
uint8_t tsc_oml; /* configured via OML */
|
||||||
uint8_t tsc; /* currently in use */
|
bool tsc_oml_configured;
|
||||||
|
uint8_t tsc_rsl; /* configured via RSL (Osmo extension) */
|
||||||
|
bool tsc_rsl_configured;
|
||||||
|
uint8_t tsc; /* TSC currently in use. Preference: RSL, OML, BTS-BSIC-OML */
|
||||||
/* Training Sequence Set (range 0..3) */
|
/* Training Sequence Set (range 0..3) */
|
||||||
uint8_t tsc_set;
|
uint8_t tsc_set;
|
||||||
|
|
||||||
@@ -193,6 +237,8 @@ int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts,
|
|||||||
|
|
||||||
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
|
bool ts_is_pdch(const struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
|
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
|
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
|
||||||
|
|
||||||
#endif /* _GSM_DATA_H */
|
#endif /* _GSM_DATA_H */
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -96,10 +98,11 @@ 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);
|
||||||
|
int l1sap_uplink_access(struct gsm_lchan *lchan, bool active);
|
||||||
|
|
||||||
enum l1sap_common_sapi {
|
enum l1sap_common_sapi {
|
||||||
L1SAP_COMMON_SAPI_UNKNOWN,
|
L1SAP_COMMON_SAPI_UNKNOWN,
|
||||||
@@ -139,9 +142,11 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg,
|
|||||||
|
|
||||||
#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h)
|
#define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h)
|
||||||
|
|
||||||
|
void radio_link_timeout_reset(struct gsm_lchan *lchan);
|
||||||
|
|
||||||
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
|
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
|
||||||
uint8_t *data, int len);
|
uint8_t *data, int len);
|
||||||
|
|
||||||
int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn);
|
enum ccch_msgt get_ccch_msgt(struct gsm_bts_trx *trx, uint32_t fn);
|
||||||
|
|
||||||
#endif /* L1SAP_H */
|
#endif /* L1SAP_H */
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <osmocom/core/timer.h>
|
#include <osmocom/core/timer.h>
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
#include <osmocom/core/logging.h>
|
#include <osmocom/core/logging.h>
|
||||||
#include <osmocom/gsm/gsm_utils.h>
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/codec/codec.h>
|
||||||
#include <osmocom/codec/ecu.h>
|
#include <osmocom/codec/ecu.h>
|
||||||
#include <osmocom/gsm/lapdm.h>
|
#include <osmocom/gsm/lapdm.h>
|
||||||
#include <osmocom/gsm/sysinfo.h>
|
#include <osmocom/gsm/sysinfo.h>
|
||||||
@@ -14,6 +16,7 @@
|
|||||||
#include <osmocom/gsm/gsm48_rest_octets.h>
|
#include <osmocom/gsm/gsm48_rest_octets.h>
|
||||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
#include <osmocom/gsm/meas_rep.h>
|
#include <osmocom/gsm/meas_rep.h>
|
||||||
|
#include <osmocom/netif/osmux.h>
|
||||||
|
|
||||||
#include <osmo-bts/power_control.h>
|
#include <osmo-bts/power_control.h>
|
||||||
|
|
||||||
@@ -52,7 +55,7 @@ struct bts_ul_meas {
|
|||||||
/* timing advance offset (in 1/256 bits) */
|
/* timing advance offset (in 1/256 bits) */
|
||||||
int16_t ta_offs_256bits;
|
int16_t ta_offs_256bits;
|
||||||
/* C/I ratio in cB */
|
/* C/I ratio in cB */
|
||||||
int16_t c_i;
|
int16_t ci_cb;
|
||||||
/* flags */
|
/* flags */
|
||||||
uint8_t is_sub:1;
|
uint8_t is_sub:1;
|
||||||
/* RSSI in dBm * -1 */
|
/* RSSI in dBm * -1 */
|
||||||
@@ -67,21 +70,22 @@ struct amr_mode {
|
|||||||
|
|
||||||
struct amr_multirate_conf {
|
struct amr_multirate_conf {
|
||||||
uint8_t gsm48_ie[2];
|
uint8_t gsm48_ie[2];
|
||||||
struct amr_mode ms_mode[4];
|
struct amr_mode mode[4];
|
||||||
struct amr_mode bts_mode[4];
|
|
||||||
uint8_t num_modes;
|
uint8_t num_modes;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lchan_csd_mode {
|
enum lchan_csd_mode {
|
||||||
LCHAN_CSD_M_NT,
|
LCHAN_CSD_M_NT = 0,
|
||||||
LCHAN_CSD_M_T_1200_75,
|
LCHAN_CSD_M_T_1200_75,
|
||||||
LCHAN_CSD_M_T_600,
|
LCHAN_CSD_M_T_600,
|
||||||
LCHAN_CSD_M_T_1200,
|
LCHAN_CSD_M_T_1200,
|
||||||
LCHAN_CSD_M_T_2400,
|
LCHAN_CSD_M_T_2400,
|
||||||
|
LCHAN_CSD_M_T_4800,
|
||||||
LCHAN_CSD_M_T_9600,
|
LCHAN_CSD_M_T_9600,
|
||||||
LCHAN_CSD_M_T_14400,
|
LCHAN_CSD_M_T_14400,
|
||||||
LCHAN_CSD_M_T_29000,
|
LCHAN_CSD_M_T_29000,
|
||||||
LCHAN_CSD_M_T_32000,
|
LCHAN_CSD_M_T_32000,
|
||||||
|
_LCHAN_CSD_M_NUM,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* State of the SAPIs in the lchan */
|
/* State of the SAPIs in the lchan */
|
||||||
@@ -139,6 +143,8 @@ struct gsm_lchan {
|
|||||||
uint8_t nr;
|
uint8_t nr;
|
||||||
/* The logical channel type */
|
/* The logical channel type */
|
||||||
enum gsm_chan_t type;
|
enum gsm_chan_t type;
|
||||||
|
/* RSL channel rate and type */
|
||||||
|
enum rsl_cmod_crt rsl_chan_rt;
|
||||||
/* RSL channel mode */
|
/* RSL channel mode */
|
||||||
enum rsl_cmod_spd rsl_cmode;
|
enum rsl_cmod_spd rsl_cmode;
|
||||||
/* If TCH, traffic channel mode */
|
/* If TCH, traffic channel mode */
|
||||||
@@ -162,7 +168,20 @@ struct gsm_lchan {
|
|||||||
uint16_t conn_id;
|
uint16_t conn_id;
|
||||||
uint8_t rtp_payload;
|
uint8_t rtp_payload;
|
||||||
uint8_t rtp_payload2;
|
uint8_t rtp_payload2;
|
||||||
|
uint8_t rtp_extensions;
|
||||||
uint8_t speech_mode;
|
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;
|
struct osmo_rtp_socket *rtp_socket;
|
||||||
} abis_ip;
|
} abis_ip;
|
||||||
|
|
||||||
@@ -190,7 +209,10 @@ struct gsm_lchan {
|
|||||||
uint8_t sapis_dl[23];
|
uint8_t sapis_dl[23];
|
||||||
uint8_t sapis_ul[23];
|
uint8_t sapis_ul[23];
|
||||||
struct lapdm_channel lapdm_ch;
|
struct lapdm_channel lapdm_ch;
|
||||||
|
/* It is required to have L3 info with DL establishment. */
|
||||||
|
bool l3_info_estab;
|
||||||
struct llist_head dl_tch_queue;
|
struct llist_head dl_tch_queue;
|
||||||
|
unsigned int dl_tch_queue_len;
|
||||||
struct {
|
struct {
|
||||||
/* bitmask of all SI that are present/valid in si_buf */
|
/* bitmask of all SI that are present/valid in si_buf */
|
||||||
uint32_t valid;
|
uint32_t valid;
|
||||||
@@ -251,9 +273,26 @@ struct gsm_lchan {
|
|||||||
/* last UL SPEECH resume flag */
|
/* last UL SPEECH resume flag */
|
||||||
bool is_speech_resume;
|
bool is_speech_resume;
|
||||||
} dtx;
|
} dtx;
|
||||||
|
struct {
|
||||||
|
bool last_rtp_input_was_sid;
|
||||||
|
uint8_t last_sid[GSM_FR_BYTES];
|
||||||
|
uint8_t last_sid_len;
|
||||||
|
uint8_t last_sid_age;
|
||||||
|
/* A SID was transmitted on the DL in the period
|
||||||
|
* beginning with the last transmitted speech frame
|
||||||
|
* or the last mandatory-Tx position, whichever was
|
||||||
|
* more recent. */
|
||||||
|
bool dl_sid_transmitted;
|
||||||
|
/* The current frame in the DL is taken up by FACCH */
|
||||||
|
bool dl_facch_stealing;
|
||||||
|
} dtx_fr_hr_efr;
|
||||||
uint8_t last_cmr;
|
uint8_t last_cmr;
|
||||||
uint32_t last_fn;
|
uint32_t last_fn;
|
||||||
|
struct {
|
||||||
|
/* buffers to re-combine RLP frame from multiple Um blocks */
|
||||||
|
uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */
|
||||||
|
uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */
|
||||||
|
} csd;
|
||||||
} tch;
|
} tch;
|
||||||
|
|
||||||
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
||||||
@@ -273,6 +312,19 @@ struct gsm_lchan {
|
|||||||
/* counts up to Ny1 */
|
/* counts up to Ny1 */
|
||||||
unsigned int phys_info_count;
|
unsigned int phys_info_count;
|
||||||
} ho;
|
} ho;
|
||||||
|
struct {
|
||||||
|
bool listener_detected;
|
||||||
|
uint8_t talker_active;
|
||||||
|
uint8_t ref;
|
||||||
|
uint32_t fn;
|
||||||
|
/* T3115: VGCS UPLINK GRANT retransmission */
|
||||||
|
struct osmo_timer_list t3115;
|
||||||
|
/* counts up to Ny2 */
|
||||||
|
unsigned int vgcs_ul_grant_count;
|
||||||
|
/* uplink free message */
|
||||||
|
bool uplink_free;
|
||||||
|
uint8_t uplink_free_msg[GSM_MACBLOCK_LEN];
|
||||||
|
} asci;
|
||||||
/* S counter for link loss */
|
/* S counter for link loss */
|
||||||
int s;
|
int s;
|
||||||
/* Kind of the release/activation. E.g. RSL or PCU */
|
/* Kind of the release/activation. E.g. RSL or PCU */
|
||||||
@@ -355,6 +407,12 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan);
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
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)
|
static inline bool lchan_is_dcch(const struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
switch (lchan->type) {
|
switch (lchan->type) {
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ enum {
|
|||||||
DLOOP,
|
DLOOP,
|
||||||
DABIS,
|
DABIS,
|
||||||
DRTP,
|
DRTP,
|
||||||
DSUM,
|
DOSMUX,
|
||||||
|
DASCI,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct log_info bts_log_info;
|
extern const struct log_info bts_log_info;
|
||||||
@@ -37,4 +38,12 @@ extern const struct log_info bts_log_info;
|
|||||||
#define DEBUGPFN(ss, fn, fmt, args...) \
|
#define DEBUGPFN(ss, fn, fmt, args...) \
|
||||||
LOGP(ss, LOGL_DEBUG, "%s " fmt, gsm_fn_as_gsmtime_str(fn), ## args)
|
LOGP(ss, LOGL_DEBUG, "%s " fmt, gsm_fn_as_gsmtime_str(fn), ## args)
|
||||||
|
|
||||||
|
/* LOGP with lchan + frame number prefix */
|
||||||
|
#define LOGPLCFN(lchan, fn, ss, lvl, fmt, args...) \
|
||||||
|
LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), gsm_fn_as_gsmtime_str(fn), ## args)
|
||||||
|
|
||||||
|
/* LOGP with lchan + gsm_time prefix */
|
||||||
|
#define LOGPLCGT(lchan, gt, ss, lvl, fmt, args...) \
|
||||||
|
LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), osmo_dump_gsmtime(gt), ## args)
|
||||||
|
|
||||||
#endif /* _LOGGING_H */
|
#endif /* _LOGGING_H */
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ struct msgb;
|
|||||||
/* Access 3rd part of msgb control buffer */
|
/* Access 3rd part of msgb control buffer */
|
||||||
#define rtpmsg_ts(x) ((x)->cb[2])
|
#define rtpmsg_ts(x) ((x)->cb[2])
|
||||||
|
|
||||||
|
/* Access 4th part of msgb control buffer */
|
||||||
|
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classification of OML message. ETSI for plain GSM 12.21
|
* Classification of OML message. ETSI for plain GSM 12.21
|
||||||
* messages and IPA/Osmo for manufacturer messages.
|
* messages and IPA/Osmo for manufacturer messages.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
|
/* 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 */
|
GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
|
||||||
|
|
||||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -30,18 +30,18 @@
|
|||||||
/* Common */
|
/* Common */
|
||||||
enum nm_fsm_events {
|
enum nm_fsm_events {
|
||||||
NM_EV_SW_ACT,
|
NM_EV_SW_ACT,
|
||||||
NM_EV_SETATTR_ACK, /* data: struct nm_fsm_ev_setattr_data */
|
NM_EV_RX_SETATTR, /* data: struct nm_fsm_ev_setattr_data */
|
||||||
NM_EV_SETATTR_NACK, /* data: struct nm_fsm_ev_setattr_data */
|
NM_EV_RX_OPSTART,
|
||||||
NM_EV_OPSTART_ACK,
|
NM_EV_OPSTART_ACK,
|
||||||
NM_EV_OPSTART_NACK,
|
NM_EV_OPSTART_NACK,
|
||||||
NM_EV_SHUTDOWN_START,
|
NM_EV_SHUTDOWN_START,
|
||||||
NM_EV_SHUTDOWN_FINISH,
|
NM_EV_SHUTDOWN_FINISH,
|
||||||
|
NM_EV_OML_UP,
|
||||||
NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
|
NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
NM_EV_RSL_DOWN, /* 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_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
||||||
NM_EV_DISABLE, /* 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_ENABLED, /* Radio Channel only */
|
||||||
NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
|
NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
|
||||||
NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
|
NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
|
||||||
@@ -50,8 +50,7 @@ enum nm_fsm_events {
|
|||||||
extern const struct value_string nm_fsm_event_names[];
|
extern const struct value_string nm_fsm_event_names[];
|
||||||
|
|
||||||
struct nm_fsm_ev_setattr_data {
|
struct nm_fsm_ev_setattr_data {
|
||||||
struct msgb *msg; /* msgb ownership is transferred to FSM */
|
const struct msgb *msg;
|
||||||
int cause;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -95,3 +94,30 @@ enum nm_chan_op_fsm_states {
|
|||||||
NM_CHAN_ST_OP_ENABLED,
|
NM_CHAN_ST_OP_ENABLED,
|
||||||
};
|
};
|
||||||
extern struct osmo_fsm nm_chan_fsm;
|
extern struct osmo_fsm nm_chan_fsm;
|
||||||
|
|
||||||
|
/* GPRS NSE */
|
||||||
|
enum nm_gprs_nse_op_fsm_states {
|
||||||
|
NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY,
|
||||||
|
NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_GPRS_NSE_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_gprs_nse_fsm;
|
||||||
|
|
||||||
|
/* GPRS NSVC */
|
||||||
|
enum nm_gprs_nsvc_op_fsm_states {
|
||||||
|
NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY,
|
||||||
|
NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_GPRS_NSVC_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_gprs_nsvc_fsm;
|
||||||
|
|
||||||
|
/* GPRS CELL */
|
||||||
|
enum nm_gprs_cell_op_fsm_states {
|
||||||
|
NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED,
|
||||||
|
NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY,
|
||||||
|
NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE,
|
||||||
|
NM_GPRS_CELL_ST_OP_ENABLED,
|
||||||
|
};
|
||||||
|
extern struct osmo_fsm nm_gprs_cell_fsm;
|
||||||
|
|||||||
61
include/osmo-bts/notification.h
Normal file
61
include/osmo-bts/notification.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* Maintain and generate ASCI notifications */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0+
|
||||||
|
*
|
||||||
|
* Author: Harald Welte
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* one [concurrent] ASCI (VBS/VGCS) notification */
|
||||||
|
struct asci_notification {
|
||||||
|
struct llist_head list; /* linked to bts->asci.notifications */
|
||||||
|
|
||||||
|
/* Group call reference (TS 24.008 10.5.1.9 "Descriptive group or broadcast call reference") */
|
||||||
|
uint8_t group_call_ref[5];
|
||||||
|
|
||||||
|
/* Group Channel Description (TS 44.018 10.5.2.14b) */
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t value[255];
|
||||||
|
uint8_t len;
|
||||||
|
} chan_desc;
|
||||||
|
|
||||||
|
/* NCH DRX Information (TS 48.058 9.3.47) */
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
struct rsl_ie_nch_drx_info value;
|
||||||
|
} nch_drx_info;
|
||||||
|
};
|
||||||
|
|
||||||
|
int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc,
|
||||||
|
uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info);
|
||||||
|
|
||||||
|
int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref);
|
||||||
|
|
||||||
|
int bts_asci_notification_reset(struct gsm_bts *bts);
|
||||||
|
|
||||||
|
const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts);
|
||||||
|
|
||||||
|
void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len);
|
||||||
|
|
||||||
|
int bts_asci_notify_nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf);
|
||||||
|
int bts_asci_notify_facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref,
|
||||||
|
const uint8_t *chan_desc, uint8_t chan_desc_len);
|
||||||
@@ -63,11 +63,12 @@ int oml_tx_state_changed(const struct gsm_abis_mo *mo);
|
|||||||
int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo);
|
int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo);
|
||||||
|
|
||||||
int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
|
int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
|
||||||
|
int oml_fom_ack_nack_copy_msg(const struct msgb *old_msg, uint8_t cause);
|
||||||
|
|
||||||
int oml_mo_fom_ack_nack(const struct gsm_abis_mo *mo, uint8_t orig_msg_type,
|
int oml_mo_fom_ack_nack(const struct gsm_abis_mo *mo, uint8_t orig_msg_type,
|
||||||
uint8_t cause);
|
uint8_t cause);
|
||||||
|
|
||||||
extern const unsigned int oml_default_t200_ms[7];
|
extern const uint32_t oml_default_t200_fn[7];
|
||||||
|
|
||||||
/* Transmit failure event report */
|
/* Transmit failure event report */
|
||||||
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,
|
||||||
@@ -77,11 +78,11 @@ 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);
|
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,
|
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
||||||
const struct abis_om_obj_inst *obj_inst);
|
const struct abis_om_obj_inst *obj_inst,
|
||||||
|
enum abis_nm_nack_cause *c);
|
||||||
|
|
||||||
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,
|
void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
|
||||||
const struct abis_om_obj_inst *obj_inst);
|
const struct abis_om_obj_inst *obj_inst,
|
||||||
|
enum abis_nm_nack_cause *c);
|
||||||
|
|
||||||
#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);
|
||||||
@@ -7,6 +7,55 @@
|
|||||||
|
|
||||||
struct paging_state;
|
struct paging_state;
|
||||||
struct gsm_bts;
|
struct gsm_bts;
|
||||||
|
struct asci_notification;
|
||||||
|
|
||||||
|
/* abstract representation of P1 rest octets; we only implement those parts we need for now */
|
||||||
|
struct p1_rest_octets {
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t nln;
|
||||||
|
uint8_t nln_status;
|
||||||
|
} nln_pch;
|
||||||
|
bool packet_page_ind[2];
|
||||||
|
bool r8_present;
|
||||||
|
struct {
|
||||||
|
bool prio_ul_access;
|
||||||
|
bool etws_present;
|
||||||
|
struct {
|
||||||
|
bool is_first;
|
||||||
|
uint8_t page_nr;
|
||||||
|
const uint8_t *page;
|
||||||
|
size_t page_bytes;
|
||||||
|
} etws;
|
||||||
|
} r8;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* abstract representation of P2 rest octets; we only implement those parts we need for now */
|
||||||
|
struct p2_rest_octets {
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t cn3;
|
||||||
|
} cneed;
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t nln;
|
||||||
|
uint8_t nln_status;
|
||||||
|
} nln_pch;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* abstract representation of P3 rest octets; we only implement those parts we need for now */
|
||||||
|
struct p3_rest_octets {
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t cn3;
|
||||||
|
uint8_t cn4;
|
||||||
|
} cneed;
|
||||||
|
struct {
|
||||||
|
bool present;
|
||||||
|
uint8_t nln;
|
||||||
|
uint8_t nln_status;
|
||||||
|
} nln_pch;
|
||||||
|
};
|
||||||
|
|
||||||
/* initialize paging code */
|
/* initialize paging code */
|
||||||
struct paging_state *paging_init(struct gsm_bts *bts,
|
struct paging_state *paging_init(struct gsm_bts *bts,
|
||||||
@@ -35,9 +84,15 @@ int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr
|
|||||||
int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
|
int paging_add_identity(struct paging_state *ps, uint8_t paging_group,
|
||||||
const uint8_t *identity_lv, uint8_t chan_needed);
|
const uint8_t *identity_lv, uint8_t chan_needed);
|
||||||
|
|
||||||
/* Add an IMM.ASS message to the paging queue */
|
/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a
|
||||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
* PAGING COMMAND (from the PCU) */
|
||||||
uint8_t len, bool from_pcu);
|
int paging_add_macblock(struct paging_state *ps, uint32_t msg_id, const char *imsi, bool confirm, const uint8_t *macblock);
|
||||||
|
|
||||||
|
/* Paging rest octests */
|
||||||
|
void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro,
|
||||||
|
const struct asci_notification *notif);
|
||||||
|
void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro);
|
||||||
|
void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro);
|
||||||
|
|
||||||
/* 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,
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <osmo-bts/pcuif_proto.h>
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
|
||||||
|
struct gsm_bts_sm;
|
||||||
|
|
||||||
extern int pcu_direct;
|
extern int pcu_direct;
|
||||||
|
|
||||||
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
|
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
|
||||||
@@ -21,11 +23,11 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
|||||||
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_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_data_cnf(uint32_t msg_id, uint8_t sapi);
|
||||||
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_send(struct msgb *msg);
|
||||||
|
|
||||||
int pcu_sock_init(const char *path);
|
int pcu_sock_init(const char *path, int qlength_max);
|
||||||
void pcu_sock_exit(void);
|
void pcu_sock_exit(void);
|
||||||
|
|
||||||
bool pcu_connected(void);
|
bool pcu_connected(void);
|
||||||
|
|||||||
@@ -3,20 +3,20 @@
|
|||||||
|
|
||||||
#include <osmocom/gsm/l1sap.h>
|
#include <osmocom/gsm/l1sap.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||||
|
|
||||||
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
|
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
|
||||||
|
|
||||||
#define PCU_IF_VERSION 0x0a
|
#define PCU_IF_VERSION 0x0c
|
||||||
#define TXT_MAX_LEN 128
|
#define TXT_MAX_LEN 128
|
||||||
|
|
||||||
/* msg_type */
|
/* msg_type */
|
||||||
#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */
|
#define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */
|
||||||
#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 transmit 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_2 0x11 /* confirm (using message id) */
|
||||||
#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 */
|
||||||
@@ -28,17 +28,16 @@
|
|||||||
|
|
||||||
/* sapi */
|
/* sapi */
|
||||||
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
|
#define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */
|
||||||
#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */
|
|
||||||
#define PCU_IF_SAPI_PCH 0x03 /* paging/assignment on PCH */
|
|
||||||
#define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */
|
#define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */
|
||||||
#define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */
|
#define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */
|
||||||
#define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */
|
#define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */
|
||||||
#define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */
|
#define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */
|
||||||
#define PCU_IF_SAPI_AGCH_DT 0x08 /* assignment on AGCH but with additional TLLI */
|
#define PCU_IF_SAPI_PCH_2 0x08 /* assignment on PCH (confirmed using message id) */
|
||||||
|
#define PCU_IF_SAPI_AGCH_2 0x09 /* assignment on AGCH (confirmed using message id) */
|
||||||
|
|
||||||
/* flags */
|
/* flags */
|
||||||
#define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */
|
#define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */
|
||||||
#define PCU_IF_FLAG_SYSMO (1 << 1)/* access PDCH of sysmoBTS directly */
|
#define PCU_IF_FLAG_DIRECT_PHY (1 << 1)/* access PHY directly via dedicated hardware support */
|
||||||
#define PCU_IF_FLAG_CS1 (1 << 16)
|
#define PCU_IF_FLAG_CS1 (1 << 16)
|
||||||
#define PCU_IF_FLAG_CS2 (1 << 17)
|
#define PCU_IF_FLAG_CS2 (1 << 17)
|
||||||
#define PCU_IF_FLAG_CS3 (1 << 18)
|
#define PCU_IF_FLAG_CS3 (1 << 18)
|
||||||
@@ -58,6 +57,20 @@
|
|||||||
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */
|
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */
|
||||||
#define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */
|
#define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */
|
||||||
|
|
||||||
|
/* BTS model */
|
||||||
|
enum gsm_pcuif_bts_model {
|
||||||
|
PCU_IF_BTS_MODEL_UNSPEC,
|
||||||
|
PCU_IF_BTS_MODEL_LC15,
|
||||||
|
PCU_IF_BTS_MODEL_OC2G,
|
||||||
|
PCU_IF_BTS_MODEL_OCTPHY,
|
||||||
|
PCU_IF_BTS_MODEL_SYSMO,
|
||||||
|
PCU_IF_BTS_MODEL_TRX,
|
||||||
|
PCU_IF_BTS_MODEL_RBS,
|
||||||
|
};
|
||||||
|
|
||||||
|
#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,
|
||||||
@@ -83,19 +96,10 @@ struct gsm_pcu_if_data {
|
|||||||
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
|
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
/* data confirmation with direct tlli (instead of raw mac block with tlli) */
|
/* data confirmation with message id (instead of raw mac block) */
|
||||||
struct gsm_pcu_if_data_cnf_dt {
|
struct gsm_pcu_if_data_cnf {
|
||||||
uint8_t sapi;
|
uint8_t sapi;
|
||||||
uint32_t tlli;
|
uint32_t msg_id;
|
||||||
uint32_t fn;
|
|
||||||
uint16_t arfcn;
|
|
||||||
uint8_t trx_nr;
|
|
||||||
uint8_t ts_nr;
|
|
||||||
uint8_t block_nr;
|
|
||||||
int8_t rssi;
|
|
||||||
uint16_t ber10k; /* !< \brief BER in units of 0.01% */
|
|
||||||
int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */
|
|
||||||
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
|
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if_rts_req {
|
struct gsm_pcu_if_rts_req {
|
||||||
@@ -140,7 +144,7 @@ struct gsm_pcu_if_info_trx {
|
|||||||
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;
|
||||||
@@ -169,14 +173,15 @@ 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];
|
||||||
uint8_t address_type[2];
|
uint8_t address_type[PCU_IF_NUM_NSVC];
|
||||||
union {
|
union {
|
||||||
struct in_addr v4;
|
struct in_addr v4;
|
||||||
struct in6_addr v6;
|
struct in6_addr v6;
|
||||||
} remote_ip[2];
|
} remote_ip[PCU_IF_NUM_NSVC];
|
||||||
|
uint8_t bts_model; /* enum gsm_pcuif_bts_model */
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct gsm_pcu_if_act_req {
|
struct gsm_pcu_if_act_req {
|
||||||
@@ -226,6 +231,32 @@ struct gsm_pcu_if_container {
|
|||||||
uint8_t data[0];
|
uint8_t data[0];
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request
|
||||||
|
* (data_req) under SAPI PCU_IF_SAPI_PCH_2. */
|
||||||
|
struct gsm_pcu_if_pch {
|
||||||
|
/* message id as reference for confirmation */
|
||||||
|
uint32_t msg_id;
|
||||||
|
/* IMSI (to derive paging group) */
|
||||||
|
char imsi[OSMO_IMSI_BUF_SIZE];
|
||||||
|
/* GSM mac-block (with immediate assignment message) */
|
||||||
|
uint8_t data[GSM_MACBLOCK_LEN];
|
||||||
|
/* Set to true in case the receiving end must send a confirmation
|
||||||
|
* when the MAC block (data) has been sent. */
|
||||||
|
bool confirm;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via AGCH. The struct is sent as a data request
|
||||||
|
* (data_req) under SAPI PCU_IF_SAPI_AGCH_2. */
|
||||||
|
struct gsm_pcu_if_agch {
|
||||||
|
/* message id as reference for confirmation */
|
||||||
|
uint32_t msg_id;
|
||||||
|
/* GSM mac-block (with immediate assignment message) */
|
||||||
|
uint8_t data[GSM_MACBLOCK_LEN];
|
||||||
|
/* Set to true in case the receiving end must send a confirmation
|
||||||
|
* when the MAC block (data) has been sent. */
|
||||||
|
bool confirm;
|
||||||
|
} __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 */
|
||||||
@@ -234,8 +265,7 @@ struct gsm_pcu_if {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
struct gsm_pcu_if_data data_req;
|
struct gsm_pcu_if_data data_req;
|
||||||
struct gsm_pcu_if_data data_cnf;
|
struct gsm_pcu_if_data_cnf data_cnf2;
|
||||||
struct gsm_pcu_if_data_cnf_dt data_cnf_dt;
|
|
||||||
struct gsm_pcu_if_data data_ind;
|
struct gsm_pcu_if_data data_ind;
|
||||||
struct gsm_pcu_if_susp_req susp_req;
|
struct gsm_pcu_if_susp_req susp_req;
|
||||||
struct gsm_pcu_if_rts_req rts_req;
|
struct gsm_pcu_if_rts_req rts_req;
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
#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);
|
bool rsl_chan_rt_is_asci(enum rsl_cmod_crt chan_rt);
|
||||||
|
bool rsl_chan_rt_is_vgcs(enum rsl_cmod_crt chan_rt);
|
||||||
|
|
||||||
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);
|
||||||
@@ -16,6 +17,8 @@ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause);
|
|||||||
int rsl_tx_conn_fail(const 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 rsl_tx_listener_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
|
||||||
|
int rsl_tx_talker_det(struct gsm_lchan *lchan, uint8_t *acc_delay);
|
||||||
|
|
||||||
/* 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);
|
||||||
@@ -32,6 +35,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, const uint8_t *l3, int l3_len, int timing_offset);
|
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 */
|
||||||
|
|||||||
20
include/osmo-bts/rtp_input_preen.h
Normal file
20
include/osmo-bts/rtp_input_preen.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* RTP input validation function: makes the accept-or-drop decision,
|
||||||
|
* and for some codecs signals additional required actions such as
|
||||||
|
* dropping one header octet.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
|
||||||
|
enum pl_input_decision {
|
||||||
|
PL_DECISION_DROP,
|
||||||
|
PL_DECISION_ACCEPT,
|
||||||
|
PL_DECISION_STRIP_HDR_OCTET,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pl_input_decision
|
||||||
|
rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
|
||||||
|
unsigned rtp_pl_len, bool *rfc5993_sid_flag);
|
||||||
@@ -5,13 +5,6 @@
|
|||||||
|
|
||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
|
||||||
/* Whether a logical channel must be activated automatically */
|
|
||||||
#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0)
|
|
||||||
|
|
||||||
/* FIXME: we should actually activate 'auto-active' channels */
|
|
||||||
#define TRX_CHAN_IS_ACTIVE(state, chan) \
|
|
||||||
(trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active)
|
|
||||||
|
|
||||||
#define TRX_GMSK_NB_TSC(br) \
|
#define TRX_GMSK_NB_TSC(br) \
|
||||||
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
||||||
|
|
||||||
@@ -80,6 +73,7 @@ enum trx_mod_type {
|
|||||||
|
|
||||||
/* A set of measurements belonging to one Uplink burst */
|
/* A set of measurements belonging to one Uplink burst */
|
||||||
struct l1sched_meas_set {
|
struct l1sched_meas_set {
|
||||||
|
uint32_t fn; /* TDMA frame number */
|
||||||
int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */
|
int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */
|
||||||
int16_t ci_cb; /* Carrier-to-Interference (cB) */
|
int16_t ci_cb; /* Carrier-to-Interference (cB) */
|
||||||
float rssi; /* RSSI (dBm) */
|
float rssi; /* RSSI (dBm) */
|
||||||
@@ -96,13 +90,12 @@ struct l1sched_chan_state {
|
|||||||
bool 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_mod_type dl_mod_type; /* Downlink modulation type */
|
enum trx_mod_type dl_mod_type; /* Downlink modulation type */
|
||||||
|
uint8_t dl_mask; /* mask of transmitted bursts */
|
||||||
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 */
|
uint32_t ul_mask; /* mask of received bursts */
|
||||||
|
|
||||||
/* 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 */
|
||||||
@@ -113,20 +106,17 @@ 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 */
|
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 */
|
||||||
struct l1sched_meas_set meas_avg_facch; /* measurement results for last FACCH */
|
|
||||||
uint16_t ber10k_facch; /* bit error rate for last FACCH */
|
|
||||||
|
|
||||||
uint8_t dl_facch_bursts; /* number of remaining DL FACCH bursts */
|
uint8_t dl_facch_bursts; /* number of remaining DL FACCH bursts */
|
||||||
|
|
||||||
@@ -141,7 +131,7 @@ struct l1sched_chan_state {
|
|||||||
/* Uplink measurements */
|
/* Uplink measurements */
|
||||||
struct {
|
struct {
|
||||||
/* Active channel measurements (simple ring buffer) */
|
/* Active channel measurements (simple ring buffer) */
|
||||||
struct l1sched_meas_set buf[8]; /* up to 8 entries */
|
struct l1sched_meas_set buf[24]; /* up to 24 (BUFMAX) entries */
|
||||||
unsigned int current; /* current position */
|
unsigned int current; /* current position */
|
||||||
|
|
||||||
/* Interference measurements */
|
/* Interference measurements */
|
||||||
@@ -195,6 +185,12 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch
|
|||||||
/*! \brief set all matching logical channels active/inactive */
|
/*! \brief set all matching logical channels active/inactive */
|
||||||
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
|
int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active);
|
||||||
|
|
||||||
|
/*! \brief set uplink access on given logical channels active/inactive */
|
||||||
|
int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active);
|
||||||
|
|
||||||
|
/*! \brief set all logical channels of BCCH/CCCH active/inactive */
|
||||||
|
int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool 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 gsm_bts_trx_ts *ts, 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,
|
||||||
@@ -233,7 +229,7 @@ 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)
|
||||||
@@ -243,6 +239,7 @@ extern const struct trx_sched_multiframe trx_sched_multiframes[];
|
|||||||
#define TRX_BI_F_TRX_NUM (1 << 4)
|
#define TRX_BI_F_TRX_NUM (1 << 4)
|
||||||
#define TRX_BI_F_BATCH_IND (1 << 5)
|
#define TRX_BI_F_BATCH_IND (1 << 5)
|
||||||
#define TRX_BI_F_SHADOW_IND (1 << 6)
|
#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 {
|
||||||
@@ -306,18 +303,24 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi);
|
|||||||
|
|
||||||
/* Averaging mode for trx_sched_meas_avg() */
|
/* Averaging mode for trx_sched_meas_avg() */
|
||||||
enum sched_meas_avg_mode {
|
enum sched_meas_avg_mode {
|
||||||
/* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */
|
/* first 22 of last 24 bursts (for TCH/F14.4, TCH/F9.6, TCH/F4.8) */
|
||||||
SCHED_MEAS_AVG_M_QUAD,
|
SCHED_MEAS_AVG_M_S24N22,
|
||||||
|
/* last 22 bursts (for TCH/H4.8, TCH/H2.4) */
|
||||||
|
SCHED_MEAS_AVG_M_S22N22,
|
||||||
|
/* last 4 bursts (default for xCCH, PTCCH and PDTCH) */
|
||||||
|
SCHED_MEAS_AVG_M_S4N4,
|
||||||
/* last 8 bursts (default for TCH/F and FACCH/F) */
|
/* last 8 bursts (default for TCH/F and FACCH/F) */
|
||||||
SCHED_MEAS_AVG_M_OCTO,
|
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) */
|
/* last 6 bursts (default for FACCH/H) */
|
||||||
SCHED_MEAS_AVG_M_SIX,
|
SCHED_MEAS_AVG_M_S6N6,
|
||||||
/* first 4 of last 8 bursts */
|
/* first 4 of last 8 bursts */
|
||||||
SCHED_MEAS_AVG_M8_FIRST_QUAD,
|
SCHED_MEAS_AVG_M_S8N4,
|
||||||
/* first 2 of last 6 bursts */
|
/* first 2 of last 6 bursts */
|
||||||
SCHED_MEAS_AVG_M6_FIRST_TWO,
|
SCHED_MEAS_AVG_M_S6N2,
|
||||||
/* middle 2 of last 6 bursts */
|
/* middle 2 of last 6 bursts */
|
||||||
SCHED_MEAS_AVG_M6_MIDDLE_TWO,
|
SCHED_MEAS_AVG_M_S4N2,
|
||||||
};
|
};
|
||||||
|
|
||||||
void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
|
void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
|
||||||
@@ -325,3 +328,5 @@ void trx_sched_meas_push(struct l1sched_chan_state *chan_state,
|
|||||||
void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state,
|
void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state,
|
||||||
struct l1sched_meas_set *avg,
|
struct l1sched_meas_set *avg,
|
||||||
enum sched_meas_avg_mode mode);
|
enum sched_meas_avg_mode mode);
|
||||||
|
uint32_t trx_sched_lookup_fn(const struct l1sched_chan_state *chan_state,
|
||||||
|
const unsigned int shift);
|
||||||
|
|||||||
@@ -42,16 +42,18 @@ extern const ubit_t _sched_train_seq_gmsk_sb[64];
|
|||||||
struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
|
struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br);
|
||||||
|
|
||||||
int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, 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_len, float rssi,
|
const uint8_t *data, size_t data_len,
|
||||||
|
uint16_t ber10k, 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,
|
|
||||||
enum osmo_ph_pres_info_type presence_info);
|
enum osmo_ph_pres_info_type presence_info);
|
||||||
|
|
||||||
int _sched_compose_tch_ind(struct l1sched_ts *l1ts, 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,
|
||||||
int16_t ta_offs_256bits, uint16_t ber10k, float rssi,
|
const uint8_t *data, size_t data_len,
|
||||||
int16_t link_qual_cb, uint8_t is_sub);
|
uint16_t ber10k, float rssi,
|
||||||
|
int16_t ta_offs_256bits, int16_t link_qual_cb,
|
||||||
|
uint8_t is_sub);
|
||||||
|
|
||||||
int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
int tx_sch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br);
|
||||||
|
|||||||
@@ -77,7 +77,12 @@ int get_p_trxout_target_mdBm_lchan(const struct gsm_lchan *lchan);
|
|||||||
int get_p_trxout_actual_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red);
|
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 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, ramp_compl_cb_t ramp_compl_cb);
|
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_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);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ enum bts_vty_node {
|
|||||||
PHY_INST_NODE,
|
PHY_INST_NODE,
|
||||||
BTS_NODE,
|
BTS_NODE,
|
||||||
TRX_NODE,
|
TRX_NODE,
|
||||||
|
OSMUX_NODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct cmd_element cfg_bts_auto_band_cmd;
|
extern struct cmd_element cfg_bts_auto_band_cmd;
|
||||||
@@ -20,12 +21,9 @@ extern struct cmd_element cfg_bts_no_auto_band_cmd;
|
|||||||
struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr);
|
struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr);
|
||||||
|
|
||||||
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_init(void *ctx);
|
int bts_vty_init(void *ctx);
|
||||||
|
|
||||||
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;
|
extern struct gsm_bts *g_bts;
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ AM_CFLAGS = \
|
|||||||
$(LIBOSMOCORE_CFLAGS) \
|
$(LIBOSMOCORE_CFLAGS) \
|
||||||
$(LIBOSMOTRAU_CFLAGS) \
|
$(LIBOSMOTRAU_CFLAGS) \
|
||||||
$(LIBOSMOCODEC_CFLAGS) \
|
$(LIBOSMOCODEC_CFLAGS) \
|
||||||
|
$(LIBOSMONETIF_CFLAGS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
LDADD = \
|
LDADD = \
|
||||||
$(LIBOSMOCORE_LIBS) \
|
$(LIBOSMOCORE_LIBS) \
|
||||||
$(LIBOSMOTRAU_LIBS) \
|
$(LIBOSMOTRAU_LIBS) \
|
||||||
$(LIBOSMOCODEC_LIBS) \
|
$(LIBOSMOCODEC_LIBS) \
|
||||||
|
$(LIBOSMONETIF_LIBS) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
if ENABLE_LC15BTS
|
if ENABLE_LC15BTS
|
||||||
@@ -29,13 +31,17 @@ libbts_a_SOURCES = \
|
|||||||
abis.c \
|
abis.c \
|
||||||
abis_osmo.c \
|
abis_osmo.c \
|
||||||
oml.c \
|
oml.c \
|
||||||
|
osmux.c \
|
||||||
bts.c \
|
bts.c \
|
||||||
|
bts_sm.c \
|
||||||
bts_trx.c \
|
bts_trx.c \
|
||||||
rsl.c \
|
rsl.c \
|
||||||
|
rtp_input_preen.c \
|
||||||
vty.c \
|
vty.c \
|
||||||
paging.c \
|
paging.c \
|
||||||
measurement.c \
|
measurement.c \
|
||||||
amr.c \
|
amr.c \
|
||||||
|
asci.c \
|
||||||
lchan.c \
|
lchan.c \
|
||||||
load_indication.c \
|
load_indication.c \
|
||||||
pcu_sock.c \
|
pcu_sock.c \
|
||||||
@@ -45,6 +51,7 @@ libbts_a_SOURCES = \
|
|||||||
bts_ctrl_commands.c \
|
bts_ctrl_commands.c \
|
||||||
bts_ctrl_lookup.c \
|
bts_ctrl_lookup.c \
|
||||||
bts_shutdown_fsm.c \
|
bts_shutdown_fsm.c \
|
||||||
|
csd_v110.c \
|
||||||
l1sap.c \
|
l1sap.c \
|
||||||
cbch.c \
|
cbch.c \
|
||||||
power_control.c \
|
power_control.c \
|
||||||
@@ -58,7 +65,11 @@ libbts_a_SOURCES = \
|
|||||||
nm_bts_fsm.c \
|
nm_bts_fsm.c \
|
||||||
nm_bb_transc_fsm.c \
|
nm_bb_transc_fsm.c \
|
||||||
nm_channel_fsm.c \
|
nm_channel_fsm.c \
|
||||||
|
nm_gprs_cell_fsm.c \
|
||||||
|
nm_gprs_nse_fsm.c \
|
||||||
|
nm_gprs_nsvc_fsm.c \
|
||||||
nm_radio_carrier_fsm.c \
|
nm_radio_carrier_fsm.c \
|
||||||
|
notification.c \
|
||||||
probes.d \
|
probes.d \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -225,11 +225,19 @@ static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *
|
|||||||
|
|
||||||
/* Then iterate over the RSL signalling links */
|
/* Then iterate over the RSL signalling links */
|
||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
if (trx->rsl_link) {
|
if (trx->bb_transc.rsl.link) {
|
||||||
e1inp_sign_link_destroy(trx->rsl_link);
|
e1inp_sign_link_destroy(trx->bb_transc.rsl.link);
|
||||||
trx->rsl_link = NULL;
|
trx->bb_transc.rsl.link = NULL;
|
||||||
if (trx == trx->bts->c0)
|
if (trx == trx->bts->c0)
|
||||||
load_timer_stop(trx->bts);
|
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
|
/* Note: Here we could send NM_EV_RSL_DOWN to each
|
||||||
* trx->(bb_transc.)mo.fi, but we are starting shutdown of the
|
* trx->(bb_transc.)mo.fi, but we are starting shutdown of the
|
||||||
@@ -356,7 +364,7 @@ int abis_bts_rsl_sendmsg(struct msgb *msg)
|
|||||||
|
|
||||||
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
||||||
* the signalling link at msg->dst */
|
* the signalling link at msg->dst */
|
||||||
msg->dst = msg->trx->rsl_link;
|
msg->dst = msg->trx->bb_transc.rsl.link;
|
||||||
return abis_sendmsg(msg);
|
return abis_sendmsg(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,10 +404,10 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
e1inp_ts_config_sign(sign_ts, line);
|
e1inp_ts_config_sign(sign_ts, line);
|
||||||
trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||||
trx, trx->rsl_tei, 0);
|
trx, trx->bb_transc.rsl.tei, 0);
|
||||||
trx_link_estab(trx);
|
trx_link_estab(trx);
|
||||||
return trx->rsl_link;
|
return trx->bb_transc.rsl.link;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* OSMO extenion link associated to same line as oml_link: */
|
/* OSMO extenion link associated to same line as oml_link: */
|
||||||
|
|
||||||
/* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -30,8 +30,7 @@
|
|||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/pcu_if.h>
|
#include <osmo-bts/pcu_if.h>
|
||||||
#include <osmo-bts/pcuif_proto.h>
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
#include <osmo-bts/bts_sm.h>
|
||||||
extern struct gsm_network bts_gsmnet;
|
|
||||||
|
|
||||||
#define OM_HEADROOM_SIZE 128
|
#define OM_HEADROOM_SIZE 128
|
||||||
|
|
||||||
@@ -106,7 +105,7 @@ static int rx_down_osmo_pcu(struct gsm_bts *bts, struct msgb *msg)
|
|||||||
/* Trim Abis lower layers: */
|
/* Trim Abis lower layers: */
|
||||||
msgb_pull_to_l2(msg);
|
msgb_pull_to_l2(msg);
|
||||||
/* we simply forward it to PCUIF: */
|
/* we simply forward it to PCUIF: */
|
||||||
return pcu_sock_send(&bts_gsmnet, msg);
|
return pcu_sock_send(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* incoming IPA/OSMO extension Abis message from BSC */
|
/* incoming IPA/OSMO extension Abis message from BSC */
|
||||||
|
|||||||
131
src/common/amr.c
131
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;
|
||||||
@@ -117,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;
|
||||||
@@ -171,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;
|
||||||
|
}
|
||||||
|
|||||||
211
src/common/asci.c
Normal file
211
src/common/asci.c
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
/* ASCI (VGCS/VBS) related common code */
|
||||||
|
|
||||||
|
/* (C) 2023 by Harald Welte <laforge@osmocom.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 <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
|
#include <osmocom/gsm/rsl.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/rsl.h>
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/l1sap.h>
|
||||||
|
#include <osmo-bts/asci.h>
|
||||||
|
|
||||||
|
static int tx_vgcs_ul_grant(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
struct gsm0408_vgcs_ul_grant ul_grant;
|
||||||
|
struct gsm_time gt;
|
||||||
|
struct msgb *msg;
|
||||||
|
|
||||||
|
gsm_fn2gsmtime(>, lchan->asci.fn);
|
||||||
|
|
||||||
|
/* build the RR VGCS UPLINK GRANT message as per TS 44.018 Section 9.1.49 */
|
||||||
|
ul_grant = (struct gsm0408_vgcs_ul_grant) {
|
||||||
|
.hdr = {
|
||||||
|
.proto_discr = GSM48_PDISC_RR,
|
||||||
|
.msg_type = GSM48_MT_RR_VGCS_UPL_GRANT,
|
||||||
|
},
|
||||||
|
.req_ref = {
|
||||||
|
.ra = lchan->asci.ref,
|
||||||
|
.t1 = gt.t1,
|
||||||
|
.t2 = gt.t2,
|
||||||
|
.t3_low = gt.t3 & 7,
|
||||||
|
.t3_high = gt.t3 >> 3,
|
||||||
|
},
|
||||||
|
.ta = lchan->ta_ctrl.current,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Wrap it in a RSL UNITDATA REQUEST */
|
||||||
|
msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0);
|
||||||
|
msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */
|
||||||
|
msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(ul_grant), (uint8_t *) &ul_grant);
|
||||||
|
|
||||||
|
/* send it towards MS, just like a RSL message from the BSC */
|
||||||
|
return lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* timer call-back for T3115 (VGCS UPLINK GRANT re-transmit) */
|
||||||
|
static void vgcs_t3115_cb(void *data)
|
||||||
|
{
|
||||||
|
struct gsm_lchan *lchan = data;
|
||||||
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "T3115 timeout (%d resends left)\n",
|
||||||
|
bts->ny2 - lchan->asci.vgcs_ul_grant_count);
|
||||||
|
|
||||||
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "is not active. It is in state %s. Ignoring\n",
|
||||||
|
gsm_lchans_name(lchan->state));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lchan->asci.vgcs_ul_grant_count >= bts->ny2) {
|
||||||
|
lchan->asci.vgcs_ul_grant_count = 0;
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "NY2 reached, sending CONNection FAILure to BSC.\n");
|
||||||
|
rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL);
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_vgcs_ul_grant(lchan);
|
||||||
|
lchan->asci.vgcs_ul_grant_count++;
|
||||||
|
osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Received random access on dedicated channel. */
|
||||||
|
void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn)
|
||||||
|
{
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "VGCS RACH on dedicated channel type %s received with "
|
||||||
|
"TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra);
|
||||||
|
|
||||||
|
if (ra == 0x25) { /* See TS 44.018 Table 9.1.45.1 */
|
||||||
|
/* Listener Detection (TS 48.058 Section 4.14) */
|
||||||
|
if (!lchan->asci.listener_detected) {
|
||||||
|
rsl_tx_listener_det(lchan, &acc_delay);
|
||||||
|
lchan->asci.listener_detected = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Talker Detection (TS 48.058 Section 4.13) */
|
||||||
|
struct gsm_bts *bts = lchan->ts->trx->bts;
|
||||||
|
|
||||||
|
/* Talker detection on group channels only */
|
||||||
|
if (!rsl_chan_rt_is_vgcs(lchan->rsl_chan_rt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lchan->asci.talker_active != VGCS_TALKER_NONE) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Ignoring RACH, there is an active talker already.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set timing advance, power level and activate SACCH */
|
||||||
|
lchan->ta_ctrl.current = acc_delay;
|
||||||
|
lchan->ms_power_ctrl.current = lchan->ms_power_ctrl.max;
|
||||||
|
lchan->want_dl_sacch_active = true;
|
||||||
|
|
||||||
|
/* Stop RACH detection, wait for valid frame */
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
|
||||||
|
if (l1sap_uplink_access(lchan, false) != 0) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n");
|
||||||
|
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lchan->asci.ref = ra;
|
||||||
|
lchan->asci.fn = fn;
|
||||||
|
|
||||||
|
/* Send TALKER DETECT via RSL to BSC */
|
||||||
|
rsl_tx_talker_det(lchan, &acc_delay);
|
||||||
|
|
||||||
|
/* Send VGCS UPLINK GRANT */
|
||||||
|
lchan->asci.vgcs_ul_grant_count = 1;
|
||||||
|
tx_vgcs_ul_grant(lchan);
|
||||||
|
|
||||||
|
/* Start T3115 */
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Starting T3115 with %u ms\n", bts->t3115_ms);
|
||||||
|
lchan->asci.t3115.cb = vgcs_t3115_cb;
|
||||||
|
lchan->asci.t3115.data = lchan;
|
||||||
|
osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Received channel activation. */
|
||||||
|
void vgcs_lchan_activate(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated.\n");
|
||||||
|
if (l1sap_uplink_access(lchan, true) != 0) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to activate uplink access after channel activation.\n");
|
||||||
|
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Received channel reactivation. (for assignment) */
|
||||||
|
void vgcs_lchan_react(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n");
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME;
|
||||||
|
if (l1sap_uplink_access(lchan, false) != 0) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access for assignment.\n");
|
||||||
|
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
|
||||||
|
}
|
||||||
|
radio_link_timeout_reset(lchan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Received first valid data frame on dedicated channel. */
|
||||||
|
void vgcs_talker_frame(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "First valid frame detected, talker now active.\n");
|
||||||
|
osmo_timer_del(&lchan->asci.t3115);
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_ACTIVE;
|
||||||
|
radio_link_timeout_reset(lchan);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release VGCS Talker state. */
|
||||||
|
void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access)
|
||||||
|
{
|
||||||
|
if (lchan->asci.talker_active == VGCS_TALKER_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Uplink released, no talker.\n");
|
||||||
|
|
||||||
|
/* Stop T3115 */
|
||||||
|
osmo_timer_del(&lchan->asci.t3115);
|
||||||
|
|
||||||
|
/* Talker released. */
|
||||||
|
lchan->asci.talker_active = VGCS_TALKER_NONE;
|
||||||
|
if (ul_access) {
|
||||||
|
if (l1sap_uplink_access(lchan, true) != 0) {
|
||||||
|
LOGPLCHAN(lchan, DASCI, LOGL_ERROR,
|
||||||
|
"Failed to activate uplink access after uplink became free.\n");
|
||||||
|
rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release VGCS Listener state. */
|
||||||
|
void vgcs_listener_reset(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
lchan->asci.listener_detected = false;
|
||||||
|
}
|
||||||
320
src/common/bts.c
320
src/common/bts.c
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -44,8 +44,10 @@
|
|||||||
#include <osmo-bts/abis.h>
|
#include <osmo-bts/abis.h>
|
||||||
#include <osmo-bts/bts.h>
|
#include <osmo-bts/bts.h>
|
||||||
#include <osmo-bts/bts_model.h>
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/bts_sm.h>
|
||||||
#include <osmo-bts/dtx_dl_amr_fsm.h>
|
#include <osmo-bts/dtx_dl_amr_fsm.h>
|
||||||
#include <osmo-bts/pcuif_proto.h>
|
#include <osmo-bts/pcuif_proto.h>
|
||||||
|
#include <osmo-bts/pcu_if.h>
|
||||||
#include <osmo-bts/rsl.h>
|
#include <osmo-bts/rsl.h>
|
||||||
#include <osmo-bts/oml.h>
|
#include <osmo-bts/oml.h>
|
||||||
#include <osmo-bts/signal.h>
|
#include <osmo-bts/signal.h>
|
||||||
@@ -54,17 +56,15 @@
|
|||||||
#include <osmo-bts/bts_shutdown_fsm.h>
|
#include <osmo-bts/bts_shutdown_fsm.h>
|
||||||
#include <osmo-bts/nm_common_fsm.h>
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
#include <osmo-bts/power_control.h>
|
#include <osmo-bts/power_control.h>
|
||||||
|
#include <osmo-bts/osmux.h>
|
||||||
|
#include <osmo-bts/notification.h>
|
||||||
|
|
||||||
|
#define MAX_TA_DEF 63 /* default max Timing Advance value */
|
||||||
#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 */
|
||||||
|
|
||||||
static void bts_update_agch_max_queue_length(struct gsm_bts *bts);
|
static void bts_update_agch_max_queue_length(struct gsm_bts *bts);
|
||||||
|
|
||||||
struct gsm_network bts_gsmnet = {
|
|
||||||
.bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list },
|
|
||||||
.num_bts = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
void *tall_bts_ctx;
|
void *tall_bts_ctx;
|
||||||
|
|
||||||
/* Table 3.1 TS 04.08: Values of parameter S */
|
/* Table 3.1 TS 04.08: Values of parameter S */
|
||||||
@@ -97,12 +97,22 @@ static const struct rate_ctr_desc bts_ctr_desc[] = {
|
|||||||
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
|
[BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"},
|
||||||
[BTS_CTR_RACH_DROP] = {"rach:drop", "Dropped RACH requests (Um)"},
|
[BTS_CTR_RACH_DROP] = {"rach:drop", "Dropped RACH requests (Um)"},
|
||||||
[BTS_CTR_RACH_HO] = {"rach:handover", "Received RACH requests (Handover)"},
|
[BTS_CTR_RACH_HO] = {"rach:handover", "Received RACH requests (Handover)"},
|
||||||
|
[BTS_CTR_RACH_VGCS] = {"rach:vgcs", "Received RACH requests (VGCS)"},
|
||||||
[BTS_CTR_RACH_CS] = {"rach:cs", "Received RACH requests (CS/Abis)"},
|
[BTS_CTR_RACH_CS] = {"rach:cs", "Received RACH requests (CS/Abis)"},
|
||||||
[BTS_CTR_RACH_PS] = {"rach:ps", "Received RACH requests (PS/PCU)"},
|
[BTS_CTR_RACH_PS] = {"rach:ps", "Received RACH requests (PS/PCU)"},
|
||||||
|
|
||||||
[BTS_CTR_AGCH_RCVD] = {"agch:rcvd", "Received AGCH requests (Abis)"},
|
[BTS_CTR_AGCH_RCVD] = {"agch:rcvd", "Received AGCH requests (Abis)"},
|
||||||
[BTS_CTR_AGCH_SENT] = {"agch:sent", "Sent AGCH requests (Abis)"},
|
[BTS_CTR_AGCH_SENT] = {"agch:sent", "Sent AGCH requests (Abis)"},
|
||||||
[BTS_CTR_AGCH_DELETED] = {"agch:delete", "Sent AGCH DELETE IND (Abis)"},
|
[BTS_CTR_AGCH_DELETED] = {"agch:delete", "Sent AGCH DELETE IND (Abis)"},
|
||||||
|
|
||||||
|
[BTS_CTR_RTP_RX_TOTAL] = {"rtp:rx:total", "Total number of received RTP packets"},
|
||||||
|
[BTS_CTR_RTP_RX_MARKER] = {"rtp:rx:marker", "Number of received RTP packets with marker bit set"},
|
||||||
|
[BTS_CTR_RTP_RX_DROP_PREEN] = {"rtp:rx:drop:preen", "Total number of received RTP packets dropped during preening"},
|
||||||
|
[BTS_CTR_RTP_RX_DROP_LOOPBACK] = {"rtp:rx:drop:loopback", "Total number of received RTP packets dropped during loopback"},
|
||||||
|
[BTS_CTR_RTP_RX_DROP_OVERFLOW] = {"rtp:rx:drop:overflow", "Total number of received RTP packets dropped during DL queue overflow"},
|
||||||
|
[BTS_CTR_RTP_RX_DROP_V110_DEC] = {"rtp:rx:drop:v110_dec", "Total number of received RTP packets dropped during V.110 decode"},
|
||||||
|
[BTS_CTR_RTP_TX_TOTAL] = {"rtp:tx:total", "Total number of transmitted RTP packets"},
|
||||||
|
[BTS_CTR_RTP_TX_MARKER] = {"rtp:tx:marker", "Number of transmitted RTP packets with marker bit set"},
|
||||||
};
|
};
|
||||||
static const struct rate_ctr_group_desc bts_ctrg_desc = {
|
static const struct rate_ctr_group_desc bts_ctrg_desc = {
|
||||||
"bts",
|
"bts",
|
||||||
@@ -148,7 +158,6 @@ struct osmo_tdef abis_T_defs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
|
|
||||||
static const uint8_t bts_cell_timer_default[] =
|
static const uint8_t bts_cell_timer_default[] =
|
||||||
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
||||||
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
||||||
@@ -206,32 +215,46 @@ const char *btsatttr2str(enum bts_attribute v)
|
|||||||
const struct value_string bts_impl_flag_desc[] = {
|
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_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
|
||||||
{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" },
|
{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" },
|
||||||
|
{ BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, "OML RadioChannel MO depends on RadioCarrier MO" },
|
||||||
|
{ BTS_INTERNAL_FLAG_INTERF_MEAS, "Uplink interference measurements" },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Ensure that all BTS_INTERNAL_FLAG_* entries are present in bts_impl_flag_desc[] */
|
||||||
|
osmo_static_assert(ARRAY_SIZE(bts_impl_flag_desc) == _BTS_INTERNAL_FLAG_NUM + 1, _bts_impl_flag_desc);
|
||||||
|
|
||||||
static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
|
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) {
|
if (bts->mo.fi) {
|
||||||
osmo_fsm_inst_free(bts->mo.fi);
|
osmo_fsm_inst_free(bts->mo.fi);
|
||||||
bts->mo.fi = NULL;
|
bts->mo.fi = NULL;
|
||||||
}
|
}
|
||||||
|
if (bts->shutdown_fi) {
|
||||||
|
osmo_fsm_inst_free(bts->shutdown_fi);
|
||||||
|
bts->shutdown_fi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bts_osmux_release(bts);
|
||||||
|
|
||||||
|
llist_del(&bts->list);
|
||||||
|
g_bts_sm->num_bts--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts);
|
struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts);
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!bts)
|
if (!bts)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
talloc_set_destructor(bts, gsm_bts_talloc_destructor);
|
talloc_set_destructor(bts, gsm_bts_talloc_destructor);
|
||||||
|
|
||||||
|
/* add to list of BTSs */
|
||||||
|
llist_add_tail(&bts->list, &bts_sm->bts_list);
|
||||||
|
g_bts_sm->num_bts++;
|
||||||
|
|
||||||
|
bts->site_mgr = bts_sm;
|
||||||
bts->nr = bts_num;
|
bts->nr = bts_num;
|
||||||
bts->num_trx = 0;
|
bts->num_trx = 0;
|
||||||
INIT_LLIST_HEAD(&bts->trx_list);
|
INIT_LLIST_HEAD(&bts->trx_list);
|
||||||
@@ -244,32 +267,19 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
|||||||
LOGL_INFO, NULL);
|
LOGL_INFO, NULL);
|
||||||
osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
|
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,
|
/* NM BTS */
|
||||||
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,
|
bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
|
||||||
LOGL_INFO, NULL);
|
LOGL_INFO, NULL);
|
||||||
osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
|
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);
|
gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
|
/* NM GPRS CELL */
|
||||||
bts->gprs.nsvc[i].bts = bts;
|
bts->gprs.cell.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_cell_fsm, bts, &bts->gprs.cell,
|
||||||
bts->gprs.nsvc[i].id = i;
|
LOGL_INFO, NULL);
|
||||||
gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
|
osmo_fsm_inst_update_id_f(bts->gprs.cell.mo.fi, "gprs_cell%d-0", bts->nr);
|
||||||
bts->nr, i, 0xff);
|
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, bts->nr, 0, 0xff);
|
||||||
}
|
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, sizeof(bts->gprs.cell.rlc_cfg));
|
||||||
memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
|
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer));
|
||||||
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() */
|
/* create our primary TRX. It will be initialized during bts_init() */
|
||||||
bts->c0 = gsm_bts_trx_alloc(bts);
|
bts->c0 = gsm_bts_trx_alloc(bts);
|
||||||
@@ -285,14 +295,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
|||||||
return bts;
|
return bts;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num)
|
struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts;
|
struct gsm_bts *bts;
|
||||||
|
|
||||||
if (num >= net->num_bts)
|
if (num >= bts_sm->num_bts)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
llist_for_each_entry(bts, &bts_sm->bts_list, list) {
|
||||||
if (bts->nr == num)
|
if (bts->nr == num)
|
||||||
return bts;
|
return bts;
|
||||||
}
|
}
|
||||||
@@ -308,19 +318,14 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
static int initialized = 0;
|
static int initialized = 0;
|
||||||
void *tall_rtp_ctx;
|
void *tall_rtp_ctx;
|
||||||
|
|
||||||
/* add to list of BTSs */
|
|
||||||
llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
|
|
||||||
|
|
||||||
bts->band = GSM_BAND_1800;
|
bts->band = GSM_BAND_1800;
|
||||||
|
|
||||||
INIT_LLIST_HEAD(&bts->agch_queue.queue);
|
INIT_LLIST_HEAD(&bts->agch_queue.queue);
|
||||||
bts->agch_queue.length = 0;
|
bts->agch_queue.length = 0;
|
||||||
|
|
||||||
bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
|
bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
|
||||||
if (!bts->ctrs) {
|
if (!bts->ctrs)
|
||||||
llist_del(&bts->list);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
/* enable management with default levels,
|
/* enable management with default levels,
|
||||||
* raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
|
* raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
|
||||||
@@ -338,58 +343,67 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
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;
|
bts->rtp_priority = -1;
|
||||||
|
bts->emit_hr_rfc5993 = true;
|
||||||
|
|
||||||
/* Default (fall-back) MS/BS Power control parameters */
|
/* Default (fall-back) MS/BS Power control parameters */
|
||||||
power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
|
power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
|
||||||
power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
|
power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
|
||||||
|
|
||||||
/* configurable via OML */
|
/* configurable via OML */
|
||||||
|
bts->bsic = 0xff; /* invalid value, guarded by bsc_configured=false */
|
||||||
|
bts->bsic_configured = false;
|
||||||
bts->load.ccch.load_ind_period = 112;
|
bts->load.ccch.load_ind_period = 112;
|
||||||
bts->rtp_jitter_buf_ms = 100;
|
bts->rtp_jitter_buf_ms = 100;
|
||||||
bts->max_ta = 63;
|
bts->max_ta = MAX_TA_DEF;
|
||||||
bts->ny1 = 4;
|
bts->ny1 = 4;
|
||||||
|
bts->ny2 = 4;
|
||||||
bts->t3105_ms = 300;
|
bts->t3105_ms = 300;
|
||||||
|
bts->t3115_ms = 300;
|
||||||
bts->min_qual_rach = MIN_QUAL_RACH;
|
bts->min_qual_rach = MIN_QUAL_RACH;
|
||||||
bts->min_qual_norm = MIN_QUAL_NORM;
|
bts->min_qual_norm = MIN_QUAL_NORM;
|
||||||
bts->max_ber10k_rach = 1707; /* 7 of 41 bits is Eb/N0 of 0 dB = 0.1707 */
|
bts->max_ber10k_rach = 1707; /* 7 of 41 bits is Eb/N0 of 0 dB = 0.1707 */
|
||||||
bts->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT);
|
bts->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT);
|
||||||
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++)
|
bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT;
|
||||||
bts->t200_ms[i] = oml_default_t200_ms[i];
|
for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++)
|
||||||
|
bts->t200_fn[i] = oml_default_t200_fn[i];
|
||||||
|
|
||||||
/* default RADIO_LINK_TIMEOUT */
|
/* default RADIO_LINK_TIMEOUT */
|
||||||
bts->radio_link_timeout.oml = 32;
|
bts->radio_link_timeout.oml = 32;
|
||||||
bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
|
bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
|
||||||
|
|
||||||
/* Start with the site manager */
|
/* Start with the BTS */
|
||||||
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);
|
oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
/* set BTS attr to dependency */
|
|
||||||
oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
|
|
||||||
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, 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[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 */
|
||||||
|
rc = bts_osmux_init(bts);
|
||||||
|
if (rc < 0)
|
||||||
|
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_ETWS_PN);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_DYN_TS_SDCCH8);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS001);
|
||||||
|
|
||||||
|
/* Maximum TA supported by the PHY (can be overridden by PHY specific code) */
|
||||||
|
bts->support.max_ta = MAX_TA_DEF;
|
||||||
|
|
||||||
rc = bts_model_init(bts);
|
rc = bts_model_init(bts);
|
||||||
if (rc < 0) {
|
if (rc < 0)
|
||||||
llist_del(&bts->list);
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
|
|
||||||
/* 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_model_trx_init(bts->c0);
|
bts_model_trx_init(bts->c0);
|
||||||
bts_gsmnet.num_bts++;
|
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
|
osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
|
||||||
@@ -406,6 +420,9 @@ 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;
|
||||||
|
|
||||||
|
bts->asci.pos_nch = -ENOTSUP;
|
||||||
|
INIT_LLIST_HEAD(&bts->asci.notifications);
|
||||||
|
|
||||||
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
|
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
|
||||||
|
|
||||||
/* register DTX DL FSM */
|
/* register DTX DL FSM */
|
||||||
@@ -423,33 +440,13 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
/* 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;
|
LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status\n");
|
||||||
|
|
||||||
LOGP(DSUM, LOGL_INFO, "Main link established, sending NM Status.\n");
|
/* Signal OML UP to BTS SITE MGR. It will automatically SW_ACT repoort
|
||||||
|
* and become Disabled-Offline, then dispatch same event to its children
|
||||||
/* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
|
* objects.
|
||||||
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL);
|
*/
|
||||||
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL);
|
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_UP, NULL);
|
||||||
|
|
||||||
/* those should all be in DEPENDENCY */
|
|
||||||
oml_tx_state_changed(&bts->gprs.nse.mo);
|
|
||||||
oml_tx_state_changed(&bts->gprs.cell.mo);
|
|
||||||
oml_tx_state_changed(&bts->gprs.nsvc[0].mo);
|
|
||||||
oml_tx_state_changed(&bts->gprs.nsvc[1].mo);
|
|
||||||
|
|
||||||
/* All other objects start off-line until the BTS Model code says otherwise */
|
|
||||||
for (i = 0; i < bts->num_trx; i++) {
|
|
||||||
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i);
|
|
||||||
|
|
||||||
oml_tx_state_changed(&trx->mo);
|
|
||||||
oml_tx_state_changed(&trx->bb_transc.mo);
|
|
||||||
|
|
||||||
for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
|
|
||||||
struct gsm_bts_trx_ts *ts = &trx->ts[j];
|
|
||||||
|
|
||||||
oml_tx_state_changed(&ts->mo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bts_model_oml_estab(bts);
|
return bts_model_oml_estab(bts);
|
||||||
}
|
}
|
||||||
@@ -648,7 +645,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),
|
||||||
@@ -676,7 +673,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
|
static struct msgb *bts_agch_dequeue(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
struct msgb *msg = msgb_dequeue(&bts->agch_queue.queue);
|
struct msgb *msg = msgb_dequeue(&bts->agch_queue.queue);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
@@ -742,12 +739,12 @@ static void compact_agch_queue(struct gsm_bts *bts)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
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, enum ccch_msgt ccch)
|
||||||
int is_ag_res)
|
|
||||||
{
|
{
|
||||||
struct msgb *msg = NULL;
|
struct msgb *msg = NULL;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int is_empty = 1;
|
int is_empty = 1;
|
||||||
|
const struct bts_agch_msg_cb *msg_cb;
|
||||||
|
|
||||||
/* Do queue house keeping.
|
/* Do queue house keeping.
|
||||||
* This needs to be done every time a CCCH message is requested, since
|
* This needs to be done every time a CCCH message is requested, since
|
||||||
@@ -756,26 +753,39 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt
|
|||||||
*/
|
*/
|
||||||
compact_agch_queue(bts);
|
compact_agch_queue(bts);
|
||||||
|
|
||||||
/* Check for paging messages first if this is PCH */
|
switch (ccch) {
|
||||||
if (!is_ag_res)
|
case CCCH_MSGT_NCH:
|
||||||
|
/* Send NCH message, it has priority over AGCH and does not overlap with PCH. */
|
||||||
|
rc = bts_asci_notify_nch_gen_msg(bts, out_buf);
|
||||||
|
return rc;
|
||||||
|
case CCCH_MSGT_PCH:
|
||||||
|
/* Check whether the block may be overwritten by AGCH. */
|
||||||
rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty);
|
rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty);
|
||||||
|
|
||||||
/* Check whether the block may be overwritten */
|
|
||||||
if (!is_empty)
|
if (!is_empty)
|
||||||
return rc;
|
return rc;
|
||||||
|
/* fall-through */
|
||||||
|
case CCCH_MSGT_AGCH:
|
||||||
|
/* If fallen here and the AGCH queue is empty, return empty PCH message. */
|
||||||
msg = bts_agch_dequeue(bts);
|
msg = bts_agch_dequeue(bts);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return rc;
|
return rc;
|
||||||
|
/* Continue to return AGCH message. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_SENT);
|
rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_SENT);
|
||||||
|
|
||||||
|
/* Confirm sending of the AGCH message towards the PCU */
|
||||||
|
msg_cb = (struct bts_agch_msg_cb *) msg->cb;
|
||||||
|
if (msg_cb->confirm)
|
||||||
|
pcu_tx_data_cnf(msg_cb->msg_id, PCU_IF_SAPI_AGCH_2);
|
||||||
|
|
||||||
/* Copy AGCH message */
|
/* Copy AGCH message */
|
||||||
memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
|
memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
|
||||||
rc = msgb_l3len(msg);
|
rc = msgb_l3len(msg);
|
||||||
msgb_free(msg);
|
msgb_free(msg);
|
||||||
|
|
||||||
if (is_ag_res)
|
if (ccch == CCCH_MSGT_AGCH)
|
||||||
bts->agch_queue.agch_msgs++;
|
bts->agch_queue.agch_msgs++;
|
||||||
else
|
else
|
||||||
bts->agch_queue.pch_msgs++;
|
bts->agch_queue.pch_msgs++;
|
||||||
@@ -803,30 +813,35 @@ struct gsm_time *get_time(struct gsm_bts *bts)
|
|||||||
return &bts->gsm_time;
|
return &bts->gsm_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bts_supports_cm(const struct gsm_bts *bts,
|
bool bts_supports_cm_speech(const struct gsm_bts *bts,
|
||||||
const struct rsl_ie_chan_mode *cm)
|
const struct rsl_ie_chan_mode *cm)
|
||||||
{
|
{
|
||||||
enum osmo_bts_features feature = _NUM_BTS_FEAT;
|
enum osmo_bts_features feature = _NUM_BTS_FEAT;
|
||||||
|
|
||||||
switch (cm->spd_ind) {
|
/* Stage 1: check support for the requested channel type */
|
||||||
case RSL_CMOD_SPD_SIGN:
|
switch (cm->chan_rt) {
|
||||||
/* We assume that signalling support is mandatory,
|
case RSL_CMOD_CRT_TCH_GROUP_Bm:
|
||||||
* there is no BTS_FEAT_* definition to check that. */
|
case RSL_CMOD_CRT_TCH_GROUP_Lm:
|
||||||
return 1;
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VGCS))
|
||||||
case RSL_CMOD_SPD_SPEECH:
|
return false;
|
||||||
|
break;
|
||||||
|
case RSL_CMOD_CRT_TCH_BCAST_Bm:
|
||||||
|
case RSL_CMOD_CRT_TCH_BCAST_Lm:
|
||||||
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VBS))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
|
||||||
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
|
||||||
|
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
||||||
|
return false;
|
||||||
break;
|
break;
|
||||||
case RSL_CMOD_SPD_DATA:
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before the requested pchan/cm combination can be checked, we need to
|
/* Stage 2: check support for the requested codec */
|
||||||
* convert it to a feature identifier we can check */
|
|
||||||
switch (cm->chan_rt) {
|
switch (cm->chan_rt) {
|
||||||
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
|
||||||
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
case RSL_CMOD_CRT_TCH_GROUP_Bm:
|
||||||
return 0;
|
case RSL_CMOD_CRT_TCH_BCAST_Bm:
|
||||||
/* fall-through */
|
|
||||||
case RSL_CMOD_CRT_TCH_Bm:
|
case RSL_CMOD_CRT_TCH_Bm:
|
||||||
switch (cm->chan_rate) {
|
switch (cm->chan_rate) {
|
||||||
case RSL_CMOD_SP_GSM1:
|
case RSL_CMOD_SP_GSM1:
|
||||||
@@ -840,14 +855,13 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Invalid speech codec type => Not supported! */
|
/* Invalid speech codec type => Not supported! */
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
|
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
|
||||||
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
case RSL_CMOD_CRT_TCH_GROUP_Lm:
|
||||||
return 0;
|
case RSL_CMOD_CRT_TCH_BCAST_Lm:
|
||||||
/* fall-through */
|
|
||||||
case RSL_CMOD_CRT_TCH_Lm:
|
case RSL_CMOD_CRT_TCH_Lm:
|
||||||
switch (cm->chan_rate) {
|
switch (cm->chan_rate) {
|
||||||
case RSL_CMOD_SP_GSM1:
|
case RSL_CMOD_SP_GSM1:
|
||||||
@@ -858,7 +872,7 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Invalid speech codec type => Not supported! */
|
/* Invalid speech codec type => Not supported! */
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -866,35 +880,81 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
|||||||
LOGP(DRSL, LOGL_ERROR,
|
LOGP(DRSL, LOGL_ERROR,
|
||||||
"Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
|
"Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
|
||||||
cm->chan_rt, cm->chan_rate);
|
cm->chan_rt, cm->chan_rate);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the feature is supported by this BTS */
|
/* Check if the feature is supported by this BTS */
|
||||||
if (osmo_bts_has_feature(bts->features, feature))
|
if (osmo_bts_has_feature(bts->features, feature))
|
||||||
return 1;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool bts_supports_cm_data(const struct gsm_bts *bts,
|
||||||
|
const struct rsl_ie_chan_mode *cm)
|
||||||
|
{
|
||||||
|
switch (bts->variant) {
|
||||||
|
case BTS_OSMO_TRX:
|
||||||
|
switch (cm->chan_rate) {
|
||||||
|
/* TODO: RSL_CMOD_CSD_NT_14k5 */
|
||||||
|
/* TODO: RSL_CMOD_CSD_T_14k4 */
|
||||||
|
case RSL_CMOD_CSD_NT_12k0:
|
||||||
|
case RSL_CMOD_CSD_T_9k6:
|
||||||
|
if (cm->chan_rt != RSL_CMOD_CRT_TCH_Bm)
|
||||||
|
return false; /* invalid */
|
||||||
|
/* fall-through */
|
||||||
|
case RSL_CMOD_CSD_NT_6k0:
|
||||||
|
case RSL_CMOD_CSD_T_4k8:
|
||||||
|
case RSL_CMOD_CSD_T_2k4:
|
||||||
|
case RSL_CMOD_CSD_T_1k2:
|
||||||
|
case RSL_CMOD_CSD_T_600:
|
||||||
|
case RSL_CMOD_CSD_T_1200_75:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bts_supports_cm(const struct gsm_bts *bts,
|
||||||
|
const struct rsl_ie_chan_mode *cm)
|
||||||
|
{
|
||||||
|
switch (cm->spd_ind) {
|
||||||
|
case RSL_CMOD_SPD_SIGN:
|
||||||
|
/* We assume that signalling support is mandatory,
|
||||||
|
* there is no BTS_FEAT_* definition to check that. */
|
||||||
|
return true;
|
||||||
|
case RSL_CMOD_SPD_SPEECH:
|
||||||
|
return bts_supports_cm_speech(bts, cm);
|
||||||
|
case RSL_CMOD_SPD_DATA:
|
||||||
|
return bts_supports_cm_data(bts, cm);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* return the gsm_lchan for the CBCH (if it exists at all) */
|
/* 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 *gsm_bts_get_cbch(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
struct gsm_lchan *lchan = NULL;
|
|
||||||
struct gsm_bts_trx *trx = bts->c0;
|
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)
|
if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH)
|
||||||
lchan = &trx->ts[0].lchan[2];
|
return &trx->ts[0].lchan[2]; /* C0/TS0 */
|
||||||
else {
|
|
||||||
int i;
|
llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */
|
||||||
for (i = 0; i < 8; i++) {
|
unsigned int tn;
|
||||||
if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) {
|
for (tn = 0; tn <= 3; tn++) { /* TS0..3 */
|
||||||
lchan = &trx->ts[i].lchan[2];
|
struct gsm_bts_trx_ts *ts = &trx->ts[tn];
|
||||||
break;
|
if (ts->pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH)
|
||||||
}
|
return &ts->lchan[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lchan;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BCCH carrier power reduction (see 3GPP TS 45.008, section 7.1) */
|
/* BCCH carrier power reduction (see 3GPP TS 45.008, section 7.1) */
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -84,12 +84,45 @@ static int set_oml_alert(struct ctrl_cmd *cmd, void *data)
|
|||||||
return CTRL_CMD_REPLY;
|
return CTRL_CMD_REPLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int verify_max_ber10k_rach(struct ctrl_cmd *cmd, const char *value, void *_data)
|
||||||
|
{
|
||||||
|
int max_ber10k_rach = atoi(cmd->value);
|
||||||
|
|
||||||
|
if (max_ber10k_rach < 0 || max_ber10k_rach > 10000) {
|
||||||
|
cmd->reply = "Value is out of range";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
cmd->reply = talloc_asprintf(cmd, "%u", g_bts->max_ber10k_rach);
|
||||||
|
if (!cmd->reply) {
|
||||||
|
cmd->reply = "OOM";
|
||||||
|
return CTRL_CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_max_ber10k_rach(struct ctrl_cmd *cmd, void *data)
|
||||||
|
{
|
||||||
|
g_bts->max_ber10k_rach = atoi(cmd->value);
|
||||||
|
cmd->reply = "OK";
|
||||||
|
return CTRL_CMD_REPLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CTRL_CMD_DEFINE(max_ber10k_rach, "max-ber10k-rach");
|
||||||
|
|
||||||
int bts_ctrl_cmds_install(struct gsm_bts *bts)
|
int bts_ctrl_cmds_install(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att);
|
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att);
|
||||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert);
|
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert);
|
||||||
|
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_max_ber10k_rach);
|
||||||
g_bts = bts;
|
g_bts = bts;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -88,14 +88,12 @@ err_index:
|
|||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port)
|
||||||
const char *bind_addr, uint16_t port)
|
|
||||||
{
|
{
|
||||||
struct ctrl_handle *hdl;
|
struct ctrl_handle *hdl;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
|
hdl = ctrl_interface_setup(bts, port, bts_ctrl_node_lookup);
|
||||||
bts_ctrl_node_lookup);
|
|
||||||
if (!hdl)
|
if (!hdl)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* BTS shutdown FSM */
|
/* BTS shutdown FSM */
|
||||||
|
|
||||||
/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
* Author: Pau Espin Pedrol <pespin@sysmocom.de>
|
||||||
*
|
*
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <osmo-bts/gsm_data.h>
|
#include <osmo-bts/gsm_data.h>
|
||||||
#include <osmo-bts/bts_model.h>
|
#include <osmo-bts/bts_model.h>
|
||||||
#include <osmo-bts/bts.h>
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/bts_sm.h>
|
||||||
#include <osmo-bts/nm_common_fsm.h>
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
|
||||||
#define X(s) (1 << (s))
|
#define X(s) (1 << (s))
|
||||||
@@ -60,7 +61,7 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
|||||||
switch(event) {
|
switch(event) {
|
||||||
case BTS_SHUTDOWN_EV_START:
|
case BTS_SHUTDOWN_EV_START:
|
||||||
/* Firt announce to NM objects that we are starting a shutdown procedure: */
|
/* 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);
|
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL);
|
||||||
|
|
||||||
count = count_trx_operational(bts);
|
count = count_trx_operational(bts);
|
||||||
if (count) {
|
if (count) {
|
||||||
@@ -89,6 +90,9 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t
|
|||||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||||
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
||||||
continue;
|
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);
|
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +165,7 @@ static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
|||||||
{
|
{
|
||||||
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||||
|
|
||||||
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
|
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_FINISH, NULL);
|
||||||
|
|
||||||
if (bts->shutdown_fi_exit_proc) {
|
if (bts->shutdown_fi_exit_proc) {
|
||||||
LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n");
|
LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n");
|
||||||
@@ -250,7 +254,7 @@ bool bts_shutdown_in_progress(const struct gsm_bts *bts)
|
|||||||
return fi->state != BTS_SHUTDOWN_ST_NONE;
|
return fi->state != BTS_SHUTDOWN_ST_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
|
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;
|
struct osmo_fsm_inst *fi = bts->shutdown_fi;
|
||||||
if (bts_shutdown_in_progress(bts)) {
|
if (bts_shutdown_in_progress(bts)) {
|
||||||
@@ -260,6 +264,7 @@ void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bts->shutdown_fi_exit_proc = exit_proc;
|
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",
|
LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n",
|
||||||
exit_proc, reason);
|
exit_proc, reason);
|
||||||
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
|
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
|
||||||
@@ -267,7 +272,7 @@ void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc)
|
|||||||
|
|
||||||
void bts_shutdown(struct gsm_bts *bts, const char *reason)
|
void bts_shutdown(struct gsm_bts *bts, const char *reason)
|
||||||
{
|
{
|
||||||
bts_shutdown_ext(bts, reason, true);
|
bts_shutdown_ext(bts, reason, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc)
|
void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc)
|
||||||
|
|||||||
95
src/common/bts_sm.c
Normal file
95
src/common/bts_sm.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* BTS support code common to all supported BTS models */
|
||||||
|
|
||||||
|
/* (C) 2023 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/talloc.h>
|
||||||
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
#include <osmocom/core/fsm.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/bts_sm.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/nm_common_fsm.h>
|
||||||
|
|
||||||
|
struct gsm_bts_sm *g_bts_sm;
|
||||||
|
|
||||||
|
static const uint8_t nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 };
|
||||||
|
|
||||||
|
struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse)
|
||||||
|
{
|
||||||
|
return gsm_bts_num(g_bts_sm, nse->mo.obj_inst.bts_nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int gsm_bts_sm_talloc_destructor(struct gsm_bts_sm *bts_sm)
|
||||||
|
{
|
||||||
|
struct gsm_bts *bts;
|
||||||
|
|
||||||
|
while ((bts = llist_first_entry_or_null(&bts_sm->bts_list, struct gsm_bts, list)))
|
||||||
|
talloc_free(bts);
|
||||||
|
|
||||||
|
if (bts_sm->mo.fi) {
|
||||||
|
osmo_fsm_inst_free(bts_sm->mo.fi);
|
||||||
|
bts_sm->mo.fi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx)
|
||||||
|
{
|
||||||
|
struct gsm_bts_sm *bts_sm = talloc_zero(talloc_ctx, struct gsm_bts_sm);
|
||||||
|
struct gsm_gprs_nse *nse = &bts_sm->gprs.nse;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (!bts_sm)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
talloc_set_destructor(bts_sm, gsm_bts_sm_talloc_destructor);
|
||||||
|
|
||||||
|
INIT_LLIST_HEAD(&bts_sm->bts_list);
|
||||||
|
|
||||||
|
/* NM SITE_MGR */
|
||||||
|
bts_sm->mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts_sm, bts_sm,
|
||||||
|
LOGL_INFO, "bts_sm");
|
||||||
|
gsm_mo_init(&bts_sm->mo, NULL, NM_OC_SITE_MANAGER,
|
||||||
|
0xff, 0xff, 0xff);
|
||||||
|
oml_mo_state_init(&bts_sm->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
|
||||||
|
/* NM GPRS NSE */
|
||||||
|
nse->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nse_fsm, bts_sm, nse,
|
||||||
|
LOGL_INFO, "gprs_nse0");
|
||||||
|
gsm_mo_init(&nse->mo, NULL, NM_OC_GPRS_NSE, 0, 0xff, 0xff);
|
||||||
|
oml_mo_state_init(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
memcpy(&nse->timer, nse_timer_default, sizeof(nse->timer));
|
||||||
|
|
||||||
|
/* NM GPRS NSVCs */
|
||||||
|
for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) {
|
||||||
|
struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i];
|
||||||
|
nsvc->nse = nse;
|
||||||
|
nsvc->id = i;
|
||||||
|
nsvc->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nsvc_fsm, bts_sm, nsvc,
|
||||||
|
LOGL_INFO, NULL);
|
||||||
|
osmo_fsm_inst_update_id_f(nsvc->mo.fi, "gprs_nsvc%d-%d",
|
||||||
|
nse->mo.obj_inst.bts_nr, i);
|
||||||
|
gsm_mo_init(&nsvc->mo, NULL, NM_OC_GPRS_NSVC, nse->mo.obj_inst.bts_nr, i, 0xff);
|
||||||
|
oml_mo_state_init(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bts_sm;
|
||||||
|
}
|
||||||
@@ -74,12 +74,17 @@ static void gsm_bts_trx_init_ts(struct gsm_bts_trx *trx)
|
|||||||
ts->trx = trx;
|
ts->trx = trx;
|
||||||
ts->nr = tn;
|
ts->nr = tn;
|
||||||
|
|
||||||
|
ts->tsc_oml_configured = false;
|
||||||
|
ts->tsc_rsl_configured = false;
|
||||||
|
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
|
||||||
|
|
||||||
ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts,
|
ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts,
|
||||||
LOGL_INFO, NULL);
|
LOGL_INFO, NULL);
|
||||||
osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
|
osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
|
||||||
trx->bb_transc.mo.fi->id, ts->nr);
|
trx->bb_transc.mo.fi->id, ts->nr);
|
||||||
gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
|
gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
|
||||||
trx->bts->nr, trx->nr, ts->nr);
|
trx->bts->nr, trx->nr, ts->nr);
|
||||||
|
oml_mo_state_init(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
|
||||||
gsm_bts_trx_ts_init_lchan(ts);
|
gsm_bts_trx_ts_init_lchan(ts);
|
||||||
}
|
}
|
||||||
@@ -99,6 +104,10 @@ void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx)
|
|||||||
ts->trx = trx;
|
ts->trx = trx;
|
||||||
ts->nr = tn;
|
ts->nr = tn;
|
||||||
|
|
||||||
|
ts->tsc_oml_configured = false;
|
||||||
|
ts->tsc_rsl_configured = false;
|
||||||
|
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
|
||||||
|
|
||||||
/* Link both primary and shadow */
|
/* Link both primary and shadow */
|
||||||
trx->ts[tn].vamos.peer = ts;
|
trx->ts[tn].vamos.peer = ts;
|
||||||
ts->vamos.peer = &trx->ts[tn];
|
ts->vamos.peer = &trx->ts[tn];
|
||||||
@@ -148,14 +157,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
|
|||||||
trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
|
trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
|
||||||
LOGL_INFO, NULL);
|
LOGL_INFO, NULL);
|
||||||
osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
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,
|
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, bts->nr, trx->nr, 0xff);
|
||||||
bts->nr, trx->nr, 0xff);
|
oml_mo_state_init(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
|
||||||
trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
|
trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
|
||||||
LOGL_INFO, NULL);
|
LOGL_INFO, NULL);
|
||||||
osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
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,
|
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, bts->nr, trx->nr, 0xff);
|
||||||
bts->nr, trx->nr, 0xff);
|
oml_mo_state_init(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||||
|
|
||||||
gsm_bts_trx_init_ts(trx);
|
gsm_bts_trx_init_ts(trx);
|
||||||
|
|
||||||
@@ -222,15 +231,18 @@ int trx_link_estab(struct gsm_bts_trx *trx)
|
|||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
LOGPTRX(trx, DSUM, LOGL_INFO, "RSL link up\n");
|
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->mo.fi, NM_EV_RSL_UP, NULL);
|
||||||
osmo_fsm_inst_dispatch(trx->bb_transc.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)
|
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
|
||||||
|
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
|
||||||
|
rc = rsl_tx_rf_res(trx);
|
||||||
|
if (rc < 0)
|
||||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
||||||
"Failed to establish RSL link (%d)", rc);
|
"Failed to establish RSL link (%d)", rc);
|
||||||
|
}
|
||||||
if (trx == trx->bts->c0)
|
if (trx == trx->bts->c0)
|
||||||
load_timer_start(trx->bts);
|
load_timer_start(trx->bts);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -139,12 +139,8 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t
|
|||||||
block_type->seq_nr = block_nr;
|
block_type->seq_nr = block_nr;
|
||||||
|
|
||||||
/* determine if this is the last block */
|
/* determine if this is the last block */
|
||||||
if (block_nr + 1 == msg->num_segs)
|
block_type->lb = (block_nr + 1 == msg->num_segs);
|
||||||
block_type->lb = 1;
|
if (block_type->lb) {
|
||||||
else
|
|
||||||
block_type->lb = 0;
|
|
||||||
|
|
||||||
if (block_nr == 4) {
|
|
||||||
if (msg != bts_ss->default_msg) {
|
if (msg != bts_ss->default_msg) {
|
||||||
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
||||||
chan_name, msg);
|
chan_name, msg);
|
||||||
@@ -198,7 +194,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 +229,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;
|
||||||
@@ -332,7 +328,10 @@ static void bts_smscb_state_reset(struct bts_smscb_state *bts_ss)
|
|||||||
}
|
}
|
||||||
bts_ss->queue_len = 0;
|
bts_ss->queue_len = 0;
|
||||||
rate_ctr_group_reset(bts_ss->ctrs);
|
rate_ctr_group_reset(bts_ss->ctrs);
|
||||||
TALLOC_FREE(bts_ss->cur_msg);
|
/* 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);
|
TALLOC_FREE(bts_ss->default_msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
188
src/common/csd_v110.c
Normal file
188
src/common/csd_v110.c
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||||
|
* Author: Vadim Yanitskiy <vyanitskiy@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 <stdint.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/bits.h>
|
||||||
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/gsm/gsm44021.h>
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||||
|
#include <osmocom/isdn/v110.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/csd_v110.h>
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
|
||||||
|
/* key is enum gsm48_chan_mode, so assuming a value in range 0..255 */
|
||||||
|
const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
|
||||||
|
#if 0
|
||||||
|
[GSM48_CMODE_DATA_14k5] = {
|
||||||
|
/* TCH/F14.4: 290 bits every 20 ms (14.5 kbit/s) */
|
||||||
|
.fr = { .num_blocks = 1, .num_bits = 290 },
|
||||||
|
},
|
||||||
|
#endif
|
||||||
|
[GSM48_CMODE_DATA_12k0] = {
|
||||||
|
/* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */
|
||||||
|
.fr = { .num_blocks = 4, .num_bits = 60 },
|
||||||
|
},
|
||||||
|
[GSM48_CMODE_DATA_6k0] = {
|
||||||
|
/* TCH/F4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */
|
||||||
|
.fr = { .num_blocks = 2, .num_bits = 60 },
|
||||||
|
/* TCH/H4.8: 4 * 60 bits every 40 ms (6.0 kbit/s) */
|
||||||
|
.hr = { .num_blocks = 4, .num_bits = 60 },
|
||||||
|
},
|
||||||
|
[GSM48_CMODE_DATA_3k6] = {
|
||||||
|
/* TCH/F2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */
|
||||||
|
.fr = { .num_blocks = 2, .num_bits = 36 },
|
||||||
|
/* TCH/H2.4: 4 * 36 bits every 40 ms (3.6 kbit/s) */
|
||||||
|
.hr = { .num_blocks = 4, .num_bits = 36 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */
|
||||||
|
static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = {
|
||||||
|
[LCHAN_CSD_M_T_600] = { 1, 0, 0 },
|
||||||
|
[LCHAN_CSD_M_T_1200] = { 0, 1, 0 },
|
||||||
|
[LCHAN_CSD_M_T_2400] = { 1, 1, 0 },
|
||||||
|
[LCHAN_CSD_M_T_4800] = { 0, 1, 1 },
|
||||||
|
[LCHAN_CSD_M_T_9600] = { 0, 1, 1 },
|
||||||
|
#if 0
|
||||||
|
[LCHAN_CSD_M_T_19200] = { 0, 1, 1 },
|
||||||
|
[LCHAN_CSD_M_T_38400] = { 0, 1, 1 },
|
||||||
|
[LCHAN_CSD_M_T_14400] = { 1, 0, 1 },
|
||||||
|
[LCHAN_CSD_M_T_28800] = { 1, 0, 1 },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
|
||||||
|
const uint8_t *data, size_t data_len)
|
||||||
|
{
|
||||||
|
const struct csd_v110_frame_desc *desc;
|
||||||
|
ubit_t ra_bits[80 * 4];
|
||||||
|
|
||||||
|
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||||
|
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
|
||||||
|
else
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
|
||||||
|
if (OSMO_UNLIKELY(desc->num_blocks == 0))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
/* handle empty/incomplete Uplink frames gracefully */
|
||||||
|
if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) {
|
||||||
|
/* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */
|
||||||
|
memset(&ra_bits[0], 0x01, sizeof(ra_bits));
|
||||||
|
for (unsigned int i = 0; i < desc->num_blocks; i++)
|
||||||
|
memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */
|
||||||
|
goto ra1_ra2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RA1'/RA1: convert from radio rate to an intermediate data rate */
|
||||||
|
for (unsigned int i = 0; i < desc->num_blocks; i++) {
|
||||||
|
struct osmo_v110_decoded_frame df;
|
||||||
|
|
||||||
|
/* convert a V.110 36-/60-bit frame to a V.110 80-bit frame */
|
||||||
|
if (desc->num_bits == 60)
|
||||||
|
osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
|
||||||
|
else /* desc->num_bits == 36 */
|
||||||
|
osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
|
||||||
|
|
||||||
|
/* E1 .. E3 must set by out-of-band knowledge */
|
||||||
|
if (lchan->csd_mode == LCHAN_CSD_M_NT) {
|
||||||
|
/* non-transparent: as per 3GPP TS 48.020, Table 7 */
|
||||||
|
df.e_bits[0] = 0; /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */
|
||||||
|
df.e_bits[1] = (i >> 1) & 0x01; /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */
|
||||||
|
df.e_bits[2] = (i >> 0) & 0x01; /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */
|
||||||
|
} else {
|
||||||
|
/* transparent: as per 3GPP TS 44.021, Figure 4 */
|
||||||
|
df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0]; /* E1 */
|
||||||
|
df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1]; /* E2 */
|
||||||
|
df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2]; /* E3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df);
|
||||||
|
}
|
||||||
|
|
||||||
|
ra1_ra2:
|
||||||
|
/* RA1/RA2: convert from an intermediate rate to 64 kbit/s */
|
||||||
|
if (desc->num_blocks == 4) {
|
||||||
|
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
|
||||||
|
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||||
|
rtp[i] = (0xff >> 2);
|
||||||
|
rtp[i] |= (ra_bits[j++] << 7);
|
||||||
|
rtp[i] |= (ra_bits[j++] << 6);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
|
||||||
|
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||||
|
rtp[i] = (0xff >> 1);
|
||||||
|
rtp[i] |= (ra_bits[i] << 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RFC4040_RTP_PLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||||
|
const uint8_t *rtp, size_t rtp_len)
|
||||||
|
{
|
||||||
|
const struct csd_v110_frame_desc *desc;
|
||||||
|
ubit_t ra_bits[80 * 4];
|
||||||
|
|
||||||
|
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||||
|
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
|
||||||
|
else
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
|
||||||
|
if (OSMO_UNLIKELY(desc->num_blocks == 0))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
if (OSMO_UNLIKELY(rtp_len != RFC4040_RTP_PLEN))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* RA1/RA2: convert from 64 kbit/s to an intermediate rate */
|
||||||
|
if (desc->num_blocks == 4) {
|
||||||
|
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
|
||||||
|
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||||
|
ra_bits[j++] = (rtp[i] >> 7);
|
||||||
|
ra_bits[j++] = (rtp[i] >> 6) & 0x01;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
|
||||||
|
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++)
|
||||||
|
ra_bits[i] = (rtp[i] >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RA1'/RA1: convert from an intermediate rate to radio rate */
|
||||||
|
for (unsigned int i = 0; i < desc->num_blocks; i++) {
|
||||||
|
struct osmo_v110_decoded_frame df;
|
||||||
|
|
||||||
|
/* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */
|
||||||
|
osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80);
|
||||||
|
if (desc->num_bits == 60)
|
||||||
|
osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
|
||||||
|
else /* desc->num_bits == 36 */
|
||||||
|
osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
|
||||||
|
}
|
||||||
|
|
||||||
|
return desc->num_blocks * desc->num_bits;
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|||||||
@@ -306,6 +306,29 @@ bool ts_is_pdch(const struct gsm_bts_trx_ts *ts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Apply ts->tsc based on what was configured coming from different sources.
|
||||||
|
* Priorities (preferred first, overrides ones afterward):
|
||||||
|
* 1- RSL OSMO_TSC IE
|
||||||
|
* 2- OML SetChannelAttr TSC IE
|
||||||
|
* 3- OML SetBtsAttr BSIC IE
|
||||||
|
*/
|
||||||
|
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts)
|
||||||
|
{
|
||||||
|
if (ts->tsc_rsl_configured) {
|
||||||
|
ts->tsc = ts->tsc_rsl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ts->tsc_oml_configured) {
|
||||||
|
ts->tsc = ts->tsc_oml;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ts->trx->bts->bsic_configured) {
|
||||||
|
ts->tsc = BTS_TSC(ts->trx->bts);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ts->tsc = 0xff; /* invalid value */
|
||||||
|
}
|
||||||
|
|
||||||
void gsm_ts_release(struct gsm_bts_trx_ts *ts)
|
void gsm_ts_release(struct gsm_bts_trx_ts *ts)
|
||||||
{
|
{
|
||||||
unsigned int ln;
|
unsigned int ln;
|
||||||
@@ -318,4 +341,8 @@ void gsm_ts_release(struct gsm_bts_trx_ts *ts)
|
|||||||
/* Make sure pchan_is is reset, since PCU act_req to release it will be
|
/* Make sure pchan_is is reset, since PCU act_req to release it will be
|
||||||
* ignored as the lchan will already be released. */
|
* ignored as the lchan will already be released. */
|
||||||
ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
|
ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE;
|
||||||
|
|
||||||
|
ts->tsc_oml_configured = false;
|
||||||
|
ts->tsc_rsl_configured = false;
|
||||||
|
ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -12,13 +12,15 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "btsconfig.h" /* for PACKAGE_VERSION */
|
||||||
|
|
||||||
#include <osmocom/core/logging.h>
|
#include <osmocom/core/logging.h>
|
||||||
|
|
||||||
#include <osmocom/trau/osmo_ortp.h>
|
#include <osmocom/trau/osmo_ortp.h>
|
||||||
@@ -31,6 +33,7 @@
|
|||||||
#include <osmo-bts/handover.h>
|
#include <osmo-bts/handover.h>
|
||||||
#include <osmo-bts/l1sap.h>
|
#include <osmo-bts/l1sap.h>
|
||||||
#include <osmo-bts/bts_model.h>
|
#include <osmo-bts/bts_model.h>
|
||||||
|
#include <osmo-bts/asci.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
static const struct value_string lchan_s_names[] = {
|
static const struct value_string lchan_s_names[] = {
|
||||||
@@ -54,41 +57,40 @@ const struct value_string lchan_ciph_state_names[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* prepare the per-SAPI T200 arrays for a given lchan */
|
/* 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)
|
static int t200_by_lchan(uint32_t *t200_fn_dcch, uint32_t *t200_fn_acch, struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
struct gsm_bts *bts = lchan->ts->trx->bts;
|
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) {
|
switch (lchan->type) {
|
||||||
case GSM_LCHAN_SDCCH:
|
case GSM_LCHAN_SDCCH:
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_SDCCH];
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_SDCCH_SAPI3];
|
||||||
|
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_SDCCH];
|
||||||
|
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_SDCCH];
|
||||||
break;
|
break;
|
||||||
case GSM_LCHAN_TCH_F:
|
case GSM_LCHAN_TCH_F:
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_F];
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_F];
|
||||||
|
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
|
||||||
|
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
|
||||||
break;
|
break;
|
||||||
case GSM_LCHAN_TCH_H:
|
case GSM_LCHAN_TCH_H:
|
||||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_H];
|
||||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_H];
|
||||||
|
t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0];
|
||||||
|
t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
|
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add time of two extra messages frames. */
|
||||||
|
if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
|
||||||
|
t200_fn_acch[DL_SAPI0] += 104 * 2;
|
||||||
|
t200_fn_acch[DL_SAPI3] += 104 * 2;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +132,7 @@ void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned
|
|||||||
|
|
||||||
INIT_LLIST_HEAD(&lchan->sapi_cmds);
|
INIT_LLIST_HEAD(&lchan->sapi_cmds);
|
||||||
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
|
INIT_LLIST_HEAD(&lchan->dl_tch_queue);
|
||||||
|
lchan->dl_tch_queue_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gsm_lchan_name_update(struct gsm_lchan *lchan)
|
void gsm_lchan_name_update(struct gsm_lchan *lchan)
|
||||||
@@ -148,17 +151,17 @@ void gsm_lchan_name_update(struct gsm_lchan *lchan)
|
|||||||
int lchan_init_lapdm(struct gsm_lchan *lchan)
|
int lchan_init_lapdm(struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
struct lapdm_channel *lc = &lchan->lapdm_ch;
|
struct lapdm_channel *lc = &lchan->lapdm_ch;
|
||||||
int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
|
uint32_t t200_fn_dcch[_NR_DL_SAPI], t200_fn_acch[_NR_DL_SAPI];
|
||||||
|
|
||||||
if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) {
|
if (t200_by_lchan(t200_fn_dcch, t200_fn_acch, lchan) == 0) {
|
||||||
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
|
LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG,
|
||||||
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
|
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in frames)\n",
|
||||||
t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
|
t200_fn_dcch[DL_SAPI0], t200_fn_dcch[DL_SAPI3],
|
||||||
t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
|
t200_fn_acch[DL_SAPI0], t200_fn_acch[DL_SAPI3]);
|
||||||
lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type,
|
lapdm_channel_init3(lc, LAPDM_MODE_BTS, NULL, NULL, lchan->type, gsm_lchan_name(lchan));
|
||||||
gsm_lchan_name(lchan));
|
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY | LAPDM_ENT_F_RTS);
|
||||||
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
|
|
||||||
lapdm_channel_set_l1(lc, NULL, lchan);
|
lapdm_channel_set_l1(lc, NULL, lchan);
|
||||||
|
lapdm_channel_set_t200_fn(lc, t200_fn_dcch, t200_fn_acch);
|
||||||
}
|
}
|
||||||
/* We still need to set Rx callback to receive RACH requests: */
|
/* We still need to set Rx callback to receive RACH requests: */
|
||||||
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
|
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
|
||||||
@@ -200,10 +203,12 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
|
|||||||
rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC);
|
rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC);
|
||||||
osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO,
|
osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO,
|
||||||
"Closing RTP socket on Channel Release ");
|
"Closing RTP socket on Channel Release ");
|
||||||
osmo_rtp_socket_free(lchan->abis_ip.rtp_socket);
|
lchan_rtp_socket_free(lchan);
|
||||||
lchan->abis_ip.rtp_socket = NULL;
|
} else if (lchan->abis_ip.osmux.use) {
|
||||||
msgb_queue_flush(&lchan->dl_tch_queue);
|
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
|
/* 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
|
* activated... Once we check for that, we can move this check at the
|
||||||
@@ -211,8 +216,11 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
|
|||||||
if (lchan->state == LCHAN_S_NONE)
|
if (lchan->state == LCHAN_S_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* release handover state */
|
/* release handover, listener and talker states */
|
||||||
handover_reset(lchan);
|
handover_reset(lchan);
|
||||||
|
vgcs_talker_reset(lchan, false);
|
||||||
|
vgcs_listener_reset(lchan);
|
||||||
|
vgcs_uplink_free_reset(lchan);
|
||||||
|
|
||||||
lchan->rel_act_kind = rel_kind;
|
lchan->rel_act_kind = rel_kind;
|
||||||
|
|
||||||
@@ -317,7 +325,7 @@ void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See Table 10.5.25 of GSM04.08 */
|
/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */
|
||||||
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||||
uint8_t ts_nr, uint8_t lchan_nr)
|
uint8_t ts_nr, uint8_t lchan_nr)
|
||||||
{
|
{
|
||||||
@@ -362,13 +370,13 @@ static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
|||||||
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
||||||
break;
|
break;
|
||||||
case GSM_PCHAN_NONE:
|
case GSM_PCHAN_NONE:
|
||||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
|
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
|
||||||
gsm_pchan_name(pchan));
|
ts_nr, lchan_nr, gsm_pchan_name(pchan));
|
||||||
cbits = 0x00;
|
cbits = 0x00; /* Reserved */
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
|
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
|
||||||
gsm_pchan_name(pchan), (int)pchan);
|
ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
|
||||||
OSMO_ASSERT(0);
|
OSMO_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -510,3 +518,148 @@ int lchan2ecu_codec(const struct gsm_lchan *lchan)
|
|||||||
return -1;
|
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) {
|
||||||
|
unsigned int excess = lchan->dl_tch_queue_len - limit;
|
||||||
|
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n", excess);
|
||||||
|
rate_ctr_add2(lchan->ts->trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_OVERFLOW, excess);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -84,17 +84,6 @@ static struct log_info_cat bts_log_info_cat[] = {
|
|||||||
.loglevel = LOGL_NOTICE,
|
.loglevel = LOGL_NOTICE,
|
||||||
.enabled = 1,
|
.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,
|
|
||||||
.enabled = 1,
|
|
||||||
},
|
|
||||||
[DPCU] = {
|
[DPCU] = {
|
||||||
.name = "DPCU",
|
.name = "DPCU",
|
||||||
.description = "PCU interface",
|
.description = "PCU interface",
|
||||||
@@ -116,15 +105,33 @@ 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,
|
||||||
},
|
},
|
||||||
[DSUM] = {
|
[DABIS] = {
|
||||||
.name = "DSUM",
|
.name = "DABIS",
|
||||||
.description = "DSUM",
|
.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,
|
||||||
},
|
},
|
||||||
|
[DOSMUX] = {
|
||||||
|
.name = "DOSMUX",
|
||||||
|
.description = "Osmux (Osmocom RTP multiplexing)",
|
||||||
|
.loglevel = LOGL_NOTICE,
|
||||||
|
.enabled = 1,
|
||||||
|
},
|
||||||
|
[DASCI] = {
|
||||||
|
.name = "DASCI",
|
||||||
|
.description = "ASCI (Advanced Speech Call Items: VGCS/VBS)",
|
||||||
|
.loglevel = LOGL_NOTICE,
|
||||||
|
.enabled = 1,
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int osmo_bts_filter_fn(const struct log_context *ctx, struct log_target *tgt)
|
static int osmo_bts_filter_fn(const struct log_context *ctx, struct log_target *tgt)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Affero General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
@@ -49,6 +49,7 @@
|
|||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
#include <osmo-bts/abis.h>
|
#include <osmo-bts/abis.h>
|
||||||
#include <osmo-bts/bts.h>
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/bts_sm.h>
|
||||||
#include <osmo-bts/vty.h>
|
#include <osmo-bts/vty.h>
|
||||||
#include <osmo-bts/l1sap.h>
|
#include <osmo-bts/l1sap.h>
|
||||||
#include <osmo-bts/bts_model.h>
|
#include <osmo-bts/bts_model.h>
|
||||||
@@ -233,7 +234,7 @@ static void signal_handler(int signum)
|
|||||||
oml_tx_failure_event_rep(&g_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(g_bts, "SIGINT");
|
bts_shutdown_ext(g_bts, "SIGINT", true, false);
|
||||||
}
|
}
|
||||||
quit++;
|
quit++;
|
||||||
break;
|
break;
|
||||||
@@ -257,25 +258,6 @@ static void signal_handler(int signum)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
@@ -303,13 +285,21 @@ int bts_main(int argc, char **argv)
|
|||||||
bts_vty_init(tall_bts_ctx);
|
bts_vty_init(tall_bts_ctx);
|
||||||
e1inp_vty_init();
|
e1inp_vty_init();
|
||||||
|
|
||||||
|
logging_vty_add_deprecated_subsys(tall_bts_ctx, "sum");
|
||||||
|
|
||||||
handle_options(argc, argv);
|
handle_options(argc, argv);
|
||||||
|
|
||||||
fprintf(stderr, "((*))\n |\n / \\ OsmoBTS\n");
|
fprintf(stderr, "((*))\n |\n / \\ OsmoBTS\n");
|
||||||
if (vty_test_mode)
|
if (vty_test_mode)
|
||||||
fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
|
fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
|
||||||
|
|
||||||
g_bts = gsm_bts_alloc(tall_bts_ctx, 0);
|
g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx);
|
||||||
|
if (!g_bts_sm) {
|
||||||
|
fprintf(stderr, "Failed to create BTS Site Manager structure\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bts = gsm_bts_alloc(g_bts_sm, 0);
|
||||||
if (!g_bts) {
|
if (!g_bts) {
|
||||||
fprintf(stderr, "Failed to create BTS structure\n");
|
fprintf(stderr, "Failed to create BTS structure\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -356,8 +346,6 @@ int bts_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_pid_file("osmo-bts");
|
|
||||||
|
|
||||||
/* Accept a GSMTAP host from VTY config, but a commandline option overrides that. */
|
/* Accept a GSMTAP host from VTY config, but a commandline option overrides that. */
|
||||||
if (gsmtap_ip != NULL) {
|
if (gsmtap_ip != NULL) {
|
||||||
if (g_bts->gsmtap.remote_host != NULL) {
|
if (g_bts->gsmtap.remote_host != NULL) {
|
||||||
@@ -373,27 +361,26 @@ int bts_main(int argc, char **argv)
|
|||||||
/* TODO: move this to gsm_bts_alloc() */
|
/* TODO: move this to gsm_bts_alloc() */
|
||||||
if (g_bts->gsmtap.remote_host != NULL) {
|
if (g_bts->gsmtap.remote_host != NULL) {
|
||||||
LOGP(DLGLOBAL, LOGL_NOTICE,
|
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||||
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
|
"Setting up GSMTAP Um forwarding '%s->'%s:%u'\n",
|
||||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||||
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
|
g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
|
||||||
GSMTAP_UDP_PORT, 1);
|
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
|
||||||
if (g_bts->gsmtap.inst == NULL) {
|
if (g_bts->gsmtap.inst == NULL) {
|
||||||
fprintf(stderr, "Failed during gsmtap_source_init()\n");
|
fprintf(stderr, "Failed during gsmtap_source_init2()\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
|
bts_controlif_setup(g_bts, OSMO_CTRL_PORT_BTS);
|
||||||
|
|
||||||
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
|
rc = telnet_init_default(tall_bts_ctx, NULL, g_vty_port_num);
|
||||||
g_vty_port_num);
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
fprintf(stderr, "Error initializing telnet\n");
|
fprintf(stderr, "Error initializing telnet\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcu_sock_init(g_bts->pcu.sock_path)) {
|
if (pcu_sock_init(g_bts->pcu.sock_path, g_bts->pcu.sock_wqueue_len_max)) {
|
||||||
fprintf(stderr, "PCU L1 socket failed\n");
|
fprintf(stderr, "PCU L1 socket failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -405,6 +392,11 @@ int bts_main(int argc, char **argv)
|
|||||||
signal(SIGUSR2, &signal_handler);
|
signal(SIGUSR2, &signal_handler);
|
||||||
osmo_init_ignore_signals();
|
osmo_init_ignore_signals();
|
||||||
|
|
||||||
|
if (bts_osmux_open(g_bts) < 0) {
|
||||||
|
fprintf(stderr, "Osmux setup failed\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (vty_test_mode) {
|
if (vty_test_mode) {
|
||||||
/* Just select-loop without connecting to the BSC, don't exit. This allows running tests on the VTY
|
/* Just select-loop without connecting to the BSC, don't exit. This allows running tests on the VTY
|
||||||
* telnet port. */
|
* telnet port. */
|
||||||
|
|||||||
@@ -16,10 +16,26 @@
|
|||||||
#include <osmo-bts/power_control.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_speech_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} */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint8_t ts45008_dtx_tchh_data_fn_map[104] = {
|
||||||
|
/* UL TCH/H(0): 52, 54, 56, 58, 60, 62, 65, 67, 69, 71 */
|
||||||
|
[52] = 1, /* block {52, 54, 56, 58, 60, 62} */
|
||||||
|
[60] = 1, /* block {60, 62, 65, 67, 69, 71} */
|
||||||
|
/* UL TCH/H(1): 70, 72, 74, 76, 79, 81, 83, 85, 87, 89 */
|
||||||
|
[70] = 1, /* block {70, 72, 74, 76, 79, 81} */
|
||||||
|
[79] = 1, /* block {79, 81, 83, 85, 87, 89} */
|
||||||
|
};
|
||||||
|
|
||||||
/* 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
|
||||||
@@ -31,22 +47,11 @@ static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
|
|||||||
static const struct bts_ul_meas measurement_dummy = {
|
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 ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
||||||
@@ -54,61 +59,59 @@ 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 implement the logic for both speech and data (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: /* TCH/F sign: DTX *is* permitted */
|
||||||
case GSM48_CMODE_SPEECH_V1:
|
case GSM48_CMODE_SPEECH_V1:
|
||||||
|
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||||
case GSM48_CMODE_SPEECH_EFR:
|
case GSM48_CMODE_SPEECH_EFR:
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
case GSM48_CMODE_SPEECH_V2_VAMOS:
|
||||||
return true;
|
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
|
||||||
if (ARRAY_CONTAINS(ts45008_83_tch_f, fn104))
|
* There is only one *complete* block in this subset starting at FN=52.
|
||||||
|
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
|
||||||
|
* contain only 50% of the useful bits (partial SID) and thus ~50% BER. */
|
||||||
|
if (fn104 == 52)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SPEECH_AMR:
|
case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
|
||||||
if (trx_sched_is_sacch_fn(lchan->ts, fn, true))
|
case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
|
||||||
return true;
|
/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
|
||||||
break;
|
* the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
|
||||||
case GSM48_CMODE_SIGN:
|
* have been received as FACCH/F frames at the corresponding frame positions. */
|
||||||
/* 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",
|
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||||
gsm_lchan_name(lchan), lchan->tch_mode);
|
return fn104 == 52;
|
||||||
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
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))
|
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||||
return true;
|
if (ts45008_dtx_tchh_speech_fn_map[fn104])
|
||||||
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;
|
return true;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SIGN:
|
case GSM48_CMODE_SIGN:
|
||||||
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
||||||
* SUB */
|
* SUB */
|
||||||
return true;
|
return true;
|
||||||
|
case GSM48_CMODE_DATA_6k0: /* TCH/H4.8 */
|
||||||
|
case GSM48_CMODE_DATA_3k6: /* TCH/H2.4 */
|
||||||
|
/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
|
||||||
|
* the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
|
||||||
|
* have been received as FACCH/H frames at the corresponding frame positions. */
|
||||||
default:
|
default:
|
||||||
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
|
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||||
gsm_lchan_name(lchan), lchan->tch_mode);
|
return ts45008_dtx_tchh_data_fn_map[fn104] == 1;
|
||||||
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -287,9 +290,8 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc == 1) {
|
if (rc == 1) {
|
||||||
DEBUGP(DMEAS,
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "meas period end fn_mod:%d, status:%d, pchan:%s\n", fn_mod,
|
||||||
"%s meas period end fn:%u, fn_mod:%i, status:%d, pchan:%s\n",
|
rc, gsm_pchan_name(pchan));
|
||||||
gsm_lchan_name(lchan), fn, fn_mod, rc, gsm_pchan_name(pchan));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -325,16 +327,15 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
|||||||
struct bts_ul_meas *dest;
|
struct bts_ul_meas *dest;
|
||||||
|
|
||||||
if (lchan->state != LCHAN_S_ACTIVE) {
|
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||||
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
|
||||||
"%s measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
|
"measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
|
||||||
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
|
gsm_lchans_name(lchan->state), lchan->meas.num_ul_meas, fn_mod);
|
||||||
lchan->meas.num_ul_meas, fn_mod);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
|
if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
|
||||||
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
|
||||||
"%s no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n",
|
"no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", lchan->meas.num_ul_meas,
|
||||||
gsm_lchan_name(lchan), lchan->meas.num_ul_meas, fn_mod);
|
fn_mod);
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,10 +347,10 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
|||||||
if (!ulm->is_sub)
|
if (!ulm->is_sub)
|
||||||
dest->is_sub = ts45008_83_is_sub(lchan, fn);
|
dest->is_sub = ts45008_83_is_sub(lchan, fn);
|
||||||
|
|
||||||
DEBUGPFN(DMEAS, fn, "%s adding measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, is_sub=%u, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG,
|
||||||
gsm_lchan_name(lchan), ulm->ber10k, ulm->ta_offs_256bits,
|
"adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
|
||||||
ulm->c_i, dest->is_sub, ulm->inv_rssi, lchan->meas.num_ul_meas,
|
dest->is_sub ? "SUB" : "FULL", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
||||||
fn_mod);
|
lchan->meas.num_ul_meas, fn_mod);
|
||||||
|
|
||||||
lchan->meas.last_fn = fn;
|
lchan->meas.last_fn = fn;
|
||||||
|
|
||||||
@@ -423,32 +424,50 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* In DTX a subset of blocks must always be transmitted
|
/* In DTX a subset of blocks must always be transmitted
|
||||||
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */
|
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX)
|
||||||
static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
|
* Return value N: (N < 0) -- at least N SUB frames expected;
|
||||||
|
* (N > 0) -- exactly N SUB frames expected;
|
||||||
|
* (N == 0) - unknown channel type/mode? */
|
||||||
|
static int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
|
||||||
{
|
{
|
||||||
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
|
enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
|
||||||
|
|
||||||
/* AMR is using a more elaborated model with a dymanic amount of
|
|
||||||
* DTX blocks so this function is not applicable to determine the
|
|
||||||
* amount of expected SUB Measurements when AMR is used */
|
|
||||||
OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR);
|
|
||||||
|
|
||||||
switch (pchan) {
|
switch (pchan) {
|
||||||
case GSM_PCHAN_TCH_F:
|
case GSM_PCHAN_TCH_F:
|
||||||
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||||
/* 1 block SACCH, 24 blocks TCH (see note 1) */
|
return 1 + 1; /* 1 x SACCH + 1 x FACCH */
|
||||||
return 25;
|
/* else: signalling or speech */
|
||||||
} else {
|
switch (lchan->tch_mode) {
|
||||||
/* 1 block SACCH, 2 blocks TCH */
|
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
|
||||||
return 3;
|
case GSM48_CMODE_SPEECH_V1: /* TCH/FS */
|
||||||
|
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||||
|
case GSM48_CMODE_SPEECH_EFR: /* TCH/EFS */
|
||||||
|
case GSM48_CMODE_SPEECH_V2_VAMOS:
|
||||||
|
return 1 + 1; /* 1 x SACCH + 1 x TCH */
|
||||||
|
case GSM48_CMODE_SPEECH_AMR: /* TCH/AFS */
|
||||||
|
case GSM48_CMODE_SPEECH_V3_VAMOS:
|
||||||
|
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WFS */
|
||||||
|
case GSM48_CMODE_SPEECH_V5: /* TCH/WFS */
|
||||||
|
case GSM48_CMODE_SPEECH_V5_VAMOS:
|
||||||
|
default:
|
||||||
|
return -1; /* at least 1 x SACCH + M x TCH (variable) */
|
||||||
}
|
}
|
||||||
case GSM_PCHAN_TCH_H:
|
case GSM_PCHAN_TCH_H:
|
||||||
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||||
/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
|
return 1 + 2; /* 1 x SACCH + 2 x FACCH */
|
||||||
return 13;
|
/* else: signalling or speech */
|
||||||
} else {
|
switch (lchan->tch_mode) {
|
||||||
/* 1 block SACCH, 4 blocks TCH */
|
case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
|
||||||
return 5;
|
return 1 + 12; /* 1 x SACCH + 12 x TCH */
|
||||||
|
case GSM48_CMODE_SPEECH_V1:
|
||||||
|
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||||
|
return 1 + 2; /* 1 x SACCH + 2 x TCH */
|
||||||
|
case GSM48_CMODE_SPEECH_AMR: /* TCH/AHS */
|
||||||
|
case GSM48_CMODE_SPEECH_V3_VAMOS:
|
||||||
|
case GSM48_CMODE_SPEECH_V4: /* O-TCH/WHS */
|
||||||
|
case GSM48_CMODE_SPEECH_V6: /* O-TCH/AHS */
|
||||||
|
default:
|
||||||
|
return -1; /* at least 1 x SACCH + M x TCH (variable) */
|
||||||
}
|
}
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C:
|
case GSM_PCHAN_SDCCH8_SACCH8C:
|
||||||
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
|
||||||
@@ -461,8 +480,6 @@ 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,
|
||||||
@@ -568,7 +585,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
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;
|
||||||
unsigned int num_meas_sub_subst = 0;
|
unsigned int num_meas_sub_subst = 0;
|
||||||
unsigned int num_meas_sub_expect;
|
int num_meas_sub_expect;
|
||||||
unsigned int num_ul_meas;
|
unsigned int num_ul_meas;
|
||||||
unsigned int num_ul_meas_actual = 0;
|
unsigned int num_ul_meas_actual = 0;
|
||||||
unsigned int num_ul_meas_subst = 0;
|
unsigned int num_ul_meas_subst = 0;
|
||||||
@@ -588,16 +605,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
* intentionally to save energy. It is not necessarly an error
|
* intentionally to save energy. It is not necessarly an error
|
||||||
* when we get less measurements as we expect. */
|
* when we get less measurements as we expect. */
|
||||||
num_ul_meas_expect = lchan_meas_num_expected(lchan);
|
num_ul_meas_expect = lchan_meas_num_expected(lchan);
|
||||||
|
|
||||||
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 {
|
|
||||||
/* When AMR is used, we expect at least one SUB frame, since
|
|
||||||
* the SACCH will always be SUB frame. There may occur more
|
|
||||||
* SUB frames but since DTX periods in AMR are dynamic, we
|
|
||||||
* 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;
|
||||||
@@ -631,24 +639,21 @@ 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->c_i;
|
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->c_i;
|
ci_full_sum += m->ci_cb;
|
||||||
|
|
||||||
num_ul_meas_actual++;
|
num_ul_meas_actual++;
|
||||||
} else {
|
} else {
|
||||||
m = &measurement_dummy;
|
m = &measurement_dummy;
|
||||||
|
|
||||||
/* For AMR the amount of SUB frames is defined by the
|
/* only if we know the exact number of SUB measurements */
|
||||||
* the occurrence of DTX periods, which are dynamically
|
if (num_meas_sub_expect >= 0) {
|
||||||
* negotiated in AMR, so we can not know if and how many
|
if (num_meas_sub < num_meas_sub_expect) {
|
||||||
* SUB frames are missing. */
|
|
||||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
|
||||||
if (num_meas_sub <= i) {
|
|
||||||
num_meas_sub_subst++;
|
num_meas_sub_subst++;
|
||||||
is_sub = true;
|
is_sub = true;
|
||||||
}
|
}
|
||||||
@@ -664,16 +669,6 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
|
||||||
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
|
|
||||||
"Received UL measurements contain %u SUB measurements, expected %u\n",
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, "
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, "
|
||||||
"from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst);
|
"from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst);
|
||||||
|
|
||||||
@@ -684,17 +679,24 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
* 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_expect < 0) {
|
||||||
if (num_meas_sub != num_meas_sub_expect) {
|
num_meas_sub_expect = -num_meas_sub_expect;
|
||||||
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
|
||||||
|
"Received UL measurements contain %u SUB measurements, expected at least %d\n",
|
||||||
|
num_meas_sub_actual, num_meas_sub_expect);
|
||||||
|
if (OSMO_UNLIKELY(num_meas_sub < num_meas_sub_expect)) {
|
||||||
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
||||||
"Incorrect number of SUB measurements detected! "
|
"Incorrect number of SUB measurements detected! "
|
||||||
"(%u vs exp %u)\n", num_meas_sub, num_meas_sub_expect);
|
"(%u vs exp >=%d)\n", num_meas_sub, num_meas_sub_expect);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (num_meas_sub < num_meas_sub_expect) {
|
LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG,
|
||||||
|
"Received UL measurements contain %u SUB measurements, expected %d\n",
|
||||||
|
num_meas_sub_actual, num_meas_sub_expect);
|
||||||
|
if (OSMO_UNLIKELY(num_meas_sub != num_meas_sub_expect)) {
|
||||||
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
LOGPLCHAN(lchan, DMEAS, LOGL_ERROR,
|
||||||
"Incorrect number of SUB measurements detected! "
|
"Incorrect number of SUB measurements detected! "
|
||||||
"(%u vs exp >=%u)\n", num_meas_sub, num_meas_sub_expect);
|
"(%u vs exp %d)\n", num_meas_sub, num_meas_sub_expect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,6 +935,8 @@ void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)
|
|||||||
uint8_t ms_ta;
|
uint8_t ms_ta;
|
||||||
int8_t ul_rssi;
|
int8_t ul_rssi;
|
||||||
int16_t ul_ci_cb;
|
int16_t ul_ci_cb;
|
||||||
|
uint8_t *l3;
|
||||||
|
unsigned int l3_len;
|
||||||
|
|
||||||
if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) {
|
if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) {
|
||||||
/* Some brilliant engineer decided that the ordering of
|
/* Some brilliant engineer decided that the ordering of
|
||||||
@@ -962,7 +966,9 @@ void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, ms_ta) : -1;
|
timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, ms_ta) : -1;
|
||||||
rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), timing_offset);
|
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 */
|
if (rc == 0) /* Count successful transmissions */
|
||||||
lchan->meas.res_nr++;
|
lchan->meas.res_nr++;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user