mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-06 15:13:26 +00:00
Compare commits
388 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7db79cc39a | ||
|
|
8d11671539 | ||
|
|
cb5b10e7b7 | ||
|
|
d9b456ce6d | ||
|
|
a9f3c01ece | ||
|
|
799ad7240b | ||
|
|
d4bb8d61e7 | ||
|
|
aa743cd97e | ||
|
|
65c497a69a | ||
|
|
b032208a4a | ||
|
|
c963f0b6eb | ||
|
|
a7b3a780ae | ||
|
|
62b37b32f9 | ||
|
|
c211b34955 | ||
|
|
88f03f8d1d | ||
|
|
c8946a077e | ||
|
|
8797837deb | ||
|
|
5bd8543a5f | ||
|
|
7b712121b8 | ||
|
|
f33e3c8378 | ||
|
|
ff4b83dc23 | ||
|
|
64d9f142ab | ||
|
|
4af496d44c | ||
|
|
6f9ccafde4 | ||
|
|
a928fce659 | ||
|
|
0a34af1530 | ||
|
|
02951e4af3 | ||
|
|
7accf7579d | ||
|
|
5bed286c6c | ||
|
|
414e1ca8ed | ||
|
|
c40e75277f | ||
|
|
59686cd276 | ||
|
|
82d500ccac | ||
|
|
aeb78dcc77 | ||
|
|
a880011a5f | ||
|
|
89415e7433 | ||
|
|
332976672e | ||
|
|
9512355ebc | ||
|
|
2d9643f2ce | ||
|
|
8c060ccc5f | ||
|
|
3750c36f40 | ||
|
|
2849b1e0f0 | ||
|
|
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 |
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)
|
||||||
|
|||||||
16
README.md
16
README.md
@@ -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
|
||||||
|
|||||||
11
TODO-RELEASE
11
TODO-RELEASE
@@ -1,2 +1,9 @@
|
|||||||
# 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://osmocom.org/projects/cellular-infrastructure/wiki/Make_a_new_release
|
||||||
|
# In short: https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
|
||||||
|
# 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:a.
|
||||||
|
# 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
|
||||||
|
|||||||
20
configure.ac
20
configure.ac
@@ -69,14 +69,15 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
dnl checks for libraries
|
dnl checks for libraries
|
||||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.7.0)
|
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.11.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 2.0.0)
|
||||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.3.0)
|
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 2.0.0)
|
||||||
|
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.6.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,
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -8,8 +8,8 @@ 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 libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# shellcheck source=contrib/jenkins_common.sh
|
# shellcheck source=contrib/jenkins_common.sh
|
||||||
. $(dirname "$0")/jenkins_common.sh
|
. $(dirname "$0")/jenkins_common.sh
|
||||||
|
|
||||||
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 libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# shellcheck source=contrib/jenkins_common.sh
|
# shellcheck source=contrib/jenkins_common.sh
|
||||||
. $(dirname "$0")/jenkins_common.sh
|
. $(dirname "$0")/jenkins_common.sh
|
||||||
|
|
||||||
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 libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# shellcheck source=contrib/jenkins_common.sh
|
# shellcheck source=contrib/jenkins_common.sh
|
||||||
. $(dirname "$0")/jenkins_common.sh
|
. $(dirname "$0")/jenkins_common.sh
|
||||||
|
|
||||||
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 libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
|
osmo-layer1-headers.sh oct "$FIRMWARE_VERSION"
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ 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 libosmocore "" --disable-doxygen
|
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
osmo-build-dep.sh libosmo-abis
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
cd "$deps"
|
cd "$deps"
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,12 @@
|
|||||||
# shellcheck source=contrib/jenkins_common.sh
|
# shellcheck source=contrib/jenkins_common.sh
|
||||||
. $(dirname "$0")/jenkins_common.sh
|
. $(dirname "$0")/jenkins_common.sh
|
||||||
|
|
||||||
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 libosmocore "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||||
|
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||||
|
|
||||||
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.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmocoding) >= 1.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmocore) >= 1.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmogsm) >= 1.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmovty) >= 1.7.0
|
|
||||||
BuildRequires: pkgconfig(libosmoabis) >= 1.3.0
|
|
||||||
BuildRequires: pkgconfig(libosmotrau) >= 1.3.0
|
|
||||||
### 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
|
||||||
|
|
||||||
|
|||||||
464
debian/changelog
vendored
464
debian/changelog
vendored
@@ -1,3 +1,467 @@
|
|||||||
|
osmo-bts (1.9.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Mychaela N. Falconia ]
|
||||||
|
* sysmo: generate empty TCH/H payload on FACCH/H Rx
|
||||||
|
* CSD: implement half-rate modes correctly
|
||||||
|
* csd_v110: set E2 bit correctly for TCH/[FH]4.8 NT
|
||||||
|
* CSD RTP: verify alignment of V.110 frames
|
||||||
|
* csd_v110_rtp_decode: preserve E2 & E3 bits for RLP alignment
|
||||||
|
* cosmetic: eliminate else-after-return in gsmtap_csd_rlp_process()
|
||||||
|
* cosmetic: move gsmtap_csd_rlp_process() to csd_rlp.c
|
||||||
|
* CSD NT modes: transmit properly aligned RLP frames on DL
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* tests/csd: add NT variants for TCH/F4.8 and TCH/F9.6
|
||||||
|
* l1sap: prevent buffer overflow in l1sap_rtp_rx_cb()
|
||||||
|
* l1sap: move struct osmo_rlp_frame_decoded to the if-scope
|
||||||
|
* rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode for NT CSD
|
||||||
|
* vty: lchan_dump_full_vty(): print CSD mode
|
||||||
|
* l1sap: make send_ul_rtp_packet_hrdata() NULL-safe
|
||||||
|
* osmo-bts-trx: fix scheduling of DL FACCH/H for TCH/H4.8 and TCH/H2.4
|
||||||
|
* l1sap: l1sap_tch_rts_ind(): fix NULL ptr dereference
|
||||||
|
* csd_v110: use osmo_csd_ra2_* API from libosmotrau
|
||||||
|
* csd_v110: add CSD_V110_NUM_BITS macro
|
||||||
|
* csd_v110: clarify field names in csd_v110_lchan_desc[]
|
||||||
|
* csd_v110: clarify lchan description for TCH/F14.4
|
||||||
|
* csd_v110: handle TCH/F14.4
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* jenkins.sh: libosmo-netif no longer depends on libosmo-abis
|
||||||
|
* bts-omldummy: Support configuring logging through cmdline
|
||||||
|
* bts-omldummy: print category names instead of hex values
|
||||||
|
* Fix missing quote char in log line
|
||||||
|
* abis: Log line and ts nr of signal
|
||||||
|
* abis: Fix reusing bts->*_link while it is being destroyed
|
||||||
|
* Drop use of libosmo-abis osmocom/abis/ipaccess.h
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* pcu_sock: do not receive a TXT ind. with PCU_VERSION for a specific BTS
|
||||||
|
|
||||||
|
-- Oliver Smith <osmith@sysmocom.de> Wed, 12 Feb 2025 12:56:09 +0100
|
||||||
|
|
||||||
|
osmo-bts (1.8.0) unstable; urgency=medium
|
||||||
|
|
||||||
|
[ Vadim Yanitskiy ]
|
||||||
|
* osmo-bts-{oc2g,lc15}: signal CBCH support to BSC
|
||||||
|
* oml: oml_tx_attr_resp(): pass *mo to handle_attrs_{bts,trx}()
|
||||||
|
* oml: refactor generation of Get Attribute Response
|
||||||
|
* oml: oml_tx_attr_resp(): handle common nm_state attributes
|
||||||
|
* oml: implement handling of NM_ATT_IPACC_SUPP_FEATURES
|
||||||
|
* l1sap: l1sap_tch_ind(): fix segfault on stale TCH.ind
|
||||||
|
* osmo-bts-trx: rx_tchh_fn(): fix copy-pasted comment
|
||||||
|
* meas: also match stderr logging for meas_test
|
||||||
|
* meas: lchan_meas_sub_num_expected(): proper cmode enforcement
|
||||||
|
* meas: lchan_meas_check_compute(): fix -SUB frame substitution
|
||||||
|
* meas: handle VAMOS specific chan modes
|
||||||
|
* meas: fix ts45008_83_is_sub(): DTX is permitted on TCH/F sign
|
||||||
|
* meas: ts45008_83_is_sub(): properly handle CSD modes
|
||||||
|
* meas: lchan_meas_sub_num_expected(): handle CSD modes
|
||||||
|
* osmo-bts-trx: tx_tch[fh]_fn(): use BUFPOS macro everywhere
|
||||||
|
* osmo-bts-trx: tx_tch[fh]_fn(): rework generation of dummy FACCH
|
||||||
|
* osmo-bts-trx: tx_tch[fh]_fn(): fix sending idle CSD frames
|
||||||
|
* osmo-bts-trx: add_sbits(): simplify, improve coding style
|
||||||
|
* osmo-bts-trx: use BPLEN macro instead of magic numbers
|
||||||
|
* osmo-bts-trx: eliminate ul_bursts_prev, use the primary buffer
|
||||||
|
* l1sap: fix logic error in gsmtap_csd_rlp_process()
|
||||||
|
* osmo-bts-trx: add test VTY command to send arbitrary TRXC messages
|
||||||
|
* doc/examples: fix missing config files in release tarballs
|
||||||
|
* osmo-bts-{trx,virtual}: do not advertise TCH/F14.4 NT
|
||||||
|
* tests/osmo-bts.vty: aligh with recent libosmovty changes
|
||||||
|
* README.md: cosmetic: fix a typo
|
||||||
|
* doc/examples: use common 'ipa unit-id' in all files
|
||||||
|
* doc/examples: drop no-op 'gsmtap-sapi' lines
|
||||||
|
* doc/examples: osmo-bts-trx.cfg: set 'oml remote-ip' to '127.0.0.1'
|
||||||
|
|
||||||
|
[ Pau Espin Pedrol ]
|
||||||
|
* oml: Store RSL connect related fields in bb_transc
|
||||||
|
* Move trx->rsl_link to trx->bb_transc.rsl.link
|
||||||
|
* nm: delay RSL connect until BBTRANSC object is OPSTARTed
|
||||||
|
* cosmetic: oc2g_mgr: fix trailing whitespace
|
||||||
|
* Drop use of deprectated vty callback is_config_node
|
||||||
|
* Revert "trx_if: Allow calling trx_if_flush/close from within TRXC callback"
|
||||||
|
* trx_if: Allow calling trx_if_flush/close from within TRXC callback (v2)
|
||||||
|
|
||||||
|
[ Andreas Eversberg ]
|
||||||
|
* ASCI: Ignore LAPD frames from MS, while the uplink is not active
|
||||||
|
* Do not prefix UI header to System Information Type 10
|
||||||
|
* Increase RR scheduler priority to 20, to avoid dropped bursts
|
||||||
|
* ASCI: Add control of uplink access to osmo-bts-trx
|
||||||
|
* ASCI: Add control of uplink access to osmo-bts-sysmo
|
||||||
|
* ASCI: Enable voice group/broadcast call feature at osmo-bts-trx
|
||||||
|
* ASCI: Control uplink access bursts detection of physical interface
|
||||||
|
* ASCI: Add library requirements for uplink access to TODO-RELEASE
|
||||||
|
* Use uniform log format for default config files
|
||||||
|
* Transmit invalid AMR speech blocks instead of dummy FACCH
|
||||||
|
* LAPDm: Reject (release) establishment on DCCH, SAPI 0 without L3 payload
|
||||||
|
* Handle empty (idle) PDCH blocks gracefully
|
||||||
|
* Use polling based LAPDm with frame numbers
|
||||||
|
* OML: Add Get Attributes for supported MOs for BTS Object Class
|
||||||
|
* OML: Add Get Attributes for supported MOs for Radio Carrier Object Class
|
||||||
|
* OML: Add Get Attributes for supported MOs for Channel Object Class
|
||||||
|
* Fix ASCI access burst detection with osmo-bts-trx
|
||||||
|
|
||||||
|
[ Oliver Smith ]
|
||||||
|
* systemd: remove RestartPreventExitStatus=1
|
||||||
|
* contrib: remove rpm spec file
|
||||||
|
* contrib/systemd: run as osmocom user
|
||||||
|
|
||||||
|
[ Philipp Maier ]
|
||||||
|
* pcuif_proto: rename PCU_IF_FLAG_SYSMO to PCU_IF_FLAG_DIRECT_PHY
|
||||||
|
* pcuif_proto: clean up last remains of old PCUIF v10
|
||||||
|
* pcuif_proto: signal BTS model via PCUIF
|
||||||
|
|
||||||
|
[ Harald Welte ]
|
||||||
|
* Add GSMTAP encapsulation of RLP frames in CSD NT mode
|
||||||
|
* gsmtap-rlp: Add support for skipping generating NULL frames
|
||||||
|
* Fix license headers.
|
||||||
|
* sysmobts_mgr_temp: Migrate to ctrl_cmd_send2()
|
||||||
|
* osmo-bts-virtual: Port over to osmo_io
|
||||||
|
* common: Add RTP related rate counters
|
||||||
|
* Add funding link to github mirror
|
||||||
|
* README.md: Add Forum + Issue Tracker sections
|
||||||
|
|
||||||
|
[ Matan Perelman ]
|
||||||
|
* ctrl: Add max ber10k rach
|
||||||
|
|
||||||
|
[ Neels Hofmeyr ]
|
||||||
|
* early-IA: use the correct TRX
|
||||||
|
|
||||||
|
[ Keith ]
|
||||||
|
* vty info: MS power levels in dBm are not negative
|
||||||
|
|
||||||
|
[ Mychaela N. Falconia ]
|
||||||
|
* rsl.adoc: mention currently undocumented IEs
|
||||||
|
* rsl: parse RSL_IE_OSMO_OSMUX_CID correctly
|
||||||
|
* common: add support for TW-TS-001
|
||||||
|
|
||||||
|
-- Oliver Smith <osmith@sysmocom.de> Wed, 24 Jul 2024 16:40:02 +0200
|
||||||
|
|
||||||
|
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
|
osmo-bts (1.5.0) unstable; urgency=medium
|
||||||
|
|
||||||
[ Pau Espin Pedrol ]
|
[ Pau Espin Pedrol ]
|
||||||
|
|||||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
|||||||
9
|
10
|
||||||
|
|||||||
9
debian/control
vendored
9
debian/control
vendored
@@ -2,16 +2,17 @@ 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.7.0),
|
libosmocore-dev (>= 1.11.0),
|
||||||
libosmo-abis-dev (>= 1.3.0),
|
libosmo-abis-dev (>= 2.0.0),
|
||||||
|
libosmo-netif-dev (>= 1.6.0),
|
||||||
libgps-dev,
|
libgps-dev,
|
||||||
txt2man,
|
txt2man,
|
||||||
osmo-gsm-manuals-dev (>= 1.3.0)
|
osmo-gsm-manuals-dev (>= 1.6.0)
|
||||||
Standards-Version: 3.9.8
|
Standards-Version: 3.9.8
|
||||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts
|
||||||
|
|||||||
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
|
||||||
@@ -35,7 +39,7 @@ phy 1
|
|||||||
trx-calibration-path /mnt/rom/factory/calib
|
trx-calibration-path /mnt/rom/factory/calib
|
||||||
bts 0
|
bts 0
|
||||||
band 900
|
band 900
|
||||||
ipa unit-id 1500 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 192.168.234.185
|
oml remote-ip 192.168.234.185
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -32,7 +36,7 @@ phy 0
|
|||||||
trx-calibration-path /mnt/rom/factory/calib
|
trx-calibration-path /mnt/rom/factory/calib
|
||||||
bts 0
|
bts 0
|
||||||
band 900
|
band 900
|
||||||
ipa unit-id 1500 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 10.42.0.1
|
oml remote-ip 10.42.0.1
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -25,7 +29,7 @@ phy 0
|
|||||||
instance 0
|
instance 0
|
||||||
bts 0
|
bts 0
|
||||||
band 1800
|
band 1800
|
||||||
ipa unit-id 1234 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 127.0.0.1
|
oml remote-ip 127.0.0.1
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -26,7 +30,7 @@ phy 0
|
|||||||
instance 1
|
instance 1
|
||||||
bts 0
|
bts 0
|
||||||
band 1800
|
band 1800
|
||||||
ipa unit-id 1234 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 127.0.0.1
|
oml remote-ip 127.0.0.1
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -23,7 +27,7 @@ phy 0
|
|||||||
instance 0
|
instance 0
|
||||||
bts 0
|
bts 0
|
||||||
band 1800
|
band 1800
|
||||||
ipa unit-id 666 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 10.1.2.3
|
oml remote-ip 10.1.2.3
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -30,8 +34,6 @@ phy 0
|
|||||||
bts 0
|
bts 0
|
||||||
oml remote-ip 127.0.0.1
|
oml remote-ip 127.0.0.1
|
||||||
ipa unit-id 6969 0
|
ipa unit-id 6969 0
|
||||||
gsmtap-sapi pdtch
|
|
||||||
gsmtap-sapi ccch
|
|
||||||
band 900
|
band 900
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -26,8 +30,6 @@ phy 0
|
|||||||
bts 0
|
bts 0
|
||||||
band 1800
|
band 1800
|
||||||
ipa unit-id 6969 0
|
ipa unit-id 6969 0
|
||||||
oml remote-ip 192.168.122.1
|
oml remote-ip 127.0.0.1
|
||||||
gsmtap-sapi ccch
|
|
||||||
gsmtap-sapi pdtch
|
|
||||||
trx 0
|
trx 0
|
||||||
phy 0 instance 0
|
phy 0 instance 0
|
||||||
|
|||||||
@@ -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>>
|
||||||
|===
|
|===
|
||||||
|
|
||||||
@@ -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,8 @@ noinst_HEADERS = \
|
|||||||
tx_power.h \
|
tx_power.h \
|
||||||
control_if.h \
|
control_if.h \
|
||||||
cbch.h \
|
cbch.h \
|
||||||
|
csd_rlp.h \
|
||||||
|
csd_v110.h \
|
||||||
l1sap.h \
|
l1sap.h \
|
||||||
lchan.h \
|
lchan.h \
|
||||||
power_control.h \
|
power_control.h \
|
||||||
@@ -30,4 +35,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)
|
||||||
|
|||||||
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);
|
||||||
|
|
||||||
/* TODO: add a brief description of this flag */
|
enum bts_impl_flag {
|
||||||
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
|
/* TODO: add a brief description of this flag */
|
||||||
/* When this flag is set then the measurement data is included in
|
BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,
|
||||||
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
/* When this flag is set then the measurement data is included in
|
||||||
* measurement data is passed using a separate MPH INFO MEAS IND.
|
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
||||||
* (See also ticket: OS#2977) */
|
* measurement data is passed using a separate MPH INFO MEAS IND.
|
||||||
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
|
* (See also ticket: OS#2977) */
|
||||||
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,
|
||||||
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
||||||
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2)
|
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
||||||
/* Whether the BTS model reports interference measurements to L1SAP. */
|
BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER,
|
||||||
#define BTS_INTERNAL_FLAG_INTERF_MEAS (1 << 3)
|
/* Whether the BTS model reports interference measurements to L1SAP. */
|
||||||
|
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,8 +447,8 @@ 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/>.
|
||||||
|
|||||||
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;
|
||||||
@@ -27,8 +31,8 @@ struct gsm_bts_trx {
|
|||||||
uint16_t arfcn;
|
uint16_t arfcn;
|
||||||
int nominal_power; /* in dBm */
|
int nominal_power; /* in dBm */
|
||||||
unsigned int max_power_red; /* in actual dB */
|
unsigned int max_power_red; /* in actual dB */
|
||||||
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */
|
||||||
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
uint8_t c0_idle_power_red; /* in actual dB OC-2G only */
|
||||||
|
|
||||||
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
|
uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */
|
||||||
|
|
||||||
@@ -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);
|
|
||||||
|
|||||||
36
include/osmo-bts/csd_rlp.h
Normal file
36
include/osmo-bts/csd_rlp.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Declarations for functions in csd_rlp.c: alignment of downlink RLP frames
|
||||||
|
* and RLP GSMTAP mechanism for CSD NT modes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <osmocom/core/bits.h>
|
||||||
|
#include <osmocom/gsm/l1sap.h>
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
|
||||||
|
extern const uint8_t csd_tchf48_nt_e2_map[26];
|
||||||
|
|
||||||
|
/* Per TS 48.020 section 15.1, the cadence of E2+E3 bits in a properly
|
||||||
|
* aligned sequence of pseudo-V.110 frames forming a single RLP frame
|
||||||
|
* is 00-01-10-11. The following constant captures this bit sequence
|
||||||
|
* in hex, for comparison against align_bits output from
|
||||||
|
* csd_v110_rtp_decode() or against rlpdl_align_bits accumulator
|
||||||
|
* in CSD NT lchan state.
|
||||||
|
*/
|
||||||
|
#define NTCSD_ALIGNED_EBITS 0x1B
|
||||||
|
|
||||||
|
void ntcsd_dl_reset(struct gsm_lchan *lchan);
|
||||||
|
void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits,
|
||||||
|
uint8_t align_bits);
|
||||||
|
void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits,
|
||||||
|
uint8_t align_bits);
|
||||||
|
bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out);
|
||||||
|
|
||||||
|
void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink,
|
||||||
|
const struct ph_tch_param *tch_ind,
|
||||||
|
const ubit_t *data, unsigned int data_len);
|
||||||
|
void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn,
|
||||||
|
const ubit_t *data, unsigned int data_len);
|
||||||
24
include/osmo-bts/csd_v110.h
Normal file
24
include/osmo-bts/csd_v110.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/* RFC4040 "clearmode" RTP payload length */
|
||||||
|
#define RFC4040_RTP_PLEN 160
|
||||||
|
|
||||||
|
struct gsm_lchan;
|
||||||
|
|
||||||
|
struct csd_v110_lchan_desc {
|
||||||
|
uint16_t num_frames; /* number of V.110 frames in a radio block */
|
||||||
|
uint16_t num_frame_bits; /* number of bits in each V.110 frame */
|
||||||
|
uint16_t num_other_bits; /* number of other bits (e.g. M-bits for TCH/F14.4) */
|
||||||
|
uint8_t ra2_ir; /* intermediate rate (8 or 16 kbit/s) for RA2 step */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256];
|
||||||
|
|
||||||
|
#define CSD_V110_NUM_BITS(desc) \
|
||||||
|
((desc)->num_frames * (desc)->num_frame_bits + (desc)->num_other_bits)
|
||||||
|
|
||||||
|
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
|
||||||
|
const uint8_t *data, size_t data_len,
|
||||||
|
uint8_t nt48_half_num);
|
||||||
|
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||||
|
uint8_t *align_bits, 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
|
||||||
@@ -100,6 +102,7 @@ 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,14 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/bits.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 +17,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>
|
||||||
|
|
||||||
@@ -72,17 +76,25 @@ struct amr_multirate_conf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern const struct value_string lchan_csd_mode_descs[];
|
||||||
|
static inline const char *lchan_csd_mode_desc(enum lchan_csd_mode mode)
|
||||||
|
{
|
||||||
|
return get_value_string(lchan_csd_mode_descs, mode);
|
||||||
|
}
|
||||||
|
|
||||||
/* State of the SAPIs in the lchan */
|
/* State of the SAPIs in the lchan */
|
||||||
enum lchan_sapi_state {
|
enum lchan_sapi_state {
|
||||||
LCHAN_SAPI_S_NONE,
|
LCHAN_SAPI_S_NONE,
|
||||||
@@ -138,6 +150,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 */
|
||||||
@@ -161,7 +175,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;
|
||||||
|
|
||||||
@@ -189,7 +216,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;
|
||||||
@@ -250,9 +280,34 @@ 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;
|
||||||
|
/* UL SID filter to catch DTXu half-blocks,
|
||||||
|
* see tch_ul_fr_hr_efr() function. */
|
||||||
|
bool ul_sid_filter;
|
||||||
|
} dtx_fr_hr_efr;
|
||||||
uint8_t last_cmr;
|
uint8_t last_cmr;
|
||||||
uint32_t last_fn;
|
uint32_t last_fn;
|
||||||
|
struct {
|
||||||
|
/* RLP GSMTAP mechanism */
|
||||||
|
uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */
|
||||||
|
uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */
|
||||||
|
/* alignment of RLP frames in DL for NT modes */
|
||||||
|
ubit_t rlpdl_data_bits[60 * 7];
|
||||||
|
uint16_t rlpdl_align_bits;
|
||||||
|
uint8_t rlpdl_fill_level;
|
||||||
|
ubit_t tchf48_nt_2ndhalf[120];
|
||||||
|
} 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*/
|
||||||
@@ -272,6 +327,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 */
|
||||||
@@ -354,6 +422,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,6 +20,8 @@ enum {
|
|||||||
DLOOP,
|
DLOOP,
|
||||||
DABIS,
|
DABIS,
|
||||||
DRTP,
|
DRTP,
|
||||||
|
DOSMUX,
|
||||||
|
DASCI,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const struct log_info bts_log_info;
|
extern const struct log_info bts_log_info;
|
||||||
@@ -36,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 */
|
||||||
|
|||||||
@@ -13,14 +13,49 @@
|
|||||||
|
|
||||||
struct msgb;
|
struct msgb;
|
||||||
|
|
||||||
/* Access 1st part of msgb control buffer */
|
/****************************************************************
|
||||||
|
* Accessor macros for control buffer words in RTP input path (DL)
|
||||||
|
*****************************************************************/
|
||||||
|
|
||||||
|
/* Storing RTP header fields in the path from RTP and Osmux
|
||||||
|
* Rx callback functions to TCH-RTS.ind handling.
|
||||||
|
* FIXME: do we really need this RTP header info downstream
|
||||||
|
* of the jitter buffer mechanism in the RTP endpoint library?
|
||||||
|
*/
|
||||||
#define rtpmsg_marker_bit(x) ((x)->cb[0])
|
#define rtpmsg_marker_bit(x) ((x)->cb[0])
|
||||||
|
#define rtpmsg_seq(x) ((x)->cb[1])
|
||||||
|
#define rtpmsg_ts(x) ((x)->cb[2])
|
||||||
|
|
||||||
/* Access 2nd part of msgb control buffer */
|
/* l1sap_rtp_rx_cb() does some preening or preparsing on some
|
||||||
#define rtpmsg_seq(x) ((x)->cb[1])
|
* RTP payloads, and in two cases (HR with RFC 5993 input and
|
||||||
|
* CSD NT modes) this preparsing step produces some metadata
|
||||||
|
* that need to be passed to TCH-RTS.ind handling.
|
||||||
|
*/
|
||||||
|
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
|
||||||
|
#define rtpmsg_csd_align_bits(x) ((x)->cb[4])
|
||||||
|
|
||||||
/* Access 3rd part of msgb control buffer */
|
/********************************************************
|
||||||
#define rtpmsg_ts(x) ((x)->cb[2])
|
* Accessor macros for control buffer words in TCH UL path
|
||||||
|
*********************************************************/
|
||||||
|
|
||||||
|
/* We provide an ability for BTS models to indicate BFI along with payload
|
||||||
|
* bits just like in GSM 08.60 TRAU-UL frames, and the same BFI flag can
|
||||||
|
* then be set by model-independent functions for higher-level BFI
|
||||||
|
* conditions. This cb word shall act as a Boolean flag.
|
||||||
|
*/
|
||||||
|
#define tch_ul_msg_bfi(x) ((x)->cb[0])
|
||||||
|
|
||||||
|
/* For HRv1 codec, we have to pass SID classification from the function
|
||||||
|
* that makes the initial determination to TS 101 318, RFC 5993 and
|
||||||
|
* TW-TS-002 output functions. Per classic GSM specs, common across
|
||||||
|
* FR/HR/EFR, SID classification code is an integer equal to 0, 1 or 2;
|
||||||
|
* in Osmocom it is enum osmo_gsm631_sid_class.
|
||||||
|
*
|
||||||
|
* NOTE: while the actual SID ternary classification exists in exactly
|
||||||
|
* the same form across all 3 of FR/HR/EFR, we store it in a cb word
|
||||||
|
* only for HR codec where we need it for RTP output functions.
|
||||||
|
*/
|
||||||
|
#define tch_ul_msg_hr_sid(x) ((x)->cb[1])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classification of OML message. ETSI for plain GSM 12.21
|
* Classification of OML message. ETSI for plain GSM 12.21
|
||||||
|
|||||||
@@ -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,9 +3,11 @@
|
|||||||
|
|
||||||
#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))
|
||||||
|
|
||||||
int pcu_tx_info_ind(void);
|
int pcu_tx_info_ind(void);
|
||||||
int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable);
|
int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable);
|
||||||
@@ -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]
|
||||||
|
|
||||||
@@ -97,10 +90,10 @@ 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 */
|
||||||
uint32_t last_tdma_fn; /* last processed TDMA frame number */
|
uint32_t last_tdma_fn; /* last processed TDMA frame number */
|
||||||
@@ -119,7 +112,6 @@ struct l1sched_chan_state {
|
|||||||
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 */
|
||||||
@@ -139,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 */
|
||||||
@@ -193,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,
|
||||||
@@ -241,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 {
|
||||||
@@ -304,6 +303,10 @@ 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 {
|
||||||
|
/* first 22 of last 24 bursts (for TCH/F14.4, TCH/F9.6, TCH/F4.8) */
|
||||||
|
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) */
|
/* last 4 bursts (default for xCCH, PTCCH and PDTCH) */
|
||||||
SCHED_MEAS_AVG_M_S4N4,
|
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) */
|
||||||
|
|||||||
@@ -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,8 @@ 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_rlp.c \
|
||||||
|
csd_v110.c \
|
||||||
l1sap.c \
|
l1sap.c \
|
||||||
cbch.c \
|
cbch.c \
|
||||||
power_control.c \
|
power_control.c \
|
||||||
@@ -58,7 +66,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/>.
|
||||||
@@ -39,10 +39,10 @@
|
|||||||
#include <osmocom/core/signal.h>
|
#include <osmocom/core/signal.h>
|
||||||
#include <osmocom/core/macaddr.h>
|
#include <osmocom/core/macaddr.h>
|
||||||
#include <osmocom/core/fsm.h>
|
#include <osmocom/core/fsm.h>
|
||||||
|
#include <osmocom/gsm/protocol/ipaccess.h>
|
||||||
|
#include <osmocom/gsm/ipa.h>
|
||||||
#include <osmocom/abis/abis.h>
|
#include <osmocom/abis/abis.h>
|
||||||
#include <osmocom/abis/e1_input.h>
|
#include <osmocom/abis/e1_input.h>
|
||||||
#include <osmocom/abis/ipaccess.h>
|
|
||||||
#include <osmocom/gsm/ipa.h>
|
|
||||||
|
|
||||||
#include <osmo-bts/abis.h>
|
#include <osmo-bts/abis.h>
|
||||||
#include <osmo-bts/logging.h>
|
#include <osmo-bts/logging.h>
|
||||||
@@ -87,10 +87,17 @@ struct abis_link_fsm_priv {
|
|||||||
|
|
||||||
static void reset_oml_link(struct gsm_bts *bts)
|
static void reset_oml_link(struct gsm_bts *bts)
|
||||||
{
|
{
|
||||||
|
struct e1inp_sign_link *link;
|
||||||
|
|
||||||
if (bts->oml_link) {
|
if (bts->oml_link) {
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
|
||||||
e1inp_sign_link_destroy(bts->oml_link);
|
/* Mark bts->oml_link ptr null before calling sign_link_destroy,
|
||||||
|
* to avoid a callback triggering this same code path. */
|
||||||
|
link = bts->oml_link;
|
||||||
|
bts->oml_link = NULL;
|
||||||
|
|
||||||
|
e1inp_sign_link_destroy(link);
|
||||||
|
|
||||||
/* Log a special notice if the OML connection was dropped relatively quickly. */
|
/* Log a special notice if the OML connection was dropped relatively quickly. */
|
||||||
if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
|
if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 &&
|
||||||
@@ -100,14 +107,16 @@ static void reset_oml_link(struct gsm_bts *bts)
|
|||||||
"A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",
|
"A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n",
|
||||||
(uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));
|
(uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec));
|
||||||
}
|
}
|
||||||
bts->oml_link = NULL;
|
|
||||||
}
|
}
|
||||||
memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));
|
memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp));
|
||||||
|
|
||||||
/* Same for IPAC_PROTO_OSMO on the same ipa connection: */
|
/* Same for IPAC_PROTO_OSMO on the same ipa connection: */
|
||||||
if (bts->osmo_link) {
|
if (bts->osmo_link) {
|
||||||
e1inp_sign_link_destroy(bts->osmo_link);
|
/* Mark bts->osmo_link ptr null before calling sign_link_destroy,
|
||||||
|
* to avoid a callback triggering this same code path. */
|
||||||
|
link = bts->osmo_link;
|
||||||
bts->osmo_link = NULL;
|
bts->osmo_link = NULL;
|
||||||
|
e1inp_sign_link_destroy(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -225,11 +234,22 @@ 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);
|
/* Mark link ptr null before calling sign_link_destroy,
|
||||||
trx->rsl_link = NULL;
|
* to avoid a callback triggering this same code path. */
|
||||||
|
struct e1inp_sign_link *link = trx->bb_transc.rsl.link;
|
||||||
|
trx->bb_transc.rsl.link = NULL;
|
||||||
|
e1inp_sign_link_destroy(link);
|
||||||
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 +376,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 +416,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;
|
||||||
}
|
}
|
||||||
@@ -468,8 +488,11 @@ static int inp_s_cbfn(unsigned int subsys, unsigned int signal,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
struct input_signal_data *isd = signal_data;
|
struct input_signal_data *isd = signal_data;
|
||||||
DEBUGP(DABIS, "Input Signal %s received for link_type=%s\n",
|
DEBUGP(DABIS, "Input Signal %s received for ts-%u-%u link_type=%s\n",
|
||||||
get_value_string(e1inp_signal_names, signal), e1inp_signtype_name(isd->link_type));
|
get_value_string(e1inp_signal_names, signal),
|
||||||
|
isd->line ? isd->line->num : -1,
|
||||||
|
isd->ts_nr,
|
||||||
|
e1inp_signtype_name(isd->link_type));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
299
src/common/bts.c
299
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,15 +215,16 @@ 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;
|
||||||
@@ -223,19 +233,28 @@ static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
|
|||||||
osmo_fsm_inst_free(bts->shutdown_fi);
|
osmo_fsm_inst_free(bts->shutdown_fi);
|
||||||
bts->shutdown_fi = NULL;
|
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);
|
||||||
@@ -248,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);
|
||||||
@@ -289,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;
|
||||||
}
|
}
|
||||||
@@ -312,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
|
||||||
@@ -342,43 +343,48 @@ 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);
|
||||||
|
|
||||||
|
/* Osmux */
|
||||||
|
rc = bts_osmux_init(bts);
|
||||||
|
if (rc < 0)
|
||||||
|
return rc;
|
||||||
|
|
||||||
/* features implemented in 'common', available for all models,
|
/* features implemented in 'common', available for all models,
|
||||||
* order alphabetically */
|
* order alphabetically */
|
||||||
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU);
|
||||||
@@ -387,16 +393,18 @@ int bts_init(struct gsm_bts *bts)
|
|||||||
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_PAGING_COORDINATION);
|
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS001);
|
||||||
|
osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS002);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
@@ -413,6 +421,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 */
|
||||||
@@ -430,33 +441,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(DOML, 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);
|
||||||
}
|
}
|
||||||
@@ -683,7 +674,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)
|
||||||
@@ -749,12 +740,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
|
||||||
@@ -763,26 +754,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);
|
||||||
|
if (!is_empty)
|
||||||
/* Check whether the block may be overwritten */
|
return rc;
|
||||||
if (!is_empty)
|
/* fall-through */
|
||||||
return rc;
|
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++;
|
||||||
@@ -810,30 +814,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:
|
||||||
@@ -847,14 +856,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:
|
||||||
@@ -865,7 +873,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;
|
||||||
|
|
||||||
@@ -873,14 +881,59 @@ 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 0;
|
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) {
|
||||||
|
case RSL_CMOD_CSD_NT_14k5:
|
||||||
|
case 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) */
|
||||||
|
|||||||
@@ -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,7 +90,10 @@ 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;
|
||||||
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
|
||||||
@@ -227,10 +236,13 @@ int trx_link_estab(struct gsm_bts_trx *trx)
|
|||||||
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 ||
|
||||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
|
||||||
"Failed to establish RSL link (%d)", rc);
|
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,
|
||||||
|
"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);
|
||||||
|
|||||||
228
src/common/csd_rlp.c
Normal file
228
src/common/csd_rlp.c
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
/* This module has been split from l1sap.c; original header comments preserved:
|
||||||
|
*
|
||||||
|
* (C) 2011 by Harald Welte <laforge@gnumonks.org>
|
||||||
|
* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
|
||||||
|
*
|
||||||
|
* 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 <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <osmocom/core/bits.h>
|
||||||
|
#include <osmocom/core/msgb.h>
|
||||||
|
#include <osmocom/gsm/l1sap.h>
|
||||||
|
#include <osmocom/gsm/gsm_utils.h>
|
||||||
|
#include <osmocom/gsm/rsl.h>
|
||||||
|
#include <osmocom/gsm/rlp.h>
|
||||||
|
#include <osmocom/gsm/rtp_extensions.h>
|
||||||
|
#include <osmocom/core/gsmtap.h>
|
||||||
|
#include <osmocom/core/gsmtap_util.h>
|
||||||
|
#include <osmocom/core/utils.h>
|
||||||
|
|
||||||
|
#include <osmo-bts/logging.h>
|
||||||
|
#include <osmo-bts/gsm_data.h>
|
||||||
|
#include <osmo-bts/lchan.h>
|
||||||
|
#include <osmo-bts/bts.h>
|
||||||
|
#include <osmo-bts/csd_rlp.h>
|
||||||
|
|
||||||
|
/* In the case of TCH/F4.8 NT, each 240-bit RLP frame is split between
|
||||||
|
* two channel-coding blocks of 120 bits each. We need to know which
|
||||||
|
* frame numbers correspond to which half: in the UL-to-RTP path we have
|
||||||
|
* to set bit E2 based on the TDMA frame number at which we received the
|
||||||
|
* block in question, and in the DL direction we have to transmit the
|
||||||
|
* right half at the right time.
|
||||||
|
*
|
||||||
|
* See GSM 05.03 section 3.4.1 and the mapping tables of GSM 05.02;
|
||||||
|
* having "e2_map" in the array name shall serve as a mnemonic as to
|
||||||
|
* the sense of this array: 0 means 1st half and 1 means 2nd half,
|
||||||
|
* exactly as the value of bit E2 per TS 48.020 section 15.1.
|
||||||
|
*/
|
||||||
|
const uint8_t csd_tchf48_nt_e2_map[26] = {
|
||||||
|
[4] = 1, /* B1 position */
|
||||||
|
[13] = 1, /* B3 position */
|
||||||
|
[21] = 1, /* B5 position */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This function resets (clears) the state of the DL alignment buffer.
|
||||||
|
* It needs to be called when we encounter a gap (packet loss, invalid
|
||||||
|
* packets, etc) in our RTP input stream. */
|
||||||
|
void ntcsd_dl_reset(struct gsm_lchan *lchan)
|
||||||
|
{
|
||||||
|
lchan->tch.csd.rlpdl_fill_level = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is to be called with the decoded content of a single
|
||||||
|
* incoming RTP packet (data and alignment bits) for TCH/[FH]4.8 NT. */
|
||||||
|
void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits,
|
||||||
|
uint8_t align_bits)
|
||||||
|
{
|
||||||
|
memmove(lchan->tch.csd.rlpdl_data_bits,
|
||||||
|
lchan->tch.csd.rlpdl_data_bits + 60 * 2, 60 * 5);
|
||||||
|
memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 5, data_bits, 60 * 2);
|
||||||
|
lchan->tch.csd.rlpdl_align_bits <<= 4;
|
||||||
|
lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xF);
|
||||||
|
lchan->tch.csd.rlpdl_fill_level += 2;
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level > 7)
|
||||||
|
lchan->tch.csd.rlpdl_fill_level = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is to be called with the decoded content of a single
|
||||||
|
* incoming RTP packet (data and alignment bits) for TCH/F9.6 NT. */
|
||||||
|
void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits,
|
||||||
|
uint8_t align_bits)
|
||||||
|
{
|
||||||
|
memmove(lchan->tch.csd.rlpdl_data_bits,
|
||||||
|
lchan->tch.csd.rlpdl_data_bits + 60 * 4, 60 * 3);
|
||||||
|
memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 3, data_bits, 60 * 4);
|
||||||
|
lchan->tch.csd.rlpdl_align_bits <<= 8;
|
||||||
|
lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xFF);
|
||||||
|
lchan->tch.csd.rlpdl_fill_level += 4;
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level > 7)
|
||||||
|
lchan->tch.csd.rlpdl_fill_level = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is to be called to obtain a complete RLP frame for
|
||||||
|
* downlink transmission. It will provide either a properly aligned
|
||||||
|
* frame (return value true) or a filler (return value false). */
|
||||||
|
bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out)
|
||||||
|
{
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level < 4)
|
||||||
|
goto no_frame_out;
|
||||||
|
if (((lchan->tch.csd.rlpdl_align_bits >> 0) & 0xFF) == NTCSD_ALIGNED_EBITS) {
|
||||||
|
memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 3,
|
||||||
|
60 * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level < 5)
|
||||||
|
goto no_frame_out;
|
||||||
|
if (((lchan->tch.csd.rlpdl_align_bits >> 2) & 0xFF) == NTCSD_ALIGNED_EBITS) {
|
||||||
|
memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 2,
|
||||||
|
60 * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level < 6)
|
||||||
|
goto no_frame_out;
|
||||||
|
if (((lchan->tch.csd.rlpdl_align_bits >> 4) & 0xFF) == NTCSD_ALIGNED_EBITS) {
|
||||||
|
memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 1,
|
||||||
|
60 * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (lchan->tch.csd.rlpdl_fill_level < 7)
|
||||||
|
goto no_frame_out;
|
||||||
|
if (((lchan->tch.csd.rlpdl_align_bits >> 6) & 0xFF) == NTCSD_ALIGNED_EBITS) {
|
||||||
|
memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits, 60 * 4);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
no_frame_out:
|
||||||
|
/* TS 44.021 section 12.1 says that a missing/unavailable 240-bit
|
||||||
|
* RLP frame is to be filled with 0 bits, unlike ones-fill
|
||||||
|
* used everywhere else in the world of V.110 and CSD. */
|
||||||
|
memset(rlp_frame_out, 0, 60 * 4);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* process one MAC block of unpacked bits of a non-transparent CSD channel */
|
||||||
|
void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink,
|
||||||
|
const struct ph_tch_param *tch_ind,
|
||||||
|
const ubit_t *data, unsigned int data_len)
|
||||||
|
{
|
||||||
|
struct gsm_bts_trx *trx = lchan->ts->trx;
|
||||||
|
struct gsmtap_inst *inst = trx->bts->gsmtap.inst;
|
||||||
|
pbit_t *rlp_buf;
|
||||||
|
uint16_t arfcn;
|
||||||
|
int byte_len;
|
||||||
|
|
||||||
|
if (!inst || !trx->bts->gsmtap.rlp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lchan->csd_mode != LCHAN_CSD_M_NT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (is_uplink)
|
||||||
|
rlp_buf = lchan->tch.csd.rlp_buf_ul;
|
||||||
|
else
|
||||||
|
rlp_buf = lchan->tch.csd.rlp_buf_dl;
|
||||||
|
|
||||||
|
/* TCH/F 9.6: 4x60bit block => 240bit RLP frame
|
||||||
|
* TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame
|
||||||
|
* TCH/H 4.8: 4x60bit block => 240bit RLP frame
|
||||||
|
* TCH/F 2.4: 2x36bit blocks => transparent only
|
||||||
|
* TCH/H 2.4: 4x36bit blocks => transparent only
|
||||||
|
* TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (lchan->type == GSM_LCHAN_TCH_F &&
|
||||||
|
lchan->tch_mode == GSM48_CMODE_DATA_6k0 && is_uplink) {
|
||||||
|
/* In this mode we have 120-bit MAC blocks; two of them need
|
||||||
|
* to be concatenated to render a 240-bit RLP frame. The first
|
||||||
|
* block is present in B0/B2/B4, and we have to use FN to
|
||||||
|
* detect this position.
|
||||||
|
* This code path is only for UL: in the case of DL,
|
||||||
|
* alignment logic elsewhere in the code will present us
|
||||||
|
* with a fully assembled RLP frame. */
|
||||||
|
OSMO_ASSERT(data_len == 120);
|
||||||
|
if (csd_tchf48_nt_e2_map[tch_ind->fn % 26] == 0) {
|
||||||
|
osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osmo_ubit2pbit_ext(rlp_buf, 120, data, 0, data_len, 1);
|
||||||
|
byte_len = 240/8;
|
||||||
|
} else if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
|
||||||
|
/* in this mode we have 290bit MAC blocks containing M1, M2 and 288 data bits;
|
||||||
|
* two of them need to be concatenated to render a
|
||||||
|
* 576-bit RLP frame. The start of a RLP frame is
|
||||||
|
* denoted by a block with M1-bit set to 0. */
|
||||||
|
OSMO_ASSERT(data_len == 290);
|
||||||
|
ubit_t m1 = data[0];
|
||||||
|
if (m1 == 0) {
|
||||||
|
osmo_ubit2pbit_ext(rlp_buf, 0, data, 2, data_len, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
osmo_ubit2pbit_ext(rlp_buf, 288, data, 2, data_len, 1);
|
||||||
|
byte_len = 576/8;
|
||||||
|
} else {
|
||||||
|
byte_len = osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trx->bts->gsmtap.rlp_skip_null) {
|
||||||
|
struct osmo_rlp_frame_decoded rlpf;
|
||||||
|
int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len);
|
||||||
|
if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
arfcn = trx->arfcn;
|
||||||
|
if (is_uplink)
|
||||||
|
arfcn |= GSMTAP_ARFCN_F_UPLINK;
|
||||||
|
|
||||||
|
gsmtap_send_ex(inst, GSMTAP_TYPE_GSM_RLP, arfcn, lchan->ts->nr,
|
||||||
|
lchan->type == GSM_LCHAN_TCH_H ? GSMTAP_CHANNEL_VOICE_H : GSMTAP_CHANNEL_VOICE_F,
|
||||||
|
lchan->nr, tch_ind->fn, tch_ind->rssi, 0, rlp_buf, byte_len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wrapper for downlink path */
|
||||||
|
void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn,
|
||||||
|
const ubit_t *data, unsigned int data_len)
|
||||||
|
{
|
||||||
|
/* 'fake' tch_ind containing all-zero so gsmtap code can be shared
|
||||||
|
* between UL and DL */
|
||||||
|
const struct ph_tch_param fake_tch_ind = { .fn = fn };
|
||||||
|
gsmtap_csd_rlp_process(lchan, false, &fake_tch_ind, data, data_len);
|
||||||
|
}
|
||||||
242
src/common/csd_v110.c
Normal file
242
src/common/csd_v110.c
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
* (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 <stdbool.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 <osmocom/trau/csd_ra2.h>
|
||||||
|
#include <osmocom/trau/csd_raa_prime.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] = {
|
||||||
|
[GSM48_CMODE_DATA_14k5] = {
|
||||||
|
/* TCH/F14.4: 8 * 36 + 2 bits every 20 ms (14.5 kbit/s) */
|
||||||
|
.num_frames = 8,
|
||||||
|
.num_frame_bits = 36, /* D-bits */
|
||||||
|
.num_other_bits = 2, /* M-bits */
|
||||||
|
.ra2_ir = 16,
|
||||||
|
},
|
||||||
|
[GSM48_CMODE_DATA_12k0] = {
|
||||||
|
/* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */
|
||||||
|
.num_frames = 4,
|
||||||
|
.num_frame_bits = 60,
|
||||||
|
.ra2_ir = 16,
|
||||||
|
},
|
||||||
|
[GSM48_CMODE_DATA_6k0] = {
|
||||||
|
/* TCH/[FH]4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */
|
||||||
|
.num_frames = 2,
|
||||||
|
.num_frame_bits = 60,
|
||||||
|
.ra2_ir = 8,
|
||||||
|
},
|
||||||
|
[GSM48_CMODE_DATA_3k6] = {
|
||||||
|
/* TCH/[FH]2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */
|
||||||
|
.num_frames = 2,
|
||||||
|
.num_frame_bits = 36,
|
||||||
|
.ra2_ir = 8,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
uint8_t nt48_half_num)
|
||||||
|
{
|
||||||
|
const struct csd_v110_lchan_desc *desc;
|
||||||
|
ubit_t ra_bits[80 * 4];
|
||||||
|
|
||||||
|
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode];
|
||||||
|
if (OSMO_UNLIKELY(desc->num_frames == 0))
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
/* TCH/F14.4 is special: RAA' function is employed */
|
||||||
|
if (lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
|
||||||
|
/* 3GPP TS 44.021, section 10.3 "TCH/F14.4 channel coding"
|
||||||
|
* 3GPP TS 48.020, chapter 11 "THE RAA' FUNCTION" */
|
||||||
|
const ubit_t *m_bits = &data[0]; /* M-bits */
|
||||||
|
const ubit_t *d_bits = &data[2]; /* D-bits */
|
||||||
|
ubit_t c4, c5;
|
||||||
|
|
||||||
|
/* 3GPP TS 48.020, Table 3
|
||||||
|
* | C4 | Date Rate |
|
||||||
|
* | =1 | 14,4 kbit/s |
|
||||||
|
* | =0 | 14.4 kbit/s idle (IWF to BSS only) | */
|
||||||
|
c4 = 1;
|
||||||
|
/* 3GPP TS 48.020, Table 4
|
||||||
|
* | C5 | BSS to IWF FT | IWF to BSS UFE |
|
||||||
|
* | =1 | idle | framing error |
|
||||||
|
* | =0 | data | no framing error | */
|
||||||
|
c5 = 0;
|
||||||
|
|
||||||
|
/* Unless there is a bug, it's highly unlikely */
|
||||||
|
OSMO_ASSERT(data_len == CSD_V110_NUM_BITS(desc));
|
||||||
|
|
||||||
|
osmo_csd144_to_atrau_bits(&ra_bits[0], m_bits, d_bits, c4, c5);
|
||||||
|
goto ra1_ra2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle empty/incomplete Uplink frames gracefully */
|
||||||
|
if (OSMO_UNLIKELY(data_len < CSD_V110_NUM_BITS(desc))) {
|
||||||
|
/* 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_frames; 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_frames; 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_frame_bits == 60)
|
||||||
|
osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
|
||||||
|
else /* desc->num_frame_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 */
|
||||||
|
/* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */
|
||||||
|
df.e_bits[0] = 0;
|
||||||
|
/* E2: 0 for Q1/Q2, 1 for Q3/Q4 */
|
||||||
|
if (desc->num_frames == 4)
|
||||||
|
df.e_bits[1] = (i >> 1) & 0x01;
|
||||||
|
else
|
||||||
|
df.e_bits[1] = nt48_half_num;
|
||||||
|
/* E3: 0 for Q1/Q3, 1 for Q2/Q4 */
|
||||||
|
df.e_bits[2] = (i >> 0) & 0x01;
|
||||||
|
} 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->ra2_ir == 16)
|
||||||
|
osmo_csd_ra2_16k_pack(&rtp[0], &ra_bits[0], RFC4040_RTP_PLEN);
|
||||||
|
else /* desc->ra2_ir == 8 */
|
||||||
|
osmo_csd_ra2_8k_pack(&rtp[0], &ra_bits[0], RFC4040_RTP_PLEN);
|
||||||
|
|
||||||
|
return RFC4040_RTP_PLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_v110_align(const ubit_t *ra_bits)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
ubit_t bit0 = 0, bit1 = 1;
|
||||||
|
|
||||||
|
/* The weird code structure is for performance optimization,
|
||||||
|
* to avoid conditionals inside loops. */
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
bit0 |= ra_bits[i];
|
||||||
|
for (i = 1; i < 10; i++)
|
||||||
|
bit1 &= ra_bits[i * 8];
|
||||||
|
return (bit0 == 0) && (bit1 == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||||
|
uint8_t *align_bits, const uint8_t *rtp, size_t rtp_len)
|
||||||
|
{
|
||||||
|
const struct csd_v110_lchan_desc *desc;
|
||||||
|
ubit_t ra_bits[80 * 4];
|
||||||
|
uint8_t align_accum = 0;
|
||||||
|
|
||||||
|
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||||
|
desc = &csd_v110_lchan_desc[lchan->tch_mode];
|
||||||
|
if (OSMO_UNLIKELY(desc->num_frames == 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->ra2_ir == 16)
|
||||||
|
osmo_csd_ra2_16k_unpack(&ra_bits[0], &rtp[0], RFC4040_RTP_PLEN);
|
||||||
|
else /* desc->ra2_ir == 8 */
|
||||||
|
osmo_csd_ra2_8k_unpack(&ra_bits[0], &rtp[0], RFC4040_RTP_PLEN);
|
||||||
|
|
||||||
|
/* TCH/F14.4 is special: RAA' function is employed */
|
||||||
|
if (lchan->tch_mode == GSM48_CMODE_DATA_14k5) {
|
||||||
|
/* 3GPP TS 44.021, section 10.3 "TCH/F14.4 channel coding"
|
||||||
|
* 3GPP TS 48.020, chapter 11 "THE RAA' FUNCTION" */
|
||||||
|
ubit_t *m_bits = &data[0]; /* M-bits */
|
||||||
|
ubit_t *d_bits = &data[2]; /* D-bits */
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = osmo_csd144_from_atrau_bits(m_bits, d_bits, NULL, NULL, &ra_bits[0]);
|
||||||
|
return rc == 0 ? CSD_V110_NUM_BITS(desc) : rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RA1'/RA1: convert from an intermediate rate to radio rate */
|
||||||
|
for (unsigned int i = 0; i < desc->num_frames; i++) {
|
||||||
|
struct osmo_v110_decoded_frame df;
|
||||||
|
|
||||||
|
/* We require our RTP input to consist of aligned V.110
|
||||||
|
* frames. If we get misaligned input, let's catch it
|
||||||
|
* explicitly, rather than send garbage downstream. */
|
||||||
|
if (!check_v110_align(&ra_bits[i * 80]))
|
||||||
|
return -EINVAL;
|
||||||
|
/* 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_frame_bits == 60)
|
||||||
|
osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
|
||||||
|
else /* desc->num_frame_bits == 36 */
|
||||||
|
osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
|
||||||
|
/* save bits E2 & E3 that may be needed for RLP alignment */
|
||||||
|
align_accum <<= 2;
|
||||||
|
align_accum |= df.e_bits[1] << 1;
|
||||||
|
align_accum |= df.e_bits[2] << 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (align_bits)
|
||||||
|
*align_bits = align_accum;
|
||||||
|
return CSD_V110_NUM_BITS(desc);
|
||||||
|
}
|
||||||
@@ -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/>.
|
||||||
|
|||||||
1408
src/common/l1sap.c
1408
src/common/l1sap.c
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[] = {
|
||||||
@@ -53,42 +56,55 @@ const struct value_string lchan_ciph_state_names[] = {
|
|||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct value_string lchan_csd_mode_descs[] = {
|
||||||
|
{ LCHAN_CSD_M_NT, "non-transparent" },
|
||||||
|
{ LCHAN_CSD_M_T_1200_75, "transparent @ 1200/75 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_600, "transparent @ 600 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_1200, "transparent @ 1200 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_2400, "transparent @ 2400 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_4800, "transparent @ 4800 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_9600, "transparent @ 9600 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_14400, "transparent @ 14400 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_29000, "transparent @ 29000 bps" },
|
||||||
|
{ LCHAN_CSD_M_T_32000, "transparent @ 32000 bps" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
/* 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 +146,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 +165,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 +217,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 +230,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 +339,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 +384,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 +532,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",
|
||||||
@@ -119,6 +108,30 @@ static struct log_info_cat bts_log_info_cat[] = {
|
|||||||
.color = "\033[0;94m",
|
.color = "\033[0;94m",
|
||||||
.enabled = 1, .loglevel = LOGL_NOTICE,
|
.enabled = 1, .loglevel = LOGL_NOTICE,
|
||||||
},
|
},
|
||||||
|
[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,
|
||||||
|
},
|
||||||
|
[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;
|
||||||
@@ -311,7 +293,13 @@ int bts_main(int argc, char **argv)
|
|||||||
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);
|
||||||
@@ -358,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) {
|
||||||
@@ -375,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);
|
||||||
}
|
}
|
||||||
@@ -407,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. */
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
|
/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3).
|
||||||
* This mapping is used to determine if a L2 block starting at the given TDMA FN
|
* This mapping is used to determine if a L2 block starting at the given TDMA FN
|
||||||
* belongs to the SUB set and thus shall always be transmitted in DTX mode. */
|
* belongs to the SUB set and thus shall always be transmitted in DTX mode. */
|
||||||
static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
|
static const uint8_t ts45008_dtx_tchh_speech_fn_map[104] = {
|
||||||
/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
|
/* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */
|
||||||
[0] = 1, /* block { 0, 2, 4, 6} */
|
[0] = 1, /* block { 0, 2, 4, 6} */
|
||||||
[52] = 1, /* block {52, 54, 56, 58} */
|
[52] = 1, /* block {52, 54, 56, 58} */
|
||||||
@@ -28,6 +28,15 @@ static const uint8_t ts45008_dtx_tchh_fn_map[104] = {
|
|||||||
[66] = 1, /* block {66, 68, 70, 72} */
|
[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
|
||||||
* conditions. We set up a dummy measurement result here that reflects the
|
* conditions. We set up a dummy measurement result here that reflects the
|
||||||
@@ -50,7 +59,7 @@ 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 */
|
/* AMR is special, SID frames may be scheduled dynamically at any time */
|
||||||
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
|
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
|
||||||
@@ -59,8 +68,11 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
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:
|
||||||
|
case GSM48_CMODE_SPEECH_V2_VAMOS:
|
||||||
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
|
/* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59.
|
||||||
* There is only one *complete* block in this subset starting at FN=52.
|
* There is only one *complete* block in this subset starting at FN=52.
|
||||||
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
|
* Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...}
|
||||||
@@ -68,29 +80,38 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
if (fn104 == 52)
|
if (fn104 == 52)
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case GSM48_CMODE_SIGN:
|
case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
|
||||||
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
|
||||||
* SUB */
|
/* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on
|
||||||
return true;
|
* the TDMA frames given in the table of subclause 8.3 only if L2 fill frames
|
||||||
|
* have been received as FACCH/F 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 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 (ts45008_dtx_tchh_fn_map[fn104])
|
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||||
|
if (ts45008_dtx_tchh_speech_fn_map[fn104])
|
||||||
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;
|
||||||
@@ -269,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;
|
||||||
@@ -307,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,10 +347,9 @@ 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 a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
|
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG,
|
||||||
gsm_lchan_name(lchan),
|
"adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n",
|
||||||
dest->is_sub ? "SUB" : "FULL",
|
dest->is_sub ? "SUB" : "FULL", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
||||||
ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
|
||||||
lchan->meas.num_ul_meas, fn_mod);
|
lchan->meas.num_ul_meas, fn_mod);
|
||||||
|
|
||||||
lchan->meas.last_fn = fn;
|
lchan->meas.last_fn = fn;
|
||||||
@@ -406,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, 1 block TCH */
|
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
|
||||||
return 2;
|
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, 2 blocks TCH */
|
case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
|
||||||
return 3;
|
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:
|
||||||
@@ -444,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,
|
||||||
@@ -551,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;
|
||||||
@@ -571,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);
|
||||||
|
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
|
||||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
|
|
||||||
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;
|
||||||
@@ -626,12 +651,9 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
|
|||||||
} 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;
|
||||||
}
|
}
|
||||||
@@ -647,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);
|
||||||
|
|
||||||
@@ -667,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -916,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
|
||||||
@@ -945,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