mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-bts.git
synced 2025-11-06 15:13:26 +00:00
Compare commits
291 Commits
daniel/abi
...
jolly/test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
152d8e5b8a | ||
|
|
9c6c6b043b | ||
|
|
5076fef0ec | ||
|
|
e01cf27678 | ||
|
|
b7aa08f69b | ||
|
|
36e4fb63b8 | ||
|
|
076324446d | ||
|
|
18e5eb668e | ||
|
|
38dbebc48c | ||
|
|
65337b739a | ||
|
|
3c09964b11 | ||
|
|
798b28728b | ||
|
|
aec0422c8f | ||
|
|
3c133dc386 | ||
|
|
3af73977dd | ||
|
|
a7263b6474 | ||
|
|
82a2a8d9b4 | ||
|
|
e94553a547 | ||
|
|
088f4ffd57 | ||
|
|
950ed8bc4d | ||
|
|
59c641d20e | ||
|
|
1f755bcfee | ||
|
|
7786d9b673 | ||
|
|
f60f45e7ab | ||
|
|
722767a49d | ||
|
|
90f6ebcd3b | ||
|
|
17fe7d6841 | ||
|
|
1013ca3b8b | ||
|
|
647b8d0978 | ||
|
|
bc6cc67115 | ||
|
|
bc4ca18a31 | ||
|
|
4a6a2fdf7e | ||
|
|
28b8759465 | ||
|
|
25aae40e17 | ||
|
|
dc3b78da01 | ||
|
|
7c76630024 | ||
|
|
bcb9875176 | ||
|
|
863d4d933e | ||
|
|
791d121bd9 | ||
|
|
771e9f2838 | ||
|
|
e5d8a469d2 | ||
|
|
8fafc1a74c | ||
|
|
d88cc624ed | ||
|
|
bd777b0276 | ||
|
|
3bd97d839e | ||
|
|
6ed4a9a1eb | ||
|
|
d265ce68b2 | ||
|
|
586e897eea | ||
|
|
955b7dc637 | ||
|
|
695080745c | ||
|
|
fe005cb76e | ||
|
|
b960c7558a | ||
|
|
b8a185cc12 | ||
|
|
08f058789f | ||
|
|
8bff3b6898 | ||
|
|
aaa1f26e52 | ||
|
|
40ba43a2e8 | ||
|
|
c6211a8bec | ||
|
|
aa06f97326 | ||
|
|
188f76275a | ||
|
|
ddc15996dd | ||
|
|
f5c1cd3889 | ||
|
|
0978d1df71 | ||
|
|
852b2cbadc | ||
|
|
c4e836838d | ||
|
|
9aaaacc7aa | ||
|
|
9d9d9e2f27 | ||
|
|
fbd8aa8a77 | ||
|
|
e8518ae375 | ||
|
|
fd4654e1b8 | ||
|
|
e97834f2db | ||
|
|
8a1f740dfc | ||
|
|
1d53d231da | ||
|
|
d2d938c261 | ||
|
|
f20e13d160 | ||
|
|
55a21dc1c3 | ||
|
|
b33502a39b | ||
|
|
183c088864 | ||
|
|
37e639cb8f | ||
|
|
7e5a62e9f3 | ||
|
|
9171e37aff | ||
|
|
086b46a77f | ||
|
|
ff085f63c9 | ||
|
|
bbb3a1ed17 | ||
|
|
88de4d6789 | ||
|
|
66eae187b9 | ||
|
|
8ae829cabc | ||
|
|
007e72d5bc | ||
|
|
ca418643b3 | ||
|
|
d1f8f3429c | ||
|
|
97d3bd3e62 | ||
|
|
467d63e387 | ||
|
|
be93b87a64 | ||
|
|
ba5d2e4a5f | ||
|
|
0a2b0a20b3 | ||
|
|
290085787a | ||
|
|
6fa1dfce61 | ||
|
|
65c8f0de94 | ||
|
|
98e5d6f7c6 | ||
|
|
29fcae8632 | ||
|
|
fa90ff3e67 | ||
|
|
15330e2368 | ||
|
|
cdbd83affd | ||
|
|
2ae45aba3f | ||
|
|
6c83527e62 | ||
|
|
d04e3e708b | ||
|
|
4344f323f2 | ||
|
|
17087a08c7 | ||
|
|
f2c902c2af | ||
|
|
bb596dddc7 | ||
|
|
4bbfb904b8 | ||
|
|
deef79ffae | ||
|
|
95407f3f63 | ||
|
|
f3a63758d1 | ||
|
|
34077236f2 | ||
|
|
d53a084fd6 | ||
|
|
2bdb2201f6 | ||
|
|
84d220abc1 | ||
|
|
34838ee4e9 | ||
|
|
44c94fdeae | ||
|
|
f0510b6207 | ||
|
|
3480a2ab4c | ||
|
|
ad15414fd9 | ||
|
|
f98a55b713 | ||
|
|
1f5fdf8c8d | ||
|
|
d78968422f | ||
|
|
c860309aea | ||
|
|
5c1401d6f3 | ||
|
|
477fb3d9a4 | ||
|
|
e5c2bc346b | ||
|
|
c938a95e25 | ||
|
|
4c3b4e2868 | ||
|
|
676e9e5804 | ||
|
|
f0f91fc66c | ||
|
|
805340cb9c | ||
|
|
81ebfb34b4 | ||
|
|
07c3d86356 | ||
|
|
34ab6f1470 | ||
|
|
235d2bfbc4 | ||
|
|
fd544caae1 | ||
|
|
3f9e507d77 | ||
|
|
b2c6b68a10 | ||
|
|
c9a8eca543 | ||
|
|
9b5721b3fb | ||
|
|
194d1e8bc2 | ||
|
|
282c87ab2d | ||
|
|
785e731def | ||
|
|
592030eee7 | ||
|
|
3302d4adfe | ||
|
|
405368b697 | ||
|
|
1dd710944f | ||
|
|
a84b9a0261 | ||
|
|
d9de1a5b28 | ||
|
|
a0770250bc | ||
|
|
c18f9f256c | ||
|
|
44d47b2cdd | ||
|
|
4b945ec327 | ||
|
|
1160cabefb | ||
|
|
208127986e | ||
|
|
05b4629166 | ||
|
|
9cc85c1a6a | ||
|
|
2c511d5755 | ||
|
|
0eb90a0a98 | ||
|
|
7f03444d8b | ||
|
|
81cfbb10cb | ||
|
|
e38618f7cc | ||
|
|
5755946beb | ||
|
|
8b306b6f93 | ||
|
|
267c2606ad | ||
|
|
04a373cf6a | ||
|
|
3f5a343098 | ||
|
|
2a60cc3087 | ||
|
|
acaf6c563b | ||
|
|
dfd6224484 | ||
|
|
8b535ee77a | ||
|
|
cf8736e916 | ||
|
|
204cd4d7e3 | ||
|
|
1d7133e936 | ||
|
|
a4a9c28f15 | ||
|
|
f729ff970a | ||
|
|
bbdb10ee48 | ||
|
|
ac1eb71d78 | ||
|
|
11ec99d419 | ||
|
|
fad8986f06 | ||
|
|
b96d975f7d | ||
|
|
30601ccaf4 | ||
|
|
a1927f32f7 | ||
|
|
be18d2b275 | ||
|
|
cb0c0dfa15 | ||
|
|
8a21e7c27a | ||
|
|
4c56bed4d7 | ||
|
|
31c759165a | ||
|
|
38491d813b | ||
|
|
1dc9e3f2f8 | ||
|
|
b07e19d185 | ||
|
|
c3e059ce04 | ||
|
|
36ef885a6c | ||
|
|
7cd45a7cfe | ||
|
|
6be13437b7 | ||
|
|
3481dd40b3 | ||
|
|
66543fe422 | ||
|
|
c3d839be9e | ||
|
|
5b75e5dc8d | ||
|
|
9c4b472179 | ||
|
|
10d5499d03 | ||
|
|
d50d239914 | ||
|
|
989d99ca00 | ||
|
|
633bbf174a | ||
|
|
4190537d7d | ||
|
|
cea6c230ad | ||
|
|
92d1d1582b | ||
|
|
f4505f6caf | ||
|
|
91a1295a5a | ||
|
|
8894fe6f4c | ||
|
|
aebd2a21b5 | ||
|
|
8c397da917 | ||
|
|
c4a17d35ec | ||
|
|
c12bc93db8 | ||
|
|
7a646f963b | ||
|
|
914e55caf3 | ||
|
|
0350824203 | ||
|
|
4ff6888a81 | ||
|
|
5f556af232 | ||
|
|
909d943fe8 | ||
|
|
1266c068d7 | ||
|
|
61e7fdbb3f | ||
|
|
50710f4e8e | ||
|
|
acf0f0f0bb | ||
|
|
f06b959c7d | ||
|
|
2551882c1c | ||
|
|
96263aa908 | ||
|
|
362f2e50c2 | ||
|
|
3d2c107922 | ||
|
|
9584980ea2 | ||
|
|
80c605dd0b | ||
|
|
c29ca5eb7d | ||
|
|
32682c63f6 | ||
|
|
e1e204fae3 | ||
|
|
ac23ce2e03 | ||
|
|
c17697d337 | ||
|
|
bb3ed23e71 | ||
|
|
a563640f86 | ||
|
|
61b005193c | ||
|
|
d47d288630 | ||
|
|
e464ef6524 | ||
|
|
dbd70bca75 | ||
|
|
8fe6479358 | ||
|
|
8e04613e4f | ||
|
|
e7085d1699 | ||
|
|
ef9b27526c | ||
|
|
4bdc5a74cc | ||
|
|
767f690f05 | ||
|
|
48b00783f8 | ||
|
|
c88ed31d9e | ||
|
|
149de0c113 | ||
|
|
ca72961bbd | ||
|
|
50de553a1f | ||
|
|
c1909e7258 | ||
|
|
729037de0a | ||
|
|
33956215a7 | ||
|
|
f162fa9009 | ||
|
|
9b88fd8481 | ||
|
|
61933e6a7a | ||
|
|
a023df5c7f | ||
|
|
a21545e374 | ||
|
|
72f991f541 | ||
|
|
a981e28128 | ||
|
|
c48b4651a1 | ||
|
|
fa109255ac | ||
|
|
69bca44a84 | ||
|
|
54840a203b | ||
|
|
66bcdd839c | ||
|
|
cc13ea8b66 | ||
|
|
bdc438299b | ||
|
|
f19f533139 | ||
|
|
af9466159e | ||
|
|
633c09ee50 | ||
|
|
dfe96b786f | ||
|
|
d28ce3287f | ||
|
|
495cf39cb9 | ||
|
|
2f6e105956 | ||
|
|
c66b812c16 | ||
|
|
757180beba | ||
|
|
f1b7ee6a63 | ||
|
|
809879daae | ||
|
|
0701788724 | ||
|
|
0336b6e8e5 | ||
|
|
a743ae1c1e | ||
|
|
6a6a47f554 | ||
|
|
63baf960c6 | ||
|
|
7377344771 |
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/package.m4
|
||||
tests/amr/amr_test
|
||||
tests/csd/csd_test
|
||||
tests/agch/agch_test
|
||||
tests/paging/paging_test
|
||||
tests/cipher/cipher_test
|
||||
@@ -93,6 +94,7 @@ debian/tmp/
|
||||
doc/manuals/*.html
|
||||
doc/manuals/*.svg
|
||||
doc/manuals/*.pdf
|
||||
doc/manuals/vty/*.pdf
|
||||
doc/manuals/*__*.png
|
||||
doc/manuals/*.check
|
||||
doc/manuals/generated/
|
||||
@@ -104,3 +106,7 @@ doc/manuals/common
|
||||
doc/manuals/build
|
||||
|
||||
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 \
|
||||
README.md \
|
||||
contrib/dump_docs.py \
|
||||
contrib/osmo-bts.spec.in \
|
||||
debian \
|
||||
git-version-gen \
|
||||
$(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)
|
||||
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
|
||||
------------
|
||||
|
||||
@@ -69,13 +76,20 @@ Please observe the [Osmocom Mailing List
|
||||
Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules)
|
||||
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
|
||||
------------
|
||||
|
||||
Our coding standards are described at
|
||||
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
|
||||
https://osmocom.org/projects/cellular-infrastructure/wiki/Gerrit for
|
||||
more details
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
# If any interfaces have been added since the last public release: c:r:a + 1.
|
||||
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||
#library what description / commit summary line
|
||||
libosmocore >1.7.0 BTS_FEAT_OSMUX, RSL_IE_OSMO_OSMUX_CID
|
||||
libosmo-netif >1.2.0 OSMUX_DEFAULT_PORT, new osmux APIs
|
||||
libosmo-abis >1.3.0 e1inp_ipa_bts_rsl_close_n()
|
||||
libosmogsm >1.9.0 added new PRIM_INFO to include/osmocom/gsm/l1sap.h
|
||||
libosmogsm >1.9.0 use of RLP code in libosmogsm
|
||||
libosmogsm >1.9.0 BTS feature & RSL defs for ThemWi RTP extensions
|
||||
libosmoctrl >1.9.0 use ctrl_cmd_send2()
|
||||
|
||||
22
configure.ac
22
configure.ac
@@ -69,16 +69,15 @@ then
|
||||
fi
|
||||
|
||||
dnl checks for libraries
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.2.0)
|
||||
#FIXME: ^ it actually needs > 1.2.0
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
|
||||
|
||||
AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool])
|
||||
AC_ARG_ENABLE(sysmobts-calib,
|
||||
@@ -446,10 +445,11 @@ AC_OUTPUT(
|
||||
tests/power/Makefile
|
||||
tests/meas/Makefile
|
||||
tests/amr/Makefile
|
||||
tests/csd/Makefile
|
||||
doc/Makefile
|
||||
doc/examples/Makefile
|
||||
doc/manuals/Makefile
|
||||
contrib/Makefile
|
||||
contrib/ber/Makefile
|
||||
contrib/systemd/Makefile
|
||||
contrib/osmo-bts.spec
|
||||
Makefile)
|
||||
|
||||
@@ -1 +1 @@
|
||||
SUBDIRS = systemd
|
||||
SUBDIRS = systemd ber
|
||||
|
||||
28
contrib/ber/Makefile.am
Normal file
28
contrib/ber/Makefile.am
Normal file
@@ -0,0 +1,28 @@
|
||||
AM_CPPFLAGS = \
|
||||
$(all_includes) \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/include \
|
||||
-I$(builddir) \
|
||||
$(NULL)
|
||||
|
||||
AM_CFLAGS = \
|
||||
-Wall \
|
||||
$(LIBOSMOCORE_CFLAGS) \
|
||||
$(LIBOSMOTRAU_CFLAGS) \
|
||||
$(LIBOSMOCODEC_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
LDADD = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOTRAU_LIBS) \
|
||||
$(LIBOSMOCODEC_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
noinst_PROGRAMS = rtp_ber rtp_gen_map
|
||||
|
||||
rtp_ber_SOURCES = rtp_ber.c codec_bit_class.h
|
||||
|
||||
rtp_gen_map_SOURCES = rtp_gen_map.c
|
||||
|
||||
update_codec_bit_class_h: rtp_gen_map
|
||||
$(AM_V_GEN)./$< > $(top_srcdir)/contrib/ber/codec_bit_class.h
|
||||
26
contrib/ber/README
Normal file
26
contrib/ber/README
Normal file
@@ -0,0 +1,26 @@
|
||||
BER testing tool
|
||||
----------------
|
||||
|
||||
* Check all configs (MSC/BSC/BTS) for proper codec support
|
||||
- FR enabled
|
||||
- EFR enabled
|
||||
- AMR 12.2 enabled (and all other modes disabled !)
|
||||
- Use `amr-payload octet-aligned` in BSC config
|
||||
|
||||
* Check BTS config
|
||||
- Disable jitter buffer : `bts N / rtp jitter-buffer 0`
|
||||
|
||||
* Check BSC config
|
||||
- Disable radio timeout : `network / bts n / radio-link-timeout infinite`
|
||||
|
||||
* Start BER testing tool
|
||||
- `./rtp_ber 4000`
|
||||
|
||||
* On the MSC CLI, start a silent-call, then request GSM to test loop
|
||||
- `subscriber imsi <XXX> silent-call start tch/f speech-amr`
|
||||
- `subscriber imsi <XXX> ms-test close-loop b`
|
||||
|
||||
Don't forget to terminate the loop and terminate the silent call !
|
||||
|
||||
- `subscriber imsi <XXX> ms-test open-loop`
|
||||
- `subscriber imsi <XXX> silent-call stop`
|
||||
59
contrib/ber/codec_bit_class.h
Normal file
59
contrib/ber/codec_bit_class.h
Normal file
@@ -0,0 +1,59 @@
|
||||
static const int gsm_fr_bitclass[] = {
|
||||
-1, -1, -1, -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 2,
|
||||
0, 0, 1, 2, 2, 0, 0, 1, 2, 2, 0, 1, 1, 2, 0, 1,
|
||||
2, 2, 0, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
|
||||
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||
1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||
1, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1,
|
||||
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1,
|
||||
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1,
|
||||
2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2,
|
||||
1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1,
|
||||
2, 2, 1, 2, 2, 1, 2, 2,
|
||||
};
|
||||
|
||||
static const int gsm_efr_bitclass[] = {
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
|
||||
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
|
||||
1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
|
||||
1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1,
|
||||
1, 1, 1, 1, 2, 2, 1, 2,
|
||||
};
|
||||
|
||||
static const int gsm_amr_12_2_bitclass[] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, -1, -1, -1, -1,
|
||||
};
|
||||
|
||||
483
contrib/ber/rtp_ber.c
Normal file
483
contrib/ber/rtp_ber.c
Normal file
@@ -0,0 +1,483 @@
|
||||
/* RTP based GSM BER testing for osmo-bts, implementing ideas described in
|
||||
* https://osmocom.org/projects/osmobts/wiki/BER_Testing
|
||||
*
|
||||
* In short: The command transmits a PRBS sequence encapsulated in RTP frames, which are sent
|
||||
* to the BTS, which transmits that data in the (unimpaired) downlink. The mobile station
|
||||
* receives the data and is instructed to loop it back in the (possibly impaired) uplink.
|
||||
* The BTS receives that uplink, puts in in RTP frames which end up being received back by this
|
||||
* very tool. By correlating the received RTP with the PRBS sequence, this tool can compute
|
||||
* the BER (Bit Error Rate) of the (possibly impaired) uplink. Doing this with different
|
||||
* RF channel model simulators in the uplink allows to establish BER at different levels and
|
||||
* channel conditions. */
|
||||
|
||||
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <osmocom/codec/codec.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/core/prbs.h>
|
||||
#include <osmocom/core/timer.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/trau/osmo_ortp.h>
|
||||
|
||||
#include <codec_bit_class.h>
|
||||
|
||||
|
||||
struct app_state {
|
||||
struct osmo_rtp_socket *rs;
|
||||
|
||||
enum {
|
||||
WAIT_CONN = 0, /* Wait for incoming connection */
|
||||
WAIT_LOOP, /* Wait for a somewhat valid packet to start measuring */
|
||||
RUNNING, /* Main state */
|
||||
} state;
|
||||
|
||||
int pt;
|
||||
|
||||
int ref_len;
|
||||
uint8_t ref_bytes[GSM_FR_BYTES]; /* FR is the largest possible one */
|
||||
ubit_t ref_bits[8*GSM_FR_BYTES];
|
||||
|
||||
struct osmo_timer_list rtp_timer;
|
||||
|
||||
uint16_t rx_last_seq;
|
||||
uint32_t rx_last_ts;
|
||||
uint32_t rx_idx;
|
||||
uint32_t tx_idx;
|
||||
|
||||
const int *err_tbl; /* Classification table */
|
||||
int err_frames; /* Number of accumulated frames */
|
||||
int err_cnt[3]; /* Bit error counter */
|
||||
int err_tot[3]; /* Total # bits in that class */
|
||||
};
|
||||
|
||||
#define FLOW_REG_TX_MAX_ADVANCE 200
|
||||
#define FLOW_REG_TX_MIN_ADVANCE 50
|
||||
|
||||
|
||||
const struct log_info log_info;
|
||||
|
||||
|
||||
static const uint8_t amr_size_by_ft[] = {
|
||||
[0] = 12, /* 4.75 */
|
||||
[1] = 13, /* 5.15 */
|
||||
[2] = 15, /* 5.9 */
|
||||
[3] = 17, /* 6.7 */
|
||||
[4] = 19, /* 7.4 */
|
||||
[5] = 20, /* 7.95 */
|
||||
[6] = 26, /* 10.2 */
|
||||
[7] = 31, /* 12.2 */
|
||||
[8] = 5, /* SID */
|
||||
};
|
||||
|
||||
static const char * const amr_rate_by_ft[] = {
|
||||
[0] = "4.75",
|
||||
[1] = "5.15",
|
||||
[2] = "5.9",
|
||||
[3] = "6.7",
|
||||
[4] = "7.4",
|
||||
[5] = "7.95",
|
||||
[6] = "10.2",
|
||||
[7] = "12.2",
|
||||
[8] = "SID",
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
_gsm_fr_gen_ref(struct app_state *as)
|
||||
{
|
||||
struct osmo_prbs_state pn9;
|
||||
|
||||
/* Length */
|
||||
as->ref_len = GSM_FR_BYTES;
|
||||
|
||||
/* Marker */
|
||||
as->ref_bits[0] = 1;
|
||||
as->ref_bits[1] = 1;
|
||||
as->ref_bits[2] = 0;
|
||||
as->ref_bits[3] = 1;
|
||||
|
||||
/* PN */
|
||||
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||
pn9.state = 31;
|
||||
osmo_prbs_get_ubits(&as->ref_bits[4], 260, &pn9);
|
||||
|
||||
/* Convert to bytes */
|
||||
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_FR_BYTES, 0);
|
||||
|
||||
/* Init error classes */
|
||||
as->err_tot[0] = 50;
|
||||
as->err_tot[1] = 132;
|
||||
as->err_tot[2] = 78;
|
||||
as->err_tbl = gsm_fr_bitclass;
|
||||
}
|
||||
|
||||
static void
|
||||
_gsm_efr_gen_ref(struct app_state *as)
|
||||
{
|
||||
struct osmo_prbs_state pn9;
|
||||
|
||||
/* Length */
|
||||
as->ref_len = GSM_EFR_BYTES;
|
||||
|
||||
/* Marker */
|
||||
as->ref_bits[0] = 1;
|
||||
as->ref_bits[1] = 1;
|
||||
as->ref_bits[2] = 0;
|
||||
as->ref_bits[3] = 0;
|
||||
|
||||
/* PN */
|
||||
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||
pn9.state = 31;
|
||||
osmo_prbs_get_ubits(&as->ref_bits[4], 244, &pn9);
|
||||
|
||||
/* Convert to bytes */
|
||||
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_EFR_BYTES, 0);
|
||||
|
||||
/* Init error classes */
|
||||
as->err_tot[0] = 50;
|
||||
as->err_tot[1] = 125;
|
||||
as->err_tot[2] = 73;
|
||||
as->err_tbl = gsm_efr_bitclass;
|
||||
}
|
||||
|
||||
static void
|
||||
_gsm_amr_gen_ref(struct app_state *as)
|
||||
{
|
||||
struct osmo_prbs_state pn9;
|
||||
uint8_t hdr[2];
|
||||
|
||||
/* Length */
|
||||
as->ref_len = 33;
|
||||
|
||||
/* Header */
|
||||
hdr[0] = 0x70;
|
||||
hdr[1] = 0x3c;
|
||||
osmo_pbit2ubit_ext(as->ref_bits, 0, hdr, 0, 16, 0);
|
||||
|
||||
/* PN */
|
||||
osmo_prbs_state_init(&pn9, &osmo_prbs9);
|
||||
pn9.state = 31;
|
||||
osmo_prbs_get_ubits(&as->ref_bits[16], 244, &pn9);
|
||||
|
||||
/* Unused bits */
|
||||
as->ref_bits[260] = 0;
|
||||
as->ref_bits[261] = 0;
|
||||
as->ref_bits[262] = 0;
|
||||
as->ref_bits[263] = 0;
|
||||
|
||||
/* Convert to bytes */
|
||||
osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 264, 0);
|
||||
|
||||
/* Init error classes */
|
||||
as->err_tot[0] = 81;
|
||||
as->err_tot[1] = 163;
|
||||
as->err_tot[2] = -1;
|
||||
as->err_tbl = gsm_amr_12_2_bitclass;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_gsm_gen_ref(struct app_state *as)
|
||||
{
|
||||
switch (as->pt) {
|
||||
case RTP_PT_GSM_FULL:
|
||||
_gsm_fr_gen_ref(as);
|
||||
break;
|
||||
case RTP_PT_GSM_EFR:
|
||||
_gsm_efr_gen_ref(as);
|
||||
break;
|
||||
case RTP_PT_AMR:
|
||||
_gsm_amr_gen_ref(as);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "[!] Unsupported payload type for BER measurement\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_gsm_ber(struct app_state *as, const uint8_t *payload, unsigned int payload_len)
|
||||
{
|
||||
ubit_t rx_bits[8*33];
|
||||
int err[3]; /* Class 1a, 1b, 2 */
|
||||
int ones;
|
||||
int i, j;
|
||||
|
||||
if (payload) {
|
||||
/* Process real-payload */
|
||||
osmo_pbit2ubit_ext(rx_bits, 0, payload, 0, 8*payload_len, 0);
|
||||
|
||||
err[0] = err[1] = err[2] = 0;
|
||||
ones = 0;
|
||||
|
||||
for (i = 0; i < 8 * payload_len; i++) {
|
||||
j = as->err_tbl[i];
|
||||
if (j >= 0) {
|
||||
err[j] += rx_bits[i] ^ as->ref_bits[i];
|
||||
ones += rx_bits[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (ones < 32) { // This frames is probably us underrunning Tx, don't use it
|
||||
fprintf(stderr, "[w] Frame ignored as probably TX underrun %d %d\n", as->tx_idx, as->rx_idx);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/* No payload -> Lost frame completely */
|
||||
err[0] = as->err_tot[0] / 2;
|
||||
err[1] = as->err_tot[1] / 2;
|
||||
err[2] = as->err_tot[2] / 2;
|
||||
}
|
||||
|
||||
if (as->state == RUNNING) {
|
||||
/* Update records */
|
||||
if (err[0] != 0) {
|
||||
/* Class 1a bits bad -> Frame error */
|
||||
as->err_cnt[0]++;
|
||||
}
|
||||
|
||||
as->err_cnt[1] += err[1]; /* Class 1b */
|
||||
as->err_cnt[2] += err[2]; /* class 2 */
|
||||
|
||||
as->err_frames++;
|
||||
|
||||
/* Enough for a read-out ? */
|
||||
if (as->err_frames == 200) {
|
||||
printf("FBER: %4.2f C1b RBER: %5.3f C2 RBER: %5.3f\n",
|
||||
100.0f * as->err_cnt[0] / as->err_frames,
|
||||
100.0f * as->err_cnt[1] / (as->err_tot[1] * as->err_frames),
|
||||
100.0f * as->err_cnt[2] / (as->err_tot[2] * as->err_frames)
|
||||
);
|
||||
memset(as->err_cnt, 0, sizeof(as->err_cnt));
|
||||
as->err_frames = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return err[0] != 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_rtp_check_payload_type(const uint8_t *payload, unsigned int payload_len)
|
||||
{
|
||||
uint8_t ft;
|
||||
int pt = -1;
|
||||
|
||||
switch (payload_len) {
|
||||
case GSM_FR_BYTES: /* FR or AMR 12.2k */
|
||||
/* Check for AMR */
|
||||
ft = (payload[1] >> 3) & 0xf;
|
||||
if (ft == 7)
|
||||
pt = RTP_PT_AMR;
|
||||
|
||||
/* Check for FR */
|
||||
else if ((payload[0] & 0xF0) == 0xD0)
|
||||
pt = RTP_PT_GSM_FULL;
|
||||
|
||||
/* None of the above */
|
||||
else
|
||||
fprintf(stderr, "[!] FR without 0xD0 signature or AMR with unknwon Frame Type ?!?\n");
|
||||
|
||||
break;
|
||||
case GSM_EFR_BYTES: /* EFR */
|
||||
if ((payload[0] & 0xF0) != 0xC0)
|
||||
fprintf(stderr, "[!] EFR without 0xC0 signature ?!?\n");
|
||||
pt = RTP_PT_GSM_EFR;
|
||||
break;
|
||||
case GSM_HR_BYTES: /* HR */
|
||||
pt = RTP_PT_GSM_HALF;
|
||||
break;
|
||||
default: /* AMR */
|
||||
{
|
||||
uint8_t cmr, cmi, sti;
|
||||
cmr = payload[0] >> 4;
|
||||
ft = (payload[1] >> 3) & 0xf;
|
||||
|
||||
if (payload_len != amr_size_by_ft[ft]+2)
|
||||
fprintf(stderr, "AMR FT %u(%s) but size %u\n",
|
||||
ft, amr_rate_by_ft[ft], payload_len);
|
||||
|
||||
switch (ft) {
|
||||
case 0: case 1: case 2: case 3:
|
||||
case 4: case 5: case 6: case 7:
|
||||
cmi = ft;
|
||||
printf("AMR SPEECH with FT/CMI %u(%s), "
|
||||
"CMR %u\n",
|
||||
cmi, amr_rate_by_ft[cmi],
|
||||
cmr);
|
||||
break;
|
||||
case 8: /* SID */
|
||||
cmi = (payload[2+4] >> 1) & 0x7;
|
||||
sti = payload[2+4] & 0x10;
|
||||
printf("AMR SID %s with CMI %u(%s), CMR %u(%s)\n",
|
||||
sti ? "UPDATE" : "FIRST",
|
||||
cmi, amr_rate_by_ft[cmi],
|
||||
cmr, amr_rate_by_ft[cmr]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
static void
|
||||
rtp_timer_cb(void *priv)
|
||||
{
|
||||
struct app_state *as = (struct app_state *)priv;
|
||||
|
||||
/* Send at least one frame if we're not too far ahead */
|
||||
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MAX_ADVANCE)) {
|
||||
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
|
||||
as->tx_idx++;
|
||||
} else {
|
||||
fprintf(stderr, "Skipped\n");
|
||||
}
|
||||
|
||||
/* Then maybe a second one to try and catch up to RX */
|
||||
if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MIN_ADVANCE)) {
|
||||
osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION);
|
||||
as->tx_idx++;
|
||||
}
|
||||
|
||||
/* Re-schedule */
|
||||
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
|
||||
}
|
||||
|
||||
static int
|
||||
rtp_seq_num_diff(uint16_t new, uint16_t old)
|
||||
{
|
||||
int d = (int)new - (int)old;
|
||||
while (d > 49152)
|
||||
d -= 65536;
|
||||
while (d < -49152)
|
||||
d += 65536;
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
rtp_rx_cb(struct osmo_rtp_socket *rs,
|
||||
const uint8_t *payload, unsigned int payload_len,
|
||||
uint16_t seq_number, uint32_t timestamp, bool marker)
|
||||
{
|
||||
struct app_state *as = (struct app_state *)rs->priv;
|
||||
int pt, rc, d;
|
||||
|
||||
// printf("Rx(%u, %d, %d, %d): %s\n", payload_len, seq_number, timestamp, marker, osmo_hexdump(payload, payload_len));
|
||||
|
||||
/* Identify payload */
|
||||
pt = _rtp_check_payload_type(payload, payload_len);
|
||||
|
||||
/* First packet ? */
|
||||
if (as->state == WAIT_CONN) {
|
||||
/* Setup for this payload type */
|
||||
as->pt = pt;
|
||||
osmo_rtp_socket_set_pt(as->rs, pt);
|
||||
_gsm_gen_ref(as);
|
||||
|
||||
/* Timer every 20 ms */
|
||||
osmo_timer_setup(&as->rtp_timer, rtp_timer_cb, as);
|
||||
osmo_timer_add(&as->rtp_timer);
|
||||
osmo_timer_schedule(&as->rtp_timer, 0, 20000);
|
||||
|
||||
/* Init our time tracking */
|
||||
as->rx_last_seq = seq_number;
|
||||
as->rx_last_ts = timestamp;
|
||||
|
||||
/* Now we wait for a loop */
|
||||
as->state = WAIT_LOOP;
|
||||
}
|
||||
|
||||
/* RX sequence & timstamp tracking */
|
||||
if (rtp_seq_num_diff(seq_number, as->rx_last_seq) > 1)
|
||||
fprintf(stderr, "[!] RTP sequence number discontinuity (%d -> %d)\n", as->rx_last_seq, seq_number);
|
||||
|
||||
d = (timestamp - as->rx_last_ts) / GSM_RTP_DURATION;
|
||||
|
||||
as->rx_idx += d;
|
||||
as->rx_last_seq = seq_number;
|
||||
as->rx_last_ts = timestamp;
|
||||
|
||||
/* Account for missing frames in BER tracking */
|
||||
if (d > 1) {
|
||||
fprintf(stderr, "[!] RTP %d missing frames assumed lost @%d\n", d-1, seq_number);
|
||||
while (--d)
|
||||
_gsm_ber(as, NULL, 0);
|
||||
}
|
||||
|
||||
/* BER analysis */
|
||||
rc = _gsm_ber(as, payload, payload_len);
|
||||
|
||||
if ((as->state == WAIT_LOOP) && (rc == 0))
|
||||
as->state = RUNNING;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct app_state _as, *as = &_as;
|
||||
int rc, port;
|
||||
|
||||
/* Args */
|
||||
if (argc < 2)
|
||||
return -1;
|
||||
|
||||
port = atoi(argv[1]);
|
||||
|
||||
/* App init */
|
||||
memset(as, 0x00, sizeof(struct app_state));
|
||||
|
||||
log_init(&log_info, NULL);
|
||||
osmo_rtp_init(NULL);
|
||||
|
||||
/* Start auto-connect RTP socket */
|
||||
as->rs = osmo_rtp_socket_create(NULL, 0);
|
||||
|
||||
as->rs->priv = as;
|
||||
as->rs->rx_cb = rtp_rx_cb;
|
||||
|
||||
/* Jitter buffer gets in the way, we want the raw traffic */
|
||||
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JIT_ADAP, 0);
|
||||
osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JITBUF, 0);
|
||||
|
||||
/* Bind to requested port */
|
||||
fprintf(stderr, "[+] Binding RTP socket on port %u...\n", port);
|
||||
rc = osmo_rtp_socket_bind(as->rs, "0.0.0.0", port);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "[!] error binding RTP socket: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* We 'connect' to the first source we hear from */
|
||||
osmo_rtp_socket_autoconnect(as->rs);
|
||||
|
||||
/* Main loop */
|
||||
while (1)
|
||||
osmo_select_main(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
145
contrib/ber/rtp_gen_map.c
Normal file
145
contrib/ber/rtp_gen_map.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* utility to generate codec_bit_class.h, a file with structures
|
||||
* describing which [protection] class each bit of a given codec frame belongs to */
|
||||
|
||||
/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <osmocom/codec/codec.h>
|
||||
|
||||
|
||||
static int
|
||||
gen_table_fr(int *tbl)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
|
||||
|
||||
for (i = 0; i < 260; i++) {
|
||||
j = 4 + gsm610_bitorder[i];
|
||||
if (i < 50)
|
||||
tbl[j] = 0; /* Class 1a */
|
||||
else if (i < 182)
|
||||
tbl[j] = 1; /* Class 1b */
|
||||
else
|
||||
tbl[j] = 2; /* Class 2 */
|
||||
}
|
||||
|
||||
return GSM_FR_BYTES * 8;
|
||||
}
|
||||
|
||||
static int
|
||||
gen_table_efr(int *tbl)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1;
|
||||
|
||||
for (i = 0; i < 260; i++) {
|
||||
j = gsm660_bitorder[i];
|
||||
|
||||
if (j < 71)
|
||||
k = j;
|
||||
else if (j < 73)
|
||||
k = 71;
|
||||
else if (j < 123)
|
||||
k = j - 2;
|
||||
else if (j < 125)
|
||||
k = 119;
|
||||
else if (j < 178)
|
||||
k = j - 4;
|
||||
else if (j < 180)
|
||||
k = 172;
|
||||
else if (j < 230)
|
||||
k = j - 6;
|
||||
else if (j < 232)
|
||||
k = 222;
|
||||
else if (j < 252)
|
||||
k = j - 8;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (i < 50)
|
||||
tbl[k] = 0; /* Class 1a */
|
||||
else if (i < 182)
|
||||
tbl[k] = 1; /* Class 1b */
|
||||
else
|
||||
tbl[k] = 2; /* Class 2 */
|
||||
}
|
||||
|
||||
return GSM_EFR_BYTES * 8;
|
||||
}
|
||||
|
||||
static int
|
||||
gen_table_amr_12_2(int *tbl)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
tbl[i] = -1;
|
||||
|
||||
for (i = 0; i < 244; i++)
|
||||
tbl[i+16] = i < 81 ? 0 : 1;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
tbl[i+16+244] = -1;
|
||||
|
||||
return 8 * 33;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_table(const char *name, int *tbl, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("static const int %s[] = {\n", name);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if ((i & 15) == 0)
|
||||
printf("\t");
|
||||
|
||||
printf("%2d", tbl[i]);
|
||||
|
||||
if (((i & 15) == 15) || (i == len-1))
|
||||
printf(",\n");
|
||||
else
|
||||
printf(", ");
|
||||
}
|
||||
|
||||
printf("};\n\n");
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int tbl[33*8];
|
||||
int rv;
|
||||
|
||||
rv = gen_table_fr(tbl);
|
||||
print_table("gsm_fr_bitclass", tbl, rv);
|
||||
|
||||
rv = gen_table_efr(tbl);
|
||||
print_table("gsm_efr_bitclass", tbl, rv);
|
||||
|
||||
rv = gen_table_amr_12_2(tbl);
|
||||
print_table("gsm_amr_12_2_bitclass", tbl, rv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -9,7 +9,7 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen
|
||||
export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export LD_LIBRARY_PATH="$inst/lib"
|
||||
|
||||
osmo-build-dep.sh libosmo-abis
|
||||
osmo-build-dep.sh libosmo-abis "" --disable-dahdi
|
||||
osmo-build-dep.sh libosmo-netif "" --disable-doxygen
|
||||
|
||||
cd "$deps"
|
||||
|
||||
@@ -1,118 +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
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.2.0
|
||||
### FIXME: DependencyHACK to include osmocom/gprs/protocol/gsm_04_60.h
|
||||
BuildRequires: pkgconfig(libosmogb)
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
Osmocom BTS-Side code (A-bis, scheduling).
|
||||
|
||||
%package -n osmo-bts-virtual
|
||||
Summary: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP)
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description -n osmo-bts-virtual
|
||||
This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but
|
||||
utilizes GSMTAP-over-UDP frames for the Um interface. This is useful
|
||||
in fully virtualized setups e.g. in combination with OsmocomBB virt_phy.
|
||||
|
||||
%package -n osmo-bts-omldummy
|
||||
Summary: Osmocom CI: Bring up only OML without RSL
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description -n osmo-bts-omldummy
|
||||
This is used only in integration testing, where in the TTCN-3 testsuite
|
||||
we currently have no A-bis OML implementation, but only a RSL one.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
echo "%{version}" >.tarball-version
|
||||
autoreconf -fi
|
||||
%configure \
|
||||
--docdir="%{_docdir}/%{name}" \
|
||||
--with-systemdsystemunitdir=%{_unitdir} \
|
||||
--enable-trx
|
||||
make V=1 %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%pre %service_add_pre osmo-bts-trx.service
|
||||
%post %service_add_post osmo-bts-trx.service
|
||||
%preun %service_del_preun osmo-bts-trx.service
|
||||
%postun %service_del_postun osmo-bts-trx.service
|
||||
%pre virtual %service_add_pre osmo-bts-virtual.service
|
||||
%post virtual %service_add_post osmo-bts-virtual.service
|
||||
%preun virtual %service_del_preun osmo-bts-virtual.service
|
||||
%postun virtual %service_del_postun osmo-bts-virtual.service
|
||||
%endif
|
||||
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc README.md
|
||||
%dir %{_docdir}/%{name}
|
||||
%dir %{_docdir}/%{name}/examples
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bts-trx
|
||||
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx-calypso.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-bts-trx/osmo-bts-trx.cfg
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bts-virtual
|
||||
%{_docdir}/%{name}/examples/osmo-bts-virtual/osmo-bts-virtual.cfg
|
||||
%{_bindir}/osmo-bts-trx
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-trx.cfg
|
||||
%{_unitdir}/osmo-bts-trx.service
|
||||
|
||||
%files -n osmo-bts-virtual
|
||||
%{_bindir}/osmo-bts-virtual
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bts-virtual.cfg
|
||||
%{_unitdir}/osmo-bts-virtual.service
|
||||
|
||||
%files -n osmo-bts-omldummy
|
||||
%{_bindir}/osmo-bts-omldummy
|
||||
|
||||
%changelog
|
||||
@@ -2,6 +2,8 @@
|
||||
Description=osmo-bts manager for LC15 / sysmoBTS 2100
|
||||
After=lc15-sysdev-remap.service
|
||||
Wants=lc15-sysdev-remap.service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
Description=osmo-bts manager for OC-2G
|
||||
After=oc2g-sysdev-remap.service
|
||||
Wants=oc2g-sysdev-remap.service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=osmo-bts for LC15 / sysmoBTS 2100
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -9,7 +11,6 @@ WorkingDirectory=%S/osmocom
|
||||
RuntimeDirectory=osmo-bts
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=osmo-bts for OC-2G
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -9,7 +11,6 @@ WorkingDirectory=%S/osmocom
|
||||
RuntimeDirectory=osmo-bts
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=osmo-bts for sysmocom sysmoBTS
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -11,12 +13,11 @@ StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority):
|
||||
CPUSchedulingPriority=11
|
||||
CPUSchedulingPriority=20
|
||||
# See sched(7) for further details on real-time policies and priorities
|
||||
|
||||
[Install]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=Osmocom osmo-bts for osmo-trx
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -8,6 +10,9 @@ StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
AmbientCapabilities=CAP_SYS_NICE
|
||||
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
@@ -8,6 +10,9 @@ StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
Restart=always
|
||||
RestartSec=2
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
AmbientCapabilities=CAP_SYS_NICE
|
||||
|
||||
# CPU scheduling policy:
|
||||
CPUSchedulingPolicy=rr
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
[Unit]
|
||||
Description=osmo-bts manager for sysmoBTS
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
|
||||
326
debian/changelog
vendored
326
debian/changelog
vendored
@@ -1,3 +1,329 @@
|
||||
osmo-bts (1.7.0) unstable; urgency=medium
|
||||
|
||||
[ arehbein ]
|
||||
* common: Fix memleak in get_smscb_block()
|
||||
* doc: Adapt to use of 'telnet_init_default'
|
||||
* common: Remove redundant checks
|
||||
* common: Remove unused function gsm_objclass2nmstate()
|
||||
* gsm_objclass2mo(): Change signature/set NACK cause
|
||||
* gsm_objclass2obj(): Change signature/set NACK cause
|
||||
* PCU interface: Log version when starting listener
|
||||
* common: Have PCU socket connection use osmo_wqueue
|
||||
* common: Make socket queue max. length configurable
|
||||
|
||||
[ Max ]
|
||||
* bts-virtual: fix segfault
|
||||
* osmo-bts-trx: log TRXC/TRXD connection address
|
||||
* osmo-bts-trx: use bool for true/false flags
|
||||
* GSMTAP: allow configuring local address
|
||||
* license: fix typos
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* paging_add_imm_ass(): remove meaningless from_pcu argument
|
||||
* osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down()
|
||||
* osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down()
|
||||
* osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down()
|
||||
* GSMTAP: print 'gsmtap-local-host' if not NULL
|
||||
* osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC
|
||||
* rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack()
|
||||
* rsl: reduce logging verbosity on some messages
|
||||
* tests: use -no-install libtool flag to avoid ./lt-* scripts
|
||||
* scheduler: log pchan value in trx_sched_set_pchan()
|
||||
* osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts()
|
||||
* contrib/osmo-bts.spec.in: do not depend on libosmogb
|
||||
* osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH
|
||||
* rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values
|
||||
* osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req()
|
||||
* tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual
|
||||
* osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH
|
||||
* flags: add missing entries to bts_impl_flag_desc[]
|
||||
* flags: group BTS_INTERNAL_FLAG_* into an enum
|
||||
* flags: ensure completeness of bts_impl_flag_desc[]
|
||||
* fixup: common: Remove unused function gsm_objclass2nmstate()
|
||||
* oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately
|
||||
* oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class
|
||||
* oml: reset BCCH carrier power reduction mode (if enabled)
|
||||
* copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
|
||||
* osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan()
|
||||
* osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts
|
||||
* osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames
|
||||
* osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len()
|
||||
* osmo-bts-trx: fix recent regression in Tx lchan handlers
|
||||
* osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind
|
||||
* l1sap: use gsm0502_fn2ccch_block() from libosmogsm
|
||||
* scheduler: fix wrong union field in _sched_compose_tch_ind()
|
||||
* scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind()
|
||||
* scheduler: unify argument names/order for _sched_compose_*_ind()
|
||||
* scheduler: constify *data pointer in _sched_compose_*_ind()
|
||||
* scheduler: use size_t for data_len in _sched_compose_*_ind()
|
||||
* fix bts_supports_cm(): properly check feature flags for VGCS/VBS
|
||||
* measurement: suppress unsupported tch_mode warnings for CSD
|
||||
* osmo-bts-trx: pull the AMR header in tch_dl_dequeue()
|
||||
* osmo-bts-trx: implement CSD scheduling support
|
||||
* osmo-bts-trx: implement FACCH/[FH] support for CSD
|
||||
* osmo-bts-trx: implement TCH/F2.4 support for CSD
|
||||
* osmo-bts-trx: visualize rx_tch[fh]_fn() functions
|
||||
* osmo-bts-trx: unify and enrich 'Received bad data' logging
|
||||
* osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above
|
||||
* osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs
|
||||
* osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG
|
||||
* osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference
|
||||
* osmo-bts-trx: document/clarify the meaning of BUFMAX=24
|
||||
* l1sap: proper rate adaptation for CSD (RFC4040 'clearmode')
|
||||
* csd_v110_rtp_encode(): properly set E1/E2/E3 bits
|
||||
* osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes
|
||||
* rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode
|
||||
* rsl: rsl_handle_chan_mod_ie(): do not use legacy defines
|
||||
* csd_v110: fix comments in csd_v110_rtp_{en,de}code()
|
||||
* csd_v110: properly set E1/E2/E3 for non-transparent data
|
||||
* csd_v110: handle empty/incomplete Uplink frames gracefully
|
||||
|
||||
[ Philipp Maier ]
|
||||
* pcu_sock: rename rc to fd
|
||||
* pcu_sock: cosmetic: remove whitespace after type cast
|
||||
* pcu_sock: cosmetic: remove unnecessary line breaks
|
||||
* pcu_sock: do not mess with the osmo fd flags directly
|
||||
* sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant
|
||||
* l1sap: fix wording in comment
|
||||
* pcu_sock: don not continue when running out of TRX space
|
||||
* paging: cosmetic: rename all IMM.ASS references to MAC block
|
||||
* paging: parse PCUIF data indication outside of paging.c
|
||||
* paging: do not confirm PAGING COMMAND messages
|
||||
* pcu_sock: move variable declaration of imsi[4] into related scope
|
||||
* l1sap: cosmetic: rename payload_len to rtp_pl_len
|
||||
* pcu_sock: use PCUIF version 11 (direct TLLI)
|
||||
* paging: also accept zero length IMSI strings 3
|
||||
* pcuif_proto: rename tlli to msg_id
|
||||
* pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf
|
||||
* pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
|
||||
* pcuif_proto: get rid of _DT, _dt (Direct TLLI)
|
||||
* bts: make bts_agch_dequeue static
|
||||
* pcuif_proto: use confirm flag in struct gsm_pcu_if_pch
|
||||
* pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
|
||||
* pcu_sock: print SAPI and msg_id when sending confirmation
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked
|
||||
* pcu_sock: Submit all DATA.ind regardless of link quality
|
||||
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
|
||||
* Rewrite pcu_sock_write()
|
||||
* lchan: Improve error path logging in gsm_pchan2chan_nr()
|
||||
* cosmetic: gsm_pchan2chan_nr(): Update spec documentation
|
||||
* cosmetic: bts_trx.h: Fix whitespace
|
||||
* Avoid tx RF Resource Ind for disabled TRX
|
||||
* bts-trx: Avoid pushing interf_meas for disabled TRX
|
||||
* contrib/ber: Avoid regenerating codec_bit_class.h every build
|
||||
* bts-trx: Drop unused param to internal function
|
||||
* Clarify configuration of TSC on each timeslot
|
||||
* bts_model_apply_oml(): Drop unneded code
|
||||
* oml.c: Remove dot character at the end of log lines
|
||||
* nm: Apply BTS/TRX/TS OML Attributes through NM FSMs
|
||||
* nm: Drop NM_EV_SETATTR_{ACK/NACK}
|
||||
* oml: Get rid of unused tlv_parsed param in bts_model_apply_oml()
|
||||
* bts_model_apply_oml(): Improve definition of parameter
|
||||
* lc15,oc2g,sysmo: Update GPRS NM object state at the right time
|
||||
* Simplify implementation of bts_model_opstart() in all bts types
|
||||
* nm: Apply OPSTART through NM FSMs
|
||||
* NM: NACK received OML OPSTART if no attributes were set beforehand
|
||||
* Introduce NM FSM for GPRS NSE object
|
||||
* Fix octet 2 of NM GPRS Cell
|
||||
* Introduce NM FSM for GPRS Cell object
|
||||
* Rearrange declaration of struct gsm_bts_gprs_nsvc
|
||||
* Move NSVC structs to be part of NSE
|
||||
* bts: Simplify lifecycle of BTS inside bts_list
|
||||
* Introduce NM FSM for GPRS NSVC object
|
||||
* nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children
|
||||
* Merge gsm_network into gsm_bts_sm and place gsm_bts under it
|
||||
* Move GPRS NSE under BTS SiteMgr
|
||||
* Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT
|
||||
* nm: Document current state of SW_ACT in TRX related objects
|
||||
* Properly report all states through NM FSM upon OML link up
|
||||
* Update g_bts_sm->num_bts when bts is added/removed from bts list
|
||||
* Move pcu_sock_state to gprs section of bts_sm
|
||||
* pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context
|
||||
* pcu_sock: Drop bts_sm pointer
|
||||
* oml: Fix potential null ptr access on trx object
|
||||
* bts-sysmo: Fix pinst->version filled too early
|
||||
* bts-sysmo: Delay marking phy_link as connected until L1 reset + got info
|
||||
* vty.c: Use already available tpp pointer
|
||||
* octphy: Fix clearly wrong noop assignment
|
||||
* bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART
|
||||
* Increase PCUIF wqueue size
|
||||
* bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC
|
||||
* rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change
|
||||
|
||||
[ Oliver Smith ]
|
||||
* gitignore: add vty pdf
|
||||
* doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT
|
||||
* rsl_rx_ipac_XXcx: parse csd_fmt_d/ir
|
||||
* debian: set compat level to 10
|
||||
* systemd: depend on networking-online.target
|
||||
* gitignore: add arm-poky-linux-gnueabi-libtool
|
||||
* osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status
|
||||
* osmo-bts-sysmo: activate_rf: no dispatch on fail
|
||||
* osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up
|
||||
* osmo-bts-sysmo: mute PHY until OML is ready
|
||||
|
||||
[ Harald Welte ]
|
||||
* DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET
|
||||
* cosmetic: Replace %i with %d
|
||||
* Introduce LOGPLCFN() for logging lchan-name + frame number
|
||||
* bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1
|
||||
* common/vty: Print AMR MultiRate Configuration in "show lchan"
|
||||
* bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req
|
||||
* cosmetic: use __func__ instead of __FUNCTION__
|
||||
* lc15: fix compiler warning about wrong indent
|
||||
* lc15: Remove unused warning
|
||||
* lc15/oc2g: remove unused variables
|
||||
* oc2g: Fix 'unused variable' compiler warning
|
||||
* cosmetic: Remove "FIXME?" from Odd AMR CMI phase
|
||||
* lc15: fix compiler warning about unused variable cell_size
|
||||
* Replace explicit gsm_lchan_name() calls with LOGPLCHAN
|
||||
* logging: Introduce LOGPLCGT()
|
||||
* cosmetic: Change LOGPLCFN argument order
|
||||
* paging: Add support for generating NLN/NLN-Status in P1 Rest Octets
|
||||
* Add ASCI (advanced speech call items) log sub-system
|
||||
* ASCI: NCH / NOTIFICATION support
|
||||
* validate RSL "channel rate and type" against VGCS/VBS flags
|
||||
* Store "Channel rate and type" from RSL Channel Mode IE in BTS
|
||||
* ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT
|
||||
* sysmo: Enable VGSCS + VBS feature flags
|
||||
* omldummy: Claim to support VBS + VGCS towards BSC
|
||||
|
||||
[ Mychaela N. Falconia ]
|
||||
* trx: detect UL SID in EFR just like in FR
|
||||
* sysmo: fix handling of SID in EFR
|
||||
* common: implement rtp continuous-streaming mode
|
||||
* rtp continuous-streaming: fix BFI in the quality-suppressed case
|
||||
* sysmo: emit empty RTP ticks during FACCH stealing on TCH/F
|
||||
* bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid()
|
||||
* RTP input, FR & EFR: preen incoming payloads for SID errors
|
||||
* lc15,oc2g: fix handling of SID in EFR
|
||||
* all models, FR/EFR UL: change SID check to _is_any_sid()
|
||||
* trx: remove model-specific BFI packet formats
|
||||
* refactor: replace rtppayload_is_valid() with preening before enqueue
|
||||
* all models, HR1 codec: accept both TS101318 and RFC5993 formats
|
||||
* trx: fix HR1 codec breakage from format change
|
||||
* trx, HR1 codec: change UL PHY output format to TS 101 318
|
||||
* all models, HR1 codec: select RTP output format via vty option
|
||||
* FR/HR/EFR TCH DL: implement DTX rules
|
||||
* HR1 codec: validate ToC header in RFC5993 RTP input
|
||||
* HR1 codec: act on SID indication in RFC5993 RTP input
|
||||
* trx TCH DL: transmit invalid speech blocks instead of dummy FACCH
|
||||
* ECU in UL path: make it optional per vty config
|
||||
* ECU in UL path: move state alloc/free to l1sap
|
||||
* ECU in UL path: move it from trx model to l1sap
|
||||
|
||||
[ Sylvain Munaut ]
|
||||
* contrib: Add BER testing tool
|
||||
|
||||
[ Andreas Eversberg ]
|
||||
* Change return value of bts_supports_cm() from int to bool
|
||||
* ASCI: Add function to reactivate channel
|
||||
* ASCI: Retrieve NCH position from System Information 1
|
||||
* ASCI: Add Notification CHannel (NCH) support
|
||||
* ASCI: Add support for rest octets in Paging request type 2 and 3
|
||||
* ASCI: Send only NLN on Paging request type 1 rest octets
|
||||
* ASCI: Add Notification/FACCH support
|
||||
* ASCI: Repeat UPLINK FREE message until uplink becomes busy
|
||||
* Add test cases for rest octets of Paging Requests
|
||||
* ASCI: Enable UPLINK ACCESS on various BTS models
|
||||
|
||||
[ Keith ]
|
||||
* Fix incorrect order of params passed to logging macro
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:05:30 +0200
|
||||
|
||||
osmo-bts (1.6.0) unstable; urgency=medium
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* osmo-bts-trx: call osmo_timer_del() unconditionally
|
||||
* osmo-bts-trx: amr_loop: trigger the loop unconditionally
|
||||
* osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY
|
||||
* osmo-bts-trx: rx_rach_fn(): properly detect handover RACH
|
||||
* osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst
|
||||
* osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink
|
||||
* osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi()
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* rsl: rx ipac crcx/mdcx: Log payload_type2
|
||||
* logging: Move category descriptions to be in order with enum
|
||||
* Clean up osmo-bts-*/Makefile.am
|
||||
* Split out lchan rtp socket creation from rsl handling code
|
||||
* Avoid counting lchan->dl_tch_queue length every time a msg is enqueued
|
||||
* Use libosmocore API msgb_queue_free() to free lists
|
||||
* rsl: Reduce scope of variable
|
||||
* Move lchan_dl_tch_queue_enqueue to lchan.c and make it public
|
||||
* cosmetic: Fix formatting of if-else block brackets
|
||||
* Depend on libosmo-netif
|
||||
* Clarify RTP AMR header offset in TCH enc/dec
|
||||
* tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS
|
||||
* tests/*/Makefile.am: Add missing libosmo-netif cflags
|
||||
* oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS
|
||||
* Introduce Osmux support
|
||||
* abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down
|
||||
* osmux: Log sendto() error
|
||||
* lchan: Reset Abis RTP/Osmux config during lchan release
|
||||
* vty: Fix SPEECH_MODE printed with hex prefix but dec value
|
||||
* vty: Print Osmux CID on lchans using Osmux
|
||||
* Allocate struct osmux_in_handle through new libosmo-netif APIs
|
||||
* osmux: Drop logging of osmux internal counters
|
||||
* osmux: Match remote address in osmux_lchan_find()
|
||||
* osmux: Log remote address upon rx of osmux pkt
|
||||
* osmux: Lower log level when osmux batch received for unknown CID
|
||||
* osmux: nullify osmux.rtpst after freeing it
|
||||
* osmux: Skip lchans in lookup which still have no remote associated
|
||||
* osmux: Close osmux socket when bts is freed
|
||||
* osmux: Fix null ptr dereference sending UL data before the remote is configured
|
||||
* osmux: Rotate over available Osmux CID when allocating a new one
|
||||
* osmux: Use new osmux_xfrm_input API to set name on each link
|
||||
* vty: Fix typo in write-config: osmux / local-port
|
||||
* vty: Fix typo in symbol name
|
||||
|
||||
[ Max ]
|
||||
* Set working directory in systemd service file
|
||||
* Don't manually create pid file
|
||||
* Document realtime options in .service units
|
||||
* Update realtime scheduling priority in service file
|
||||
* ctrl: take both address and port from vty config
|
||||
* Add SI10 support
|
||||
|
||||
[ Philipp Maier ]
|
||||
* pcu_sock: fix sourcecode formatting
|
||||
* measurement: do not call msgb_l3len without checking
|
||||
* l1sap: do not call msgb_l2hlen without checking
|
||||
* rsl: use unsigned int
|
||||
* pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers
|
||||
* sched_lchan_tchf: replace numeric constant with define constant
|
||||
* l1sap: remove unused pointer variable
|
||||
* pcuif_proto: use define constant to specify nax number of trx
|
||||
* pcu_sock: use ARRAY_SIZE rather then magic number
|
||||
|
||||
[ Keith ]
|
||||
* osmo-bts-trx: respond to tx-attenuation config in real time.
|
||||
|
||||
[ Harald Welte ]
|
||||
* update outdated vty copyright statement
|
||||
|
||||
[ Daniel Willmann ]
|
||||
* shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C
|
||||
* shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power
|
||||
|
||||
[ daniel ]
|
||||
* Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C"
|
||||
|
||||
[ Alexander Couzens ]
|
||||
* OML: NSVC[1] MO should have the same initial state as NVSC[0]
|
||||
|
||||
[ Oliver Smith ]
|
||||
* oc2gbts_mgr_calib: fix build against gpsd >= 3.20
|
||||
* contrib/jenkins: build libosmo-abis without dahdi
|
||||
|
||||
[ arehbein ]
|
||||
* osmo-bts: Transition to use of 'telnet_init_default'
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:15:52 +0100
|
||||
|
||||
osmo-bts (1.5.0) unstable; urgency=medium
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
|
||||
2
debian/compat
vendored
2
debian/compat
vendored
@@ -1 +1 @@
|
||||
9
|
||||
10
|
||||
|
||||
10
debian/control
vendored
10
debian/control
vendored
@@ -2,17 +2,17 @@ Source: osmo-bts
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Section: net
|
||||
Priority: optional
|
||||
Build-Depends: debhelper (>= 9),
|
||||
Build-Depends: debhelper (>= 10),
|
||||
pkg-config,
|
||||
dh-autoreconf,
|
||||
autotools-dev,
|
||||
pkg-config,
|
||||
libosmocore-dev (>= 1.7.0),
|
||||
libosmo-abis-dev (>= 1.3.0),
|
||||
libosmo-netif-dev (>= 1.2.0),
|
||||
libosmocore-dev (>= 1.9.0),
|
||||
libosmo-abis-dev (>= 1.5.0),
|
||||
libosmo-netif-dev (>= 1.4.0),
|
||||
libgps-dev,
|
||||
txt2man,
|
||||
osmo-gsm-manuals-dev (>= 1.3.0)
|
||||
osmo-gsm-manuals-dev (>= 1.5.0)
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Browser: 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_virtual_DATA = \
|
||||
virtual/osmo-bts-virtual.cfg
|
||||
EXTRA_DIST = $(doc_virtual_DATA)
|
||||
OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg
|
||||
|
||||
if ENABLE_SYSMOBTS
|
||||
doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo
|
||||
doc_sysmo_DATA = \
|
||||
sysmo/osmo-bts-sysmo.cfg \
|
||||
sysmo/sysmobts-mgr.cfg
|
||||
EXTRA_DIST += $(doc_sysmo_DATA)
|
||||
OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg
|
||||
endif
|
||||
|
||||
@@ -19,7 +32,6 @@ doc_trxdir = $(docdir)/examples/osmo-bts-trx
|
||||
doc_trx_DATA = \
|
||||
trx/osmo-bts-trx.cfg \
|
||||
trx/osmo-bts-trx-calypso.cfg
|
||||
EXTRA_DIST += $(doc_trx_DATA)
|
||||
OSMOCONF_FILES += trx/osmo-bts-trx.cfg
|
||||
endif
|
||||
|
||||
@@ -28,7 +40,6 @@ doc_octphydir = $(docdir)/examples/osmo-bts-octphy
|
||||
doc_octphy_DATA = \
|
||||
octphy/osmo-bts-trx2dsp1.cfg \
|
||||
octphy/osmo-bts-octphy.cfg
|
||||
EXTRA_DIST += $(doc_octphy_DATA)
|
||||
OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg
|
||||
endif
|
||||
|
||||
@@ -37,7 +48,6 @@ doc_lc15dir = $(docdir)/examples/osmo-bts-lc15
|
||||
doc_lc15_DATA = \
|
||||
litecell15/osmo-bts-lc15.cfg \
|
||||
litecell15/lc15bts-mgr.cfg
|
||||
EXTRA_DIST += $(doc_lc15_DATA)
|
||||
OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg
|
||||
endif
|
||||
|
||||
@@ -46,7 +56,6 @@ doc_oc2gdir = $(docdir)/examples/osmo-bts-oc2g
|
||||
doc_oc2g_DATA = \
|
||||
oc2g/osmo-bts-oc2g.cfg \
|
||||
oc2g/oc2gbts-mgr.cfg
|
||||
EXTRA_DIST += $(doc_oc2g_DATA)
|
||||
OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg
|
||||
endif
|
||||
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 0
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level temp info
|
||||
logging level fw info
|
||||
logging level find info
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
logging level rll notice
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category 0
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level temp info
|
||||
logging level fw info
|
||||
logging level find info
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
logging level rll notice
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
logging level rll notice
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
logging level rll notice
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
logging level rll notice
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level temp info
|
||||
logging level fw info
|
||||
logging level find info
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl notice
|
||||
logging level oml notice
|
||||
logging level rll notice
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
!
|
||||
log stderr
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl notice
|
||||
logging level oml notice
|
||||
logging level rll notice
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
!!
|
||||
!
|
||||
log stderr
|
||||
logging filter all 1
|
||||
logging color 0
|
||||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level rsl info
|
||||
logging level oml info
|
||||
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
|
||||
| 0x0d | RSL_SYSTEM_INFO_5bis
|
||||
| 0x0e | RSL_SYSTEM_INFO_5ter
|
||||
| 0x0f | RSL_SYSTEM_INFO_10
|
||||
| 0x47 | RSL_EXT_MEAS_ORDER
|
||||
| 0x48 | RSL_MEAS_INFO
|
||||
|===
|
||||
@@ -516,6 +517,7 @@ number*.
|
||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | 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]]
|
||||
@@ -576,6 +578,7 @@ properties of a user-plane RTP connection.
|
||||
| Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3
|
||||
| IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | 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]]
|
||||
@@ -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>>
|
||||
| 0x60 | RSL_IE_OSMO_REP_ACCH_CAP | <<RSL_IE_OSMO_REP_ACCH_CAP>>
|
||||
| 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>>
|
||||
| 0xf1 | RSL_IE_IPAC_REMOTE_PORT | <<RSL_IE_IPAC_REMOTE_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>>
|
||||
| 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>>
|
||||
| 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>>
|
||||
|===
|
||||
|
||||
@@ -1085,6 +1091,49 @@ for future use.
|
||||
| 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
|
||||
|
||||
Upon receiving the 'IPA RSL CONNECT' OML message by the respective
|
||||
|
||||
@@ -82,7 +82,7 @@ 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
|
||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||
| 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 | main() | Installation of signal handlers
|
||||
| common | abis_open() | Start of the A-bis connection to BSC
|
||||
|
||||
@@ -21,7 +21,7 @@ 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
|
||||
| common | bts_controlif_setup() | Initialization of Control Interface
|
||||
| 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 | main() | Installation of signal handlers
|
||||
| common | abis_open() | Start of the A-bis connection to BSC
|
||||
|
||||
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 = \
|
||||
abis.h \
|
||||
abis_osmo.h \
|
||||
asci.h \
|
||||
bts.h \
|
||||
bts_model.h \
|
||||
bts_shutdown_fsm.h \
|
||||
bts_sm.h \
|
||||
bts_trx.h \
|
||||
gsm_data.h \
|
||||
logging.h \
|
||||
@@ -11,6 +13,7 @@ noinst_HEADERS = \
|
||||
oml.h \
|
||||
paging.h \
|
||||
rsl.h \
|
||||
rtp_input_preen.h \
|
||||
signal.h \
|
||||
vty.h \
|
||||
amr.h \
|
||||
@@ -21,6 +24,7 @@ noinst_HEADERS = \
|
||||
tx_power.h \
|
||||
control_if.h \
|
||||
cbch.h \
|
||||
csd_v110.h \
|
||||
l1sap.h \
|
||||
lchan.h \
|
||||
power_control.h \
|
||||
@@ -30,5 +34,6 @@ noinst_HEADERS = \
|
||||
dtx_dl_amr_fsm.h \
|
||||
ta_control.h \
|
||||
nm_common_fsm.h \
|
||||
notification.h \
|
||||
osmux.h \
|
||||
$(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;
|
||||
}
|
||||
@@ -25,11 +25,21 @@ enum {
|
||||
BTS_CTR_RACH_RCVD,
|
||||
BTS_CTR_RACH_DROP,
|
||||
BTS_CTR_RACH_HO,
|
||||
BTS_CTR_RACH_VGCS,
|
||||
BTS_CTR_RACH_CS,
|
||||
BTS_CTR_RACH_PS,
|
||||
BTS_CTR_AGCH_RCVD,
|
||||
BTS_CTR_AGCH_SENT,
|
||||
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 */
|
||||
@@ -53,36 +63,28 @@ enum gsm_bts_type_variant {
|
||||
};
|
||||
const char *btsvariant2str(enum gsm_bts_type_variant v);
|
||||
|
||||
/* TODO: add a brief description of this flag */
|
||||
#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0)
|
||||
/* When this flag is set then the measurement data is included in
|
||||
enum bts_impl_flag {
|
||||
/* TODO: add a brief description of this flag */
|
||||
BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP,
|
||||
/* When this flag is set then the measurement data is included in
|
||||
* (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the
|
||||
* measurement data is passed using a separate MPH INFO MEAS IND.
|
||||
* (See also ticket: OS#2977) */
|
||||
#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1)
|
||||
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
||||
BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB,
|
||||
/* Whether the BTS model requires RadioCarrier MO to be in Enabled state
|
||||
* (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */
|
||||
#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2)
|
||||
/* Whether the BTS model reports interference measurements to L1SAP. */
|
||||
#define BTS_INTERNAL_FLAG_INTERF_MEAS (1 << 3)
|
||||
BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER,
|
||||
/* 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) */
|
||||
#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) \
|
||||
bts->flags |= (typeof(bts->flags)) flag
|
||||
|
||||
struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_bts *bts;
|
||||
/* data read via VTY config file, to configure the BTS
|
||||
* via OML from BSC */
|
||||
int id;
|
||||
uint16_t nsvci;
|
||||
struct osmo_sockaddr local; /* on the BTS */
|
||||
struct osmo_sockaddr remote; /* on the SGSN */
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
};
|
||||
bts->flags |= (typeof(bts->flags))(1 << flag)
|
||||
|
||||
struct gprs_rlc_cfg {
|
||||
uint16_t parameter[_NUM_RLC_PAR];
|
||||
@@ -131,9 +133,15 @@ struct bts_power_ctrl_params {
|
||||
} pf;
|
||||
};
|
||||
|
||||
/* BTS Site Manager */
|
||||
struct gsm_bts_sm {
|
||||
/* GPRS CELL; ip.access specific NM Object */
|
||||
struct gsm_gprs_cell {
|
||||
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) */
|
||||
@@ -142,9 +150,11 @@ struct bsc_oml_host {
|
||||
char *addr;
|
||||
};
|
||||
|
||||
#define BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
|
||||
|
||||
/* One BTS */
|
||||
struct gsm_bts {
|
||||
/* list header in net->bts_list */
|
||||
/* list header in g_bts_sm->bts_list */
|
||||
struct llist_head list;
|
||||
|
||||
/* number of the BTS in network */
|
||||
@@ -158,6 +168,7 @@ struct gsm_bts {
|
||||
/* Base Station Identification Code (BSIC), lower 3 bits is BCC,
|
||||
* which is used as TSC for the CCCH */
|
||||
uint8_t bsic;
|
||||
bool bsic_configured;
|
||||
/* type of BTS */
|
||||
enum gsm_bts_type_variant variant;
|
||||
enum gsm_band band;
|
||||
@@ -193,7 +204,7 @@ struct gsm_bts {
|
||||
/* CCCH is on 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 */
|
||||
uint32_t si_valid;
|
||||
@@ -223,18 +234,7 @@ struct gsm_bts {
|
||||
|
||||
/* Not entirely sure how ip.access specific this is */
|
||||
struct {
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
uint16_t nsei;
|
||||
uint8_t timer[7];
|
||||
} nse;
|
||||
struct {
|
||||
struct gsm_abis_mo mo;
|
||||
uint16_t bvci;
|
||||
uint8_t timer[11];
|
||||
struct gprs_rlc_cfg rlc_cfg;
|
||||
} cell;
|
||||
struct gsm_bts_gprs_nsvc nsvc[2];
|
||||
struct gsm_gprs_cell cell;
|
||||
uint8_t rac;
|
||||
} gprs;
|
||||
|
||||
@@ -250,8 +250,9 @@ struct gsm_bts {
|
||||
int16_t boundary[6];
|
||||
uint8_t intave;
|
||||
} interference;
|
||||
unsigned int t200_ms[7];
|
||||
uint32_t t200_fn[7];
|
||||
unsigned int t3105_ms;
|
||||
unsigned int t3115_ms; /* VGCS UPLINK GRANT repeat timer */
|
||||
struct {
|
||||
uint8_t overload_period;
|
||||
struct {
|
||||
@@ -274,6 +275,7 @@ struct gsm_bts {
|
||||
} rach;
|
||||
} load;
|
||||
uint8_t ny1;
|
||||
uint8_t ny2; /* maximum number of repetitions for the VGCS UPLINK GRANT */
|
||||
uint8_t max_ta;
|
||||
|
||||
/* AGCH queuing */
|
||||
@@ -303,6 +305,15 @@ struct gsm_bts {
|
||||
bool pni; /* Primary Notification Identifier */
|
||||
} 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 llist_head bsc_oml_hosts;
|
||||
unsigned int rtp_jitter_buf_ms;
|
||||
@@ -314,8 +325,13 @@ struct gsm_bts {
|
||||
int rtp_ip_dscp;
|
||||
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 {
|
||||
uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */
|
||||
uint8_t max_ta; /* maximum timing advance */
|
||||
} support;
|
||||
struct {
|
||||
uint8_t tc4_ctr;
|
||||
@@ -360,20 +376,25 @@ struct gsm_bts {
|
||||
|
||||
struct {
|
||||
char *sock_path;
|
||||
unsigned int sock_wqueue_len_max;
|
||||
} pcu;
|
||||
|
||||
/* GSMTAP Um logging (disabled by default) */
|
||||
struct {
|
||||
struct gsmtap_inst *inst;
|
||||
char *remote_host;
|
||||
char *local_host;
|
||||
uint32_t sapi_mask;
|
||||
uint8_t sapi_acch;
|
||||
bool rlp;
|
||||
bool rlp_skip_null;
|
||||
} gsmtap;
|
||||
|
||||
struct osmux_state osmux;
|
||||
|
||||
struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */
|
||||
bool shutdown_fi_exit_proc; /* exit process when shutdown_fsm is finished? */
|
||||
bool shutdown_fi_skip_power_ramp; /* Skip power ramping and change power in one step? */
|
||||
struct osmo_fsm_inst *abis_link_fi; /* FSM instance to manage abis connection during process startup and link failure */
|
||||
struct osmo_tdef *T_defs; /* Timer defines */
|
||||
|
||||
@@ -387,24 +408,30 @@ extern void *tall_bts_ctx;
|
||||
#define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i))
|
||||
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
||||
|
||||
static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) {
|
||||
return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr);
|
||||
static inline struct gsm_bts *gsm_gprs_cell_get_bts(struct gsm_gprs_cell *cell)
|
||||
{
|
||||
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_num(const struct gsm_network *net, int 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_bts_sm *bts_sm, int num);
|
||||
|
||||
int bts_init(struct gsm_bts *bts);
|
||||
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_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_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);
|
||||
uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time);
|
||||
void regenerate_si3_restoctets(struct gsm_bts *bts);
|
||||
@@ -420,7 +447,7 @@ struct gsm_time *get_time(struct gsm_bts *bts);
|
||||
|
||||
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);
|
||||
|
||||
int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts);
|
||||
@@ -430,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);
|
||||
|
||||
/* 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 */
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/protocol/gsm_12_21.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,
|
||||
void *obj);
|
||||
|
||||
int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
|
||||
struct tlv_parsed *new_attr, int obj_kind, void *obj);
|
||||
int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg,
|
||||
struct gsm_abis_mo *mo, void *obj);
|
||||
|
||||
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
|
||||
void *obj);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
|
||||
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
|
||||
|
||||
#include <osmocom/core/sockaddr_str.h>
|
||||
#include <osmo-bts/gsm_data.h>
|
||||
|
||||
struct gsm_bts_bb_trx {
|
||||
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 */
|
||||
@@ -16,9 +23,6 @@ struct gsm_bts_trx {
|
||||
uint8_t nr;
|
||||
/* human readable name / description */
|
||||
char *description;
|
||||
/* how do we talk RSL with this TRX? */
|
||||
uint8_t rsl_tei;
|
||||
struct e1inp_sign_link *rsl_link;
|
||||
|
||||
/* NM Radio Carrier and Baseband Transciever */
|
||||
struct gsm_abis_mo mo;
|
||||
@@ -40,6 +44,12 @@ struct gsm_bts_trx {
|
||||
/* The associated PHY instance */
|
||||
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];
|
||||
};
|
||||
|
||||
@@ -58,6 +68,7 @@ int trx_link_estab(struct gsm_bts_trx *trx);
|
||||
void trx_operability_update(struct gsm_bts_trx *trx);
|
||||
|
||||
uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg);
|
||||
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);
|
||||
|
||||
#define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#pragma once
|
||||
|
||||
int bts_ctrl_cmds_install(struct gsm_bts *bts);
|
||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
||||
const char *bind_addr, uint16_t port);
|
||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port);
|
||||
|
||||
23
include/osmo-bts/csd_v110.h
Normal file
23
include/osmo-bts/csd_v110.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
/* RFC4040 "clearmode" RTP payload length */
|
||||
#define RFC4040_RTP_PLEN 160
|
||||
|
||||
struct gsm_lchan;
|
||||
|
||||
struct csd_v110_frame_desc {
|
||||
uint16_t num_blocks;
|
||||
uint16_t num_bits;
|
||||
};
|
||||
|
||||
struct csd_v110_lchan_desc {
|
||||
struct csd_v110_frame_desc fr;
|
||||
struct csd_v110_frame_desc hr;
|
||||
};
|
||||
|
||||
extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256];
|
||||
|
||||
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
|
||||
const uint8_t *data, size_t data_len);
|
||||
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||
const uint8_t *rtp, size_t rtp_len);
|
||||
@@ -41,12 +41,6 @@
|
||||
#define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41
|
||||
#define GSM_BTS_AGCH_QUEUE_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:
|
||||
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,
|
||||
use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */
|
||||
#define CCCH_LCHAN 4
|
||||
#define CBCH_LCHAN 2
|
||||
|
||||
#define TRX_NR_TS 8
|
||||
#define TS_MAX_LCHAN 8
|
||||
|
||||
#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 {
|
||||
TS_F_PDCH_ACTIVE = 0x1000,
|
||||
TS_F_PDCH_ACT_PENDING = 0x2000,
|
||||
@@ -90,7 +131,10 @@ struct gsm_bts_trx_ts {
|
||||
|
||||
/* Training Sequence Code (range 0..7) */
|
||||
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) */
|
||||
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);
|
||||
|
||||
void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts);
|
||||
|
||||
void gsm_ts_release(struct gsm_bts_trx_ts *ts);
|
||||
|
||||
#endif /* _GSM_DATA_H */
|
||||
|
||||
@@ -102,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_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_uplink_access(struct gsm_lchan *lchan, bool active);
|
||||
|
||||
enum l1sap_common_sapi {
|
||||
L1SAP_COMMON_SAPI_UNKNOWN,
|
||||
@@ -141,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)
|
||||
|
||||
void radio_link_timeout_reset(struct gsm_lchan *lchan);
|
||||
|
||||
int bts_check_for_first_ciphrd(struct gsm_lchan *lchan,
|
||||
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 */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/logging.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/codec/codec.h>
|
||||
#include <osmocom/codec/ecu.h>
|
||||
#include <osmocom/gsm/lapdm.h>
|
||||
#include <osmocom/gsm/sysinfo.h>
|
||||
@@ -74,15 +75,17 @@ struct amr_multirate_conf {
|
||||
};
|
||||
|
||||
enum lchan_csd_mode {
|
||||
LCHAN_CSD_M_NT,
|
||||
LCHAN_CSD_M_NT = 0,
|
||||
LCHAN_CSD_M_T_1200_75,
|
||||
LCHAN_CSD_M_T_600,
|
||||
LCHAN_CSD_M_T_1200,
|
||||
LCHAN_CSD_M_T_2400,
|
||||
LCHAN_CSD_M_T_4800,
|
||||
LCHAN_CSD_M_T_9600,
|
||||
LCHAN_CSD_M_T_14400,
|
||||
LCHAN_CSD_M_T_29000,
|
||||
LCHAN_CSD_M_T_32000,
|
||||
_LCHAN_CSD_M_NUM,
|
||||
};
|
||||
|
||||
/* State of the SAPIs in the lchan */
|
||||
@@ -140,6 +143,8 @@ struct gsm_lchan {
|
||||
uint8_t nr;
|
||||
/* The logical channel type */
|
||||
enum gsm_chan_t type;
|
||||
/* RSL channel rate and type */
|
||||
enum rsl_cmod_crt rsl_chan_rt;
|
||||
/* RSL channel mode */
|
||||
enum rsl_cmod_spd rsl_cmode;
|
||||
/* If TCH, traffic channel mode */
|
||||
@@ -163,6 +168,7 @@ struct gsm_lchan {
|
||||
uint16_t conn_id;
|
||||
uint8_t rtp_payload;
|
||||
uint8_t rtp_payload2;
|
||||
uint8_t rtp_extensions;
|
||||
uint8_t speech_mode;
|
||||
struct {
|
||||
bool use;
|
||||
@@ -203,6 +209,8 @@ struct gsm_lchan {
|
||||
uint8_t sapis_dl[23];
|
||||
uint8_t sapis_ul[23];
|
||||
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;
|
||||
unsigned int dl_tch_queue_len;
|
||||
struct {
|
||||
@@ -265,9 +273,26 @@ struct gsm_lchan {
|
||||
/* last UL SPEECH resume flag */
|
||||
bool is_speech_resume;
|
||||
} dtx;
|
||||
struct {
|
||||
bool last_rtp_input_was_sid;
|
||||
uint8_t last_sid[GSM_FR_BYTES];
|
||||
uint8_t last_sid_len;
|
||||
uint8_t last_sid_age;
|
||||
/* A SID was transmitted on the DL in the period
|
||||
* beginning with the last transmitted speech frame
|
||||
* or the last mandatory-Tx position, whichever was
|
||||
* more recent. */
|
||||
bool dl_sid_transmitted;
|
||||
/* The current frame in the DL is taken up by FACCH */
|
||||
bool dl_facch_stealing;
|
||||
} dtx_fr_hr_efr;
|
||||
uint8_t last_cmr;
|
||||
uint32_t last_fn;
|
||||
|
||||
struct {
|
||||
/* buffers to re-combine RLP frame from multiple Um blocks */
|
||||
uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */
|
||||
uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */
|
||||
} csd;
|
||||
} tch;
|
||||
|
||||
/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
|
||||
@@ -287,6 +312,19 @@ struct gsm_lchan {
|
||||
/* counts up to Ny1 */
|
||||
unsigned int phys_info_count;
|
||||
} 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 */
|
||||
int s;
|
||||
/* Kind of the release/activation. E.g. RSL or PCU */
|
||||
|
||||
@@ -21,6 +21,7 @@ enum {
|
||||
DABIS,
|
||||
DRTP,
|
||||
DOSMUX,
|
||||
DASCI,
|
||||
};
|
||||
|
||||
extern const struct log_info bts_log_info;
|
||||
@@ -37,4 +38,12 @@ extern const struct log_info bts_log_info;
|
||||
#define DEBUGPFN(ss, fn, fmt, args...) \
|
||||
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 */
|
||||
|
||||
@@ -22,6 +22,9 @@ struct msgb;
|
||||
/* Access 3rd part of msgb control buffer */
|
||||
#define rtpmsg_ts(x) ((x)->cb[2])
|
||||
|
||||
/* Access 4th part of msgb control buffer */
|
||||
#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3])
|
||||
|
||||
/**
|
||||
* Classification of OML message. ETSI for plain GSM 12.21
|
||||
* messages and IPA/Osmo for manufacturer messages.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
|
||||
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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -14,7 +14,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -30,18 +30,18 @@
|
||||
/* Common */
|
||||
enum nm_fsm_events {
|
||||
NM_EV_SW_ACT,
|
||||
NM_EV_SETATTR_ACK, /* data: struct nm_fsm_ev_setattr_data */
|
||||
NM_EV_SETATTR_NACK, /* data: struct nm_fsm_ev_setattr_data */
|
||||
NM_EV_RX_SETATTR, /* data: struct nm_fsm_ev_setattr_data */
|
||||
NM_EV_RX_OPSTART,
|
||||
NM_EV_OPSTART_ACK,
|
||||
NM_EV_OPSTART_NACK,
|
||||
NM_EV_SHUTDOWN_START,
|
||||
NM_EV_SHUTDOWN_FINISH,
|
||||
NM_EV_OML_UP,
|
||||
NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||
NM_EV_RSL_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
||||
NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */
|
||||
NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
|
||||
NM_EV_DISABLE, /* RadioCarrier and BaseBand Transceiver only */
|
||||
NM_EV_BBTRANSC_INSTALLED, /* Radio Channel only */
|
||||
NM_EV_BBTRANSC_ENABLED, /* Radio Channel only */
|
||||
NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */
|
||||
NM_EV_RCARRIER_ENABLED, /* Radio Channel only */
|
||||
@@ -50,8 +50,7 @@ enum nm_fsm_events {
|
||||
extern const struct value_string nm_fsm_event_names[];
|
||||
|
||||
struct nm_fsm_ev_setattr_data {
|
||||
struct msgb *msg; /* msgb ownership is transferred to FSM */
|
||||
int cause;
|
||||
const struct msgb *msg;
|
||||
};
|
||||
|
||||
|
||||
@@ -95,3 +94,30 @@ enum nm_chan_op_fsm_states {
|
||||
NM_CHAN_ST_OP_ENABLED,
|
||||
};
|
||||
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_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,
|
||||
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 */
|
||||
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);
|
||||
|
||||
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,
|
||||
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 */
|
||||
|
||||
@@ -7,6 +7,55 @@
|
||||
|
||||
struct paging_state;
|
||||
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 */
|
||||
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,
|
||||
const uint8_t *identity_lv, uint8_t chan_needed);
|
||||
|
||||
/* Add an IMM.ASS message to the paging queue */
|
||||
int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data,
|
||||
uint8_t len, bool from_pcu);
|
||||
/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a
|
||||
* PAGING COMMAND (from the 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 */
|
||||
int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt,
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include <osmo-bts/pcuif_proto.h>
|
||||
|
||||
struct gsm_bts_sm;
|
||||
|
||||
extern int pcu_direct;
|
||||
|
||||
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
|
||||
@@ -21,11 +23,11 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
|
||||
int pcu_tx_time_ind(uint32_t fn);
|
||||
int pcu_tx_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_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_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);
|
||||
|
||||
bool pcu_connected(void);
|
||||
|
||||
@@ -3,20 +3,20 @@
|
||||
|
||||
#include <osmocom/gsm/l1sap.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
|
||||
#define PCU_SOCK_DEFAULT "/tmp/pcu_bts"
|
||||
|
||||
#define PCU_IF_VERSION 0x0a
|
||||
#define PCU_IF_VERSION 0x0c
|
||||
#define TXT_MAX_LEN 128
|
||||
|
||||
/* msg_type */
|
||||
#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_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_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_INFO_IND 0x32 /* retrieve BTS info */
|
||||
#define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */
|
||||
@@ -28,17 +28,16 @@
|
||||
|
||||
/* sapi */
|
||||
#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_PDTCH 0x05 /* packet data/control/ccch block */
|
||||
#define PCU_IF_SAPI_PRACH 0x06 /* packet random access 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 */
|
||||
#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_CS2 (1 << 17)
|
||||
#define PCU_IF_FLAG_CS3 (1 << 18)
|
||||
@@ -58,6 +57,17 @@
|
||||
#define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 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
|
||||
|
||||
@@ -86,19 +96,10 @@ struct gsm_pcu_if_data {
|
||||
int16_t lqual_cb; /* !< \brief Link quality in centiBel */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* data confirmation with direct tlli (instead of raw mac block with tlli) */
|
||||
struct gsm_pcu_if_data_cnf_dt {
|
||||
/* data confirmation with message id (instead of raw mac block) */
|
||||
struct gsm_pcu_if_data_cnf {
|
||||
uint8_t sapi;
|
||||
uint32_t tlli;
|
||||
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 */
|
||||
uint32_t msg_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm_pcu_if_rts_req {
|
||||
@@ -180,6 +181,7 @@ struct gsm_pcu_if_info_ind {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
} remote_ip[PCU_IF_NUM_NSVC];
|
||||
uint8_t bts_model; /* enum gsm_pcuif_bts_model */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct gsm_pcu_if_act_req {
|
||||
@@ -229,6 +231,32 @@ struct gsm_pcu_if_container {
|
||||
uint8_t data[0];
|
||||
} __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 {
|
||||
/* context based information */
|
||||
uint8_t msg_type; /* message type */
|
||||
@@ -237,8 +265,7 @@ struct gsm_pcu_if {
|
||||
|
||||
union {
|
||||
struct gsm_pcu_if_data data_req;
|
||||
struct gsm_pcu_if_data data_cnf;
|
||||
struct gsm_pcu_if_data_cnf_dt data_cnf_dt;
|
||||
struct gsm_pcu_if_data_cnf data_cnf2;
|
||||
struct gsm_pcu_if_data data_ind;
|
||||
struct gsm_pcu_if_susp_req susp_req;
|
||||
struct gsm_pcu_if_rts_req rts_req;
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#define LCHAN_FN_DUMMY 0xFFFFFFFF
|
||||
#define LCHAN_FN_WAIT 0xFFFFFFFE
|
||||
|
||||
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 rsl_tx_rf_res(struct gsm_bts_trx *trx);
|
||||
int rsl_tx_chan_rqd(struct gsm_bts_trx *trx, struct gsm_time *gtime,
|
||||
@@ -14,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_rf_rel_ack(struct gsm_lchan *lchan);
|
||||
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 */
|
||||
int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx);
|
||||
|
||||
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>
|
||||
|
||||
/* 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) \
|
||||
_sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc]
|
||||
|
||||
@@ -97,10 +90,10 @@ struct l1sched_chan_state {
|
||||
bool active; /* Channel is active */
|
||||
ubit_t *dl_bursts; /* burst buffer for TX */
|
||||
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_prev;/* previous burst buffer for RX (repeated SACCH) */
|
||||
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 */
|
||||
uint32_t last_tdma_fn; /* last processed TDMA frame number */
|
||||
@@ -138,7 +131,7 @@ struct l1sched_chan_state {
|
||||
/* Uplink measurements */
|
||||
struct {
|
||||
/* 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 */
|
||||
|
||||
/* Interference measurements */
|
||||
@@ -192,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 */
|
||||
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) */
|
||||
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,
|
||||
@@ -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() */
|
||||
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) */
|
||||
SCHED_MEAS_AVG_M_S4N4,
|
||||
/* 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);
|
||||
|
||||
int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn,
|
||||
enum trx_chan_type chan, uint8_t *l2,
|
||||
uint8_t l2_len, float rssi,
|
||||
enum trx_chan_type chan,
|
||||
const uint8_t *data, size_t data_len,
|
||||
uint16_t ber10k, float rssi,
|
||||
int16_t ta_offs_256bits, int16_t link_qual_cb,
|
||||
uint16_t ber10k,
|
||||
enum osmo_ph_pres_info_type presence_info);
|
||||
|
||||
int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn,
|
||||
enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len,
|
||||
int16_t ta_offs_256bits, uint16_t ber10k, float rssi,
|
||||
int16_t link_qual_cb, uint8_t is_sub);
|
||||
enum trx_chan_type chan,
|
||||
const uint8_t *data, size_t data_len,
|
||||
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_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_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_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm);
|
||||
|
||||
@@ -21,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);
|
||||
|
||||
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);
|
||||
|
||||
struct gsm_network *gsmnet_from_vty(struct vty *v);
|
||||
|
||||
extern struct vty_app_info bts_vty_info;
|
||||
extern struct gsm_bts *g_bts;
|
||||
|
||||
|
||||
@@ -33,12 +33,15 @@ libbts_a_SOURCES = \
|
||||
oml.c \
|
||||
osmux.c \
|
||||
bts.c \
|
||||
bts_sm.c \
|
||||
bts_trx.c \
|
||||
rsl.c \
|
||||
rtp_input_preen.c \
|
||||
vty.c \
|
||||
paging.c \
|
||||
measurement.c \
|
||||
amr.c \
|
||||
asci.c \
|
||||
lchan.c \
|
||||
load_indication.c \
|
||||
pcu_sock.c \
|
||||
@@ -48,6 +51,7 @@ libbts_a_SOURCES = \
|
||||
bts_ctrl_commands.c \
|
||||
bts_ctrl_lookup.c \
|
||||
bts_shutdown_fsm.c \
|
||||
csd_v110.c \
|
||||
l1sap.c \
|
||||
cbch.c \
|
||||
power_control.c \
|
||||
@@ -61,7 +65,11 @@ libbts_a_SOURCES = \
|
||||
nm_bts_fsm.c \
|
||||
nm_bb_transc_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 \
|
||||
notification.c \
|
||||
probes.d \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -225,9 +225,9 @@ static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *
|
||||
|
||||
/* Then iterate over the RSL signalling links */
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
if (trx->rsl_link) {
|
||||
e1inp_sign_link_destroy(trx->rsl_link);
|
||||
trx->rsl_link = NULL;
|
||||
if (trx->bb_transc.rsl.link) {
|
||||
e1inp_sign_link_destroy(trx->bb_transc.rsl.link);
|
||||
trx->bb_transc.rsl.link = NULL;
|
||||
if (trx == trx->bts->c0)
|
||||
load_timer_stop(trx->bts);
|
||||
} else {
|
||||
@@ -364,7 +364,7 @@ int abis_bts_rsl_sendmsg(struct msgb *msg)
|
||||
|
||||
/* osmo-bts uses msg->trx internally, but libosmo-abis uses
|
||||
* the signalling link at msg->dst */
|
||||
msg->dst = msg->trx->rsl_link;
|
||||
msg->dst = msg->trx->bb_transc.rsl.link;
|
||||
return abis_sendmsg(msg);
|
||||
}
|
||||
|
||||
@@ -404,10 +404,10 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line,
|
||||
break;
|
||||
}
|
||||
e1inp_ts_config_sign(sign_ts, line);
|
||||
trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||
trx, trx->rsl_tei, 0);
|
||||
trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL,
|
||||
trx, trx->bb_transc.rsl.tei, 0);
|
||||
trx_link_estab(trx);
|
||||
return trx->rsl_link;
|
||||
return trx->bb_transc.rsl.link;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -30,8 +30,7 @@
|
||||
#include <osmo-bts/logging.h>
|
||||
#include <osmo-bts/pcu_if.h>
|
||||
#include <osmo-bts/pcuif_proto.h>
|
||||
|
||||
extern struct gsm_network bts_gsmnet;
|
||||
#include <osmo-bts/bts_sm.h>
|
||||
|
||||
#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: */
|
||||
msgb_pull_to_l2(msg);
|
||||
/* 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 */
|
||||
|
||||
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;
|
||||
}
|
||||
280
src/common/bts.c
280
src/common/bts.c
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -44,8 +44,10 @@
|
||||
#include <osmo-bts/abis.h>
|
||||
#include <osmo-bts/bts.h>
|
||||
#include <osmo-bts/bts_model.h>
|
||||
#include <osmo-bts/bts_sm.h>
|
||||
#include <osmo-bts/dtx_dl_amr_fsm.h>
|
||||
#include <osmo-bts/pcuif_proto.h>
|
||||
#include <osmo-bts/pcu_if.h>
|
||||
#include <osmo-bts/rsl.h>
|
||||
#include <osmo-bts/oml.h>
|
||||
#include <osmo-bts/signal.h>
|
||||
@@ -55,17 +57,14 @@
|
||||
#include <osmo-bts/nm_common_fsm.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_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */
|
||||
|
||||
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;
|
||||
|
||||
/* Table 3.1 TS 04.08: Values of parameter S */
|
||||
@@ -98,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_DROP] = {"rach:drop", "Dropped RACH requests (Um)"},
|
||||
[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_PS] = {"rach:ps", "Received RACH requests (PS/PCU)"},
|
||||
|
||||
[BTS_CTR_AGCH_RCVD] = {"agch:rcvd", "Received 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_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 = {
|
||||
"bts",
|
||||
@@ -149,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[] =
|
||||
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
||||
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
||||
@@ -207,15 +215,16 @@ const char *btsatttr2str(enum bts_attribute v)
|
||||
const struct value_string bts_impl_flag_desc[] = {
|
||||
{ BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" },
|
||||
{ BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" },
|
||||
{ BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, "OML RadioChannel MO depends on RadioCarrier MO" },
|
||||
{ BTS_INTERNAL_FLAG_INTERF_MEAS, "Uplink interference measurements" },
|
||||
{ 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)
|
||||
{
|
||||
if (bts->site_mgr.mo.fi) {
|
||||
osmo_fsm_inst_free(bts->site_mgr.mo.fi);
|
||||
bts->site_mgr.mo.fi = NULL;
|
||||
}
|
||||
if (bts->mo.fi) {
|
||||
osmo_fsm_inst_free(bts->mo.fi);
|
||||
bts->mo.fi = NULL;
|
||||
@@ -226,19 +235,26 @@ static int gsm_bts_talloc_destructor(struct gsm_bts *bts)
|
||||
}
|
||||
|
||||
bts_osmux_release(bts);
|
||||
|
||||
llist_del(&bts->list);
|
||||
g_bts_sm->num_bts--;
|
||||
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);
|
||||
int i;
|
||||
struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts);
|
||||
|
||||
if (!bts)
|
||||
return NULL;
|
||||
|
||||
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->num_trx = 0;
|
||||
INIT_LLIST_HEAD(&bts->trx_list);
|
||||
@@ -251,32 +267,19 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr);
|
||||
|
||||
bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr,
|
||||
LOGL_INFO, "bts_sm");
|
||||
gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER,
|
||||
0xff, 0xff, 0xff);
|
||||
|
||||
/* NM BTS */
|
||||
bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts,
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr);
|
||||
gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) {
|
||||
bts->gprs.nsvc[i].bts = bts;
|
||||
bts->gprs.nsvc[i].id = i;
|
||||
gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC,
|
||||
bts->nr, i, 0xff);
|
||||
}
|
||||
memcpy(&bts->gprs.nse.timer, bts_nse_timer_default,
|
||||
sizeof(bts->gprs.nse.timer));
|
||||
gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE,
|
||||
bts->nr, 0xff, 0xff);
|
||||
memcpy(&bts->gprs.cell.timer, bts_cell_timer_default,
|
||||
sizeof(bts->gprs.cell.timer));
|
||||
gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL,
|
||||
bts->nr, 0xff, 0xff);
|
||||
memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default,
|
||||
sizeof(bts->gprs.cell.rlc_cfg));
|
||||
/* NM GPRS CELL */
|
||||
bts->gprs.cell.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_cell_fsm, bts, &bts->gprs.cell,
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(bts->gprs.cell.mo.fi, "gprs_cell%d-0", bts->nr);
|
||||
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.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer));
|
||||
|
||||
/* create our primary TRX. It will be initialized during bts_init() */
|
||||
bts->c0 = gsm_bts_trx_alloc(bts);
|
||||
@@ -292,14 +295,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num)
|
||||
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;
|
||||
|
||||
if (num >= net->num_bts)
|
||||
if (num >= bts_sm->num_bts)
|
||||
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)
|
||||
return bts;
|
||||
}
|
||||
@@ -315,19 +318,14 @@ int bts_init(struct gsm_bts *bts)
|
||||
static int initialized = 0;
|
||||
void *tall_rtp_ctx;
|
||||
|
||||
/* add to list of BTSs */
|
||||
llist_add_tail(&bts->list, &bts_gsmnet.bts_list);
|
||||
|
||||
bts->band = GSM_BAND_1800;
|
||||
|
||||
INIT_LLIST_HEAD(&bts->agch_queue.queue);
|
||||
bts->agch_queue.length = 0;
|
||||
|
||||
bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr);
|
||||
if (!bts->ctrs) {
|
||||
llist_del(&bts->list);
|
||||
if (!bts->ctrs)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* enable management with default levels,
|
||||
* raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to
|
||||
@@ -345,37 +343,37 @@ int bts_init(struct gsm_bts *bts)
|
||||
bts->rtp_port_range_next = bts->rtp_port_range_start;
|
||||
bts->rtp_ip_dscp = -1;
|
||||
bts->rtp_priority = -1;
|
||||
bts->emit_hr_rfc5993 = true;
|
||||
|
||||
/* Default (fall-back) MS/BS Power control parameters */
|
||||
power_ctrl_params_def_reset(&bts->bs_dpc_params, true);
|
||||
power_ctrl_params_def_reset(&bts->ms_dpc_params, false);
|
||||
|
||||
/* configurable via OML */
|
||||
bts->bsic = 0xff; /* invalid value, guarded by bsc_configured=false */
|
||||
bts->bsic_configured = false;
|
||||
bts->load.ccch.load_ind_period = 112;
|
||||
bts->rtp_jitter_buf_ms = 100;
|
||||
bts->max_ta = 63;
|
||||
bts->max_ta = MAX_TA_DEF;
|
||||
bts->ny1 = 4;
|
||||
bts->ny2 = 4;
|
||||
bts->t3105_ms = 300;
|
||||
bts->t3115_ms = 300;
|
||||
bts->min_qual_rach = MIN_QUAL_RACH;
|
||||
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->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT);
|
||||
for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++)
|
||||
bts->t200_ms[i] = oml_default_t200_ms[i];
|
||||
bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT;
|
||||
for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++)
|
||||
bts->t200_fn[i] = oml_default_t200_fn[i];
|
||||
|
||||
/* default RADIO_LINK_TIMEOUT */
|
||||
bts->radio_link_timeout.oml = 32;
|
||||
bts->radio_link_timeout.current = bts->radio_link_timeout.oml;
|
||||
|
||||
/* Start with the site manager */
|
||||
oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||
/* Start with the BTS */
|
||||
oml_mo_state_init(&bts->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_DEPENDENCY);
|
||||
oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||
|
||||
/* allocate a talloc pool for ORTP to ensure it doesn't have to go back
|
||||
* to the libc malloc all the time */
|
||||
@@ -384,10 +382,8 @@ int bts_init(struct gsm_bts *bts)
|
||||
|
||||
/* Osmux */
|
||||
rc = bts_osmux_init(bts);
|
||||
if (rc < 0) {
|
||||
llist_del(&bts->list);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* features implemented in 'common', available for all models,
|
||||
* order alphabetically */
|
||||
@@ -397,16 +393,17 @@ 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_IPV6_NSVC);
|
||||
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
|
||||
osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS001);
|
||||
|
||||
/* Maximum TA supported by the PHY (can be overridden by PHY specific code) */
|
||||
bts->support.max_ta = MAX_TA_DEF;
|
||||
|
||||
rc = bts_model_init(bts);
|
||||
if (rc < 0) {
|
||||
llist_del(&bts->list);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */
|
||||
bts_model_trx_init(bts->c0);
|
||||
bts_gsmnet.num_bts++;
|
||||
|
||||
if (!initialized) {
|
||||
osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL);
|
||||
@@ -423,6 +420,9 @@ int bts_init(struct gsm_bts *bts)
|
||||
bts->smscb_queue_tgt_len = 2;
|
||||
bts->smscb_queue_hyst = 2;
|
||||
|
||||
bts->asci.pos_nch = -ENOTSUP;
|
||||
INIT_LLIST_HEAD(&bts->asci.notifications);
|
||||
|
||||
INIT_LLIST_HEAD(&bts->bsc_oml_hosts);
|
||||
|
||||
/* register DTX DL FSM */
|
||||
@@ -440,33 +440,13 @@ int bts_init(struct gsm_bts *bts)
|
||||
/* main link is established, send status report */
|
||||
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");
|
||||
|
||||
/* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
/* Signal OML UP to BTS SITE MGR. It will automatically SW_ACT repoort
|
||||
* and become Disabled-Offline, then dispatch same event to its children
|
||||
* objects.
|
||||
*/
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_UP, NULL);
|
||||
|
||||
return bts_model_oml_estab(bts);
|
||||
}
|
||||
@@ -693,7 +673,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
|
||||
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);
|
||||
if (!msg)
|
||||
@@ -759,12 +739,12 @@ static void compact_agch_queue(struct gsm_bts *bts)
|
||||
return;
|
||||
}
|
||||
|
||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt,
|
||||
int is_ag_res)
|
||||
int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch)
|
||||
{
|
||||
struct msgb *msg = NULL;
|
||||
int rc = 0;
|
||||
int is_empty = 1;
|
||||
const struct bts_agch_msg_cb *msg_cb;
|
||||
|
||||
/* Do queue house keeping.
|
||||
* This needs to be done every time a CCCH message is requested, since
|
||||
@@ -773,26 +753,39 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt
|
||||
*/
|
||||
compact_agch_queue(bts);
|
||||
|
||||
/* Check for paging messages first if this is PCH */
|
||||
if (!is_ag_res)
|
||||
switch (ccch) {
|
||||
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);
|
||||
|
||||
/* Check whether the block may be overwritten */
|
||||
if (!is_empty)
|
||||
return rc;
|
||||
|
||||
/* fall-through */
|
||||
case CCCH_MSGT_AGCH:
|
||||
/* If fallen here and the AGCH queue is empty, return empty PCH message. */
|
||||
msg = bts_agch_dequeue(bts);
|
||||
if (!msg)
|
||||
return rc;
|
||||
/* Continue to return AGCH message. */
|
||||
break;
|
||||
}
|
||||
|
||||
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 */
|
||||
memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg));
|
||||
rc = msgb_l3len(msg);
|
||||
msgb_free(msg);
|
||||
|
||||
if (is_ag_res)
|
||||
if (ccch == CCCH_MSGT_AGCH)
|
||||
bts->agch_queue.agch_msgs++;
|
||||
else
|
||||
bts->agch_queue.pch_msgs++;
|
||||
@@ -820,30 +813,35 @@ struct gsm_time *get_time(struct gsm_bts *bts)
|
||||
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)
|
||||
{
|
||||
enum osmo_bts_features feature = _NUM_BTS_FEAT;
|
||||
|
||||
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 1;
|
||||
case RSL_CMOD_SPD_SPEECH:
|
||||
/* Stage 1: check support for the requested channel type */
|
||||
switch (cm->chan_rt) {
|
||||
case RSL_CMOD_CRT_TCH_GROUP_Bm:
|
||||
case RSL_CMOD_CRT_TCH_GROUP_Lm:
|
||||
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VGCS))
|
||||
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;
|
||||
case RSL_CMOD_SPD_DATA:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Before the requested pchan/cm combination can be checked, we need to
|
||||
* convert it to a feature identifier we can check */
|
||||
/* Stage 2: check support for the requested codec */
|
||||
switch (cm->chan_rt) {
|
||||
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm:
|
||||
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
||||
return 0;
|
||||
/* fall-through */
|
||||
case RSL_CMOD_CRT_TCH_GROUP_Bm:
|
||||
case RSL_CMOD_CRT_TCH_BCAST_Bm:
|
||||
case RSL_CMOD_CRT_TCH_Bm:
|
||||
switch (cm->chan_rate) {
|
||||
case RSL_CMOD_SP_GSM1:
|
||||
@@ -857,14 +855,13 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
||||
break;
|
||||
default:
|
||||
/* Invalid speech codec type => Not supported! */
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm:
|
||||
if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS))
|
||||
return 0;
|
||||
/* fall-through */
|
||||
case RSL_CMOD_CRT_TCH_GROUP_Lm:
|
||||
case RSL_CMOD_CRT_TCH_BCAST_Lm:
|
||||
case RSL_CMOD_CRT_TCH_Lm:
|
||||
switch (cm->chan_rate) {
|
||||
case RSL_CMOD_SP_GSM1:
|
||||
@@ -875,7 +872,7 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
||||
break;
|
||||
default:
|
||||
/* Invalid speech codec type => Not supported! */
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -883,14 +880,59 @@ int bts_supports_cm(const struct gsm_bts *bts,
|
||||
LOGP(DRSL, LOGL_ERROR,
|
||||
"Unhandled RSL channel type=0x%02x/rate=0x%02x\n",
|
||||
cm->chan_rt, cm->chan_rate);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if the feature is supported by this BTS */
|
||||
if (osmo_bts_has_feature(bts->features, feature))
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool bts_supports_cm_data(const struct gsm_bts *bts,
|
||||
const struct rsl_ie_chan_mode *cm)
|
||||
{
|
||||
switch (bts->variant) {
|
||||
case BTS_OSMO_TRX:
|
||||
switch (cm->chan_rate) {
|
||||
/* TODO: RSL_CMOD_CSD_NT_14k5 */
|
||||
/* TODO: RSL_CMOD_CSD_T_14k4 */
|
||||
case RSL_CMOD_CSD_NT_12k0:
|
||||
case RSL_CMOD_CSD_T_9k6:
|
||||
if (cm->chan_rt != RSL_CMOD_CRT_TCH_Bm)
|
||||
return false; /* invalid */
|
||||
/* fall-through */
|
||||
case RSL_CMOD_CSD_NT_6k0:
|
||||
case RSL_CMOD_CSD_T_4k8:
|
||||
case RSL_CMOD_CSD_T_2k4:
|
||||
case RSL_CMOD_CSD_T_1k2:
|
||||
case RSL_CMOD_CSD_T_600:
|
||||
case RSL_CMOD_CSD_T_1200_75:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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) */
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -84,12 +84,45 @@ static int set_oml_alert(struct ctrl_cmd *cmd, void *data)
|
||||
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 rc = 0;
|
||||
|
||||
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_max_ber10k_rach);
|
||||
g_bts = bts;
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -88,14 +88,12 @@ err_index:
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts,
|
||||
const char *bind_addr, uint16_t port)
|
||||
struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port)
|
||||
{
|
||||
struct ctrl_handle *hdl;
|
||||
int rc = 0;
|
||||
|
||||
hdl = ctrl_interface_setup_dynip(bts, bind_addr, port,
|
||||
bts_ctrl_node_lookup);
|
||||
hdl = ctrl_interface_setup(bts, port, bts_ctrl_node_lookup);
|
||||
if (!hdl)
|
||||
return NULL;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <osmo-bts/gsm_data.h>
|
||||
#include <osmo-bts/bts_model.h>
|
||||
#include <osmo-bts/bts.h>
|
||||
#include <osmo-bts/bts_sm.h>
|
||||
#include <osmo-bts/nm_common_fsm.h>
|
||||
|
||||
#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) {
|
||||
case BTS_SHUTDOWN_EV_START:
|
||||
/* Firt announce to NM objects that we are starting a shutdown procedure: */
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SHUTDOWN_START, NULL);
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL);
|
||||
|
||||
count = count_trx_operational(bts);
|
||||
if (count) {
|
||||
@@ -89,6 +90,9 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
|
||||
continue;
|
||||
if (bts->shutdown_fi_skip_power_ramp)
|
||||
power_ramp_force(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
||||
else
|
||||
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
bts->shutdown_fi_exit_proc = exit_proc;
|
||||
bts->shutdown_fi_skip_power_ramp = skip_power_ramp;
|
||||
LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n",
|
||||
exit_proc, reason);
|
||||
osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL);
|
||||
@@ -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)
|
||||
{
|
||||
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)
|
||||
|
||||
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->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,
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u",
|
||||
trx->bb_transc.mo.fi->id, ts->nr);
|
||||
gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL,
|
||||
trx->bts->nr, trx->nr, ts->nr);
|
||||
oml_mo_state_init(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
|
||||
|
||||
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->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 */
|
||||
trx->ts[tn].vamos.peer = ts;
|
||||
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,
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
||||
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
|
||||
bts->nr, trx->nr, 0xff);
|
||||
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, 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,
|
||||
LOGL_INFO, NULL);
|
||||
osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
|
||||
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
|
||||
bts->nr, trx->nr, 0xff);
|
||||
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, 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);
|
||||
|
||||
@@ -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->bb_transc.mo.fi, NM_EV_RSL_UP, NULL);
|
||||
|
||||
if ((rc = rsl_tx_rf_res(trx)) < 0)
|
||||
if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED ||
|
||||
trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) {
|
||||
rc = rsl_tx_rf_res(trx);
|
||||
if (rc < 0)
|
||||
oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL,
|
||||
"Failed to establish RSL link (%d)", rc);
|
||||
|
||||
}
|
||||
if (trx == trx->bts->c0)
|
||||
load_timer_start(trx->bts);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -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;
|
||||
|
||||
/* determine if this is the last block */
|
||||
if (block_nr + 1 == msg->num_segs)
|
||||
block_type->lb = 1;
|
||||
else
|
||||
block_type->lb = 0;
|
||||
|
||||
if (block_nr == 4) {
|
||||
block_type->lb = (block_nr + 1 == msg->num_segs);
|
||||
if (block_type->lb) {
|
||||
if (msg != bts_ss->default_msg) {
|
||||
DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n",
|
||||
chan_name, msg);
|
||||
|
||||
188
src/common/csd_v110.c
Normal file
188
src/common/csd_v110.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <osmocom/core/bits.h>
|
||||
#include <osmocom/core/utils.h>
|
||||
#include <osmocom/gsm/gsm44021.h>
|
||||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
#include <osmocom/isdn/v110.h>
|
||||
|
||||
#include <osmo-bts/csd_v110.h>
|
||||
#include <osmo-bts/lchan.h>
|
||||
|
||||
/* key is enum gsm48_chan_mode, so assuming a value in range 0..255 */
|
||||
const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = {
|
||||
#if 0
|
||||
[GSM48_CMODE_DATA_14k5] = {
|
||||
/* TCH/F14.4: 290 bits every 20 ms (14.5 kbit/s) */
|
||||
.fr = { .num_blocks = 1, .num_bits = 290 },
|
||||
},
|
||||
#endif
|
||||
[GSM48_CMODE_DATA_12k0] = {
|
||||
/* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */
|
||||
.fr = { .num_blocks = 4, .num_bits = 60 },
|
||||
},
|
||||
[GSM48_CMODE_DATA_6k0] = {
|
||||
/* TCH/F4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */
|
||||
.fr = { .num_blocks = 2, .num_bits = 60 },
|
||||
/* TCH/H4.8: 4 * 60 bits every 40 ms (6.0 kbit/s) */
|
||||
.hr = { .num_blocks = 4, .num_bits = 60 },
|
||||
},
|
||||
[GSM48_CMODE_DATA_3k6] = {
|
||||
/* TCH/F2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */
|
||||
.fr = { .num_blocks = 2, .num_bits = 36 },
|
||||
/* TCH/H2.4: 4 * 36 bits every 40 ms (3.6 kbit/s) */
|
||||
.hr = { .num_blocks = 4, .num_bits = 36 },
|
||||
},
|
||||
};
|
||||
|
||||
/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */
|
||||
static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = {
|
||||
[LCHAN_CSD_M_T_600] = { 1, 0, 0 },
|
||||
[LCHAN_CSD_M_T_1200] = { 0, 1, 0 },
|
||||
[LCHAN_CSD_M_T_2400] = { 1, 1, 0 },
|
||||
[LCHAN_CSD_M_T_4800] = { 0, 1, 1 },
|
||||
[LCHAN_CSD_M_T_9600] = { 0, 1, 1 },
|
||||
#if 0
|
||||
[LCHAN_CSD_M_T_19200] = { 0, 1, 1 },
|
||||
[LCHAN_CSD_M_T_38400] = { 0, 1, 1 },
|
||||
[LCHAN_CSD_M_T_14400] = { 1, 0, 1 },
|
||||
[LCHAN_CSD_M_T_28800] = { 1, 0, 1 },
|
||||
#endif
|
||||
};
|
||||
|
||||
int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp,
|
||||
const uint8_t *data, size_t data_len)
|
||||
{
|
||||
const struct csd_v110_frame_desc *desc;
|
||||
ubit_t ra_bits[80 * 4];
|
||||
|
||||
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
|
||||
else
|
||||
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
|
||||
if (OSMO_UNLIKELY(desc->num_blocks == 0))
|
||||
return -ENOTSUP;
|
||||
|
||||
/* handle empty/incomplete Uplink frames gracefully */
|
||||
if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) {
|
||||
/* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */
|
||||
memset(&ra_bits[0], 0x01, sizeof(ra_bits));
|
||||
for (unsigned int i = 0; i < desc->num_blocks; i++)
|
||||
memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */
|
||||
goto ra1_ra2;
|
||||
}
|
||||
|
||||
/* RA1'/RA1: convert from radio rate to an intermediate data rate */
|
||||
for (unsigned int i = 0; i < desc->num_blocks; i++) {
|
||||
struct osmo_v110_decoded_frame df;
|
||||
|
||||
/* convert a V.110 36-/60-bit frame to a V.110 80-bit frame */
|
||||
if (desc->num_bits == 60)
|
||||
osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60);
|
||||
else /* desc->num_bits == 36 */
|
||||
osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36);
|
||||
|
||||
/* E1 .. E3 must set by out-of-band knowledge */
|
||||
if (lchan->csd_mode == LCHAN_CSD_M_NT) {
|
||||
/* non-transparent: as per 3GPP TS 48.020, Table 7 */
|
||||
df.e_bits[0] = 0; /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */
|
||||
df.e_bits[1] = (i >> 1) & 0x01; /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */
|
||||
df.e_bits[2] = (i >> 0) & 0x01; /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */
|
||||
} else {
|
||||
/* transparent: as per 3GPP TS 44.021, Figure 4 */
|
||||
df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0]; /* E1 */
|
||||
df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1]; /* E2 */
|
||||
df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2]; /* E3 */
|
||||
}
|
||||
|
||||
osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df);
|
||||
}
|
||||
|
||||
ra1_ra2:
|
||||
/* RA1/RA2: convert from an intermediate rate to 64 kbit/s */
|
||||
if (desc->num_blocks == 4) {
|
||||
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
|
||||
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||
rtp[i] = (0xff >> 2);
|
||||
rtp[i] |= (ra_bits[j++] << 7);
|
||||
rtp[i] |= (ra_bits[j++] << 6);
|
||||
}
|
||||
} else {
|
||||
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
|
||||
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||
rtp[i] = (0xff >> 1);
|
||||
rtp[i] |= (ra_bits[i] << 7);
|
||||
}
|
||||
}
|
||||
|
||||
return RFC4040_RTP_PLEN;
|
||||
}
|
||||
|
||||
int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data,
|
||||
const uint8_t *rtp, size_t rtp_len)
|
||||
{
|
||||
const struct csd_v110_frame_desc *desc;
|
||||
ubit_t ra_bits[80 * 4];
|
||||
|
||||
OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc));
|
||||
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||
desc = &csd_v110_lchan_desc[lchan->tch_mode].fr;
|
||||
else
|
||||
desc = &csd_v110_lchan_desc[lchan->tch_mode].hr;
|
||||
if (OSMO_UNLIKELY(desc->num_blocks == 0))
|
||||
return -ENOTSUP;
|
||||
|
||||
if (OSMO_UNLIKELY(rtp_len != RFC4040_RTP_PLEN))
|
||||
return -EINVAL;
|
||||
|
||||
/* RA1/RA2: convert from 64 kbit/s to an intermediate rate */
|
||||
if (desc->num_blocks == 4) {
|
||||
/* 4 * 80 bits (16 kbit/s) => 2 bits per octet */
|
||||
for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) {
|
||||
ra_bits[j++] = (rtp[i] >> 7);
|
||||
ra_bits[j++] = (rtp[i] >> 6) & 0x01;
|
||||
}
|
||||
} else {
|
||||
/* 2 * 80 bits (8 kbit/s) => 1 bit per octet */
|
||||
for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++)
|
||||
ra_bits[i] = (rtp[i] >> 7);
|
||||
}
|
||||
|
||||
/* RA1'/RA1: convert from an intermediate rate to radio rate */
|
||||
for (unsigned int i = 0; i < desc->num_blocks; i++) {
|
||||
struct osmo_v110_decoded_frame df;
|
||||
|
||||
/* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */
|
||||
osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80);
|
||||
if (desc->num_bits == 60)
|
||||
osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df);
|
||||
else /* desc->num_bits == 36 */
|
||||
osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df);
|
||||
}
|
||||
|
||||
return desc->num_blocks * desc->num_bits;
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* 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.
|
||||
* 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/>.
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
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
|
||||
* ignored as the lchan will already be released. */
|
||||
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,
|
||||
* 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.
|
||||
* 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/>.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <osmo-bts/handover.h>
|
||||
#include <osmo-bts/l1sap.h>
|
||||
#include <osmo-bts/bts_model.h>
|
||||
#include <osmo-bts/asci.h>
|
||||
#include <errno.h>
|
||||
|
||||
static const struct value_string lchan_s_names[] = {
|
||||
@@ -56,41 +57,40 @@ const struct value_string lchan_ciph_state_names[] = {
|
||||
};
|
||||
|
||||
/* 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;
|
||||
|
||||
/* we have to compensate for the "RTS advance" due to the asynchronous interface between
|
||||
* the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */
|
||||
int32_t fn_advance = bts_get_avg_fn_advance(bts);
|
||||
int32_t fn_advance_us = fn_advance * 4615;
|
||||
int fn_advance_ms = fn_advance_us / 1000;
|
||||
|
||||
t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
||||
t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
|
||||
|
||||
if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) {
|
||||
t200_ms_acch[DL_SAPI0] *= 2;
|
||||
t200_ms_acch[DL_SAPI3] *= 2;
|
||||
}
|
||||
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_SDCCH:
|
||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
|
||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms;
|
||||
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_SDCCH];
|
||||
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;
|
||||
case GSM_LCHAN_TCH_F:
|
||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms;
|
||||
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_F];
|
||||
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;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
||||
t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms;
|
||||
t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_H];
|
||||
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;
|
||||
default:
|
||||
/* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -151,17 +151,17 @@ void gsm_lchan_name_update(struct gsm_lchan *lchan)
|
||||
int lchan_init_lapdm(struct gsm_lchan *lchan)
|
||||
{
|
||||
struct lapdm_channel *lc = &lchan->lapdm_ch;
|
||||
int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI];
|
||||
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,
|
||||
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n",
|
||||
t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3],
|
||||
t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]);
|
||||
lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type,
|
||||
gsm_lchan_name(lchan));
|
||||
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY);
|
||||
"Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in frames)\n",
|
||||
t200_fn_dcch[DL_SAPI0], t200_fn_dcch[DL_SAPI3],
|
||||
t200_fn_acch[DL_SAPI0], t200_fn_acch[DL_SAPI3]);
|
||||
lapdm_channel_init3(lc, LAPDM_MODE_BTS, NULL, NULL, lchan->type, gsm_lchan_name(lchan));
|
||||
lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY | LAPDM_ENT_F_RTS);
|
||||
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: */
|
||||
lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan);
|
||||
@@ -216,8 +216,11 @@ void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind
|
||||
if (lchan->state == LCHAN_S_NONE)
|
||||
return;
|
||||
|
||||
/* release handover state */
|
||||
/* release handover, listener and talker states */
|
||||
handover_reset(lchan);
|
||||
vgcs_talker_reset(lchan, false);
|
||||
vgcs_listener_reset(lchan);
|
||||
vgcs_uplink_free_reset(lchan);
|
||||
|
||||
lchan->rel_act_kind = rel_kind;
|
||||
|
||||
@@ -322,7 +325,7 @@ void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state)
|
||||
}
|
||||
}
|
||||
|
||||
/* See Table 10.5.25 of GSM04.08 */
|
||||
/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */
|
||||
static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||
uint8_t ts_nr, uint8_t lchan_nr)
|
||||
{
|
||||
@@ -367,13 +370,13 @@ static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan,
|
||||
cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH;
|
||||
break;
|
||||
case GSM_PCHAN_NONE:
|
||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n",
|
||||
gsm_pchan_name(pchan));
|
||||
cbits = 0x00;
|
||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n",
|
||||
ts_nr, lchan_nr, gsm_pchan_name(pchan));
|
||||
cbits = 0x00; /* Reserved */
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n",
|
||||
gsm_pchan_name(pchan), (int)pchan);
|
||||
LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n",
|
||||
ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan);
|
||||
OSMO_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
@@ -649,9 +652,11 @@ void lchan_rtp_socket_free(struct gsm_lchan *lchan)
|
||||
/*! limit number of queue entries to %u; drops any surplus messages */
|
||||
void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit)
|
||||
{
|
||||
if (lchan->dl_tch_queue_len > limit)
|
||||
LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n",
|
||||
lchan->dl_tch_queue_len - limit);
|
||||
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);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -125,6 +125,13 @@ static struct log_info_cat bts_log_info_cat[] = {
|
||||
.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)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <osmo-bts/logging.h>
|
||||
#include <osmo-bts/abis.h>
|
||||
#include <osmo-bts/bts.h>
|
||||
#include <osmo-bts/bts_sm.h>
|
||||
#include <osmo-bts/vty.h>
|
||||
#include <osmo-bts/l1sap.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,
|
||||
NM_SEVER_CRITICAL, OSMO_EVT_CRIT_PROC_STOP,
|
||||
"BTS: SIGINT received -> shutdown");
|
||||
bts_shutdown(g_bts, "SIGINT");
|
||||
bts_shutdown_ext(g_bts, "SIGINT", true, false);
|
||||
}
|
||||
quit++;
|
||||
break;
|
||||
@@ -292,7 +293,13 @@ int bts_main(int argc, char **argv)
|
||||
if (vty_test_mode)
|
||||
fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n");
|
||||
|
||||
g_bts = gsm_bts_alloc(tall_bts_ctx, 0);
|
||||
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) {
|
||||
fprintf(stderr, "Failed to create BTS structure\n");
|
||||
exit(1);
|
||||
@@ -354,27 +361,26 @@ int bts_main(int argc, char **argv)
|
||||
/* TODO: move this to gsm_bts_alloc() */
|
||||
if (g_bts->gsmtap.remote_host != NULL) {
|
||||
LOGP(DLGLOBAL, LOGL_NOTICE,
|
||||
"Setting up GSMTAP Um forwarding to '%s:%u'\n",
|
||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||
g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host,
|
||||
GSMTAP_UDP_PORT, 1);
|
||||
"Setting up GSMTAP Um forwarding '%s->'%s:%u'\n",
|
||||
g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT);
|
||||
g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0,
|
||||
g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1);
|
||||
if (g_bts->gsmtap.inst == NULL) {
|
||||
fprintf(stderr, "Failed during gsmtap_source_init()\n");
|
||||
fprintf(stderr, "Failed during gsmtap_source_init2()\n");
|
||||
exit(1);
|
||||
}
|
||||
gsmtap_source_add_sink(g_bts->gsmtap.inst);
|
||||
}
|
||||
|
||||
bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS);
|
||||
bts_controlif_setup(g_bts, OSMO_CTRL_PORT_BTS);
|
||||
|
||||
rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(),
|
||||
g_vty_port_num);
|
||||
rc = telnet_init_default(tall_bts_ctx, NULL, g_vty_port_num);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Error initializing telnet\n");
|
||||
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");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
/* 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
|
||||
* 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 */
|
||||
[0] = 1, /* block { 0, 2, 4, 6} */
|
||||
[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} */
|
||||
};
|
||||
|
||||
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
|
||||
* 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
|
||||
@@ -50,7 +59,7 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
||||
uint32_t fn104 = fn % 104;
|
||||
|
||||
/* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules
|
||||
* implemented here. We only implement the logic for Voice, not CSD */
|
||||
* implemented here. We implement the logic for both speech and data (CSD). */
|
||||
|
||||
/* AMR is special, SID frames may be scheduled dynamically at any time */
|
||||
if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)
|
||||
@@ -59,8 +68,11 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn)
|
||||
switch (lchan->type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
case GSM48_CMODE_SPEECH_V1_VAMOS:
|
||||
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.
|
||||
* There is only one *complete* block in this subset starting at FN=52.
|
||||
* 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)
|
||||
return true;
|
||||
break;
|
||||
case GSM48_CMODE_SIGN:
|
||||
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
||||
* SUB */
|
||||
return true;
|
||||
case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */
|
||||
case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */
|
||||
/* 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/F frames at the corresponding frame positions. */
|
||||
default:
|
||||
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
|
||||
gsm_lchan_name(lchan), lchan->tch_mode);
|
||||
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||
return fn104 == 52;
|
||||
LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
switch (lchan->tch_mode) {
|
||||
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;
|
||||
break;
|
||||
case GSM48_CMODE_SIGN:
|
||||
/* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are
|
||||
* SUB */
|
||||
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:
|
||||
LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n",
|
||||
gsm_lchan_name(lchan), lchan->tch_mode);
|
||||
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||
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;
|
||||
@@ -269,9 +290,8 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
|
||||
}
|
||||
|
||||
if (rc == 1) {
|
||||
DEBUGP(DMEAS,
|
||||
"%s meas period end fn:%u, fn_mod:%i, status:%d, pchan:%s\n",
|
||||
gsm_lchan_name(lchan), fn, fn_mod, rc, gsm_pchan_name(pchan));
|
||||
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "meas period end fn_mod:%d, status:%d, pchan:%s\n", fn_mod,
|
||||
rc, gsm_pchan_name(pchan));
|
||||
}
|
||||
|
||||
return rc;
|
||||
@@ -307,16 +327,15 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
||||
struct bts_ul_meas *dest;
|
||||
|
||||
if (lchan->state != LCHAN_S_ACTIVE) {
|
||||
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
||||
"%s measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
|
||||
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state),
|
||||
lchan->meas.num_ul_meas, fn_mod);
|
||||
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
|
||||
"measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n",
|
||||
gsm_lchans_name(lchan->state), lchan->meas.num_ul_meas, fn_mod);
|
||||
}
|
||||
|
||||
if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) {
|
||||
LOGPFN(DMEAS, LOGL_NOTICE, fn,
|
||||
"%s no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n",
|
||||
gsm_lchan_name(lchan), lchan->meas.num_ul_meas, fn_mod);
|
||||
LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE,
|
||||
"no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", lchan->meas.num_ul_meas,
|
||||
fn_mod);
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
@@ -328,10 +347,9 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan,
|
||||
if (!ulm->is_sub)
|
||||
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",
|
||||
gsm_lchan_name(lchan),
|
||||
dest->is_sub ? "SUB" : "FULL",
|
||||
ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
||||
LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG,
|
||||
"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", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi,
|
||||
lchan->meas.num_ul_meas, fn_mod);
|
||||
|
||||
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
|
||||
* 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)
|
||||
* See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX)
|
||||
* 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);
|
||||
|
||||
/* 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) {
|
||||
case GSM_PCHAN_TCH_F:
|
||||
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
||||
/* 1 block SACCH, 24 blocks TCH (see note 1) */
|
||||
return 25;
|
||||
} else {
|
||||
/* 1 block SACCH, 1 block TCH */
|
||||
return 2;
|
||||
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||
return 1 + 1; /* 1 x SACCH + 1 x FACCH */
|
||||
/* else: signalling or speech */
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */
|
||||
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:
|
||||
if (lchan->tch_mode == GSM48_CMODE_SIGN) {
|
||||
/* 1 block SACCH, 12 blocks TCH (see ynote 1) */
|
||||
return 13;
|
||||
} else {
|
||||
/* 1 block SACCH, 2 blocks TCH */
|
||||
return 3;
|
||||
if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA)
|
||||
return 1 + 2; /* 1 x SACCH + 2 x FACCH */
|
||||
/* else: signalling or speech */
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */
|
||||
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_CBCH:
|
||||
@@ -444,8 +480,6 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan)
|
||||
default:
|
||||
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,
|
||||
@@ -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_actual = 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_actual = 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
|
||||
* when we get less measurements as we expect. */
|
||||
num_ul_meas_expect = lchan_meas_num_expected(lchan);
|
||||
|
||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR)
|
||||
num_meas_sub_expect = lchan_meas_sub_num_expected(lchan);
|
||||
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)
|
||||
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 {
|
||||
m = &measurement_dummy;
|
||||
|
||||
/* For AMR the amount of SUB frames is defined by the
|
||||
* the occurrence of DTX periods, which are dynamically
|
||||
* negotiated in AMR, so we can not know if and how many
|
||||
* SUB frames are missing. */
|
||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||
if (num_meas_sub <= i) {
|
||||
/* only if we know the exact number of SUB measurements */
|
||||
if (num_meas_sub_expect >= 0) {
|
||||
if (num_meas_sub < num_meas_sub_expect) {
|
||||
num_meas_sub_subst++;
|
||||
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, "
|
||||
"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
|
||||
* it can not remove excess SUB measurements or add missing SUB
|
||||
* measurements when there is no more room in the interval. */
|
||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||
if (num_meas_sub != num_meas_sub_expect) {
|
||||
if (num_meas_sub_expect < 0) {
|
||||
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,
|
||||
"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 {
|
||||
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,
|
||||
"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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -380,15 +380,19 @@ static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn)
|
||||
static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 },
|
||||
h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 },
|
||||
h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 };
|
||||
if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) {
|
||||
switch (lchan->tch_mode) {
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
if (lchan->type == GSM_LCHAN_TCH_F)
|
||||
return fn_chk(f, fn, ARRAY_SIZE(f));
|
||||
else
|
||||
return fn_chk(lchan->nr ? h1 : h0, fn,
|
||||
lchan->nr ? ARRAY_SIZE(h1) :
|
||||
ARRAY_SIZE(h0));
|
||||
}
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
return fn_chk(f, fn, ARRAY_SIZE(f));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper type,
|
||||
@@ -466,10 +470,6 @@ void dtx_int_signal(struct gsm_lchan *lchan)
|
||||
*/
|
||||
uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn)
|
||||
{
|
||||
/* FIXME: add EFR support */
|
||||
if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)
|
||||
return 0;
|
||||
|
||||
if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) {
|
||||
if (dtx_sched_optional(lchan, fn))
|
||||
return 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* NM Radio Carrier 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -70,17 +70,17 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
|
||||
static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
|
||||
{
|
||||
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||
int i;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SW_ACT:
|
||||
oml_mo_tx_sw_act_rep(&bb_transc->mo);
|
||||
nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
|
||||
for (i = 0; i < TRX_NR_TS; i++) {
|
||||
struct gsm_bts_trx_ts *ts = &trx->ts[i];
|
||||
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_INSTALLED, NULL);
|
||||
}
|
||||
ev_dispatch_children(bb_transc, event);
|
||||
return;
|
||||
case NM_EV_OML_UP:
|
||||
/* Report current state: */
|
||||
oml_tx_state_changed(&bb_transc->mo);
|
||||
ev_dispatch_children(bb_transc, event);
|
||||
return;
|
||||
case NM_EV_RSL_UP:
|
||||
return;
|
||||
@@ -119,17 +119,48 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
|
||||
{
|
||||
struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
|
||||
struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
|
||||
struct gsm_bts *bts = trx->bts;
|
||||
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||
bool phy_state_connected;
|
||||
bool rsl_link_connected;
|
||||
int rc;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SETATTR_ACK:
|
||||
case NM_EV_SETATTR_NACK:
|
||||
case NM_EV_OML_UP:
|
||||
/* Report current state: */
|
||||
oml_tx_state_changed(&bb_transc->mo);
|
||||
ev_dispatch_children(bb_transc, event);
|
||||
return;
|
||||
case NM_EV_RX_SETATTR:
|
||||
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||
bb_transc->mo.setattr_success = setattr_data->cause == 0;
|
||||
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||
break;
|
||||
rc = bts_model_apply_oml(trx->bts, setattr_data->msg,
|
||||
&bb_transc->mo, bb_transc);
|
||||
bb_transc->mo.setattr_success = rc == 0;
|
||||
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
|
||||
return;
|
||||
case NM_EV_RX_OPSTART:
|
||||
#if 0
|
||||
/* Disabled because osmo-bsc doesn't send SetAttr on BB_TRANSC object */
|
||||
if (!bb_transc->mo.setattr_success) {
|
||||
oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Connect RSL link: */
|
||||
if (bts->variant == BTS_OSMO_OMLDUMMY) {
|
||||
LOGPFSML(fi, LOGL_NOTICE, "Not connecting RSL in OML-DUMMY!\n");
|
||||
} else {
|
||||
rc = e1inp_ipa_bts_rsl_connect_n(bts->oml_link->ts->line,
|
||||
bb_transc->rsl.rem_addrstr.ip,
|
||||
bb_transc->rsl.rem_addrstr.port, trx->nr);
|
||||
if (rc < 0) {
|
||||
LOGPFSML(fi, LOGL_NOTICE, "Error connecting IPA RSL: %d\n", rc);
|
||||
oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
}
|
||||
bts_model_opstart(trx->bts, &bb_transc->mo, bb_transc);
|
||||
return;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
bb_transc->mo.opstart_success = true;
|
||||
oml_mo_opstart_ack(&bb_transc->mo);
|
||||
@@ -153,10 +184,10 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
|
||||
}
|
||||
|
||||
|
||||
if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
|
||||
if (bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
|
||||
struct phy_instance *pinst = trx_phy_instance(trx);
|
||||
phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
|
||||
rsl_link_connected = !!trx->rsl_link;
|
||||
rsl_link_connected = !!trx->bb_transc.rsl.link;
|
||||
} else {
|
||||
phy_state_connected = true;
|
||||
rsl_link_connected = true;
|
||||
@@ -231,6 +262,7 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
|
||||
[NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SW_ACT) |
|
||||
X(NM_EV_OML_UP) |
|
||||
X(NM_EV_RSL_UP) |
|
||||
X(NM_EV_RSL_DOWN) |
|
||||
X(NM_EV_PHYLINK_UP) |
|
||||
@@ -245,8 +277,9 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
|
||||
},
|
||||
[NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SETATTR_ACK) |
|
||||
X(NM_EV_SETATTR_NACK) |
|
||||
X(NM_EV_OML_UP) |
|
||||
X(NM_EV_RX_SETATTR) |
|
||||
X(NM_EV_RX_OPSTART) |
|
||||
X(NM_EV_OPSTART_ACK) |
|
||||
X(NM_EV_OPSTART_NACK) |
|
||||
X(NM_EV_RSL_UP) |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* NM BTS 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <osmo-bts/nm_common_fsm.h>
|
||||
#include <osmo-bts/phy_link.h>
|
||||
#include <osmo-bts/cbch.h>
|
||||
#include <osmo-bts/notification.h>
|
||||
|
||||
#define X(s) (1 << (s))
|
||||
|
||||
@@ -60,8 +61,13 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3
|
||||
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||
/* Reset state: */
|
||||
bts->si_valid = 0;
|
||||
bts->bsic_configured = false;
|
||||
bts->bsic = 0xff; /* invalid value */
|
||||
TALLOC_FREE(bts->mo.nm_attr);
|
||||
bts_cbch_reset(bts);
|
||||
bts_asci_notification_reset(bts);
|
||||
if (bts->c0_power_red_db > 0)
|
||||
bts_set_c0_pwr_red(bts, 0);
|
||||
|
||||
bts->mo.setattr_success = false;
|
||||
bts->mo.opstart_success = false;
|
||||
@@ -74,7 +80,8 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SW_ACT:
|
||||
case NM_EV_OML_UP:
|
||||
/* automatic SW_ACT upon OML link establishment: */
|
||||
oml_mo_tx_sw_act_rep(&bts->mo);
|
||||
|
||||
llist_for_each_entry(trx, &bts->trx_list, list) {
|
||||
@@ -91,6 +98,7 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
|
||||
}
|
||||
|
||||
nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE);
|
||||
ev_dispatch_children(bts, event);
|
||||
return;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
@@ -109,13 +117,21 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
|
||||
{
|
||||
struct gsm_bts *bts = (struct gsm_bts *)fi->priv;
|
||||
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||
int rc;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SETATTR_ACK:
|
||||
case NM_EV_SETATTR_NACK:
|
||||
case NM_EV_RX_SETATTR:
|
||||
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||
bts->mo.setattr_success = setattr_data->cause == 0;
|
||||
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||
rc = bts_model_apply_oml(bts, setattr_data->msg, &bts->mo, bts);
|
||||
bts->mo.setattr_success = rc == 0;
|
||||
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
|
||||
break;
|
||||
case NM_EV_RX_OPSTART:
|
||||
if (!bts->mo.setattr_success) {
|
||||
oml_mo_opstart_nack(&bts->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
bts_model_opstart(bts, &bts->mo, bts);
|
||||
break;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
bts->mo.opstart_success = true;
|
||||
@@ -166,7 +182,7 @@ static void nm_bts_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data
|
||||
static struct osmo_fsm_state nm_bts_fsm_states[] = {
|
||||
[NM_BTS_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SW_ACT),
|
||||
X(NM_EV_OML_UP),
|
||||
.out_state_mask =
|
||||
X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) |
|
||||
X(NM_BTS_ST_OP_DISABLED_OFFLINE),
|
||||
@@ -176,8 +192,8 @@ static struct osmo_fsm_state nm_bts_fsm_states[] = {
|
||||
},
|
||||
[NM_BTS_ST_OP_DISABLED_OFFLINE] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SETATTR_ACK) |
|
||||
X(NM_EV_SETATTR_NACK) |
|
||||
X(NM_EV_RX_SETATTR) |
|
||||
X(NM_EV_RX_OPSTART) |
|
||||
X(NM_EV_OPSTART_ACK) |
|
||||
X(NM_EV_OPSTART_NACK),
|
||||
.out_state_mask =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* NM BTS Site Manager 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <osmo-bts/gsm_data.h>
|
||||
#include <osmo-bts/bts_model.h>
|
||||
#include <osmo-bts/bts.h>
|
||||
#include <osmo-bts/bts_sm.h>
|
||||
#include <osmo-bts/rsl.h>
|
||||
#include <osmo-bts/nm_common_fsm.h>
|
||||
#include <osmo-bts/phy_link.h>
|
||||
@@ -44,8 +45,11 @@
|
||||
|
||||
static void ev_dispatch_children(struct gsm_bts_sm *site_mgr, uint32_t event)
|
||||
{
|
||||
struct gsm_bts *bts = gsm_bts_sm_get_bts(site_mgr);
|
||||
struct gsm_bts *bts;
|
||||
osmo_fsm_inst_dispatch(site_mgr->gprs.nse.mo.fi, event, NULL);
|
||||
llist_for_each_entry(bts, &site_mgr->bts_list, list) {
|
||||
osmo_fsm_inst_dispatch(bts->mo.fi, event, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
@@ -65,9 +69,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
|
||||
struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SW_ACT:
|
||||
case NM_EV_OML_UP:
|
||||
/* automatic SW_ACT upon OML link establishment: */
|
||||
oml_mo_tx_sw_act_rep(&site_mgr->mo);
|
||||
nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_DISABLED_OFFLINE);
|
||||
ev_dispatch_children(site_mgr, event);
|
||||
return;
|
||||
default:
|
||||
OSMO_ASSERT(0);
|
||||
@@ -86,13 +92,25 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
|
||||
{
|
||||
struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv;
|
||||
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||
int rc;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SETATTR_ACK:
|
||||
case NM_EV_SETATTR_NACK:
|
||||
case NM_EV_RX_SETATTR:
|
||||
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||
site_mgr->mo.setattr_success = setattr_data->cause == 0;
|
||||
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||
/* No bts_model_apply_oml() needed yet for site_mgr obj yet: */
|
||||
rc = 0;
|
||||
site_mgr->mo.setattr_success = rc == 0;
|
||||
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
|
||||
break;
|
||||
case NM_EV_RX_OPSTART:
|
||||
#if 0
|
||||
/* Disabled because osmo-bsc doesn't send SetAttr on SITE_MGR object */
|
||||
if (!site_mgr->mo.setattr_success) {
|
||||
oml_mo_opstart_nack(&site_mgr->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bts_model_opstart(NULL, &site_mgr->mo, site_mgr);
|
||||
break;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
site_mgr->mo.opstart_success = true;
|
||||
@@ -143,7 +161,7 @@ static void nm_bts_sm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
|
||||
static struct osmo_fsm_state nm_bts_sm_fsm_states[] = {
|
||||
[NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SW_ACT),
|
||||
X(NM_EV_OML_UP),
|
||||
.out_state_mask =
|
||||
X(NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED) |
|
||||
X(NM_BTS_SM_ST_OP_DISABLED_OFFLINE),
|
||||
@@ -153,8 +171,8 @@ static struct osmo_fsm_state nm_bts_sm_fsm_states[] = {
|
||||
},
|
||||
[NM_BTS_SM_ST_OP_DISABLED_OFFLINE] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SETATTR_ACK) |
|
||||
X(NM_EV_SETATTR_NACK) |
|
||||
X(NM_EV_RX_SETATTR) |
|
||||
X(NM_EV_RX_OPSTART) |
|
||||
X(NM_EV_OPSTART_ACK) |
|
||||
X(NM_EV_OPSTART_NACK),
|
||||
.out_state_mask =
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* NM Radio Carrier 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>
|
||||
*
|
||||
* All Rights Reserved
|
||||
@@ -13,7 +13,7 @@
|
||||
* 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.
|
||||
* 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/>.
|
||||
@@ -71,7 +71,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event
|
||||
struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_BBTRANSC_INSTALLED:
|
||||
case NM_EV_OML_UP:
|
||||
/* Report current state: */
|
||||
oml_tx_state_changed(&ts->mo);
|
||||
return;
|
||||
case NM_EV_SW_ACT:
|
||||
oml_mo_tx_sw_act_rep(&ts->mo);
|
||||
if (ts_can_be_enabled(ts))
|
||||
nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_OFFLINE);
|
||||
@@ -94,17 +98,30 @@ static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event,
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
|
||||
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||
int rc;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SETATTR_ACK:
|
||||
case NM_EV_SETATTR_NACK:
|
||||
case NM_EV_OML_UP:
|
||||
/* Report current state: */
|
||||
oml_tx_state_changed(&ts->mo);
|
||||
return;
|
||||
case NM_EV_RX_SETATTR:
|
||||
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||
ts->mo.setattr_success = setattr_data->cause == 0;
|
||||
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||
rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg,
|
||||
&ts->mo, ts);
|
||||
ts->mo.setattr_success = rc == 0;
|
||||
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
|
||||
break;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
case NM_EV_RX_OPSTART:
|
||||
LOGPFSML(fi, LOGL_NOTICE, "BSC trying to activate TS while still in avail=dependency. "
|
||||
"Allowing it to stay backward-compatible with older osmo-bts versions, but BSC is wrong.\n");
|
||||
if (!ts->mo.setattr_success) {
|
||||
oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
bts_model_opstart(ts->trx->bts, &ts->mo, ts);
|
||||
break;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
ts->mo.opstart_success = true;
|
||||
oml_mo_opstart_ack(&ts->mo);
|
||||
nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED);
|
||||
@@ -138,13 +155,26 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv;
|
||||
struct nm_fsm_ev_setattr_data *setattr_data;
|
||||
int rc;
|
||||
|
||||
switch (event) {
|
||||
case NM_EV_SETATTR_ACK:
|
||||
case NM_EV_SETATTR_NACK:
|
||||
case NM_EV_OML_UP:
|
||||
/* Report current state: */
|
||||
oml_tx_state_changed(&ts->mo);
|
||||
return;
|
||||
case NM_EV_RX_SETATTR:
|
||||
setattr_data = (struct nm_fsm_ev_setattr_data *)data;
|
||||
ts->mo.setattr_success = setattr_data->cause == 0;
|
||||
oml_fom_ack_nack(setattr_data->msg, setattr_data->cause);
|
||||
rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg,
|
||||
&ts->mo, ts);
|
||||
ts->mo.setattr_success = rc == 0;
|
||||
oml_fom_ack_nack_copy_msg(setattr_data->msg, rc);
|
||||
break;
|
||||
case NM_EV_RX_OPSTART:
|
||||
if (!ts->mo.setattr_success) {
|
||||
oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM);
|
||||
return;
|
||||
}
|
||||
bts_model_opstart(ts->trx->bts, &ts->mo, ts);
|
||||
break;
|
||||
case NM_EV_OPSTART_ACK:
|
||||
ts->mo.opstart_success = true;
|
||||
@@ -209,7 +239,8 @@ static void nm_chan_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *dat
|
||||
static struct osmo_fsm_state nm_chan_fsm_states[] = {
|
||||
[NM_CHAN_ST_OP_DISABLED_NOTINSTALLED] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_BBTRANSC_INSTALLED),
|
||||
X(NM_EV_SW_ACT) |
|
||||
X(NM_EV_OML_UP),
|
||||
.out_state_mask =
|
||||
X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) |
|
||||
X(NM_CHAN_ST_OP_DISABLED_OFFLINE) |
|
||||
@@ -220,10 +251,11 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = {
|
||||
},
|
||||
[NM_CHAN_ST_OP_DISABLED_DEPENDENCY] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SETATTR_ACK) |
|
||||
X(NM_EV_SETATTR_NACK) |
|
||||
X(NM_EV_OML_UP) |
|
||||
X(NM_EV_RX_SETATTR) |
|
||||
X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */
|
||||
X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */
|
||||
X(NM_EV_OPSTART_NACK) |
|
||||
X(NM_EV_OPSTART_NACK) | /* backward compatibility, buggy BSC */
|
||||
X(NM_EV_BBTRANSC_ENABLED) |
|
||||
X(NM_EV_RCARRIER_ENABLED) |
|
||||
X(NM_EV_BBTRANSC_DISABLED) |
|
||||
@@ -238,8 +270,9 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = {
|
||||
},
|
||||
[NM_CHAN_ST_OP_DISABLED_OFFLINE] = {
|
||||
.in_event_mask =
|
||||
X(NM_EV_SETATTR_ACK) |
|
||||
X(NM_EV_SETATTR_NACK) |
|
||||
X(NM_EV_OML_UP) |
|
||||
X(NM_EV_RX_SETATTR) |
|
||||
X(NM_EV_RX_OPSTART) |
|
||||
X(NM_EV_OPSTART_ACK) |
|
||||
X(NM_EV_OPSTART_NACK) |
|
||||
X(NM_EV_BBTRANSC_DISABLED) |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user