Compare commits
324 Commits
Author | SHA1 | Date |
---|---|---|
Oliver Smith | 3b5e7b554e | |
Oliver Smith | 99ad68f299 | |
Oliver Smith | 6c66f59314 | |
Max | 1bca191188 | |
Pau Espin | 9fb31c13df | |
Pau Espin | d7afb4341e | |
Harald Welte | 829986e06a | |
Harald Welte | 8c8e920eb7 | |
Harald Welte | bd3583ffbd | |
Harald Welte | 85687bf176 | |
Matan Perelman | cc1ac21671 | |
Matan Perelman | a5249dd96c | |
Harald Welte | ea42371454 | |
Harald Welte | 3f1b81bcf4 | |
Matan Perelman | d399e0c927 | |
Matan Perelman | 6b6714ba13 | |
Matan Perelman | 88c051447a | |
Vadim Yanitskiy | a14b4a7379 | |
Pau Espin | 0368a9e815 | |
Vadim Yanitskiy | 11d7ed2d9f | |
Vadim Yanitskiy | a885a77a1e | |
Vadim Yanitskiy | 08042c3b8a | |
Vadim Yanitskiy | 3c92391c9d | |
Andreas Eversberg | 0c1ab7d82f | |
Andreas Eversberg | 9a730ee2d4 | |
Andreas Eversberg | f405db793e | |
Vadim Yanitskiy | b2f11dbcae | |
Oliver Smith | dea9921e28 | |
Oliver Smith | fb23879651 | |
Matan Perelman | 1cfec9d2c9 | |
Matan Perelman | 5e28334fa9 | |
Neels Hofmeyr | 2323e577d9 | |
Harald Welte | f53c5588d2 | |
Matan Perelman | 126952e203 | |
Matan Perelman | c37fcff9c5 | |
Matan Perelman | 29389bd44a | |
Matan Perelman | 6f1991fd82 | |
Matan Perelman | 40ecc7d538 | |
Keith Whyte | f033c82f54 | |
Matan Perelman | 9579e8337b | |
Vadim Yanitskiy | 9da6536312 | |
Andreas Eversberg | 5dee672e96 | |
Vadim Yanitskiy | 510a868168 | |
Vadim Yanitskiy | 2376b52da2 | |
Andreas Eversberg | 71f96f1b57 | |
Neels Hofmeyr | 65e257effb | |
Oliver Smith | 6766608231 | |
Andreas Eversberg | a4fc35c3b2 | |
arehbein | 252e7f3e91 | |
Neels Hofmeyr | e24e8a3389 | |
Philipp Maier | 647bc1e698 | |
Matan Perelman | 54cc907c97 | |
Andreas Eversberg | 9baa065c8d | |
Andreas Eversberg | 9b81ef5db8 | |
arehbein | 50cb01c29f | |
Philipp Maier | 801b55ee4a | |
Andreas Eversberg | d4625a20a5 | |
Andreas Eversberg | fec682b45b | |
Andreas Eversberg | d561e2dcba | |
Andreas Eversberg | 82f10a6358 | |
Philipp Maier | a3a225a16b | |
arehbein | ea388e1db1 | |
Pau Espin | 9bb4b22152 | |
Oliver Smith | dea8aa8e61 | |
Pau Espin | eb5ac9dca4 | |
Matan Perelman | eff19b55b0 | |
Vadim Yanitskiy | 8fcd6ab174 | |
Vadim Yanitskiy | a84f30d7c5 | |
Vadim Yanitskiy | 029ab2326a | |
Vadim Yanitskiy | daf7b28387 | |
Harald Welte | c992bda3cd | |
Vadim Yanitskiy | 392cfc6a2a | |
Vadim Yanitskiy | a1745e3bdd | |
Vadim Yanitskiy | faf7592bf5 | |
Vadim Yanitskiy | fc2fb0d1a4 | |
Vadim Yanitskiy | bf7b457f1c | |
Vadim Yanitskiy | 362c040e16 | |
Vadim Yanitskiy | 4454350b42 | |
Vadim Yanitskiy | 5bdf6432f9 | |
Vadim Yanitskiy | ebffc84bf9 | |
Vadim Yanitskiy | c3446ef49e | |
Vadim Yanitskiy | 9e1b54254c | |
Vadim Yanitskiy | 9ac3459a00 | |
Vadim Yanitskiy | c8c4ac5659 | |
Vadim Yanitskiy | 0ac03bd525 | |
Vadim Yanitskiy | c4b330ba4c | |
Pau Espin | b2b5ca0613 | |
Pau Espin | 94878456e2 | |
Pau Espin | a473c260ff | |
Pau Espin | 9e5b3ad687 | |
Pau Espin | 6d4c1d84e5 | |
Philipp Maier | e55a114e8a | |
Philipp Maier | 33a2a2fed5 | |
Pau Espin | c1d7bb6908 | |
Pau Espin | 94426aae61 | |
Andreas Eversberg | 2ab39f7fa0 | |
Philipp Maier | 5c9162980d | |
Philipp Maier | 5950ea55e2 | |
Philipp Maier | 4f53837528 | |
Vadim Yanitskiy | b74b3ae38f | |
Andreas Eversberg | 7200b01577 | |
Andreas Eversberg | 2d93d61fe3 | |
Andreas Eversberg | b0712a9f22 | |
Andreas Eversberg | b620a1d994 | |
Andreas Eversberg | ded74dc220 | |
Andreas Eversberg | 55860eed89 | |
Andreas Eversberg | a0230990df | |
Andreas Eversberg | 62b9c83721 | |
Andreas Eversberg | 1f05282243 | |
Andreas Eversberg | 8ebf52ac76 | |
Andreas Eversberg | 1ad32f7430 | |
Andreas Eversberg | 1349c9c217 | |
Andreas Eversberg | 353fa5a14d | |
Andreas Eversberg | d8a6a533a1 | |
Andreas Eversberg | fd35bc917a | |
Andreas Eversberg | 0a2e79e946 | |
Andreas Eversberg | 87a6e6b651 | |
Andreas Eversberg | b18cae1952 | |
Andreas Eversberg | 2193f98f3e | |
Andreas Eversberg | 2436f40b4c | |
Andreas Eversberg | 4827437a26 | |
Andreas Eversberg | bcb7b32f5a | |
Andreas Eversberg | a7e3e0064d | |
Andreas Eversberg | e45fdd42d7 | |
Andreas Eversberg | aee1db9dc1 | |
Matan Perelman | 1c7eb78896 | |
Matan Perelman | 24e01a8225 | |
Vadim Yanitskiy | 121461669e | |
Oliver Smith | e6337315d0 | |
Matan Perelman | 241e594f7a | |
Matan Perelman | 1bae98e2d6 | |
Matan Perelman | 8b64e032e2 | |
Matan Perelman | 4e13aab269 | |
Pau Espin | bc8b61139d | |
Pau Espin | 74b34b4395 | |
Oliver Smith | 681f965710 | |
Oliver Smith | 3dc3ca5bab | |
Oliver Smith | 79b683ec24 | |
Oliver Smith | 162d8d79d4 | |
Oliver Smith | 40f5b3ff97 | |
Matan Perelman | 08b7b008c2 | |
Matan Perelman | 1dd9afe582 | |
Matan Perelman | 03b7b76a9f | |
Pau Espin | caad230e99 | |
Harald Welte | 6153c619fc | |
Philipp Maier | faff9f8fdc | |
Daniel Willmann | ee8205b46b | |
Pau Espin | ea9a6a1aea | |
Harald Welte | 43440e1fc5 | |
Matan Perelman | 633b7a9caf | |
Matan Perelman | d76bc795f7 | |
Vadim Yanitskiy | 50387d52f5 | |
Pau Espin | 9dc7211880 | |
Vadim Yanitskiy | 2a6954b3ae | |
Harald Welte | 8798689f3b | |
Vadim Yanitskiy | ff3540cb2c | |
Oliver Smith | fc914e9eb8 | |
Pau Espin | 5b60a0c8b5 | |
Philipp Maier | a1ff30920d | |
Oliver Smith | d33a66b779 | |
Vadim Yanitskiy | 1f3bfff668 | |
Max | c1e2888050 | |
Harald Welte | ef4ce1f3f1 | |
Harald Welte | ea7b53850b | |
Harald Welte | ceccba70a9 | |
Harald Welte | 5d8ab13b34 | |
Matan Perelman | ba3fe2c908 | |
Matan Perelman | a8fcc1bb73 | |
Matan Perelman | f4d9dfe6bd | |
Matan Perelman | 639cd00a22 | |
Neels Hofmeyr | 5d8d6d2079 | |
Neels Hofmeyr | a70d6b25c4 | |
Vadim Yanitskiy | ea3e3c258d | |
Vadim Yanitskiy | 16922c5017 | |
Vadim Yanitskiy | 05e2deb49c | |
Vadim Yanitskiy | 253f67f625 | |
Vadim Yanitskiy | 856c6dc2f5 | |
Oliver Smith | 758634eadf | |
Matan Perelman | 1619a82825 | |
Matan Perelman | 41e464e272 | |
Oliver Smith | 712343c321 | |
Oliver Smith | d128791919 | |
Neels Hofmeyr | a4cc4ef8ea | |
Neels Hofmeyr | 2dfffad7e3 | |
Neels Hofmeyr | 8f8af40974 | |
Vadim Yanitskiy | ba6fd4f8e4 | |
Vadim Yanitskiy | f2f0ab209d | |
Pau Espin | 58db3305d7 | |
Pau Espin | 90b83f9195 | |
Vadim Yanitskiy | 143dc67c99 | |
Vadim Yanitskiy | 117c699107 | |
Vadim Yanitskiy | a60d74ba9c | |
Vadim Yanitskiy | b8e115c646 | |
Vadim Yanitskiy | b96af7d7ec | |
Oliver Smith | 377c1e3fd7 | |
Vadim Yanitskiy | eb1de89024 | |
Vadim Yanitskiy | a9b4849e49 | |
Vadim Yanitskiy | ed5080adb3 | |
Vadim Yanitskiy | c8994ea6f7 | |
arehbein | fffd1b599c | |
Vadim Yanitskiy | 6d369665dd | |
Vadim Yanitskiy | bd6f8887e6 | |
Vadim Yanitskiy | ed8098ab2e | |
Vadim Yanitskiy | f80361d167 | |
Pau Espin | 27195c50a0 | |
Pau Espin | d38ccedad7 | |
Pau Espin | 4de0769720 | |
arehbein | 097925b626 | |
Pau Espin | ad253850d8 | |
Philipp Maier | 2365db4856 | |
Philipp Maier | f99952c2b0 | |
Philipp Maier | ccd69e9b2f | |
Philipp Maier | 4743ea578c | |
Neels Hofmeyr | 25bbe8895c | |
Neels Hofmeyr | 7a0bef1ae4 | |
arehbein | d7b277ff01 | |
Philipp Maier | 64c0e6e11c | |
Philipp Maier | 563652890c | |
Philipp Maier | a288c9f420 | |
Philipp Maier | 0625172265 | |
Philipp Maier | 10ae64a777 | |
Philipp Maier | 2af29ae92d | |
Philipp Maier | ec7842f816 | |
Philipp Maier | c4ab940544 | |
Philipp Maier | 4af073c109 | |
Philipp Maier | a10a34cf6a | |
Neels Hofmeyr | f2768d39c1 | |
Neels Hofmeyr | 2fda8dba70 | |
Pau Espin | 9f7611a32f | |
Vadim Yanitskiy | cbf3e5d850 | |
Vadim Yanitskiy | f18397aac9 | |
Pau Espin | a4fd6d9371 | |
Pau Espin | 08a7db6cd3 | |
Pau Espin | 0c87d39faf | |
Pau Espin | b4bbba72ad | |
Pau Espin | 1da0fcbbbc | |
Pau Espin | 85062ccad3 | |
Pau Espin | 9c21dc3d16 | |
Pau Espin | 646d21f2db | |
Pau Espin | 53cd4ad5fc | |
Pau Espin | 8958269ea9 | |
Pau Espin | 06d1cff11a | |
Pau Espin | c5b7d94e0f | |
Vadim Yanitskiy | 6b204ebd66 | |
Vadim Yanitskiy | 2acc7b94d2 | |
Pau Espin | c90c63bec0 | |
Vadim Yanitskiy | 30ecd0a767 | |
Pau Espin | 39d214fab5 | |
Philipp Maier | fcb9890675 | |
Oliver Smith | 2689ad73a8 | |
Philipp Maier | 6d3da5401f | |
Philipp Maier | 280ad4d966 | |
Philipp Maier | 7630b88fb5 | |
Philipp Maier | 6902fccb1b | |
Philipp Maier | ecf825dc08 | |
Oliver Smith | a8f5dbce77 | |
Philipp Maier | f85f8dd4a1 | |
Oliver Smith | d83d22bad3 | |
Oliver Smith | 722220f2dc | |
Oliver Smith | d5ca920cc3 | |
Oliver Smith | d5eb0f1b57 | |
Oliver Smith | 41ede5345c | |
Oliver Smith | 2fd39821f6 | |
Oliver Smith | 2150b307c2 | |
Oliver Smith | 0361b01614 | |
Oliver Smith | b11bf4d651 | |
Oliver Smith | e6e81e09b3 | |
Neels Hofmeyr | 25947b7aa4 | |
Oliver Smith | 17df53ea1a | |
Oliver Smith | 5a16fcee93 | |
Neels Hofmeyr | 071446d1b0 | |
Neels Hofmeyr | 220ef9a380 | |
Neels Hofmeyr | 896d694977 | |
Neels Hofmeyr | 879e7595f0 | |
Neels Hofmeyr | 76ea8562db | |
Neels Hofmeyr | 7214e56b49 | |
Neels Hofmeyr | 71e838ed02 | |
Neels Hofmeyr | 822b9dca1f | |
Neels Hofmeyr | 72fe0bf142 | |
Neels Hofmeyr | 89dd152577 | |
Oliver Smith | 5ea91cdae4 | |
Neels Hofmeyr | 881b6b2e6d | |
Neels Hofmeyr | c729d82b17 | |
Neels Hofmeyr | b599836c7a | |
Neels Hofmeyr | e073463ec4 | |
Neels Hofmeyr | 7bd795515f | |
Neels Hofmeyr | 89493f76b1 | |
Neels Hofmeyr | 3db22c6116 | |
Neels Hofmeyr | ce8d39d97c | |
Neels Hofmeyr | ec6360e005 | |
Neels Hofmeyr | f30f630a88 | |
Neels Hofmeyr | 8196ef5405 | |
Neels Hofmeyr | 8b55573a73 | |
Neels Hofmeyr | 91ab3fe5a0 | |
Neels Hofmeyr | d4a0a2c36a | |
Neels Hofmeyr | 50558c17f9 | |
Philipp Maier | 52b74175dd | |
Neels Hofmeyr | 7747fecdbe | |
Vadim Yanitskiy | 4a61575917 | |
Philipp Maier | 111b13f9a2 | |
Oliver Smith | 4e54e16b9f | |
Oliver Smith | f597a035fa | |
Oliver Smith | 71c8bdfc56 | |
Oliver Smith | 31f81d55fc | |
Michael Iedema | fbead43271 | |
Oliver Smith | 146c228df2 | |
Oliver Smith | 0e552cc9c1 | |
Philipp Maier | 3632ffe65a | |
Oliver Smith | 88133a746d | |
Harald Welte | c4b523a8f3 | |
Oliver Smith | 4bcfb7e034 | |
Oliver Smith | cb3eb23ec2 | |
Oliver Smith | 23e3e29b7a | |
Philipp Maier | 329e1cdc22 | |
Philipp Maier | d4044214ca | |
Philipp Maier | ec1a0a102f | |
Philipp Maier | ee43e37528 | |
Philipp Maier | f18e9c36f4 | |
Philipp Maier | 8a0572256b | |
Philipp Maier | 107d311d96 | |
Philipp Maier | 7a346a547e | |
Philipp Maier | 84811c901e | |
Philipp Maier | 3c4320f935 | |
Max | 54b7cd5392 |
|
@ -0,0 +1 @@
|
|||
open_collective: osmocom
|
|
@ -19,7 +19,7 @@ SUBDIRS = \
|
|||
BUILT_SOURCES = $(top_srcdir)/.version
|
||||
EXTRA_DIST = \
|
||||
.version \
|
||||
contrib/osmo-bsc.spec.in \
|
||||
README.md \
|
||||
debian \
|
||||
git-version-gen \
|
||||
osmoappdesc.py \
|
||||
|
|
39
README.md
39
README.md
|
@ -2,24 +2,25 @@ osmo-bsc - Osmocom BSC Implementation
|
|||
=====================================
|
||||
|
||||
This repository contains a C-language implementation of a GSM Base Station
|
||||
Controller (BSC). IT is part of the
|
||||
Controller (BSC). It is part of the
|
||||
[Osmocom](https://osmocom.org/) Open Source Mobile Communications
|
||||
project.
|
||||
|
||||
OsmoBSC exposes
|
||||
* A over IP towards an MSC (e.g. OsmoMSC): 3GPP AoIP or SCCPlite
|
||||
* Abis interfaces towards various kinds of BTS (osmo-bts, sysmobts, nanoBTS, Siemens, Nokia, Ericsson)
|
||||
* The Osmocom typical telnet VTY and CTRL interfaces.
|
||||
* The Osmocom typical statsd exporter.
|
||||
* Cell Broadcast Service Protocol (CBSP) towards a CBC (Cell Broadcast Centre, such as osmo-cbc).
|
||||
* Lb interface towards a SMLC (Serving Mobile Location Centre, such as osmo-smlc).
|
||||
|
||||
* *A over IP* towards an MSC (e.g. [osmo-msc](https://osmocom.org/projects/osmomsc/wiki)): 3GPP AoIP or SCCPlite
|
||||
* *Abis* interfaces towards various kinds of BTS (e.g. [osmo-bts](https://osmocom.org/projects/osmobts/wiki/Wiki), sysmobts, nanoBTS, Siemens, Nokia, Ericsson)
|
||||
* The Osmocom typical telnet *VTY* and *CTRL* interfaces.
|
||||
* The Osmocom typical *statsd* exporter.
|
||||
* Cell Broadcast Service Protocol (*CBSP*) towards a CBC (Cell Broadcast Centre, such as [osmo-cbc](https://osmocom.org/projects/osmo-cbc/wiki)).
|
||||
* Lb interface towards a *SMLC* (Serving Mobile Location Centre, such as [osmo-smlc](https://osmocom.org/projects/osmo-smlc/wiki/OsmoSMLC)).
|
||||
|
||||
|
||||
Homepage
|
||||
--------
|
||||
|
||||
You can find the OsmoBSC issue tracker and wiki online at
|
||||
<https://osmocom.org/projects/osmobsc> and <https://osmocom.org/projects/osmobsc/wiki>.
|
||||
You can find the OsmoBSC homepage with issue tracker and wiki online at
|
||||
<https://osmocom.org/projects/osmobsc/wiki>.
|
||||
|
||||
|
||||
GIT Repository
|
||||
|
@ -49,6 +50,14 @@ Maunal](https://downloads.osmocom.org/docs/latest/osmobsc-cbsp.pdf)
|
|||
describing the level of CBSP conformance.
|
||||
|
||||
|
||||
Forum
|
||||
-----
|
||||
|
||||
We welcome any osmo-bsc related discussions in the
|
||||
[Cellular Network Infrastructure -> 2G/3G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran)
|
||||
section of the osmocom discourse (web based Forum).
|
||||
|
||||
|
||||
Mailing List
|
||||
------------
|
||||
|
||||
|
@ -61,6 +70,15 @@ 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-bsc project on osmocom.org](https://osmocom.org/projects/osmobsc/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
|
||||
------------
|
||||
|
||||
|
@ -90,6 +108,3 @@ worked as a standalone osmo-bsc binary as well as a combination of libbsc and
|
|||
libmsc, i.e. the old OsmoNITB. Since the standalone OsmoMSC with a true A
|
||||
interface (and IuCS for 3G support) is available, OsmoBSC exists only as a
|
||||
separate standalone entity.
|
||||
|
||||
OsmoBSC-NAT is a specialized solution to navigating RTP streams through a NAT.
|
||||
(Todo: describe in more detail)
|
||||
|
|
|
@ -7,3 +7,5 @@
|
|||
# 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.9.0 working (compiling) OSMO_SOCKADDR_STR_FMT_ARGS_NOT_NULL
|
||||
libosmocore > 1.9.0 we use the new osmo_cbsp_segmentation_cb
|
||||
|
|
73
configure.ac
73
configure.ac
|
@ -36,38 +36,52 @@ if test "x$PKG_CONFIG_INSTALLED" = "xno"; then
|
|||
fi
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
|
||||
# Enable/disable ipaccess-utils (src/ipacces/)?
|
||||
AC_ARG_ENABLE([ipaccess-utils], [AS_HELP_STRING([--enable-ipaccess-utils], [Build ipaccess utils: abisip-find, ipaccess-config, ...])],
|
||||
# Enable/disable ipaccess-utils (src/ipacces/)
|
||||
AC_ARG_ENABLE([ipaccess-utils], [AS_HELP_STRING([--enable-ipaccess-utils], [Build ipaccess utils: abisip-find, ipaccess-config, ... [default=yes]])],
|
||||
[osmo_ac_ipa_utils="$enableval"],[osmo_ac_ipa_utils="yes"])
|
||||
AM_CONDITIONAL(BUILD_IPA_UTILS, test "x$osmo_ac_ipa_utils" = "xyes")
|
||||
AC_SUBST(osmo_ac_ipa_utils)
|
||||
|
||||
# Enable/disable osmo-meas-udp2db
|
||||
AC_ARG_ENABLE([meas-udp2db], [AS_HELP_STRING([--enable-meas-udp2db], [Build osmo-meas-udp2db: listen to meas_feed on UDP and write it to an sqlite3 database [default=no]])],
|
||||
[osmo_ac_meas_udp2db="$enableval"],[osmo_ac_meas_udp2db="no"])
|
||||
AM_CONDITIONAL(BUILD_MEAS_UDP2DB, test "x$osmo_ac_meas_udp2db" = "xyes")
|
||||
AC_SUBST(osmo_ac_meas_udp2db)
|
||||
|
||||
# Enable/disable osmo-meas-pcap2db
|
||||
AC_ARG_ENABLE([meas-pcap2db], [AS_HELP_STRING([--enable-meas-pcap2db], [Build osmo-meas-pcap2db: read PCAP file with meas_feed data and write it to an sqlite3 database [default=no]])],
|
||||
[osmo_ac_meas_pcap2db="$enableval"],[osmo_ac_meas_pcap2db="no"])
|
||||
AM_CONDITIONAL(BUILD_MEAS_PCAP2DB, test "x$osmo_ac_meas_pcap2db" = "xyes")
|
||||
AC_SUBST(osmo_ac_meas_pcap2db)
|
||||
|
||||
# Enable/disable meas_vis
|
||||
AC_ARG_ENABLE([meas-vis], [AS_HELP_STRING([--enable-meas-vis], [Build meas_vis: curses-visualization of measurements [default=no]])],
|
||||
[osmo_ac_meas_vis="$enableval"],[osmo_ac_meas_vis="no"])
|
||||
AM_CONDITIONAL(BUILD_MEAS_VIS, test "x$osmo_ac_meas_vis" = "xyes")
|
||||
AC_SUBST(osmo_ac_meas_vis)
|
||||
|
||||
dnl checks for libraries
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.3.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.7.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.11.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0)
|
||||
PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOSIGTRAN, libosmo-sigtran >= 1.8.0)
|
||||
PKG_CHECK_MODULES(LIBOSMOMGCPCLIENT, libosmo-mgcp-client >= 1.12.0)
|
||||
|
||||
dnl checks for header files
|
||||
AC_HEADER_STDC
|
||||
|
||||
found_pcap=yes
|
||||
AC_CHECK_HEADERS(pcap/pcap.h,,found_pcap=no)
|
||||
AM_CONDITIONAL(HAVE_PCAP, test "$found_pcap" = yes)
|
||||
|
||||
found_cdk=yes
|
||||
AC_CHECK_HEADERS(cdk/cdk.h,,found_cdk=no)
|
||||
AM_CONDITIONAL(HAVE_LIBCDK, test "$found_cdk" = yes)
|
||||
|
||||
found_sqlite3=yes
|
||||
PKG_CHECK_MODULES(SQLITE3, sqlite3, ,found_sqlite3=no)
|
||||
AM_CONDITIONAL(HAVE_SQLITE3, test "$found_sqlite3" = yes)
|
||||
AC_SUBST(found_sqlite3)
|
||||
|
||||
if test "$osmo_ac_meas_pcap2db" = "yes" || test "$osmo_ac_meas_udp2db" = "yes"; then
|
||||
PKG_CHECK_MODULES(SQLITE3, sqlite3)
|
||||
fi
|
||||
if test "$osmo_ac_meas_pcap2db" = "yes"; then
|
||||
AC_CHECK_HEADERS(pcap/pcap.h, [], AC_MSG_ERROR(Unable to find libpcap))
|
||||
fi
|
||||
if test "$osmo_ac_meas_vis" = "yes"; then
|
||||
AC_CHECK_HEADERS(cdk/cdk.h, [], AC_MSG_ERROR(Unable to find libcdk))
|
||||
fi
|
||||
|
||||
dnl Checks for typedefs, structures and compiler characteristics
|
||||
|
||||
|
@ -77,8 +91,7 @@ AC_ARG_ENABLE(sanitize,
|
|||
[Compile with address sanitizer enabled],
|
||||
)],
|
||||
[sanitize=$enableval], [sanitize="no"])
|
||||
if test x"$sanitize" = x"yes"
|
||||
then
|
||||
if test x"$sanitize" = x"yes"; then
|
||||
CFLAGS="$CFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
CPPFLAGS="$CPPFLAGS -fsanitize=address -fsanitize=undefined"
|
||||
fi
|
||||
|
@ -92,8 +105,7 @@ AC_ARG_ENABLE(werror,
|
|||
]
|
||||
)],
|
||||
[werror=$enableval], [werror="no"])
|
||||
if test x"$werror" = x"yes"
|
||||
then
|
||||
if test x"$werror" = x"yes"; then
|
||||
WERROR_FLAGS="-Werror"
|
||||
WERROR_FLAGS+=" -Wno-error=deprecated -Wno-error=deprecated-declarations"
|
||||
WERROR_FLAGS+=" -Wno-error=cpp" # "#warning"
|
||||
|
@ -129,8 +141,7 @@ fi
|
|||
AC_ARG_ENABLE(profile,
|
||||
[AS_HELP_STRING([--enable-profile], [Compile with profiling support enabled], )],
|
||||
[profile=$enableval], [profile="no"])
|
||||
if test x"$profile" = x"yes"
|
||||
then
|
||||
if test x"$profile" = x"yes"; then
|
||||
CFLAGS="$CFLAGS -pg"
|
||||
CPPFLAGS="$CPPFLAGS -pg"
|
||||
fi
|
||||
|
@ -163,8 +174,7 @@ AC_ARG_ENABLE(manuals,
|
|||
AM_CONDITIONAL([BUILD_MANUALS], [test x"$osmo_ac_build_manuals" = x"yes"])
|
||||
AC_ARG_VAR(OSMO_GSM_MANUALS_DIR, [path to common osmo-gsm-manuals files, overriding pkg-config and "../osmo-gsm-manuals"
|
||||
fallback])
|
||||
if test x"$osmo_ac_build_manuals" = x"yes"
|
||||
then
|
||||
if test x"$osmo_ac_build_manuals" = x"yes"; then
|
||||
# Find OSMO_GSM_MANUALS_DIR (env, pkg-conf, fallback)
|
||||
if test -n "$OSMO_GSM_MANUALS_DIR"; then
|
||||
echo "checking for OSMO_GSM_MANUALS_DIR... $OSMO_GSM_MANUALS_DIR (from env)"
|
||||
|
@ -241,5 +251,4 @@ AC_OUTPUT(
|
|||
doc/manuals/Makefile
|
||||
contrib/Makefile
|
||||
contrib/systemd/Makefile
|
||||
contrib/osmo-bsc.spec
|
||||
Makefile)
|
||||
|
|
|
@ -4,8 +4,18 @@
|
|||
# environment variables:
|
||||
# * WITH_MANUALS: build manual PDFs if set to "1"
|
||||
# * PUBLISH: upload manuals after building if set to "1" (ignored without WITH_MANUALS = "1")
|
||||
# * IS_MASTER_BUILD: set to 1 when running from master-builds (not gerrit-verifications)
|
||||
#
|
||||
|
||||
exit_tar_workspace() {
|
||||
if [ "$IS_MASTER_BUILD" = "1" ]; then
|
||||
tar -cJf "/tmp/workspace.tar.xz" "$base"
|
||||
mv /tmp/workspace.tar.xz "$base"
|
||||
fi
|
||||
|
||||
cat-testlogs.sh
|
||||
}
|
||||
|
||||
if ! [ -x "$(command -v osmo-build-dep.sh)" ]; then
|
||||
echo "Error: We need to have scripts/osmo-deps.sh from http://git.osmocom.org/osmo-ci/ in PATH !"
|
||||
exit 2
|
||||
|
@ -50,9 +60,15 @@ osmo-build-dep.sh libosmo-sccp
|
|||
osmo-build-dep.sh osmo-mgw
|
||||
|
||||
# Additional configure options and depends
|
||||
CONFIG=""
|
||||
CONFIG="
|
||||
--enable-external-tests
|
||||
--enable-meas-pcap2db
|
||||
--enable-meas-udp2db
|
||||
--enable-meas-vis
|
||||
--enable-werror
|
||||
"
|
||||
if [ "$WITH_MANUALS" = "1" ]; then
|
||||
CONFIG="--enable-manuals"
|
||||
CONFIG="$CONFIG --enable-manuals"
|
||||
fi
|
||||
|
||||
set +x
|
||||
|
@ -65,14 +81,14 @@ set -x
|
|||
|
||||
cd "$base"
|
||||
autoreconf --install --force
|
||||
./configure --enable-sanitize --enable-external-tests --enable-werror $CONFIG
|
||||
./configure --enable-sanitize $CONFIG
|
||||
$MAKE $PARALLEL_MAKE
|
||||
LD_LIBRARY_PATH="$inst/lib" $MAKE check \
|
||||
|| cat-testlogs.sh
|
||||
|| exit_tar_workspace
|
||||
LD_LIBRARY_PATH="$inst/lib" \
|
||||
DISTCHECK_CONFIGURE_FLAGS="--enable-vty-tests --enable-external-tests --enable-werror $CONFIG" \
|
||||
DISTCHECK_CONFIGURE_FLAGS="$CONFIG" \
|
||||
$MAKE $PARALLEL_MAKE distcheck \
|
||||
|| cat-testlogs.sh
|
||||
|| exit_tar_workspace
|
||||
|
||||
if [ "$WITH_MANUALS" = "1" ] && [ "$PUBLISH" = "1" ]; then
|
||||
make -C "$base/doc/manuals" publish
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
#
|
||||
# spec file for package osmo-bsc
|
||||
#
|
||||
# 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.
|
||||
|
||||
## Disable LTO for now since it breaks compilation of the tests
|
||||
## https://osmocom.org/issues/4113
|
||||
%define _lto_cflags %{nil}
|
||||
|
||||
Name: osmo-bsc
|
||||
Version: @VERSION@
|
||||
Release: 0
|
||||
Summary: OsmoBSC: Osmocom's Base Station Controller for 2G CS mobile networks
|
||||
License: AGPL-3.0-or-later AND GPL-2.0-or-later
|
||||
Group: Hardware/Mobile
|
||||
URL: https://osmocom.org/projects/osmobsc
|
||||
Source: %{name}-%{version}.tar.xz
|
||||
BuildRequires: automake >= 1.9
|
||||
BuildRequires: libtool >= 2
|
||||
BuildRequires: pkgconfig >= 0.20
|
||||
%if 0%{?suse_version}
|
||||
BuildRequires: systemd-rpm-macros
|
||||
%endif
|
||||
BuildRequires: pkgconfig(libcrypto) >= 0.9.5
|
||||
BuildRequires: pkgconfig(libosmo-mgcp-client) >= 1.11.0
|
||||
BuildRequires: pkgconfig(libosmo-netif) >= 1.3.0
|
||||
BuildRequires: pkgconfig(libosmo-sigtran) >= 1.7.0
|
||||
BuildRequires: pkgconfig(libosmoabis) >= 1.4.0
|
||||
BuildRequires: pkgconfig(libosmocore) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmoctrl) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmogb) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmogsm) >= 1.8.0
|
||||
BuildRequires: pkgconfig(libosmovty) >= 1.8.0
|
||||
BuildRequires: pkgconfig(talloc)
|
||||
%{?systemd_requires}
|
||||
|
||||
%description
|
||||
OsmoBSC: Osmocom's Base Station Controller for 2G circuit-switched mobile networks.
|
||||
|
||||
%package abisip-find
|
||||
Summary: CLI utility to find ip.access compatible BTS
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description abisip-find
|
||||
Command line utility to find ip.access compatible BTS.
|
||||
|
||||
%package ipaccess-utils
|
||||
Summary: Command line utilities for ip.access nanoBTS
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description ipaccess-utils
|
||||
This package contains utilities that are specific for nanoBTS when being
|
||||
used together with OpenBSC. It contains mainly two tools: ipaccess-config
|
||||
and ipaccess-proxy.
|
||||
|
||||
%package bs11-utils
|
||||
Summary: Command line utilities for Siemens BS-11 BTS
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description bs11-utils
|
||||
There is a tool in this package for configuring the Siemens BS-11 BTS.
|
||||
Additionally, it contains one tool for making use of an ISDN-card and the
|
||||
public telephone network as frequency standard for the E1 line.
|
||||
|
||||
%package meas-utils
|
||||
Summary: Command line utilities for OsmoBSC's measurement reports
|
||||
License: GPL-2.0-or-later
|
||||
Group: Productivity/Telephony/Utilities
|
||||
|
||||
%description meas-utils
|
||||
This package contains utilities for handling OsmoBSC's measurement reports
|
||||
* meas_json to convert measurement feed into a JSON feed
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
echo "%{version}" >.tarball-version
|
||||
autoreconf -fi
|
||||
%configure \
|
||||
--docdir=%{_docdir}/%{name} \
|
||||
--with-systemdsystemunitdir=%{_unitdir}
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
%if 0%{?suse_version}
|
||||
%preun
|
||||
%service_del_preun %{name}.service
|
||||
|
||||
%postun
|
||||
%service_del_postun %{name}.service
|
||||
|
||||
%pre
|
||||
%service_add_pre %{name}.service
|
||||
|
||||
%post
|
||||
%service_add_post %{name}.service
|
||||
%endif
|
||||
|
||||
%check
|
||||
make %{?_smp_mflags} check || (find . -name testsuite.log -exec cat {} +)
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%doc AUTHORS README.md
|
||||
%{_bindir}/osmo-bsc
|
||||
%dir %{_docdir}/%{name}/examples
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bsc
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-4trx-fh.confmerge
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-4trx.cfg
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/osmo-bsc-minimal.cfg
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bsc/ericsson
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bsc/nokia
|
||||
%dir %{_docdir}/%{name}/examples/osmo-bsc/siemens
|
||||
%{_docdir}/%{name}/examples/osmo-bsc/*/osmo-bsc*.cfg
|
||||
%dir %{_sysconfdir}/osmocom
|
||||
%config(noreplace) %{_sysconfdir}/osmocom/osmo-bsc.cfg
|
||||
%{_unitdir}/%{name}.service
|
||||
|
||||
%files abisip-find
|
||||
%{_bindir}/abisip-find
|
||||
|
||||
%files ipaccess-utils
|
||||
%{_bindir}/ipaccess-config
|
||||
%{_bindir}/ipaccess-proxy
|
||||
|
||||
%files bs11-utils
|
||||
%{_bindir}/bs11_config
|
||||
%{_bindir}/isdnsync
|
||||
|
||||
%files meas-utils
|
||||
%{_bindir}/meas_json
|
||||
|
||||
%changelog
|
|
@ -1,12 +1,17 @@
|
|||
[Unit]
|
||||
Description=Osmocom Base Station Controller (BSC)
|
||||
Wants=osmo-mgw.service
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=always
|
||||
LimitNOFILE=65536
|
||||
StateDirectory=osmocom
|
||||
WorkingDirectory=%S/osmocom
|
||||
User=osmocom
|
||||
Group=osmocom
|
||||
ExecStart=/usr/bin/osmo-bsc -c /etc/osmocom/osmo-bsc.cfg -s
|
||||
RestartSec=2
|
||||
|
||||
|
|
|
@ -1,3 +1,268 @@
|
|||
osmo-bsc (1.11.0) unstable; urgency=medium
|
||||
|
||||
[ Max ]
|
||||
* doc: correct reference and add deprecation notice
|
||||
* pcu_connected(): constify parameter
|
||||
|
||||
[ Philipp Maier ]
|
||||
* pcuif_proto: rename PCU_IF_SAPI_AGCH_DT to PCU_IF_SAPI_PCH_DT
|
||||
* pcu_sock: cosmetic: remove space before tab
|
||||
* abis_rsl: add support for sending IMMEDIATE ASSIGNMENT through PCH
|
||||
* pcu_sock: use extract_paging_group() for PCU_IF_SAPI_PCH
|
||||
* abis_rsl: constify parameters of rsl_X_imm_assign_cmd
|
||||
* pcu_sock: transfer sysinfo to PCU
|
||||
* pcu_sock: transfer E1 connection information to PCU
|
||||
* pcu_sock: set direct TLLI flag in info indication
|
||||
* bts_trx_vty: use define constant E1_SUBSLOT_FULL instead magic number
|
||||
* bsc_subscriber_conn_fsm: use subslot 0 in case of E1 full subslot
|
||||
* timeslot_fsm: fix sourcecode indenting
|
||||
* pcu_sock: print OML alerts from PCU
|
||||
* abis_rsl: guard against over long IMMEDIATE ASSIGNMENT Messages
|
||||
* pcu_sock: get rid of leaking message buffer
|
||||
* pcu_sock: activate/deactivate PDCH on pcu reconnect
|
||||
* pcu_sock: use struct to transfer IMMEDIATE ASSIGNMENT for PCH
|
||||
* pcu_sock: improve logging
|
||||
* pcu_sock: rename rc to fd
|
||||
* pcu_sock: cosmetic: remove whitespace after type cast
|
||||
* timeslot_fsm: fix PDCH activation
|
||||
* bts: is_xyz_bts check functions should return bool
|
||||
* bts: add function to check if a BTS has a BSC co located PCU
|
||||
* pcu_sock: use is_ericsson_bts() to check for ericsson BTS
|
||||
* pcu_sock: check BTS type properly in pcu_info_update()
|
||||
* pcu_sock: drop usage of PCUIF flag PCU_IF_FLAG_DT
|
||||
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing listen_bfd->fd
|
||||
* pcu_sock: handle multiple BTSs with one BSC co-located PCU (in theory)
|
||||
* pcuif_proto: increment version number
|
||||
* doc: add sample configuration for GPRS with ericsson RBS
|
||||
* doc: overview: replace section TRAU mapper / E1 sub-channel muxer
|
||||
* bts: bts: Explain Ericsson's interface switch (IS)
|
||||
* doc: running: Describe how to configure a co-located PCU
|
||||
* examples: update erissson GPRS config files
|
||||
* doc: bts-examples: discuss Ericsson RBS EGPRS configuration
|
||||
* pcu_sock: fix PCUIF interface (PCH)
|
||||
* pcu_sock: use correct SAPI in message PCUIF PCU_IF_MSG_DATA_CNF_DT
|
||||
* pcuif_proto: rename tlli to msg_id
|
||||
* pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt
|
||||
* pcuif_proto: get rid of _DT, _dt (Direct TLLI)
|
||||
* pcuif_proto: check confirm flag in struct gsm_pcu_if_pch
|
||||
* pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH
|
||||
|
||||
[ Oliver Smith ]
|
||||
* ho: remove timeout for HO_ST_WAIT_LCHAN_ACTIVE
|
||||
* ho: remove timeout for HO_ST_WAIT_LCHAN_ESTABLISHED
|
||||
* fsms: use configurable timers instead of T23042
|
||||
* osmo_bsc_main: don't allocate talloc_ctr_ctx
|
||||
* Cosmetic: fix various typos
|
||||
* Cosmetic: codec_pref: tweak comments
|
||||
* bssmap_handle_assignm_req: split up
|
||||
* bssmap_handle_ass_req_ct_speech: split up
|
||||
* bssmap_handle_ass_req_ct_speech: refactor
|
||||
* codec_pref: split test_codec_support_bts_rate
|
||||
* test_codec_support_bts_rate: add missing breaks
|
||||
* lchan.h: remove enum lchan_csd_mode
|
||||
* channel_mode_from_lchan: add GSM48_CMODE_DATA_3k6
|
||||
* bssmap_handle_ass_req_ct_data: implement
|
||||
* abis_rsl: ipacc_payload_type: handle CSD
|
||||
* bssmap_handle_ass_req_tp_codec_list: tweak log msg
|
||||
* assignment_fsm: chan mode check: support CSD
|
||||
* tests/handover: wrap functions from gsm_08_08.c
|
||||
* requires_voice_stream -> ch_indctr
|
||||
* lchan_select: chan_mode_to_chan_type: support CSD
|
||||
* rsl_tx_ipacc_crcx/mdcx: omit speech mode for CSD
|
||||
* chan_mode_to_mgcp_codec: support CSD
|
||||
* Cosmetic: channel_mode_from_lchan: remove fixme
|
||||
* check_chan_mode_rate_against…: fix never true cond
|
||||
* abis_rsl: CSD: add RTP_CSD_FMT IE to CRCX/MDCX
|
||||
* bsc_mgw_setup: use mgcp_client_pool_empty()
|
||||
* abis_rsl: fix encoding RSL_IE_IPAC_RTP_CSD_FORMAT
|
||||
* CSD: support non-transparent data rates
|
||||
* debian: set compat level to 10
|
||||
* contrib/jenkins: create workspace.tar.xz on error
|
||||
* systemd: depend on networking-online.target
|
||||
* Fix various typos
|
||||
* Cosmetic: configure: move if … then to same line
|
||||
* configure: ipa utils: add default=yes to arg help
|
||||
* Cosmetic: debian/rules: remove boilerplate
|
||||
* contrib/jenkins.sh: deduplicate configure flags
|
||||
* configure: add --enable-meas-udp2db/pcap2db/vis
|
||||
|
||||
[ Harald Welte ]
|
||||
* Work around coverity false positives in macros
|
||||
* abis_nm: Only osmo-bts re-purposes the MANUF_ID for BTS feature flags
|
||||
* cosmetic: Rename is_ipaccess_bts() to is_ipa_abisip_bts()
|
||||
* cosmetic: Clarify language ip.access nanoBTS vs. all IPA Abis/IP
|
||||
* test case fixup: Add missing (void) empty argument list specification
|
||||
* Support (optional) indication of NCH position in SI1 rest octets
|
||||
* nanobts: Request "supported features" attribute from BTS and BB_TRANSC
|
||||
* prevent bogus NCH related error message if no NCH is configured
|
||||
|
||||
[ Michael Iedema ]
|
||||
* utils: store more fields from meas-feed in db
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
* utils: fix incorrect string checks in meas_db_insert()
|
||||
* ipaccess_drop_oml(): invalidate the feature vector
|
||||
* Makefile.am: remove unneeded AM_LDFLAGS with LIBS
|
||||
* tests: use -no-install libtool flag to avoid ./lt-* scripts
|
||||
* fix bs11_read_swl_file(): properly clean up stale file list
|
||||
* fix ipacc_rtp_csd_fmt_non_transp(): add missing breaks
|
||||
* tests: $(BUILT_SOURCES) is not defined, depend on osmo-bsc
|
||||
* osmoappdesc.py: add more config files for testing
|
||||
* tests: add VTY transcript tests for 'si2quater neighbor-list'
|
||||
* tests: demonstrate the problems of 'si2quater neighbor-list'
|
||||
* doc/{examples,manuals}: remove dummy 'gprs nsvc 1'
|
||||
* tests: rename and extend gprs_{bvci_default->params}.vty
|
||||
* tests: add more tests for GPRS NSVC parameters
|
||||
* gprs: fix has_valid_nsvc(): permit local udp port 0
|
||||
* cosmetic: bts_uarfcn_add(): pass diversity directly to encode_fdd()
|
||||
* cosmetic: bts_vty: switch is not a function, add a space
|
||||
* si2quater: bts_uarfcn_add(): check if already added first
|
||||
* si2quater: bts_uarfcn_add(): modify existsing UARFCNs
|
||||
* si2quater: bts_earfcn_add(): do not add duplicate EARFCNs
|
||||
* si2quater: add CTRL commands for deleting neighbor [EU]ARFCNs
|
||||
* si2quater: check return value of osmo_earfcn_del()
|
||||
* bts_is_online(): make the BTS pointer const, return bool
|
||||
* struct gsm_bts_model: rename power_ctrl_{set->send}_c0_power_red
|
||||
* bootstrap_rsl(): cosmetic: cache trx->bts and use it directly
|
||||
* bts: st_op_enabled_on_enter(): resume C0 power reduction
|
||||
* gsm_bts_send_c0_power_red(): check if BTS is online first
|
||||
* copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH
|
||||
* fixup: contrib/jenkins: create workspace.tar.xz on error
|
||||
* tests/{ctrl,vty}_test_runner.py: raise an exception if proc's rc != 0
|
||||
* contrib/jenkins.sh: remove unrecognized --enable-vty-tests
|
||||
* lchan_select: fix lchan selection for GSM48_CMODE_DATA_{14k5,12k0}
|
||||
* fix send_assignment_complete(): proper SCE encoding for CSD
|
||||
|
||||
[ Neels Hofmeyr ]
|
||||
* examples: osmo-bsc-minimal.cfg: drop codec-list
|
||||
* pick up all *.vty in EXTRA_DIST
|
||||
* add msc.vty to test 'msc' / 'codec-list' cfg
|
||||
* cosmetic: use char literals in cfg_net_bsc_codec_list()
|
||||
* cosmetic: use i++ instead of ++i in for loop
|
||||
* vty: improve doc for 'codec-list'
|
||||
* bsc_vty.c: s/bsc/msc for commands under msc node
|
||||
* bsc_vty.c write_msc(): fix weird printf format
|
||||
* vty: msc / codec-list: tweak error msg
|
||||
* cosmetic: clarify test_codec_support_bts()
|
||||
* select_codecs(): doc tweak
|
||||
* select_codecs(): constify ct arg
|
||||
* add timeslot.vty
|
||||
* implicitly register osmo_fsm definitions
|
||||
* assignment_fsm.c: make two functions static
|
||||
* bsc_test: add 'update_exp'
|
||||
* simplify storage of bsc_msc_data->audio_support
|
||||
* vty: msc / codec-list: forbid duplicate entries
|
||||
* vty: msc / codec-list: forbid invalid codec versions
|
||||
* ensure correct phys_chan_config doc string count on VTY
|
||||
* VTY,CTRL: add pchan dynamic/{osmocom,ipaccess}
|
||||
* stat: change pchan naming to dynamic/{osmocom,ipaccess}
|
||||
* bsc_test.c: test FSM IDs that contain pchan names
|
||||
* tweak gsm_pchan_ids[]: DYNAMIC/{OSMOCOM,IPACCESS}
|
||||
* drop gsm_pchan_ids, use sanitized FSM ids instead
|
||||
* doc: add codec_resolution.msc
|
||||
* cosmetic: timeslot_fsm.c: move some code to separate function
|
||||
* vty: codec-list: fix error message
|
||||
* fix coverity (false) warning in codec-list vty
|
||||
* segfault: verify lchan presence on Assignment Complete
|
||||
* add location_services_fsm_bsc.dot
|
||||
* SCCP N-PCSTATE: trigger MSC status on PC availability
|
||||
* log: N-PCSTATE: use new value_strings
|
||||
* fix comment typo
|
||||
* fix length check in abis_rsl_rx_rll()
|
||||
* fix mscpool for large msc NRs
|
||||
|
||||
[ Pau Espin Pedrol ]
|
||||
* cosmetic: gsm_data.h: Fix typo in comment
|
||||
* constify bsc_conn_by_bsub() ptr param
|
||||
* Clarify type and values of sccp.conn_id
|
||||
* bscc_sccp: Avoid allocating conn_id 0x00FFFFFF
|
||||
* get_bsc_conn_by_conn_id(): Properly match sccp_instance
|
||||
* bscc_sccp: Small optimiztion in bsc_sccp_inst_next_conn_id()
|
||||
* Assert conn_id being looked up is inside expected range
|
||||
* pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd
|
||||
* Optimize subscr_conns lookup
|
||||
* Move bsc_conn_by_bsub() and make it static
|
||||
* bsc_subscriber: Drop unused function bsc_subscr_find_by_mi()
|
||||
* bsc_subscriber: Mark functions used only internally as static
|
||||
* bsc_subscriber: Introduce bsc_subscriber_store object
|
||||
* bsc_subscriber: Optimize lookup of bsub by TMSI
|
||||
* Fix Lb/A SCCP conn lookup after recent regression in optimization patch
|
||||
* Use new GSM0408 defines for half-octet tags
|
||||
* abis_rsl: Document spec ref of CCCH Load Ind
|
||||
* Move paging queue specific handling to signal callback outside RSL code
|
||||
* bts-rbs2k: Simplify osmo_fsm_inst_alloc_child_id()
|
||||
* ipaccess nm: Delay marking TS as usable until OML reports Enabled state
|
||||
* ipaccess nm: Handle TS_EV_OML_DOWN through NM FSM
|
||||
* UserManual: Include sigtran*.adoc from osmo-gsm-manuals.git
|
||||
* Write explicit role & sctp-role fields in ASP configurations
|
||||
* Use new mgcp_client_conf_alloc() API to alloc mgcp_client_conf
|
||||
* Use new libosmo-sccp APIs osmo_ss7_asp_get_{name,proto}()
|
||||
* SI13: Set DRX_TIMER_MAX value actually transmitted
|
||||
* cosmetic: Document DRX_TIMER_MAX upper limit on BCCH smaller than possible range
|
||||
* meas_feed: Refactor fd/wqueue lifecycle
|
||||
* meas_feed: Increase wqueue max_len to 100 and make it vty-configurable
|
||||
* oml: ipacc: Remove BSSGP value assignment being overwritten afterwards
|
||||
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_bssgp_cfg from libosmcore
|
||||
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_ns_cfg from libosmcore
|
||||
* oml: ipacc: Use new packed struct abis_nm_ipacc_att_rlc_cfg from libosmcore
|
||||
|
||||
[ arehbein ]
|
||||
* gsm_bts_check_ny1: Prevent possible division by zero
|
||||
* main: Give specific error message
|
||||
* PCU interface: Log version when starting listener
|
||||
|
||||
[ Matan Perelman ]
|
||||
* ctrl: Add cell reselection offset control
|
||||
* ctrl: Remove dots from OOM
|
||||
* ctrl: Add penalty time control
|
||||
* ctrl: Add cell reselection hysteresis control
|
||||
* ctrl: Add getting access control class
|
||||
* ctrl: Add setting access control class
|
||||
* ctrl: Add getting neighbor list
|
||||
* ctrl: Add getting SI5 neighbor list
|
||||
* ctrl: Add setting SI5 neighbor list
|
||||
* ctrl: Add bsic
|
||||
* ctrl: Add rach max delay
|
||||
* ctrl: Add getting si2quater uarfcn neighbor list
|
||||
* ctrl: Support adding si2quater uarfcn neighbor
|
||||
* ctrl: Add getting si2quater earfcn neighbor list
|
||||
* ctrl: Support adding si2quater earfcn neighbor
|
||||
* control.adoc: Remove short-name and long-name
|
||||
* control.adoc: Update with recent changes
|
||||
|
||||
[ Daniel Willmann ]
|
||||
* cosmetic: Fix type in VTY description
|
||||
|
||||
[ Andreas Eversberg ]
|
||||
* ASCI: Add new rate counters to support VGCS/VBS messages
|
||||
* Fix typo in rate counters ASSIGMENT->ASSIGNMENT
|
||||
* Cleanup code style of rate counters in osmo_bsc_msc.c
|
||||
* ASCI: Add support for NOTIFICATION COMMAND (RSL) message
|
||||
* ASCI: Add support for Group/Broadcast channel activation
|
||||
* ASCI: Add selection reason for VGCS/VBS channels
|
||||
* ASCI: Add TX support for UPLINK RELEASE message
|
||||
* ASCI: Make function to add OSMUX IE public
|
||||
* ASCI: Prepare bssmap_handle_ass_req_ct_speech() for VGCS/VBS
|
||||
* ASCI: Add new debug category "ASCI" for VGCS/VBS state machines
|
||||
* ASCI: Do not release channel, if SAPI 0 is released
|
||||
* ASCI: Do not wait for RLL establishment
|
||||
* ASCI: Add support for sending RSL UNIT-DATA towards BTS
|
||||
* ASCI: Add TX support for UPLINK FREE/BUSY messages
|
||||
* ASCI: Forward UPLINK RELEASE on dedicated channel to MSC
|
||||
* ASCI: Add encoding of VGCS/VBS A-interface messages
|
||||
* ASCI: Add processing and FSMs for VGCS/VBS
|
||||
* ASCI: Add decoding of VGCS/VBS A-interface messages
|
||||
* ASCI: Forward RLL to VGCS FSM
|
||||
* ASCI: Forward lchan activation states to VGCS FSM
|
||||
* ASCI: Indicate release of subscriber connection to VGCS FSM
|
||||
* ASCI: Add support for reception of TALKER/LISTENER DETECTION
|
||||
* ASCI: Send release on VGCS/VBS channel via unit data
|
||||
* ASCI: Add assignment to a VGCS/VBS channel
|
||||
* Select channel type by enum instead of three boolean
|
||||
* ASCI: Fix uninitialized values in vgcs_fsm.c, found by gcc 13.1.1.20230714
|
||||
|
||||
-- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:40:03 +0200
|
||||
|
||||
osmo-bsc (1.10.0) unstable; urgency=medium
|
||||
|
||||
[ Vadim Yanitskiy ]
|
||||
|
|
|
@ -1 +1 @@
|
|||
9
|
||||
10
|
||||
|
|
|
@ -2,7 +2,7 @@ Source: osmo-bsc
|
|||
Section: net
|
||||
Priority: extra
|
||||
Maintainer: Osmocom team <openbsc@lists.osmocom.org>
|
||||
Build-Depends: debhelper (>=9),
|
||||
Build-Depends: debhelper (>= 10),
|
||||
dh-autoreconf,
|
||||
autotools-dev,
|
||||
autoconf,
|
||||
|
@ -12,12 +12,12 @@ Build-Depends: debhelper (>=9),
|
|||
python3-minimal,
|
||||
libcdk5-dev,
|
||||
libtalloc-dev,
|
||||
libosmocore-dev (>= 1.8.0),
|
||||
libosmo-sigtran-dev (>= 1.7.0),
|
||||
libosmo-abis-dev (>= 1.4.0),
|
||||
libosmo-netif-dev (>= 1.3.0),
|
||||
libosmo-mgcp-client-dev (>= 1.11.0),
|
||||
osmo-gsm-manuals-dev (>= 1.4.0)
|
||||
libosmocore-dev (>= 1.9.0),
|
||||
libosmo-sigtran-dev (>= 1.8.0),
|
||||
libosmo-abis-dev (>= 1.5.0),
|
||||
libosmo-netif-dev (>= 1.4.0),
|
||||
libosmo-mgcp-client-dev (>= 1.12.0),
|
||||
osmo-gsm-manuals-dev (>= 1.5.0)
|
||||
Standards-Version: 3.9.8
|
||||
Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc
|
||||
Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc
|
||||
|
|
|
@ -25,31 +25,6 @@ License: AGPL-3.0+
|
|||
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/>.
|
||||
|
||||
Files: src/libbsc/bsc_ctrl_lookup.c
|
||||
src/libbsc/pcu_sock.c
|
||||
Copyright: 2008-2010 Harald Welte <laforge@gnumonks.org>
|
||||
2009-2012 Andreas Eversberg <jolly@eversberg.eu>
|
||||
2010-2011 Daniel Willmann <daniel@totalueberwachung.de>
|
||||
2010-2011 On-Waves
|
||||
2012 Holger Hans Peter Freyther
|
||||
License: GPL-2.0+
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
.
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
.
|
||||
On Debian systems, the complete text of the GNU General Public License
|
||||
Version 2 can be found in `/usr/share/common-licenses/GPL-2'.
|
||||
|
||||
Files: osmoappdesc.py
|
||||
Copyright: 2013 Katerina Barone-Adesi <kat.obsc@gmail.com>
|
||||
License: GPL-3.0+
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#!/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.12.0"; then
|
||||
if [ -e /etc/osmocom/osmo-bsc.cfg ]; then
|
||||
chown -v osmocom:osmocom /etc/osmocom/osmo-bsc.cfg
|
||||
chmod -v 0660 /etc/osmocom/osmo-bsc.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,57 +1,15 @@
|
|||
#!/usr/bin/make -f
|
||||
# You must remove unused comment lines for the released package.
|
||||
# See debhelper(7) (uncomment to enable)
|
||||
# This is an autogenerated template for debian/rules.
|
||||
#
|
||||
# Output every command that modifies files on the build system.
|
||||
#export DH_VERBOSE = 1
|
||||
#
|
||||
# Copy some variable definitions from pkg-info.mk and vendor.mk
|
||||
# under /usr/share/dpkg/ to here if they are useful.
|
||||
#
|
||||
# See FEATURE AREAS/ENVIRONMENT in dpkg-buildflags(1)
|
||||
# Apply all hardening options
|
||||
#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
# Package maintainers to append CFLAGS
|
||||
#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic
|
||||
# Package maintainers to append LDFLAGS
|
||||
#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
|
||||
#
|
||||
# With debhelper version 9 or newer, the dh command exports
|
||||
# all buildflags. So there is no need to include the
|
||||
# /usr/share/dpkg/buildflags.mk file here if compat is 9 or newer.
|
||||
#
|
||||
# These are rarely used code. (START)
|
||||
#
|
||||
# The following include for *.mk magically sets miscellaneous
|
||||
# variables while honoring existing values of pertinent
|
||||
# environment variables:
|
||||
#
|
||||
# Architecture-related variables such as DEB_TARGET_MULTIARCH:
|
||||
#include /usr/share/dpkg/architecture.mk
|
||||
# Vendor-related variables such as DEB_VENDOR:
|
||||
#include /usr/share/dpkg/vendor.mk
|
||||
# Package-related variables such as DEB_DISTRIBUTION
|
||||
#include /usr/share/dpkg/pkg-info.mk
|
||||
#
|
||||
# You may alternatively set them susing a simple script such as:
|
||||
# DEB_VENDOR ?= $(shell dpkg-vendor --query Vendor)
|
||||
#
|
||||
# These are rarely used code. (END)
|
||||
#
|
||||
|
||||
# main packaging script based on dh7 syntax
|
||||
%:
|
||||
dh $@ --with autoreconf
|
||||
|
||||
# debmake generated override targets
|
||||
CONFIGURE_FLAGS += --with-systemdsystemunitdir=/lib/systemd/system --enable-manuals
|
||||
CONFIGURE_FLAGS += \
|
||||
--enable-manuals \
|
||||
--enable-meas-vis \
|
||||
--with-systemdsystemunitdir=/lib/systemd/system \
|
||||
$(NULL)
|
||||
|
||||
override_dh_auto_configure:
|
||||
dh_auto_configure -- $(CONFIGURE_FLAGS)
|
||||
#
|
||||
# Do not install libtool archive, python .pyc .pyo
|
||||
#override_dh_install:
|
||||
# dh_install --list-missing -X.la -X.pyc -X.pyo
|
||||
|
||||
# See https://www.debian.org/doc/manuals/developers-reference/best-pkging-practices.html#bpp-dbg
|
||||
override_dh_strip:
|
||||
|
|
|
@ -14,6 +14,7 @@ msc: \
|
|||
$(builddir)/handover-inter-bsc-in.png \
|
||||
$(builddir)/mgw-endpoint.png \
|
||||
$(builddir)/location_services_ta.png \
|
||||
$(builddir)/codec_resolution.png \
|
||||
$(NULL)
|
||||
|
||||
dot: \
|
||||
|
@ -27,6 +28,7 @@ dot: \
|
|||
$(builddir)/handover-inter-bsc-out-fsm.png \
|
||||
$(builddir)/handover-inter-bsc-in-fsm.png \
|
||||
$(builddir)/mscpool-attach.png \
|
||||
$(builddir)/location_services_fsm_bsc.png \
|
||||
$(NULL)
|
||||
|
||||
$(builddir)/%.png: $(srcdir)/%.msc
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
msc {
|
||||
hscale="1.7";
|
||||
ms[label="MS/BTS"],cfg[label="osmo-bsc.cfg"],bsc[label="osmo-bsc"],__msc[label="MSC"],sip[label="SIP"];
|
||||
|
||||
ms => bsc [label="EST IND / Compl L3"];
|
||||
cfg => bsc [label="'msc 0'\n'codec-list fr3 hr3 fr2 fr1 hr1'"];
|
||||
bsc rbox bsc [label="build Speech Codec List\ngen_bss_supported_codec_list()"];
|
||||
bsc => __msc [label="Compl L3"];
|
||||
bsc note __msc [label="Speech Codec List (BSS Supported)\n{GSM0808_SCT_FR3 + AMR-cfg,\nGSM0808_SCT_HR3 + AMR-cfg,\nGSM0808_SCT_FR2,\nGSM0808_SCT_FR1,\nGSM0808_SCT_HR1}"];
|
||||
--- [label="AMR-cfg:"];
|
||||
bsc note __msc [label="S0-S15: 16bit flags\nS0 = 1: 4.75 ---- ---- ---- ---- ---- ---- ----\nS1 = 1: 4.75 ---- 5.90 ---- 7.40 ---- ---- 12.2\nS2 = 1: ---- ---- 5.90 ---- ---- ---- ---- ----\nS3 = 1: ---- ---- ---- 6.70 ---- ---- ---- ----\nS4 = 1: ---- ---- ---- ---- 7.40 ---- ---- ----\nS5 = 1: ---- ---- ---- ---- ---- 7.95 ---- ----\nS6 = 1: ---- ---- ---- ---- ---- ---- 10.2 ----\nS7 = 1: ---- ---- ---- ---- ---- ---- ---- 12.2\n\nS8 = 1: 4.75 ---- 5.90 ---- ---- ---- ---- ----\nS9 = 1: 4.75 ---- 5.90 6.70 ---- ---- ---- ----\nS10= 1: 4.75 ---- 5.90 6.70 7.40 ---- ---- ----\nS11= 1: ---- ---- ---- ---- ---- ---- ---- ----\nS12= 1: 4.75 ---- 5.90 6.70 ---- ---- 10.2 ----\nS13= 1: ---- ---- ---- ---- ---- ---- ---- ----\nS14= 1: 4.75 ---- 5.90 ---- ---- 7.95 ---- 12.2\nS15= 1: ---- ---- ---- ---- ---- ---- ---- ----\n\n3GPP TS 28.062 Table 7.11.3.1.3-2: \"Preferred Configurations\",\nsome removed as specified in 3GPP TS 48.008 3.2.2.103"];
|
||||
|
||||
cfg => bsc [label="'bts 0'\n'amr tch-x modes 0 2 4 7'"];
|
||||
bsc rbox bsc [label="convert AMR modes to\nbts-S0-S15"];
|
||||
cfg => bsc [label="'msc 0'\n'amr-config 4_75k allowed'"];
|
||||
bsc rbox bsc [label="convert AMR modes to\nmsc-S0-S15"];
|
||||
bsc => __msc [label="Compl L3 Speech Codec List:\nbitwise AND:\nbts-S0-S15 & msc-S0-S15"];
|
||||
---;
|
||||
|
||||
ms => __msc [label="Bearer Capabilities"];
|
||||
__msc <= sip [label="SDP"];
|
||||
__msc note sip [label="m=audio 12345 RTP/AVP 112 3 111 110\na=rtpmap:112 AMR/8000\na=fmtp:112 mode-set=0,2,4,7\na=rtpmap:3 GSM/8000\na=rtpmap:111 GSM-HR-08/8000\na=rtpmap:110 GSM-EFR/8000"];
|
||||
|
||||
__msc rbox __msc [label="combine:\nBSC: Speech Codec List\nMS: Bearer Cap\nSIP: SDP"];
|
||||
|
||||
bsc <= __msc [label="BSSMAP Assignment Request\ncontains\nChannel Type\nSpeech Codec List (MSC Preferred)"];
|
||||
bsc note __msc [label="Channel Type\nChannel Rate And Type:\n- [prefer] full rate\n- [prefer] half rate\n- indicated by Permitted Speech list\nPermitted Speech [1..9]:\n{GSM0808_PERM_FR3,\nGSM0808_PERM_HR3,\nGSM0808_PERM_FR2,\nGSM0808_PERM_FR1,\nGSM0808_PERM_HR1}"];
|
||||
bsc note __msc [label="Speech Codec List (MSC Preferred)\n{GSM0808_SCT_FR3 + AMR-cfg,\nGSM0808_SCT_HR3 + AMR-cfg,\nGSM0808_SCT_FR2,\nGSM0808_SCT_FR1,\nGSM0808_SCT_HR1}"];
|
||||
|
||||
cfg => bsc [label="'msc 0'\n'codec-list fr3 hr3 fr2 fr1 hr1'"];
|
||||
cfg => bsc [label="'bts 0'\n'phys_chan_cfg TCH/F'"];
|
||||
cfg => bsc [label="'bts 0'\n'codec-support amr efr fr hr'"];
|
||||
|
||||
cfg rbox bsc [label="combine:\n'msc 0' 'codec-list fr3 hr3 fr2 fr1 hr1'\n'bts 0' 'phys_chan_cfg TCH/F'\n'bts 0' 'codec-support amr efr fr hr'\nMSC: Channel Type\nMSC: Speech Codec List (MSC Preferred)\n=>\n{GSM48_CMODE_SPEECH_AMR, FR, S0-S15},\n{GSM48_CMODE_SPEECH_AMR, HR, S0-S15}"];
|
||||
|
||||
cfg => bsc [label="'bts 0'\n'amr tch-x bts threshold'\n'amr tch-x bts hysteresis'"];
|
||||
ms <= bsc [label="RSL CHANnel ACTIVation"];
|
||||
ms note bsc [label="Channel Rate and Type: Full/Half rate\nSpeech Coding Algorithm Version: 3 (=AMR)\nMultiRate Configuration:\n- 4.75 | 5.90 | 7.40 | 12.2\n- Threshold / Hysteresis x 3"];
|
||||
cfg => bsc [label="'bts 0'\n'amr tch-x ms threshold'\n'amr tch-x ms hysteresis'"];
|
||||
ms <= bsc [label="RSL Assignment Command"];
|
||||
ms note bsc [label="Channel Description: TCH/F\nSpeech Coding Algorithm Version: 3 (=AMR)\nMultiRate Configuration:\n- 4.75 | 5.90 | 7.40 | 12.2\n- Threshold / Hysteresis x 3"];
|
||||
|
||||
bsc => __msc [label="BSSMAP Assignment Complete"];
|
||||
bsc note __msc [label="Chosen Channel: Speech, Full Rate\nSpeech Version (Chosen): FR3\nSpeech Codec (Chosen): FR AMR, S0-S15"];
|
||||
|
||||
__msc => sip [label="SDP (optional)"];
|
||||
__msc note sip [label="m=audio 12345 RTP/AVP 112\na=rtpmap:112 AMR/8000\na=fmtp:112 mode-set=0,2,4,7"];
|
||||
}
|
|
@ -7,6 +7,12 @@ line vty
|
|||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
!
|
||||
! OpenBSC (0.9.11.308-62d46) configuration saved from vty
|
||||
!!
|
||||
! CAUTION: The 16kbps mode of the Ericcson RBS CCU only allows for a very
|
||||
! minimal GPRS configuration (C1/C2 only).
|
||||
!
|
||||
password foo
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
logging level rsl debug
|
||||
logging level llapd notice
|
||||
network
|
||||
network country code 901
|
||||
mobile network code 70
|
||||
neci 0
|
||||
paging any use tch 0
|
||||
handover 0
|
||||
handover window rxlev averaging 10
|
||||
handover window rxqual averaging 1
|
||||
handover window rxlev neighbor averaging 10
|
||||
handover power budget interval 6
|
||||
handover power budget hysteresis 3
|
||||
handover maximum distance 9999
|
||||
timer t3101 10
|
||||
timer t3105 40
|
||||
timer t3109 4
|
||||
timer t3113 60
|
||||
pcu-socket /tmp/pcu_bts
|
||||
bts 0
|
||||
type rbs2000
|
||||
band GSM900
|
||||
om2000 version-limit oml gen 12 rev 10
|
||||
cell_identity 0
|
||||
location_area_code 0x0001
|
||||
training_sequence_code 7
|
||||
base_station_id_code 63
|
||||
ms max power 15
|
||||
cell reselection hysteresis 4
|
||||
rxlev access min 0
|
||||
channel allocator mode set-all descending
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
oml e1 line 0 timeslot 1 sub-slot full
|
||||
oml e1 tei 62
|
||||
neighbor-list mode automatic
|
||||
gprs mode gprs
|
||||
gprs routing area 0
|
||||
gprs network-control-order nc0
|
||||
gprs cell bvci 2
|
||||
gprs nsei 101
|
||||
gprs nsvc 0 nsvci 101
|
||||
gprs nsvc 0 local udp port 23100
|
||||
gprs nsvc 0 remote udp port 23000
|
||||
gprs nsvc 0 remote ip 127.0.0.1
|
||||
is-connection-list add 4 512 4
|
||||
is-connection-list add 8 516 1
|
||||
is-connection-list add 12 517 1
|
||||
is-connection-list add 16 518 1
|
||||
is-connection-list add 20 519 1
|
||||
is-connection-list add 24 520 1
|
||||
is-connection-list add 28 521 1
|
||||
is-connection-list add 32 522 1
|
||||
is-connection-list add 36 523 1
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 123
|
||||
nominal power 44
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 4 sub-slot 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 7 sub-slot 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot 0
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 2
|
|
@ -0,0 +1,106 @@
|
|||
!
|
||||
! OpenBSC (0.9.11.308-62d46) configuration saved from vty
|
||||
!!
|
||||
password foo
|
||||
!
|
||||
line vty
|
||||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
logging level rsl debug
|
||||
logging level llapd notice
|
||||
network
|
||||
network country code 901
|
||||
mobile network code 70
|
||||
neci 0
|
||||
paging any use tch 0
|
||||
handover 0
|
||||
handover window rxlev averaging 10
|
||||
handover window rxqual averaging 1
|
||||
handover window rxlev neighbor averaging 10
|
||||
handover power budget interval 6
|
||||
handover power budget hysteresis 3
|
||||
handover maximum distance 9999
|
||||
timer t3101 10
|
||||
timer t3105 40
|
||||
timer t3109 4
|
||||
timer t3113 60
|
||||
pcu-socket /tmp/pcu_bts
|
||||
bts 0
|
||||
type rbs2000
|
||||
band GSM900
|
||||
om2000 version-limit oml gen 12 rev 10
|
||||
cell_identity 0
|
||||
location_area_code 0x0001
|
||||
training_sequence_code 7
|
||||
base_station_id_code 63
|
||||
ms max power 15
|
||||
cell reselection hysteresis 4
|
||||
rxlev access min 0
|
||||
channel allocator mode set-all descending
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
oml e1 line 0 timeslot 1 sub-slot full
|
||||
oml e1 tei 62
|
||||
neighbor-list mode automatic
|
||||
gprs mode egprs
|
||||
gprs routing area 0
|
||||
gprs network-control-order nc0
|
||||
gprs cell bvci 2
|
||||
gprs nsei 101
|
||||
gprs nsvc 0 nsvci 101
|
||||
gprs nsvc 0 local udp port 23100
|
||||
gprs nsvc 0 remote udp port 23000
|
||||
gprs nsvc 0 remote ip 127.0.0.1
|
||||
is-connection-list add 4 712 36
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 123
|
||||
nominal power 44
|
||||
max_power_red 0
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot full
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 4 sub-slot full
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot full
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 7 sub-slot full
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot full
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot full
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 2
|
|
@ -7,6 +7,12 @@ line vty
|
|||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
|
|
|
@ -7,6 +7,12 @@ line vty
|
|||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
|
|
|
@ -7,6 +7,12 @@ line vty
|
|||
no login
|
||||
!
|
||||
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 lmi info
|
||||
logging level linp info
|
||||
logging level nm debug
|
||||
|
|
|
@ -11,7 +11,9 @@ log stderr
|
|||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging print file 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level llapd notice
|
||||
logging level nm debug
|
||||
e1_input
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
! osmo-bsc configuration example with 4 TRX
|
||||
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
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
|
@ -46,22 +54,22 @@ network
|
|||
phys_chan_config SDCCH8+CBCH
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
trx 1
|
||||
rf_locked 0
|
||||
|
@ -71,28 +79,28 @@ network
|
|||
max_power_red 20
|
||||
rsl e1 tei 1
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
trx 2
|
||||
rf_locked 0
|
||||
|
@ -102,28 +110,28 @@ network
|
|||
max_power_red 20
|
||||
rsl e1 tei 2
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
trx 3
|
||||
rf_locked 0
|
||||
|
@ -133,28 +141,28 @@ network
|
|||
max_power_red 20
|
||||
rsl e1 tei 3
|
||||
timeslot 0
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
hopping enabled 0
|
||||
msc 0
|
||||
allow-emergency allow
|
||||
|
|
|
@ -1,3 +1,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
|
||||
|
||||
network
|
||||
network country code 901
|
||||
mobile network code 70
|
||||
|
@ -30,4 +38,3 @@ e1_input
|
|||
e1_line 0 driver ipa
|
||||
msc 0
|
||||
allow-emergency deny
|
||||
codec-list fr1
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
! osmo-bsc default configuration
|
||||
! (assumes STP to run on 127.0.0.1 and uses default point codes)
|
||||
!
|
||||
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
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
! osmo-bsc configuration example for custom SCCP addresses
|
||||
!
|
||||
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
|
||||
|
||||
e1_input
|
||||
e1_line 0 driver ipa
|
||||
network
|
||||
|
@ -74,6 +82,8 @@ cs7 instance 0
|
|||
point-code 0.42.1
|
||||
!asp asp-clnt-OsmoBSC 2905 0 m3ua
|
||||
! remote-ip 10.23.24.1 ! where to reach the STP
|
||||
! role asp
|
||||
! sctp-role client
|
||||
sccp-address msc_remote
|
||||
point-code 0.23.1
|
||||
msc 0
|
||||
|
|
|
@ -11,8 +11,9 @@ log stderr
|
|||
logging color 1
|
||||
logging print category-hex 0
|
||||
logging print category 1
|
||||
logging timestamp 1
|
||||
logging print file 1
|
||||
logging timestamp 0
|
||||
logging print file basename last
|
||||
logging print level 1
|
||||
logging level llapd notice
|
||||
logging level linp notice
|
||||
logging level lmi notice
|
||||
|
|
|
@ -32,6 +32,7 @@ labelloc=t; label="lchan FSM"
|
|||
WAIT_TS_READY -> UNUSED [label="error/timeout",style=dashed,constraint=false]
|
||||
{WAIT_ACTIV_ACK,WAIT_RF_RELEASE_ACK} -> BORKEN [label="error/timeout",style=dashed]
|
||||
BORKEN -> WAIT_AFTER_ERROR [label="late RF Release ACK"]
|
||||
BORKEN -> WAIT_RF_RELEASE_ACK [label="late Activation ACK"]
|
||||
WAIT_RLL_RTP_ESTABLISH -> WAIT_RLL_RTP_RELEASED [label=error,style=dashed]
|
||||
|
||||
WAIT_ACTIV_ACK -> rtp [label="LCHAN_RTP_EV_LCHAN_READY",style=dotted]
|
||||
|
@ -44,4 +45,13 @@ labelloc=t; label="lchan FSM"
|
|||
WAIT_RSL_CHAN_MODE_MODIFY_ACK -> ESTABLISHED [label="LCHAN_EV_RSL_CHAN_MODE_MODIFY_ACK\nno change to RTP"]
|
||||
WAIT_RR_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]
|
||||
WAIT_RSL_CHAN_MODE_MODIFY_ACK -> BORKEN [label="error/timeout",style=dashed]
|
||||
|
||||
BORKEN -> RECOVER_WAIT_ACTIV_ACK [label="X28"]
|
||||
RECOVER_WAIT_ACTIV_ACK -> BORKEN [label="error/timeout",style=dashed]
|
||||
|
||||
RECOVER_WAIT_ACTIV_ACK -> UNUSED [label="rx ACK"]
|
||||
RECOVER_WAIT_ACTIV_ACK -> RECOVER_WAIT_RF_RELEASE_ACK [label="rx NACK"]
|
||||
|
||||
RECOVER_WAIT_RF_RELEASE_ACK -> UNUSED [label="rx ACK"]
|
||||
RECOVER_WAIT_RF_RELEASE_ACK -> BORKEN [label="error/timeout",style=dashed]
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ msc {
|
|||
ts note ts [label="A dyn TS may be in PDCH mode and will asynchronously switch off PDCH first. A
|
||||
non-dynamic TS is ready immediately."];
|
||||
|||;
|
||||
--- [label="IF requires_voice_stream"];
|
||||
--- [label="IF requires_rtp_stream"];
|
||||
lchan -> rtp [label="lchan_rtp_fsm_start()"];
|
||||
rtp abox rtp [label="allocate\n LCHAN_RTP_ST_\nWAIT_MGW_ENDPOINT_\nAVAILABLE"];
|
||||
--- [label="IF no endpoint-CI yet"];
|
||||
|
@ -29,7 +29,7 @@ msc {
|
|||
rtp note mgwep [label="The CRCX OK has assigned us a new endpoint CI number"];
|
||||
rtp abox rtp [label="LCHAN_RTP_ST_WAIT_LCHAN_READY"];
|
||||
--- [label="END: no endpoint-CI yet"];
|
||||
--- [label="END: requires_voice_stream"];
|
||||
--- [label="END: requires_rtp_stream"];
|
||||
|||;
|
||||
...;
|
||||
ts -> lchan [label="LCHAN_EV_TS_READY"];
|
||||
|
@ -60,7 +60,7 @@ msc {
|
|||
lchan abox lchan [label="LCHAN_ST_WAIT_\nRLL_RTP_ESTABLISH\nT3101"];
|
||||
|||;
|
||||
|||;
|
||||
--- [label="IF requires_voice_stream"];
|
||||
--- [label="IF requires_rtp_stream"];
|
||||
lchan -> rtp [label="LCHAN_RTP_EV_LCHAN_READY"];
|
||||
|||;
|
||||
--- [label="IF ip.access style BTS"];
|
||||
|
@ -99,7 +99,7 @@ msc {
|
|||
...;
|
||||
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED\nvia gscon_change_primary_lchan()"];
|
||||
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
||||
--- [label="END: requires_voice_stream"];
|
||||
--- [label="END: requires_rtp_stream"];
|
||||
|||;
|
||||
|||;
|
||||
|
||||
|
@ -116,7 +116,7 @@ msc {
|
|||
lchan rbox lchan [label="dispatch\nHO_EV_LCHAN_ESTABLISHED\n(see Handover FSM diagrams)"];
|
||||
--- [label="END"];
|
||||
...;
|
||||
--- [label="IF requires_voice_stream"];
|
||||
--- [label="IF requires_rtp_stream"];
|
||||
lchan rbox lchan [label="Assignment or Handover FSM:"];
|
||||
lchan -> mgwep [label="CRCX/MDCX to-MSC"];
|
||||
...;
|
||||
|
@ -125,7 +125,7 @@ msc {
|
|||
lchan -> rtp [label="LCHAN_RTP_EV_ESTABLISHED"];
|
||||
rtp abox rtp [label="LCHAN_RTP_ST_\nESTABLISHED"];
|
||||
rtp box rtp [label="Forget any Rollback info"];
|
||||
--- [label="END: requires_voice_stream"];
|
||||
--- [label="END: requires_rtp_stream"];
|
||||
|
||||
...;
|
||||
...;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
digraph G {
|
||||
rankdir=TB
|
||||
labelloc=t; label="Location Services FSMs in OsmoBSC"
|
||||
|
||||
MSC [label="MSC\nvia\nA interface",shape=box3d]
|
||||
SMLC [label="SMLC\nvia\nLb interface",shape=box3d]
|
||||
SMLC2 [label="SMLC\nvia\nLb interface",shape=box3d]
|
||||
Paging [shape=box3d]
|
||||
|
||||
subgraph cluster_LCS_LOC_REQ_FSM {
|
||||
label="lcs_loc_req_fsm"
|
||||
INIT -> WAIT_LOCATION_RESPONSE
|
||||
WAIT_LOCATION_RESPONSE -> BSSLAP_TA_REQ_ONGOING -> GOT_LOCATION_RESPONSE -> terminate
|
||||
WAIT_LOCATION_RESPONSE -> GOT_LOCATION_RESPONSE
|
||||
terminate [shape=octagon]
|
||||
}
|
||||
|
||||
MSC -> INIT [label="BSSAP Perform\nLocation Request",style=dashed]
|
||||
WAIT_LOCATION_RESPONSE -> SMLC [label="BSSMAP-LE Perform\nLocation Req",style=dashed]
|
||||
SMLC -> WAIT_LOCATION_RESPONSE [label="BSSMAP-LE Perform\nLocation Resp",style=dashed]
|
||||
GOT_LOCATION_RESPONSE -> MSC [label="BSSAP Perform\nLocation Response",style=dashed]
|
||||
|
||||
subgraph cluster_LCS_TA_REQ_FSM {
|
||||
label="lcs_ta_req_fsm"
|
||||
INIT2 [label="INIT"]
|
||||
INIT2 -> WAIT_TA [label="MS idle"]
|
||||
WAIT_TA -> GOT_TA
|
||||
INIT2 -> GOT_TA [label="MS active"]
|
||||
GOT_TA -> terminate2
|
||||
terminate2 [label="terminate",shape=octagon]
|
||||
}
|
||||
|
||||
SMLC2 -> INIT2 [label="TA Request",style=dashed]
|
||||
WAIT_TA -> Paging [label="launch Paging",style=dashed]
|
||||
Paging -> WAIT_TA [label="EV_TA",style=dashed]
|
||||
GOT_TA -> SMLC2 [label="TA Response",style=dashed]
|
||||
|
||||
WAIT_TA -> BSSLAP_TA_REQ_ONGOING [label="EV_TA_REQ_START",style=dashed]
|
||||
terminate2 -> BSSLAP_TA_REQ_ONGOING [label="EV_TA_REQ_END",style=dashed,constraint=false]
|
||||
}
|
|
@ -175,6 +175,7 @@ For building a multi-TRX setup, you also need to connect the TIB cables
|
|||
between the two nanoBTS units, as well as the coaxial/RF AUX cabling.
|
||||
====
|
||||
|
||||
[[example_e1_cfg]]
|
||||
=== Example configuration for OsmoBSC with E1 BTS
|
||||
|
||||
The following configuration sample illustrates the usage of BTSs that are
|
||||
|
@ -263,7 +264,7 @@ network
|
|||
|
||||
<4> OML always requires a TEI (Terminal Equipment Identifier) to set up. This number can be found in the manual of the BTS.
|
||||
|
||||
<5> This BTS has an built in “Interface Switch” (IS) that offers flexible way to reconfigure the interconnection between the internal components of the BTS and the external E1 line. This depends on the exact BTS type and configuration.
|
||||
<5> This BTS has an built in “Interface Switch” (IS) that offers flexible way to reconfigure the interconnection between the internal components of the BTS and the external E1 line. This depends on the exact BTS type and configuration. See also <<cfg_ericsson_rbs_is>>
|
||||
|
||||
<6> Similar to OML we assign TS1 to RSL as well.
|
||||
|
||||
|
@ -273,6 +274,135 @@ network
|
|||
|
||||
<9> The bandwidth of one E1 timeslot matches the bandwidth of 4 GSM air interface timeslots. The E1 timeslot is split up into four sub-slots, which are then assigned to one GSM air interface timeslot each. Since the first timeslot on the first TRX is already used for signaling we begin the sub-slot counting with sub-slot 1 for alignment reasons.
|
||||
|
||||
=== Example configuration for OsmoBSC with Ericsson RBS E1 BTS and EGPRS
|
||||
|
||||
The following example illustrates the usage of Ericsson RBS2000/RBS6000 BTSs.
|
||||
This classic E1 BTS has no built in PCU and therefore requires the configuration
|
||||
of a BSC co-located OsmoPCU (see also: <<cfg_bsc_co_located_pcu>>).
|
||||
|
||||
It should also be noted that the Ericsson RBS2000/RBS6000 series is the first
|
||||
BTS of this type to be supported by OsmoBTS and OsmoPCU. The implementation has
|
||||
been made possible through funding by the NLnet Foundation.
|
||||
|
||||
Ericsson RBS2000/RBS6000 BTSs feature two GPRS modes. A 16kbps GPRS mode where
|
||||
only CS1 and CS2 are supported and an EGPRS mode where MCS1 to MCS9 are
|
||||
supported. OsmoPCU offers support for both modes but since the 16kbps mode only
|
||||
supports classic GPRS with CS1 and CS2 it is more of experimental interest
|
||||
and shall not be discussed further. The following example will describe how
|
||||
to configure the 64kbps mode with EGPRS.
|
||||
|
||||
In the following example we also expect that the user is already familliar
|
||||
with the E1 configuration example above (see also: <<example_e1_cfg>>)
|
||||
|
||||
.OsmoBSC configured for single-TRX E1 Ericsson DUG20 with EGPRS
|
||||
====
|
||||
----
|
||||
e1_input
|
||||
e1_line 0 driver dahdi
|
||||
e1_line 0 port 3
|
||||
network
|
||||
network country code 1
|
||||
mobile network code 1
|
||||
encryption a5 0
|
||||
neci 1
|
||||
handover 0
|
||||
pcu-socket /tmp/pcu_bts <1>
|
||||
bts 0
|
||||
type rbs2000
|
||||
band GSM900
|
||||
om2000 version-limit oml gen 12 rev 10
|
||||
cell_identity 0
|
||||
location_area_code 0x0001
|
||||
training_sequence_code 7
|
||||
base_station_id_code 63
|
||||
ms max power 15
|
||||
cell reselection hysteresis 4
|
||||
rxlev access min 0
|
||||
channel allocator mode set-all ascending
|
||||
rach tx integer 9
|
||||
rach max transmission 7
|
||||
oml e1 line 0 timeslot 1 sub-slot full
|
||||
oml e1 tei 62
|
||||
gprs mode egprs <2>
|
||||
gprs routing area 0
|
||||
gprs network-control-order nc0
|
||||
gprs cell bvci 2
|
||||
gprs nsei 101
|
||||
gprs nsvc 0 nsvci 101
|
||||
gprs nsvc 0 local udp port 23100
|
||||
gprs nsvc 0 remote udp port 23000
|
||||
gprs nsvc 0 remote ip 127.0.0.1
|
||||
is-connection-list add 4 712 36 <3>
|
||||
trx 0
|
||||
rf_locked 0
|
||||
arfcn 123
|
||||
nominal power 42
|
||||
max_power_red 12
|
||||
rsl e1 line 0 timeslot 1 sub-slot full
|
||||
rsl e1 tei 0
|
||||
timeslot 0
|
||||
phys_chan_config CCCH+SDCCH4
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 1 sub-slot full
|
||||
timeslot 1
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 3 sub-slot full <4>
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 4 sub-slot full
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 5 sub-slot full
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH <5>
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 6 sub-slot full
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 7 sub-slot full
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 8 sub-slot full
|
||||
timeslot 7
|
||||
phys_chan_config TCH/F
|
||||
hopping enabled 0
|
||||
e1 line 0 timeslot 9 sub-slot full
|
||||
----
|
||||
====
|
||||
|
||||
<1> This configures the PCU socket path (see also: <<cfg_bsc_co_located_pcu>>)
|
||||
|
||||
<2> This configures the general GPRS parameters. The configuration is no
|
||||
different from BTS with built-in PCU.
|
||||
|
||||
<3> The Ericsson RBS2000/RBS6000 series has an built in “Interface Switch” (IS)
|
||||
that offers flexible way to reconfigure the interconnection between the internal
|
||||
components of the BTS and the external E1 line. Since 16kbps subslots cannot
|
||||
supply the bandwidth required for EGPRS the IS must be configured to connect
|
||||
the 64kbps interface of the TRU to the external E1 line. For a more detailed
|
||||
description of the IS see <<cfg_ericsson_rbs_is>>.
|
||||
|
||||
<4> Since we are using the 64kbps TRU interface we must configure a full E1
|
||||
timeslot per air interface time slot. For Speech this will have no effect on
|
||||
the TRAU frame format. The only difference is that always the first 16kbps
|
||||
subslot of the assigned E1 timeslot is used. OsmoMGW will be instructed
|
||||
accordingly by OsmoBSC, so no re-configuration of OsmoMGW is required.
|
||||
|
||||
<5> In this example we will use air interface TS 4 as PDCH. As mentioned
|
||||
earlier Ericsson RBS2000/RBS6000 supports the 'DYNAMIC/OSMOCOM' timeslot model.
|
||||
PDCH timeslots must be configured as dynamic timeslots. It is not possible to
|
||||
configure static PDCHs. Therefore the phys_chan_config must be set to
|
||||
TCH/F_TCH/H_SDCCH8_PDCH in order to use the air interface timeslot as PDCH.
|
||||
|
||||
NOTE: As of March 2023 the BSC co-located PCU support for Ericsson RBS was
|
||||
tested only with a single BTS. Even though OsmoBSC and OsmoPCU should be able
|
||||
to handle multiple BTS, unexpected bahviour should be taken into account.
|
||||
|
||||
=== E1 Line number and MGCP trunk number
|
||||
The switching of the voice channels is done via OsmoMGW, which acts as a media
|
||||
converter between E1 and VoIP (RTP). OsmoBSC will use the E1 line number to
|
||||
|
|
|
@ -47,7 +47,7 @@ Description: (null)
|
|||
RF Nominal Power: 23 dBm, reduced by 0 dB, resulting BS power: 23 dBm
|
||||
NM State: Oper 'Enabled', Admin 2, Avail 'OK'
|
||||
Baseband Transceiver NM State: Oper 'Enabled', Admin 2, Avail 'OK'
|
||||
ip.access stream ID: 0x00
|
||||
IPA Abis/IP stream ID: 0x00
|
||||
----
|
||||
|
||||
The output can be restricted to the TRXs of one specified BTS number
|
||||
|
@ -181,6 +181,7 @@ manual-si5::
|
|||
means of `si5 neighbor-list (add|del) arfcn <0-1023>` for SACCH (SI5).
|
||||
|
||||
|
||||
[[config_gprs_pcu_pars]]
|
||||
=== Configuring GPRS PCU parameters of a BTS
|
||||
|
||||
In the case of BTS models using Abis/IP (IPA), the GPRS PCU is located
|
||||
|
@ -296,7 +297,7 @@ all BTS models support dynamic channels.
|
|||
.Dynamic timeslot support by various BTS models
|
||||
[cols="50%,25%,25%"]
|
||||
|===
|
||||
| |`TCH/F_TCH/H_SDCCH8_PDCH` |`TCH/F_PDCH`
|
||||
| |`DYNAMIC/OSMOCOM` |`DYNAMIC/IPACCESS`
|
||||
|ip.access nanoBTS |- |supported
|
||||
|Ericsson RBS |supported |-
|
||||
|sysmoBTS using _osmo-bts-sysmo_ |supported |supported
|
||||
|
@ -311,11 +312,13 @@ non-standard RSL messages used for these timeslot kinds.
|
|||
NOTE: Same as for dedicated PDCH timeslots, you need to enable GPRS and operate
|
||||
a PCU, SGSN and GGSN to provide the actual data service.
|
||||
|
||||
==== Osmocom Style Dynamic Timeslots (TCH/F_TCH/H_SDCCH8_PDCH)
|
||||
==== Osmocom Style Dynamic Timeslots (DYNAMIC/OSMOCOM)
|
||||
|
||||
Timeslots of the `TCH/F_TCH/H_SDCCH8_PDCH` type dynamically switch between TCH/F,
|
||||
`DYNAMIC/OSMOCOM` is an alias for `TCH/F_TCH/H_SDCCH8_PDCH`.
|
||||
|
||||
Timeslots of the `DYNAMIC/OSMOCOM` type dynamically switch between TCH/F,
|
||||
TCH/H, SDCCH8 and PDCH, depending on the channel kind requested by the MSC. The RSL
|
||||
messaging for `TCH/F_TCH/H_SDCCH8_PDCH` timeslots is compatible with Ericsson RBS.
|
||||
messaging for these timeslots is compatible with Ericsson RBS.
|
||||
|
||||
BTS models supporting this timeslot kind are shown in <<dyn_ts_compat>>.
|
||||
|
||||
|
@ -334,10 +337,12 @@ network
|
|||
In OsmoNITB, disabling TCH/F on Osmocom dynamic timeslots is the default. In
|
||||
OsmoBSC, the default is to allow both.
|
||||
|
||||
==== ip.access Style Dynamic Timeslots (TCH/F_PDCH)
|
||||
==== ip.access Style Dynamic Timeslots (DYNAMIC/IPACCESS)
|
||||
|
||||
Timeslots of the `TCH/F_PDCH` type dynamically switch between TCH/F and PDCH.
|
||||
The RSL messaging for `TCH/F_PDCH` timeslots is compatible with ip.access
|
||||
`DYNAMIC/IPACCESS` is an alias for `TCH/F_PDCH`.
|
||||
|
||||
Timeslots of the `DYNAMIC/IPACCESS` type dynamically switch between TCH/F and PDCH.
|
||||
The RSL messaging for `DYNAMIC/IPACCESS` timeslots is compatible with ip.access
|
||||
nanoBTS.
|
||||
|
||||
BTS models supporting this timeslot kind are shown in <<dyn_ts_compat>>.
|
||||
|
@ -350,7 +355,7 @@ timeslots to TCH, and no PDCH timeslots would be left for GPRS service.
|
|||
|
||||
==== Dynamic Timeslot Configuration Examples
|
||||
|
||||
This is an extract of an `osmo-bsc`` config file. A timeslot configuration with
|
||||
This is an extract of an `osmo-bsc` config file. A timeslot configuration with
|
||||
five Osmocom style dynamic timeslots and one dedicated PDCH may look like this:
|
||||
|
||||
----
|
||||
|
@ -362,20 +367,20 @@ network
|
|||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_TCH/H_SDCCH8_PDCH
|
||||
phys_chan_config DYNAMIC/OSMOCOM
|
||||
timeslot 7
|
||||
phys_chan_config PDCH
|
||||
----
|
||||
|
||||
With the ip.access nanoBTS, only `TCH/F_PDCH` dynamic timeslots are supported,
|
||||
With the ip.access nanoBTS, only `DYNAMIC/IPACCESS` dynamic timeslots are supported,
|
||||
and hence a nanoBTS configuration may look like this:
|
||||
|
||||
----
|
||||
|
@ -387,15 +392,15 @@ network
|
|||
timeslot 1
|
||||
phys_chan_config SDCCH8
|
||||
timeslot 2
|
||||
phys_chan_config TCH/F_PDCH
|
||||
phys_chan_config DYNAMIC/IPACCESS
|
||||
timeslot 3
|
||||
phys_chan_config TCH/F_PDCH
|
||||
phys_chan_config DYNAMIC/IPACCESS
|
||||
timeslot 4
|
||||
phys_chan_config TCH/F_PDCH
|
||||
phys_chan_config DYNAMIC/IPACCESS
|
||||
timeslot 5
|
||||
phys_chan_config TCH/F_PDCH
|
||||
phys_chan_config DYNAMIC/IPACCESS
|
||||
timeslot 6
|
||||
phys_chan_config TCH/F_PDCH
|
||||
phys_chan_config DYNAMIC/IPACCESS
|
||||
timeslot 7
|
||||
phys_chan_config PDCH
|
||||
----
|
||||
|
@ -641,3 +646,140 @@ network
|
|||
<2> This number affects how long the MS waits before (re-)transmitting RACH
|
||||
requests.
|
||||
<3> How often to retransmit the RACH request.
|
||||
|
||||
[[cfg_ericsson_rbs_is]]
|
||||
=== Configuring Ericsson RBS Interface Switch (IS)
|
||||
|
||||
Ericsson RBS2000/RBS6000 base stations feature a so called "Interface Switch" (IS),
|
||||
which is a built-in switchboard that interconnects between internal components
|
||||
of the BTS. It also connects to the external E1 connections. This allows to
|
||||
adapt the BTS to specific E1 networking requirements that may differ from the
|
||||
usual timeslot configuration.
|
||||
|
||||
The internals of an Ericsson RBS are quite complex. In the following we will
|
||||
only explain how to connect transceiver units (TRU) to an E1 interface pointing
|
||||
to the outside world.
|
||||
|
||||
==== Understanding the is-connection-list VTY option
|
||||
|
||||
The IS operates on 16kbps subslots (ICPs), which means that there are no fixed
|
||||
borders between E1 timeslots. Any number of consecutive subslots may be
|
||||
connected through. However, depending on the components that are connected it
|
||||
may still be a requirement to align on E1 timeslot borders.
|
||||
|
||||
The configuration of the IS is done using the is-connection-list command. The
|
||||
first two numbers are the ICP numbers that specify the first subslot on both
|
||||
sides that shall be interconnected. The third number (contiguity index) specifies
|
||||
how many of the following subslots shall be connected.
|
||||
|
||||
In the following example we connect 4 blocks with 12 subslot each. The numbers
|
||||
on the left are the ICP numbers of the E1 connection pointing to the outside.
|
||||
The numbers in the middle are the ICP numbers of the subslots occupied by the
|
||||
transceivers (one TRX per block). The third number is the contiguity index that
|
||||
spans over 12 subslots or 3 E1 timeslots.
|
||||
|
||||
.Example: 4 TRX BTS (4 x 12 subslots)
|
||||
----
|
||||
network
|
||||
bts 0
|
||||
is-connection-list add 4 512 12
|
||||
is-connection-list add 16 524 12
|
||||
is-connection-list add 28 536 12
|
||||
is-connection-list add 40 548 12
|
||||
----
|
||||
|
||||
==== E1 port and TRU ICP numbers
|
||||
|
||||
On the outside connection, the ICP counting begins at E1 timeslot 0 (port A)
|
||||
but since E1 TS 0 is reserved for framing and synchronization of the E1 line
|
||||
itself the first usable subslot is subslot 4 (beginning of E1 TS 1). Depending
|
||||
on the configuration the BTS may have multiple E1 ports. The counting scheme
|
||||
will repeat itself. This means the next usable ICP can be found at an offset
|
||||
of 128.
|
||||
|
||||
.External connections of a BTS with two E1 ports
|
||||
[options="header",cols="50%,25%,25%"]
|
||||
|===
|
||||
|Function |Subslot offset (ICP) |ICP count
|
||||
|E1 port A |4 |124
|
||||
|E1 port B |132 |124
|
||||
|===
|
||||
|
||||
Depending on the transceiver configuration, a RBS2000/RBS6000 base station
|
||||
usually features two sets of ICPs for each TRX. The reason for this is that with
|
||||
the introduction of EGPRS more bandwidth than a single 16kbps subslot could
|
||||
deliver was required. The solution to this was to add an entirely new set of IS
|
||||
ICPs where full 64kbps E1 timeslots instead of 16kbps subslots could be
|
||||
used to serve a single air interface timeslot. The two sets of ICPs must not be
|
||||
mixed. Only one set may be used at a time.
|
||||
|
||||
.ICPs to use TRU with 16kbps subslots per TRAU
|
||||
[options="header",cols="50%,25%,25%"]
|
||||
|===
|
||||
|Function |Subslot offset (ICP) |ICP count
|
||||
|TRU-0, RSL/OML |512 |4
|
||||
|TRU-0, TRAU TS0..TS7 |516 |8
|
||||
|TRU-1, RSL/OML |524 |4
|
||||
|TRU-1, TRAU TS0..TS7 |528 |8
|
||||
|TRU-2, RSL/OML |536 |4
|
||||
|TRU-2, TRAU TS0..TS7 |540 |8
|
||||
|TRU-3, RSL/OML |548 |4
|
||||
|TRU-3, TRAU TS0..TS7 |552 |8
|
||||
|TRU-4, RSL/OML |560 |4
|
||||
|TRU-4, TRAU TS0..TS7 |564 |8
|
||||
|TRU-5, RSL/OML |572 |4
|
||||
|TRU-5, TRAU TS0..TS7 |576 |8
|
||||
|TRU-6, RSL/OML |640 |4
|
||||
|TRU-6, TRAU TS0..TS7 |644 |8
|
||||
|TRU-7, RSL/OML |652 |4
|
||||
|TRU-7, TRAU TS0..TS7 |656 |8
|
||||
|TRU-8, RSL/OML |664 |4
|
||||
|TRU-8, TRAU TS0..TS7 |668 |8
|
||||
|TRU-9, RSL/OML |676 |4
|
||||
|TRU-9, TRAU TS0..TS7 |680 |8
|
||||
|TRU-10, RSL/OML |688 |4
|
||||
|TRU-10, TRAU TS0..TS7 |692 |8
|
||||
|TRU-11, RSL/OML |700 |4
|
||||
|TRU-11, TRAU TS0..TS7 |704 |8
|
||||
|===
|
||||
|
||||
NOTE: Each air interface timeslot is served by its individual TRAU, so it is
|
||||
possible to route each subslot (ICP) dedicated to TRAU individually. The
|
||||
connections on the other end may contain gaps and do not have to be
|
||||
consecutive.
|
||||
|
||||
.ICPs to use TRU with 64kbps subslots per TRAU
|
||||
[options="header",cols="50%,25%,25%"]
|
||||
|===
|
||||
|Function |Subslot offset (ICP) |ICP count
|
||||
|TRU-0, RSL/OML |712 |4
|
||||
|TRU-0, TRAU TS0..TS7 |716 |32
|
||||
|TRU-1, RSL/OML |748 |4
|
||||
|TRU-1, TRAU TS0..TS7 |752 |32
|
||||
|TRU-2, RSL/OML |784 |4
|
||||
|TRU-2, TRAU TS0..TS7 |788 |32
|
||||
|TRU-3, RSL/OML |820 |4
|
||||
|TRU-3, TRAU TS0..TS7 |824 |32
|
||||
|TRU-4, RSL/OML |856 |4
|
||||
|TRU-4, TRAU TS0..TS7 |860 |32
|
||||
|TRU-5, RSL/OML |928 |4
|
||||
|TRU-5, TRAU TS0..TS7 |932 |32
|
||||
|TRU-6, RSL/OML |964 |4
|
||||
|TRU-6, TRAU TS0..TS7 |968 |32
|
||||
|TRU-7, RSL/OML |1000 |4
|
||||
|TRU-7, TRAU TS0..TS7 |1004 |32
|
||||
|TRU-8, RSL/OML |1036 |4
|
||||
|TRU-8, TRAU TS0..TS7 |1040 |32
|
||||
|TRU-9, RSL/OML |1072 |4
|
||||
|TRU-9, TRAU TS0..TS7 |1076 |32
|
||||
|TRU-10, RSL/OML |1108 |4
|
||||
|TRU-10, TRAU TS0..TS7 |1112 |32
|
||||
|TRU-11, RSL/OML |1144 |4
|
||||
|TRU-11, TRAU TS0..TS7 |1148 |32
|
||||
|===
|
||||
|
||||
NOTE: In case voice TRAU frames are transferred, only the first of the four
|
||||
16kbps subslots is used. When the timeslot is switched to GPRS/EGPRS, the
|
||||
full 64kbps bandwidth will be used. This also means that the set of four
|
||||
ICPs per TRAU must be connected consecutively. Also the connection
|
||||
to the outside must be aligned to E1 timeslot borders.
|
|
@ -20,8 +20,6 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|
|||
|apply-configuration|WO|No|"restart"|Restart all BTSes.
|
||||
|mnc|RW|No|"<mnc>"|Set/Get MNC (value between (0, 999)).
|
||||
|mcc|RW|No|"<mcc>"|Set/Get MCC (value between (1, 999)).
|
||||
|short-name|RW|No|"<name>"|Set/Get network's short name.
|
||||
|long-name|RW|No|"<name>"|Set/Get network's long name.
|
||||
|mcc-mnc-apply|WO|No|"<mcc>,<mnc>"|Apply new MCC/MNC values if different from currently used one.
|
||||
|notification|WO|Yes|Arbitrary value| See <<notif>> for details.
|
||||
|inform-msc-v1|WO|Yes|Arbitrary value| See <<infomsc>> for details.
|
||||
|
@ -31,6 +29,8 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|
|||
|write-config-file|WO|No|"overwrite", "<filename>"|Write running configuration to file.
|
||||
|bts.N.location-area-code|RW|No|"<lac>"|Set/Get LAC (value between (0, 65535)).
|
||||
|bts.N.cell-identity|RW|No|"<id>"|Set/Get Cell Identity (value between (0, 65535)).
|
||||
|bts.N.bsic|RW|No|"<bsic>"|Set/Get BSIC (value between (0, 63)).
|
||||
|bts.N.rach-max-delay|RW|No|"<delay>"|Set/Get RACH max delay (value between (1, 127)).
|
||||
|bts.N.apply-configuration|WO|No|Ignored|Restart BTS via OML.
|
||||
|bts.N.send-new-system-informations|WO|No|Ignored|Regenerate and resend System Information messages for given BTS.
|
||||
|bts.N.send-power-control-defaults|WO|No|Ignored|Resend default power control parameters for given BTS.
|
||||
|
@ -39,6 +39,12 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|
|||
|bts.N.oml-uptime|RO|No|<uptime>|Return OML link uptime in seconds.
|
||||
|bts.N.gprs-mode|RW|No|"<mode>"|See <<gprsm>> for details.
|
||||
|bts.N.rf_state|RO|No|"<oper>,<admin>,<pol>"|See <<rfs>> for details.
|
||||
|bts.N.cell-reselection-offset|RW|No|"<cro>"|Set/Get cell reselection offset (value between (0, 126), steps of 2).
|
||||
|bts.N.cell-reselection-penalty-time|RW|No|"<penalty-time>","reserved"|Set/Get cell reselection penalty time (value between (20, 620), steps of 20).
|
||||
|bts.N.cell-reselection-hysteresis|RW|No|"<crh>"|Set/Get cell reselection hysteresis (value between (0, 14), steps of 2).
|
||||
|bts.N.rach-access-control-classes|RO|No|"<class>,(barred|allowed)"|Get concatenated pairs of RACH access control classes.
|
||||
|bts.N.rach-access-control-class.bar|WO|No|"<class>","emergency"|Set RACH access control class as barred.
|
||||
|bts.N.rach-access-control-class.allow|WO|No|"<class>","emergency"|Set RACH access control class as allowed.
|
||||
|bts.N.trx.M.arfcn|RW|No|"<arfcn>"|Set/Get ARFCN (value between (0, 1023)).
|
||||
|bts.N.trx.M.max-power-reduction|RW|No|"<mpr>"|See <<mpr>> for details.
|
||||
|[bts.N.]handover.active|RW|No|"0","1","default"|Enable/disable handover.
|
||||
|
@ -72,6 +78,16 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|
|||
|bts.N.neighbor-list.mode|WO|No|"automatic","manual","manual-si5"|Mode of Neighbor List generation.
|
||||
|bts.N.neighbor-list.add|WO|No|<0-1023>|Add to manual neighbor list.
|
||||
|bts.N.neighbor-list.del|WO|No|<0-1023>|Delete from manual neighbor list.
|
||||
|bts.N.neighbor-list.si5-add|WO|No|<0-1023>|Add to manual SI5 neighbor list.
|
||||
|bts.N.neighbor-list.si5-del|WO|No|<0-1023>|Delete from manual SI5 neighbor list.
|
||||
|bts.N.neighbor-list.si2|RO|No|"<arfcn>"|Get space concatenated list of SI2 neighbor ARFCNs.
|
||||
|bts.N.neighbor-list.si5|RO|No|"<arfcn>"|Get space concatenated list of SI5 neighbor ARFCNs.
|
||||
|bts.N.neighbor-list.si2quater.uarfcns|RO|No|"<uarfcn>,<scrambling code>,<diversity bit>"|Get space concatenated list of UARFCN neighbors.
|
||||
|bts.N.neighbor-list.si2quater.earfcns|RO|No|"<earfcn>,<thresh-hi>,<thresh-lo>,<prio>,<qrxlv>,<meas>"|Get space concatenated list of EARFCN neighbors.
|
||||
|bts.N.si2quater-neighbor-list.add.uarfcn|WO|No|"<uarfcn>,<scrambling code>,<diversity bit>"|Add UARFCN neighbor.
|
||||
|bts.N.si2quater-neighbor-list.del.uarfcn|WO|No|"<uarfcn>,<scrambling code>"|Delete UARFCN neighbor.
|
||||
|bts.N.si2quater-neighbor-list.add.earfcn|WO|No|"<earfcn>,<thresh-hi>,<thresh-lo>,<prio>,<qrxlv>,<meas>"|Add EARFCN neighbor.
|
||||
|bts.N.si2quater-neighbor-list.del.earfcn|WO|No|"<earfcn>"|Delete EARFCN neighbor (value between (0, 65535)).
|
||||
|===
|
||||
|
||||
[[notif]]
|
||||
|
|
|
@ -63,7 +63,7 @@ PDCH resources should be allocated for interference reasons.
|
|||
NOTE: Currently osmo-bsc makes no use of PDCH interference reports, neither
|
||||
they get forwarded to the BSC co-located PCU over the PCUIF.
|
||||
|
||||
For dynamic timeslots (`TCH/F_TCH/H_SDCCH/8_PDCH` and `TCH/F_PDCH`), the
|
||||
For dynamic timeslots (`DYNAMIC/OSMOCOM` and `DYNAMIC/IPACCESS`), the
|
||||
following expectations apply:
|
||||
|
||||
* when in TCH/F mode: no interference reports, because the only sub-channel is active;
|
||||
|
|
|
@ -135,11 +135,13 @@ Station Controller, i.e.
|
|||
For more information, see <<net>>, <<bts>> and <<bts-examples>>.
|
||||
|
||||
|
||||
==== TRAU mapper / E1 sub-channel muxer
|
||||
==== Speech traffic
|
||||
|
||||
Unlike classic GSM networks, OsmoBSC does not perform any transcoding.
|
||||
Rather, a compatible codec is selected for both legs of a call, and
|
||||
codec frames are passed through transparently. In order to achieve this
|
||||
with E1 based BTS, OsmoBSC contains a E1 sub-channel de- and
|
||||
re-multiplexer as well as a TRAU mapper that can map uplink to downlink
|
||||
frames and vice versa.
|
||||
OsmoBSC, by itself, does not perform any transcoding or relaying of user plane
|
||||
speech traffic. This task is handled entirely by a BSC co-located media gateway,
|
||||
such as OsmoMGW, which will take care of relaying the RTP traffic from the BTS
|
||||
into the core network.
|
||||
|
||||
In case classic E1 based BTSs are used, OsmoBSC will instruct the MGW to
|
||||
convert between TRAU frames on the E1 side and RTP frames on the IP based core
|
||||
network side.
|
||||
|
|
|
@ -69,6 +69,24 @@ To run multiple OsmoBSC instances on the same A-interface (SCCP/M3UA), each BSC
|
|||
has to configure a distinct point-code. See <<cs7_config>>.
|
||||
|
||||
|
||||
=== Configure limits
|
||||
|
||||
When connecting hundreds of TRX to OsmoBSC, it may be necessary to adjust the
|
||||
operating system's limit on open file descriptors for the osmo-bsc process. A
|
||||
typical default limit imposed by operating systems is 1024; this would be
|
||||
exceeded by, for example, about 205 BTS with 4 TRX each. (Each BTS with 4 TRX
|
||||
requires 5 file descriptors for Abis; 205 * 5 already exceeds 1024, sockets for
|
||||
other interfaces not considered yet.)
|
||||
|
||||
It should be ok to set an OS limit on open file descriptors as high as 65536
|
||||
for osmo-bsc, which practically rules out failure from running out of file
|
||||
descriptors anywhere (<50,000 TRX).
|
||||
|
||||
When using systemd, the file descriptor limit may be adjusted in the service
|
||||
file by the `LimitNOFILE` setting ("Number of Open FILE descriptors"). OsmoBSC
|
||||
ships a systemd service file with a high LimitNOFILE setting.
|
||||
|
||||
|
||||
=== Configure primary links
|
||||
|
||||
==== Connect to an MSC's _A_ interface
|
||||
|
@ -87,6 +105,7 @@ cs7 instance 0
|
|||
point-code 1.23.3
|
||||
asp asp-clnt-msc-0 2905 0 m3ua
|
||||
remote-ip 127.0.0.1
|
||||
role asp
|
||||
sctp-role client
|
||||
sccp-address msc
|
||||
point-code 0.23.1
|
||||
|
@ -218,3 +237,47 @@ smlc
|
|||
----
|
||||
|
||||
More detailed configuration is described in <<smlc-config>>.
|
||||
|
||||
[[cfg_bsc_co_located_pcu]]
|
||||
==== Configure BSC co-located PCU
|
||||
|
||||
While small IP based BTSs usually come with a built in PCU (BTS co-located
|
||||
PCU), this does not have to be the case with any BTS. Especially larger E1 BTS
|
||||
usually make use of a BSC co-located PCU.
|
||||
|
||||
In the case of OsmoBSC this means that an instance of OsmoPCU is running next
|
||||
to OsmoBSC. Both processes share a unix domain socket to exchange signaling
|
||||
traffic and configuration parameters.
|
||||
|
||||
.OsmoBSC with co-located OsmoPCU'
|
||||
[graphviz]
|
||||
----
|
||||
digraph G {
|
||||
rankdir=LR;
|
||||
BTS [label="BTS"];
|
||||
|
||||
subgraph cluster_ran {
|
||||
label="RAN";
|
||||
PCU [label="OsmoPCU"];
|
||||
BSC [label="OsmoBSC"];
|
||||
MGW [label="OsmoMGW"];
|
||||
{ rank=same BSC MGW PCU }
|
||||
}
|
||||
|
||||
BTS->PCU [label="GPRS/TRAU", style=dotted];
|
||||
BTS->BSC [label="Abis"];
|
||||
BTS->MGW [label="SPEECH/TRAU", style=dotted];
|
||||
BSC->MGW [label="MGCP"];
|
||||
BSC->PCU [label="PCU_SOCK"];
|
||||
}
|
||||
----
|
||||
|
||||
Apart from the configuration of the PCU socket path the configuration is not
|
||||
much different from those where the PCU is integrated inside the BTS. See also
|
||||
see also <<config_gprs_pcu_pars>> for a detailed description.
|
||||
|
||||
.Configure socket path to co-located PCU
|
||||
----
|
||||
network
|
||||
pcu-socket /tmp/pcu_bts
|
||||
----
|
||||
|
|
|
@ -16,6 +16,10 @@ include::./common/chapters/vty.adoc[]
|
|||
|
||||
include::./common/chapters/logging.adoc[]
|
||||
|
||||
include::./common/chapters/sigtran.adoc[]
|
||||
|
||||
include::./common/chapters/sigtran-osmocom.adoc[]
|
||||
|
||||
include::./common/chapters/cs7-config.adoc[]
|
||||
|
||||
include::{srcdir}/chapters/bts.adoc[]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
msc {
|
||||
bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts[label="BSC timeslot FSM"], bsc_lchan[label="BSC lchan FSM"];
|
||||
bts [label="MS/BTS"], bsc[label="BSC"], bsc_ts[label="BSC timeslot FSM"], bsc_lchan[label="BSC lchan FSM"], pcu_sock[label="PCU socket"];
|
||||
|
||||
bsc_ts abox bsc_ts [label="NOT_INITIALIZED"];
|
||||
|
||||
|
@ -88,6 +88,24 @@ msc {
|
|||
bsc_ts rbox bsc_ts [label="Continue at 'IN_USE' above"];
|
||||
...;
|
||||
...;
|
||||
bts rbox bsc_lchan [label="on PCU disconnect (Ericsson RBS)
|
||||
for all timeslots in state PDCH:" ];
|
||||
bsc_ts abox bsc_ts [label="PDCH"];
|
||||
bsc_ts <- pcu_sock [label="TS_EV_PDCH_DEACT"];
|
||||
bts note bsc_ts [label="PDCH release, see WAIT_PDCH_DEACT above"];
|
||||
...;
|
||||
bsc_ts abox bsc_ts [label="UNUSED"];
|
||||
...;
|
||||
...;
|
||||
bts rbox bsc_lchan [label="on PCU reconnect (Ericsson RBS)
|
||||
for all timeslots in state UNUSED:" ];
|
||||
bsc_ts abox bsc_ts [label="UNUSED"];
|
||||
bsc_ts <- pcu_sock [label="TS_EV_PDCH_ACT"];
|
||||
bts note bsc_ts [label="PDCH activation, see WAIT_PDCH_ACT above"];
|
||||
...;
|
||||
bsc_ts abox bsc_ts [label="PDCH"];
|
||||
...;
|
||||
...;
|
||||
|
||||
bts rbox bsc_lchan [label="on erratic event"];
|
||||
bsc_ts -> bsc_lchan [label="LCHAN_EV_TS_ERROR"];
|
||||
|
|
|
@ -19,6 +19,7 @@ noinst_HEADERS = \
|
|||
chan_alloc.h \
|
||||
chan_counts.h \
|
||||
codec_pref.h \
|
||||
data_rate_pref.h \
|
||||
ctrl.h \
|
||||
debug.h \
|
||||
e1_config.h \
|
||||
|
@ -45,7 +46,6 @@ noinst_HEADERS = \
|
|||
neighbor_ident.h \
|
||||
network_listen.h \
|
||||
nm_common_fsm.h \
|
||||
openbscdefines.h \
|
||||
osmo_bsc.h \
|
||||
osmo_bsc_grace.h \
|
||||
osmo_bsc_rf.h \
|
||||
|
@ -66,4 +66,5 @@ noinst_HEADERS = \
|
|||
osmo_bsc_lcls.h \
|
||||
smscb.h \
|
||||
power_control.h \
|
||||
vgcs_fsm.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -29,9 +29,6 @@
|
|||
#include <osmocom/bsc/gsm_data.h>
|
||||
#include <osmocom/bsc/signal.h>
|
||||
|
||||
/* max number of attributes represented as 3GPP TS 52.021 §9.4.62 SW Description array */
|
||||
#define MAX_BTS_ATTR 5
|
||||
|
||||
/* The BCCH info from an ip.access test, in host byte order
|
||||
* and already parsed... */
|
||||
struct ipac_bcch_info {
|
||||
|
@ -89,7 +86,8 @@ int abis_nm_set_bts_attr(struct gsm_bts *bts, uint8_t *attr, int attr_len);
|
|||
int abis_nm_set_radio_attr(struct gsm_bts_trx *trx, uint8_t *attr, int attr_len);
|
||||
int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb);
|
||||
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
|
||||
uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len);
|
||||
uint8_t i2, uint8_t i3, int nack,
|
||||
const uint8_t *attr, unsigned int attr_len);
|
||||
int abis_nm_raw_msg(struct gsm_bts *bts, int len, uint8_t *msg);
|
||||
int abis_nm_event_reports(struct gsm_bts *bts, int on);
|
||||
int abis_nm_reset_resource(struct gsm_bts *bts);
|
||||
|
|
|
@ -55,17 +55,20 @@ int rsl_encryption_cmd(struct msgb *msg);
|
|||
int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group,
|
||||
const struct osmo_mobile_identity *mi,
|
||||
uint8_t chan_needed, bool is_gprs);
|
||||
int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val);
|
||||
int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx);
|
||||
int rsl_imm_assign_cmd(const struct gsm_bts *bts, uint8_t len, const uint8_t *val);
|
||||
int rsl_tx_imm_assignment(struct gsm_lchan *lchan);
|
||||
int rsl_tx_imm_ass_rej(struct gsm_bts *bts, struct gsm48_req_ref *rqd_ref);
|
||||
int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan, uint8_t power_command);
|
||||
|
||||
int rsl_data_request(struct msgb *msg, uint8_t link_id);
|
||||
int rsl_unit_data_request(struct msgb *msg, uint8_t link_id);
|
||||
int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
int rsl_relase_request(struct gsm_lchan *lchan, uint8_t link_id);
|
||||
|
||||
/* Ericcson vendor specific RSL extensions */
|
||||
int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val);
|
||||
int rsl_ericsson_imm_assign_cmd(const struct gsm_bts *bts, uint32_t msg_id, uint8_t len,
|
||||
const uint8_t *val, uint8_t pag_grp, bool confirm);
|
||||
|
||||
/* Siemens vendor-specific RSL extensions */
|
||||
int rsl_siemens_mrpci(struct gsm_lchan *lchan, struct rsl_mrpci *mrpci);
|
||||
|
@ -119,6 +122,11 @@ int rsl_tx_dyn_ts_pdch_act_deact(struct gsm_bts_trx_ts *ts, bool activate);
|
|||
|
||||
int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uint8_t l3_info_len);
|
||||
|
||||
int ipacc_rtp_csd_fmt_transp(const struct channel_mode_and_rate *ch_mode_rate,
|
||||
const enum rsl_ipac_rtp_csd_format_d format_d);
|
||||
int ipacc_rtp_csd_fmt_non_transp(const struct channel_mode_and_rate *ch_mode_rate,
|
||||
const enum rsl_ipac_rtp_csd_format_d format_d);
|
||||
|
||||
int ipacc_speech_mode(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type);
|
||||
void ipacc_speech_mode_set_direction(uint8_t *speech_mode, bool send);
|
||||
int ipacc_payload_type(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type);
|
||||
|
|
|
@ -40,7 +40,7 @@ enum assignment_fsm_event {
|
|||
ASSIGNMENT_EV_CONN_RELEASING,
|
||||
};
|
||||
|
||||
void assignment_fsm_init(void);
|
||||
void bssap_extend_osmux(struct msgb *msg, uint8_t cid);
|
||||
|
||||
int reassignment_request_to_lchan(enum assign_for assign_for, struct gsm_lchan *lchan, struct gsm_lchan *to_lchan,
|
||||
int tsc_set, int tsc);
|
||||
|
@ -50,3 +50,4 @@ int reassignment_request_to_chan_type(enum assign_for assign_for, struct gsm_lch
|
|||
void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
|
||||
struct assignment_request *req);
|
||||
void assignment_reset(struct gsm_subscriber_connection *conn);
|
||||
void assignment_fsm_update_id(struct gsm_subscriber_connection *conn);
|
||||
|
|
|
@ -71,6 +71,15 @@ enum {
|
|||
MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR,
|
||||
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST,
|
||||
MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT,
|
||||
MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP,
|
||||
MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST,
|
||||
MSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE,
|
||||
MSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD,
|
||||
MSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD,
|
||||
MSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD,
|
||||
MSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO,
|
||||
MSC_CTR_BSSMAP_RX_DT1_VGCS_SMS,
|
||||
MSC_CTR_BSSMAP_RX_DT1_NOTIFICATION_DATA,
|
||||
|
||||
/* Tx message counters (per connection type) */
|
||||
MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT,
|
||||
|
@ -86,8 +95,8 @@ enum {
|
|||
MSC_CTR_BSSMAP_TX_UDT_RESET_ACK,
|
||||
MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST,
|
||||
MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_FAILURE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_COMPLETE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT,
|
||||
MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT,
|
||||
|
@ -102,6 +111,17 @@ enum {
|
|||
MSC_CTR_BSSMAP_TX_DT1_DTAP,
|
||||
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS,
|
||||
MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_QUEUING_INDICATION,
|
||||
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGNMENT_STATUS,
|
||||
MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_AREA_CELL_INFO,
|
||||
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION,
|
||||
MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION,
|
||||
MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA,
|
||||
|
||||
MSC_CTR_MSCPOOL_SUBSCR_NEW,
|
||||
MSC_CTR_MSCPOOL_SUBSCR_REATTACH,
|
||||
|
@ -133,8 +153,13 @@ struct bsc_msc_data {
|
|||
/* audio codecs */
|
||||
struct gsm48_multi_rate_conf amr_conf;
|
||||
bool amr_octet_aligned;
|
||||
struct gsm_audio_support **audio_support;
|
||||
|
||||
/* Practically, there can be only 5 entries in osmo-bsc: FR1 FR2 FR3 HR1 HR3. Historically, osmo-bsc allowed
|
||||
* *any* number of entries -- we should not break too strictly on old cfg files. Theoretically, there should be
|
||||
* room for FR1 to FR7 plus HR1 to HR7 less HR2. Let's just give ample room for all these aspects: */
|
||||
struct gsm_audio_support audio_support[16];
|
||||
int audio_length;
|
||||
|
||||
enum bsc_lcls_mode lcls_mode;
|
||||
bool lcls_codec_mismatch_allow;
|
||||
|
||||
|
|
|
@ -57,8 +57,6 @@ struct osmo_mgcpc_ep_ci;
|
|||
struct assignment_request;
|
||||
struct gsm_lchan;
|
||||
|
||||
void bsc_subscr_conn_fsm_init(void);
|
||||
|
||||
/* Allocate a subscriber connection and its associated FSM */
|
||||
struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *net);
|
||||
void gscon_update_id(struct gsm_subscriber_connection *conn);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/linuxrbtree.h>
|
||||
#include <osmocom/core/use_count.h>
|
||||
#include <osmocom/gsm/protocol/gsm_23_003.h>
|
||||
#include <osmocom/gsm/gsm48.h>
|
||||
|
@ -12,8 +13,19 @@
|
|||
struct log_target;
|
||||
struct gsm_bts;
|
||||
|
||||
struct bsc_subscr_store {
|
||||
struct llist_head bsub_list; /* list containing "struct bsc_subscr" */
|
||||
/* rbtree root of 'struct bsc_subscr', ordered by tmsi */
|
||||
struct rb_root bsub_tree_tmsi;
|
||||
};
|
||||
|
||||
struct bsc_subscr_store *bsc_subscr_store_alloc(void *ctx);
|
||||
|
||||
struct bsc_subscr {
|
||||
struct llist_head entry;
|
||||
struct bsc_subscr_store *store; /* backpointer to "struct bsc_subscr_store" */
|
||||
struct llist_head entry; /* entry in (struct bsc_subscr_store)->bsub_list */
|
||||
/* entry in (struct bsc_subscr_store)->bsub_tree_tmsi. Inserted if tmsi != GSM_RESERVED_TMSI: */
|
||||
struct rb_node node_tmsi;
|
||||
struct osmo_use_count use_count;
|
||||
|
||||
char imsi[GSM23003_IMSI_MAX_DIGITS+1];
|
||||
|
@ -28,30 +40,21 @@ struct bsc_subscr {
|
|||
const char *bsc_subscr_name(struct bsc_subscr *bsub);
|
||||
const char *bsc_subscr_id(struct bsc_subscr *bsub);
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct bsc_subscr_store *bsubst,
|
||||
const char *imsi,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
|
||||
const char *imei,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct bsc_subscr_store *bsubst,
|
||||
uint32_t tmsi,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct bsc_subscr_store *bsubst,
|
||||
const struct osmo_mobile_identity *mi,
|
||||
const char *use_token);
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct bsc_subscr_store *bsubst,
|
||||
const char *imsi,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
|
||||
const char *imei,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi,
|
||||
const char *use_token);
|
||||
struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
|
||||
const char *use_token);
|
||||
|
||||
int bsc_subscr_set_tmsi(struct bsc_subscr *bsub, uint32_t tmsi);
|
||||
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi);
|
||||
void bsc_subscr_set_imei(struct bsc_subscr *bsub, const char *imei);
|
||||
|
||||
|
|
|
@ -28,4 +28,5 @@ struct bssmap_reset {
|
|||
struct bssmap_reset *bssmap_reset_alloc(void *ctx, const char *label, const struct bssmap_reset_cfg *cfg);
|
||||
bool bssmap_reset_is_conn_ready(const struct bssmap_reset *bssmap_reset);
|
||||
void bssmap_reset_resend_reset(struct bssmap_reset *bssmap_reset);
|
||||
void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset);
|
||||
void bssmap_reset_term_and_free(struct bssmap_reset *bssmap_reset);
|
||||
|
|
|
@ -300,7 +300,7 @@ struct gsm_bts_model {
|
|||
/* (Optional) function for sending default MS/BS Power Control paramaters */
|
||||
int (*power_ctrl_send_def_params)(const struct gsm_bts_trx *trx);
|
||||
/* (Optional) function for toggling BCCH carrier power reduction operation */
|
||||
int (*power_ctrl_set_c0_power_red)(const struct gsm_bts *bts, const uint8_t red);
|
||||
int (*power_ctrl_send_c0_power_red)(const struct gsm_bts *bts, const uint8_t red);
|
||||
|
||||
void (*config_write_bts)(struct vty *vty, struct gsm_bts *bts);
|
||||
void (*config_write_trx)(struct vty *vty, struct gsm_bts_trx *trx);
|
||||
|
@ -375,8 +375,8 @@ struct gsm_bts {
|
|||
struct e1inp_sign_link *oml_link;
|
||||
/* Timer to use for deferred drop of OML link, see \ref ipaccess_drop_oml_deferred */
|
||||
struct osmo_timer_list oml_drop_link_timer;
|
||||
/* when OML link was established */
|
||||
time_t uptime;
|
||||
/* when OML link was established or lost */
|
||||
time_t updowntime;
|
||||
|
||||
/* Abis network management O&M handle */
|
||||
struct abis_nm_h *nmh;
|
||||
|
@ -523,6 +523,7 @@ struct gsm_bts {
|
|||
bool chan_alloc_chan_req_reverse;
|
||||
bool chan_alloc_assignment_reverse;
|
||||
bool chan_alloc_handover_reverse;
|
||||
bool chan_alloc_vgcs_reverse;
|
||||
|
||||
/* Whether to use dynamic allocation mode for assignment */
|
||||
bool chan_alloc_assignment_dynamic;
|
||||
|
@ -568,6 +569,11 @@ struct gsm_bts {
|
|||
uint16_t scramble_list[MAX_EARFCN_LIST];
|
||||
} data;
|
||||
} si_common;
|
||||
/* NCH (Notification Channel) related parameters */
|
||||
struct {
|
||||
uint8_t num_blocks; /* NCH number of CCCH blocks (0 = no NCH) */
|
||||
uint8_t first_block; /* NCH first block number */
|
||||
} nch;
|
||||
bool early_classmark_allowed;
|
||||
bool early_classmark_allowed_3g;
|
||||
/* for testing only: Have an infinitely long radio link timeout */
|
||||
|
@ -600,10 +606,6 @@ struct gsm_bts {
|
|||
/* osmux config: */
|
||||
enum osmux_usage use_osmux;
|
||||
|
||||
/* PCU socket state */
|
||||
char *pcu_sock_path;
|
||||
struct pcu_sock_state *pcu_state;
|
||||
|
||||
struct rate_ctr_group *bts_ctrs;
|
||||
struct osmo_stat_item_group *bts_statg;
|
||||
|
||||
|
@ -661,6 +663,9 @@ struct gsm_bts {
|
|||
/* We will ignore CHAN RQD with access delay greater than rach_max_delay */
|
||||
uint8_t rach_max_delay;
|
||||
|
||||
/* We will ignore CHAN RQD sitting in the queue for period greater than rach_expiry_timeout */
|
||||
uint8_t rach_expiry_timeout;
|
||||
|
||||
/* Is Fast return to LTE allowed during Chan Release in this BTS? */
|
||||
bool srvcc_fast_return_allowed;
|
||||
|
||||
|
@ -678,77 +683,100 @@ struct gsm_bts {
|
|||
#define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0])
|
||||
|
||||
/* this actually refers to the IPA transport, not the BTS model */
|
||||
static inline int is_ipaccess_bts(const struct gsm_bts *bts)
|
||||
static inline bool is_ipa_abisip_bts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int is_osmobts(const struct gsm_bts *bts)
|
||||
static inline bool is_nanobts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool is_osmobts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int is_siemens_bts(const struct gsm_bts *bts)
|
||||
static inline bool is_siemens_bts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_BS11:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int is_nokia_bts(const struct gsm_bts *bts)
|
||||
static inline bool is_nokia_bts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NOKIA_SITE:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int is_ericsson_bts(const struct gsm_bts *bts)
|
||||
static inline bool is_ericsson_bts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_RBS2000:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int is_e1_bts(const struct gsm_bts *bts)
|
||||
static inline bool is_e1_bts(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_BS11:
|
||||
case GSM_BTS_TYPE_RBS2000:
|
||||
case GSM_BTS_TYPE_NOKIA_SITE:
|
||||
return 1;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool bsc_co_located_pcu(const struct gsm_bts *bts)
|
||||
{
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_RBS2000:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts)
|
||||
|
@ -787,7 +815,7 @@ int bts_gprs_mode_is_compat(struct gsm_bts *bts, enum bts_gprs_mode mode);
|
|||
#define BTS_STORE_UPTIME_INTERVAL 10 /* in seconds */
|
||||
void bts_store_uptime(struct gsm_bts *bts);
|
||||
|
||||
unsigned long long bts_uptime(const struct gsm_bts *bts);
|
||||
unsigned long long bts_updowntime(const struct gsm_bts *bts);
|
||||
|
||||
#define BTS_STORE_LCHAN_DURATIONS_INTERVAL 1 /* in seconds */
|
||||
void bts_store_lchan_durations(struct gsm_bts *bts);
|
||||
|
@ -814,6 +842,7 @@ void gsm_bts_all_ts_dispatch(struct gsm_bts *bts, uint32_t ts_ev, void *data);
|
|||
|
||||
int gsm_bts_set_system_infos(struct gsm_bts *bts);
|
||||
|
||||
int gsm_bts_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red);
|
||||
int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red);
|
||||
|
||||
void gsm_bts_stats_reset(struct gsm_bts *bts);
|
||||
|
|
|
@ -23,12 +23,19 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/gsm/tlv.h>
|
||||
|
||||
struct gsm_bts_sm;
|
||||
struct gsm_bts;
|
||||
struct gsm_bts_trx;
|
||||
struct gsm_gprs_nsvc;
|
||||
|
||||
extern const struct tlv_definition ipacc_eie_tlv_def;
|
||||
|
||||
int ipacc_parse_supp_features(const struct gsm_bts *bts,
|
||||
const struct abis_om_fom_hdr *foh,
|
||||
const uint8_t *data, uint16_t data_len);
|
||||
|
||||
struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts);
|
||||
struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm);
|
||||
struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* BTS Site Manager */
|
||||
|
||||
/* (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
|
||||
|
@ -40,6 +40,7 @@ struct gsm_gprs_nsvc {
|
|||
/* data read via VTY config file, to configure the BTS
|
||||
* via OML from BSC */
|
||||
int id;
|
||||
bool enabled;
|
||||
uint16_t nsvci;
|
||||
uint16_t local_port; /* on the BTS */
|
||||
struct osmo_sockaddr remote;
|
||||
|
|
|
@ -43,7 +43,6 @@ struct gsm_bts_trx {
|
|||
struct e1inp_sign_link *oml_link;
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
struct tlv_parsed nm_attr;
|
||||
struct gsm_bts_bb_trx bb_transc;
|
||||
|
||||
uint16_t arfcn;
|
||||
|
|
|
@ -17,6 +17,10 @@ enum rate_pref {
|
|||
RATE_PREF_FR,
|
||||
};
|
||||
|
||||
int match_codec_pref_data(struct channel_mode_and_rate *ch_mode_rate,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const bool full_rate);
|
||||
|
||||
int match_codec_pref(struct channel_mode_and_rate *ch_mode_rate,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const struct gsm0808_speech_codec_list *scl,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <osmocom/ctrl/control_cmd.h>
|
||||
#include <osmocom/bsc/gsm_data.h>
|
||||
|
||||
struct gsm_network;
|
||||
struct gsm_bts;
|
||||
|
@ -11,8 +12,14 @@ struct ctrl_handle *bsc_controlif_setup(struct gsm_network *net, uint16_t port);
|
|||
/* Used internally in different ctrl source code files: */
|
||||
int bsc_bts_ctrl_cmds_install(void);
|
||||
int bsc_bts_trx_ctrl_cmds_install(void);
|
||||
int bsc_bts_trx_ts_ctrl_cmds_install(void);
|
||||
int bsc_bts_trx_ts_lchan_ctrl_cmds_install(void);
|
||||
void ctrl_generate_bts_location_state_trap(struct gsm_bts *bts, struct bsc_msc_data *msc);
|
||||
void osmo_bsc_send_trap(struct ctrl_cmd *cmd, struct bsc_msc_data *msc_data);
|
||||
char *lchan_dump_full_ctrl(const void *t, struct gsm_lchan *lchan);
|
||||
char *ts_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx_ts *ts);
|
||||
char *trx_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx *trx);
|
||||
char *bts_lchan_dump_full_ctrl(const void *t, struct gsm_bts *bts);
|
||||
|
||||
|
||||
enum bsc_ctrl_node {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
|
||||
struct gsm0808_channel_type;
|
||||
struct channel_mode_and_rate;
|
||||
|
||||
int match_data_rate_pref(struct channel_mode_and_rate *ch_mode_rate,
|
||||
const struct gsm0808_channel_type *ct,
|
||||
const bool full_rate);
|
|
@ -28,6 +28,7 @@ enum {
|
|||
DAS,
|
||||
DCBS,
|
||||
DLCS,
|
||||
DASCI,
|
||||
DRESET,
|
||||
DLOOP,
|
||||
Debug_LastEntry,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/msgb.h>
|
||||
#include <osmocom/core/bitvec.h>
|
||||
|
||||
enum handover_scope;
|
||||
|
||||
|
@ -18,7 +19,7 @@ struct gsm_subscriber_connection;
|
|||
void gsm_net_update_ctype(struct gsm_network *network);
|
||||
enum gsm_chan_t get_ctype_by_chreq(struct gsm_network *network, uint8_t ra);
|
||||
int get_reason_by_chreq(uint8_t ra, int neci);
|
||||
int gsm48_send_rr_release(struct gsm_lchan *lchan);
|
||||
int gsm48_send_rr_release(struct gsm_lchan *lchan, bool ui);
|
||||
int send_siemens_mrpci(struct gsm_lchan *lchan,
|
||||
uint8_t *classmark2_lv);
|
||||
int gsm48_send_rr_classmark_enquiry(struct gsm_lchan *lchan);
|
||||
|
@ -33,7 +34,11 @@ int gsm48_send_rr_ass_cmd(struct gsm_lchan *dest_lchan, struct gsm_lchan *lchan,
|
|||
int gsm48_send_rr_app_info(struct gsm_lchan *lchan, uint8_t apdu_id, uint8_t apdu_flags,
|
||||
const uint8_t *apdu_data, ssize_t apdu_data_len);
|
||||
int gsm48_lchan_modify(struct gsm_lchan *lchan, uint8_t mode);
|
||||
int gsm48_send_uplink_release(struct gsm_lchan *lchan, uint8_t cause);
|
||||
int gsm48_send_uplink_busy(struct gsm_lchan *lchan);
|
||||
int gsm48_send_uplink_free(struct gsm_lchan *lchan, uint8_t acc_bit, uint8_t *uic);
|
||||
int gsm48_rx_rr_modif_ack(struct msgb *msg);
|
||||
int neigh_list_get_arfcn(struct gsm_bts *bts, const struct bitvec *nbv, unsigned int idx);
|
||||
int gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
|
||||
|
||||
struct msgb *gsm48_create_mm_serv_rej(enum gsm48_reject_value value);
|
||||
|
|
|
@ -13,3 +13,4 @@ void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct ms
|
|||
void bsc_cm_update(struct gsm_subscriber_connection *conn,
|
||||
const uint8_t *cm2, uint8_t cm2_len,
|
||||
const uint8_t *cm3, uint8_t cm3_len);
|
||||
bool bsc_chan_ind_requires_rtp_stream(enum gsm0808_chan_indicator ch_indctr);
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <osmocom/core/fsm.h>
|
||||
#include <osmocom/core/tdef.h>
|
||||
#include <osmocom/core/time_cc.h>
|
||||
#include <osmocom/core/linuxlist.h>
|
||||
#include <osmocom/core/linuxrbtree.h>
|
||||
|
||||
#include <osmocom/crypt/auth.h>
|
||||
|
||||
|
@ -51,6 +53,9 @@
|
|||
* with delta = time between expiration of T3124 and receiving HANDOVER FAILURE by the serving BSC. */
|
||||
#define GSM_NY1_DEFAULT ((unsigned long)((GSM_T3124_MAX + GSM_NY1_REQ_DELTA)/GSM_T3105_DEFAULT + 1))
|
||||
|
||||
#define SCCP_CONN_ID_UNSET 0xFFFFFFFF
|
||||
#define SCCP_CONN_ID_MAX 0x00FFFFFE
|
||||
|
||||
struct mgcp_client_conf;
|
||||
struct mgcp_client;
|
||||
struct gsm0808_cell_id;
|
||||
|
@ -137,6 +142,7 @@ struct assignment_request {
|
|||
enum assign_for assign_for;
|
||||
|
||||
bool aoip;
|
||||
bool vgcs;
|
||||
|
||||
uint16_t msc_assigned_cic;
|
||||
|
||||
|
@ -163,6 +169,9 @@ struct assignment_request {
|
|||
/* The TSC to use if 'use' is true, otherwise automatically determine the TSC value to use. Valid range is 0 to
|
||||
* 7, as described in 3GPP TS 45.002. */
|
||||
struct optional_val tsc;
|
||||
|
||||
/* The "speech / data indicator" from 3GPP TS 48.008 § 3.2.2.11 Channel Type (speech/data/signalling). */
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
};
|
||||
|
||||
/* State of an ongoing Assignment, while the assignment_fsm is still busy. This serves as state separation to keep the
|
||||
|
@ -176,7 +185,7 @@ struct assignment_fsm_data {
|
|||
*/
|
||||
struct assignment_request req;
|
||||
|
||||
bool requires_voice_stream;
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
struct channel_mode_and_rate selected_ch_mode_rate;
|
||||
|
||||
struct osmo_fsm_inst *fi;
|
||||
|
@ -273,6 +282,21 @@ struct handover {
|
|||
struct osmo_mgcpc_ep_ci *created_ci_for_msc;
|
||||
};
|
||||
|
||||
struct gsm_subscriber_connection;
|
||||
|
||||
struct bscp_sccp_conn_node {
|
||||
/* entry in (struct bsc_sccp_inst)->connections */
|
||||
struct rb_node node;
|
||||
/* Sigtran connection ID:
|
||||
* if set: Range (0..SCCP_CONN_ID_MAX) (24 bit)
|
||||
* if unset: SCCP_CONN_ID_UNSET (-1) if unset */
|
||||
uint32_t conn_id;
|
||||
/* backpointer where this sccp conn belongs to: */
|
||||
struct gsm_subscriber_connection *gscon;
|
||||
};
|
||||
|
||||
void bscp_sccp_conn_node_init(struct bscp_sccp_conn_node *sccp_conn, struct gsm_subscriber_connection *gscon);
|
||||
|
||||
/* active radio connection of a mobile subscriber */
|
||||
struct gsm_subscriber_connection {
|
||||
/* global linked list of subscriber_connections */
|
||||
|
@ -320,14 +344,12 @@ struct gsm_subscriber_connection {
|
|||
/* flag to prevent multiple simultaneous ciphering commands */
|
||||
int ciphering_handled;
|
||||
|
||||
/* SCCP connection associatd with this subscriber_connection */
|
||||
/* SCCP connection associated with this subscriber_connection */
|
||||
struct {
|
||||
/* SCCP connection related */
|
||||
struct bsc_msc_data *msc;
|
||||
|
||||
/* Sigtran connection ID */
|
||||
int conn_id;
|
||||
enum subscr_sccp_state state;
|
||||
struct bscp_sccp_conn_node conn;
|
||||
} sccp;
|
||||
|
||||
/* for audio handling */
|
||||
|
@ -376,8 +398,8 @@ struct gsm_subscriber_connection {
|
|||
|
||||
/* Lb interface to the SMLC: BSSMAP-LE/SCCP connection associated with this subscriber */
|
||||
struct {
|
||||
int conn_id;
|
||||
enum subscr_sccp_state state;
|
||||
struct bscp_sccp_conn_node conn;
|
||||
} lb;
|
||||
} lcs;
|
||||
|
||||
|
@ -391,6 +413,60 @@ struct gsm_subscriber_connection {
|
|||
} fast_return;
|
||||
|
||||
enum gsm0808_cause clear_cause;
|
||||
|
||||
/* VGCS/VBS "call controling" connection */
|
||||
struct {
|
||||
/* Features supported by MSC/BSC */
|
||||
bool ff_present;
|
||||
struct gsm0808_vgcs_feature_flags ff;
|
||||
/* Group Call Reference IE */
|
||||
struct gsm0808_group_callref gc_ie;
|
||||
enum gsm0808_service_flag sf;
|
||||
uint32_t call_ref;
|
||||
/* Call (BSC) FSM */
|
||||
struct osmo_fsm_inst *fi;
|
||||
/* Current talker */
|
||||
struct gsm_subscriber_connection *talker;
|
||||
/* L3 info of link establihment (Talker established) */
|
||||
struct llist_head l3_queue;
|
||||
/* Flag and cause (Talker released) */
|
||||
bool talker_rel;
|
||||
uint8_t talker_cause;
|
||||
/* Flag that states acknowledgement of the talker by MSC */
|
||||
bool msc_ack;
|
||||
/* List of VGCS/VBS "resource controling" connections */
|
||||
struct llist_head chan_list;
|
||||
} vgcs_call;
|
||||
|
||||
/* VGCS/VBS "resource controling" connection */
|
||||
struct {
|
||||
/* List entry of chan_list of "call controling" connection */
|
||||
struct llist_head list;
|
||||
/* Group Call Reference IE */
|
||||
struct gsm0808_group_callref gc_ie;
|
||||
enum gsm0808_service_flag sf;
|
||||
uint32_t call_ref;
|
||||
/* Channel type IE */
|
||||
struct gsm0808_channel_type ct;
|
||||
/* Channel mode and rate */
|
||||
struct channel_mode_and_rate ch_mode_rate;
|
||||
/* Cell Identifier IE */
|
||||
struct gsm0808_cell_id ci;
|
||||
char ci_str[16];
|
||||
/* Assignment Requirements IE */
|
||||
enum gsm0808_assignment_requirement ar;
|
||||
/* Call Identifier IE */
|
||||
uint32_t call_id;
|
||||
/* Pointer to VGCS/VBS "call controling" gsconn */
|
||||
struct gsm_subscriber_connection *call;
|
||||
/* Cell (BTS) FSM */
|
||||
struct osmo_fsm_inst *fi;
|
||||
/* lchan to be assigned */
|
||||
struct gsm_lchan *new_lchan;
|
||||
/* MGW peer */
|
||||
char msc_rtp_addr[INET6_ADDRSTRLEN];
|
||||
uint16_t msc_rtp_port;
|
||||
} vgcs_chan;
|
||||
};
|
||||
|
||||
|
||||
|
@ -450,9 +526,9 @@ struct gsm_abis_mo {
|
|||
struct abis_om_obj_inst obj_inst;
|
||||
const char *name;
|
||||
struct gsm_nm_state nm_state;
|
||||
struct tlv_parsed *nm_attr;
|
||||
struct gsm_bts *bts;
|
||||
struct osmo_fsm_inst *fi;
|
||||
bool sw_act_rep_received;
|
||||
bool opstart_sent;
|
||||
bool adm_unlock_sent;
|
||||
bool get_attr_sent;
|
||||
|
@ -462,6 +538,12 @@ struct gsm_abis_mo {
|
|||
bool rsl_connect_sent;
|
||||
bool rsl_connect_ack_received;
|
||||
bool force_rf_lock;
|
||||
/* vendor specific fields below */
|
||||
union {
|
||||
struct {
|
||||
uint8_t obj_version;
|
||||
} ipaccess;
|
||||
};
|
||||
};
|
||||
|
||||
/* Ericsson OM2000 Managed Object */
|
||||
|
@ -495,9 +577,9 @@ struct om2k_mo {
|
|||
*
|
||||
* These macros convert from n to the other representations:
|
||||
*/
|
||||
#define ALG_A5_NR_TO_RSL(A5_N) ((A5_N) >= 0 ? (A5_N)+1 : 0)
|
||||
#define ALG_A5_NR_TO_RSL(A5_N) ((int)(A5_N) >= 0 ? (A5_N)+1 : 0)
|
||||
#define ALG_A5_NR_TO_BSSAP(A5_N) ALG_A5_NR_TO_RSL(A5_N)
|
||||
#define ALG_A5_NR_TO_PERM_ALG_BITS(A5_N) ((A5_N) >= 0 ? 1<<(A5_N) : 0)
|
||||
#define ALG_A5_NR_TO_PERM_ALG_BITS(A5_N) ((int)(A5_N) >= 0 ? 1<<(A5_N) : 0)
|
||||
|
||||
/* Up to 16 SI2quater are multiplexed; each fits 3 EARFCNS, so the practical maximum is 3*16.
|
||||
* The real maximum that fits in a total of 16 SI2quater rest octets also depends on the bits left by other SI2quater
|
||||
|
@ -592,7 +674,6 @@ struct gsm_bts_trx_ts {
|
|||
bool is_rsl_ready;
|
||||
|
||||
struct gsm_abis_mo mo;
|
||||
struct tlv_parsed nm_attr;
|
||||
uint8_t nm_chan_comb;
|
||||
int tsc; /* -1 == use BTS TSC */
|
||||
|
||||
|
@ -806,10 +887,7 @@ struct gsm_bts *gsm_bts_by_cell_id(const struct gsm_network *net,
|
|||
extern const struct value_string gsm_chreq_descs[];
|
||||
extern const struct value_string gsm_pchant_names[];
|
||||
extern const struct value_string gsm_pchant_descs[];
|
||||
extern const struct value_string gsm_pchan_ids[];
|
||||
const char *gsm_pchan_name(enum gsm_phys_chan_config c);
|
||||
static inline const char *gsm_pchan_id(enum gsm_phys_chan_config c)
|
||||
{ return get_value_string(gsm_pchan_ids, c); }
|
||||
enum gsm_phys_chan_config gsm_pchan_parse(const char *name);
|
||||
const char *gsm_chreq_name(enum gsm_chreq_reason_t c);
|
||||
char *gsm_ts_name(const struct gsm_bts_trx_ts *ts);
|
||||
|
@ -819,6 +897,8 @@ void gsm_abis_mo_reset(struct gsm_abis_mo *mo);
|
|||
void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts,
|
||||
uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3);
|
||||
|
||||
struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
|
||||
const struct abis_om_obj_inst *obj_inst);
|
||||
struct gsm_nm_state *
|
||||
gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class,
|
||||
const struct abis_om_obj_inst *obj_inst);
|
||||
|
@ -863,6 +943,19 @@ struct all_allocated {
|
|||
struct osmo_time_cc static_tch;
|
||||
};
|
||||
|
||||
struct bsc_sccp_inst {
|
||||
struct osmo_sccp_instance *sccp; /* backpointer */
|
||||
/* rbtree root of 'struct bscp_sccp_conn_node' in this instance, ordered by conn_id */
|
||||
struct rb_root connections;
|
||||
uint32_t next_id; /* next id to allocate */
|
||||
};
|
||||
|
||||
struct bsc_sccp_inst *bsc_sccp_inst_alloc(void *ctx);
|
||||
uint32_t bsc_sccp_inst_next_conn_id(struct bsc_sccp_inst *bsc_sccp);
|
||||
int bsc_sccp_inst_register_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn);
|
||||
void bsc_sccp_inst_unregister_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn);
|
||||
struct gsm_subscriber_connection *bsc_sccp_inst_get_gscon_by_conn_id(const struct bsc_sccp_inst *bsc_sccp, uint32_t conn_id);
|
||||
|
||||
struct gsm_network {
|
||||
struct osmo_plmn_id plmn;
|
||||
|
||||
|
@ -899,10 +992,10 @@ struct gsm_network {
|
|||
|
||||
/* msc configuration */
|
||||
struct llist_head mscs;
|
||||
uint8_t mscs_round_robin_next_nr;
|
||||
unsigned int mscs_round_robin_next_nr;
|
||||
/* Emergency calls potentially select a different set of MSCs, so to not mess up the normal round-robin
|
||||
* behavior, emergency calls need a separate round-robin counter. */
|
||||
uint8_t mscs_round_robin_next_emerg_nr;
|
||||
unsigned int mscs_round_robin_next_emerg_nr;
|
||||
|
||||
/* rf ctl related bits */
|
||||
int mid_call_timeout;
|
||||
|
@ -928,13 +1021,8 @@ struct gsm_network {
|
|||
* OsmoMSC, this should be tied to the location area code (LAC). */
|
||||
struct gsm_tz tz;
|
||||
|
||||
/* List of all struct bsc_subscr used in libbsc. This llist_head is
|
||||
* allocated so that the llist_head pointer itself can serve as a
|
||||
* talloc context (useful to not have to pass the entire gsm_network
|
||||
* struct to the bsc_subscr_* API, and for bsc_susbscr unit tests to
|
||||
* not require gsm_data.h). In an MSC-without-BSC environment, this
|
||||
* pointer is NULL to indicate absence of a bsc_subscribers list. */
|
||||
struct llist_head *bsc_subscribers;
|
||||
/* Keeps track of struct bsc_subcr. */
|
||||
struct bsc_subscr_store *bsc_subscribers;
|
||||
|
||||
/* Timer for periodic channel load measurements to maintain each BTS's T3122. */
|
||||
struct osmo_timer_list t3122_chan_load_timer;
|
||||
|
@ -977,6 +1065,11 @@ struct gsm_network {
|
|||
|
||||
struct chan_counts chan_counts;
|
||||
struct all_allocated all_allocated;
|
||||
|
||||
/* PCU socket state */
|
||||
char *pcu_sock_path;
|
||||
unsigned int pcu_sock_wqueue_len_max;
|
||||
struct pcu_sock_state *pcu_state;
|
||||
};
|
||||
|
||||
struct gsm_audio_support {
|
||||
|
@ -984,6 +1077,8 @@ struct gsm_audio_support {
|
|||
ver : 7;
|
||||
};
|
||||
|
||||
int gsm_audio_support_cmp(const struct gsm_audio_support *a, const struct gsm_audio_support *b);
|
||||
|
||||
extern void talloc_ctx_init(void *ctx_root);
|
||||
|
||||
enum gsm_bts_type parse_btstype(const char *arg);
|
||||
|
@ -1020,8 +1115,6 @@ enum gsm_phys_chan_config gsm_pchan_by_lchan_type(enum gsm_chan_t type);
|
|||
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_gsm0808_cause(enum gsm0808_cause c);
|
||||
enum gsm48_rr_cause bsc_gsm48_rr_cause_from_rsl_cause(uint8_t c);
|
||||
|
||||
int bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp);
|
||||
|
||||
/* Interference Measurement Parameters */
|
||||
struct gsm_interf_meas_params {
|
||||
/* Intave: Interference Averaging period (see 3GPP TS 45.008, table A.1) */
|
||||
|
|
|
@ -55,8 +55,6 @@ struct handover_rr_detect_data {
|
|||
const uint8_t *access_delay;
|
||||
};
|
||||
|
||||
void handover_fsm_init(void);
|
||||
|
||||
int handover_request(struct handover_out_req *req);
|
||||
void handover_start(struct handover_out_req *req);
|
||||
void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <osmocom/gsm/gsm_utils.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.h>
|
||||
#include <osmocom/gsm/protocol/gsm_08_08.h>
|
||||
#include <osmocom/gsm/protocol/gsm_08_58.h>
|
||||
#include <osmocom/gsm/gsm23003.h>
|
||||
|
||||
#include <osmocom/bsc/meas_rep.h>
|
||||
|
@ -44,24 +45,16 @@ enum channel_rate {
|
|||
|
||||
enum channel_rate chan_t_to_chan_rate(enum gsm_chan_t chan_t);
|
||||
|
||||
enum lchan_csd_mode {
|
||||
LCHAN_CSD_M_NT,
|
||||
LCHAN_CSD_M_T_1200_75,
|
||||
LCHAN_CSD_M_T_600,
|
||||
LCHAN_CSD_M_T_1200,
|
||||
LCHAN_CSD_M_T_2400,
|
||||
LCHAN_CSD_M_T_9600,
|
||||
LCHAN_CSD_M_T_14400,
|
||||
LCHAN_CSD_M_T_29000,
|
||||
LCHAN_CSD_M_T_32000,
|
||||
};
|
||||
|
||||
struct channel_mode_and_rate {
|
||||
enum gsm48_chan_mode chan_mode;
|
||||
enum channel_rate chan_rate;
|
||||
uint16_t s15_s0;
|
||||
/* only used for GSM48_CMODE_DATA_* */
|
||||
enum lchan_csd_mode csd_mode;
|
||||
bool data_transparent;
|
||||
union {
|
||||
enum rsl_cmod_csd_t t;
|
||||
enum rsl_cmod_csd_nt nt;
|
||||
} data_rate;
|
||||
};
|
||||
|
||||
/* Channel Request reason */
|
||||
|
@ -108,10 +101,18 @@ enum lchan_activate_for {
|
|||
ACTIVATE_FOR_MS_CHANNEL_REQUEST,
|
||||
ACTIVATE_FOR_ASSIGNMENT,
|
||||
ACTIVATE_FOR_HANDOVER,
|
||||
ACTIVATE_FOR_VGCS_CHANNEL,
|
||||
ACTIVATE_FOR_VTY,
|
||||
ACTIVATE_FOR_MODE_MODIFY_RTP,
|
||||
};
|
||||
|
||||
enum lchan_type_for {
|
||||
LCHAN_TYPE_FOR_NORMAL = 0,
|
||||
LCHAN_TYPE_FOR_VAMOS,
|
||||
LCHAN_TYPE_FOR_VGCS,
|
||||
LCHAN_TYPE_FOR_VBS,
|
||||
};
|
||||
|
||||
extern const struct value_string lchan_activate_mode_names[];
|
||||
static inline const char *lchan_activate_mode_name(enum lchan_activate_for activ_for)
|
||||
{ return get_value_string(lchan_activate_mode_names, activ_for); }
|
||||
|
@ -129,7 +130,7 @@ struct lchan_activate_info {
|
|||
struct gsm_subscriber_connection *for_conn;
|
||||
struct channel_mode_and_rate ch_mode_rate;
|
||||
struct gsm_encr encr;
|
||||
bool requires_voice_stream;
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
bool wait_before_switching_rtp; /*< true = requires LCHAN_EV_READY_TO_SWITCH_RTP */
|
||||
uint16_t msc_assigned_cic;
|
||||
/* During intra-BSC handover, we keep the MGW endpoint intact and just re-route to the new lchan. This
|
||||
|
@ -145,7 +146,7 @@ struct lchan_activate_info {
|
|||
* 7, as described in 3GPP TS 45.002. */
|
||||
struct optional_val tsc;
|
||||
|
||||
bool vamos;
|
||||
enum lchan_type_for type_for;
|
||||
|
||||
/* A copy of bts->imm_ass_time at the time where Channel Activation was requested. A change in the VTY
|
||||
* configuration has immediate effect on the value, so make sure we don't get mixed up when it gets changed
|
||||
|
@ -166,7 +167,7 @@ static inline const char *lchan_modify_for_name(enum lchan_modify_for modify_for
|
|||
struct lchan_modify_info {
|
||||
enum lchan_modify_for modify_for;
|
||||
struct channel_mode_and_rate ch_mode_rate;
|
||||
bool requires_voice_stream;
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
uint16_t msc_assigned_cic;
|
||||
|
||||
/* The TSC Set to use if 'use' is true, otherwise automatically determine the TSC Set value to use. Valid range
|
||||
|
@ -176,7 +177,7 @@ struct lchan_modify_info {
|
|||
* 7, as described in 3GPP TS 45.002. */
|
||||
struct optional_val tsc;
|
||||
|
||||
bool vamos;
|
||||
enum lchan_type_for type_for;
|
||||
};
|
||||
|
||||
/* Measurement pre-processing state */
|
||||
|
@ -223,6 +224,7 @@ struct gsm_lchan {
|
|||
|
||||
struct channel_mode_and_rate ch_mode_rate;
|
||||
struct gsm48_multi_rate_conf mr_conf_filtered;
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
bool activ_ack; /*< true as soon as RSL Chan Activ Ack is received */
|
||||
bool immediate_assignment_sent;
|
||||
/*! This flag ensures that when an lchan activation has succeeded, and we have already
|
||||
|
@ -246,6 +248,7 @@ struct gsm_lchan {
|
|||
|
||||
struct channel_mode_and_rate ch_mode_rate;
|
||||
struct gsm48_multi_rate_conf mr_conf_filtered;
|
||||
enum gsm0808_chan_indicator ch_indctr;
|
||||
/* Actually used TSC Set. */
|
||||
int tsc_set;
|
||||
/* Actually used TSC. */
|
||||
|
@ -291,6 +294,7 @@ struct gsm_lchan {
|
|||
uint16_t conn_id;
|
||||
uint8_t rtp_payload;
|
||||
uint8_t rtp_payload2;
|
||||
uint8_t rtp_csd_fmt;
|
||||
uint8_t speech_mode;
|
||||
|
||||
/* info we need to postpone the AoIP
|
||||
|
@ -331,6 +335,7 @@ struct gsm_lchan {
|
|||
* channel_mode_and_rate. */
|
||||
struct channel_mode_and_rate current_ch_mode_rate;
|
||||
struct gsm48_multi_rate_conf current_mr_conf;
|
||||
enum gsm0808_chan_indicator current_ch_indctr;
|
||||
|
||||
/* Circuit-Switched TSC Set in use, or -1 if no specific TSC Set was requested. The valid range is 1-4 as
|
||||
* described in the spec 3GPP TS 45.002. */
|
||||
|
|
|
@ -33,6 +33,8 @@ enum lchan_fsm_state {
|
|||
LCHAN_ST_WAIT_RF_RELEASE_ACK,
|
||||
LCHAN_ST_WAIT_AFTER_ERROR,
|
||||
LCHAN_ST_BORKEN,
|
||||
LCHAN_ST_RECOVER_WAIT_ACTIV_ACK, /*< Attempt to recover from BORKEN: first try to activate the lchan */
|
||||
LCHAN_ST_RECOVER_WAIT_RF_RELEASE_ACK, /*< Attempt to recover from BORKEN: then try to release it */
|
||||
};
|
||||
|
||||
enum lchan_fsm_event {
|
||||
|
@ -56,8 +58,6 @@ enum lchan_fsm_event {
|
|||
LCHAN_EV_REQUEST_MODE_MODIFY,
|
||||
};
|
||||
|
||||
void lchan_fsm_init(void);
|
||||
|
||||
void lchan_fsm_alloc(struct gsm_lchan *lchan);
|
||||
void lchan_release(struct gsm_lchan *lchan, bool do_rr_release,
|
||||
bool err, enum gsm48_rr_cause cause_rr,
|
||||
|
@ -80,6 +80,8 @@ static inline bool lchan_state_is(const struct gsm_lchan *lchan, uint32_t state)
|
|||
|
||||
bool lchan_may_receive_data(struct gsm_lchan *lchan);
|
||||
|
||||
bool lchan_is_asci(struct gsm_lchan *lchan);
|
||||
|
||||
void lchan_forget_conn(struct gsm_lchan *lchan);
|
||||
|
||||
void lchan_fsm_skip_error(struct gsm_lchan *lchan);
|
||||
|
|
|
@ -5,6 +5,7 @@ enum lchan_select_reason {
|
|||
SELECT_FOR_MS_CHAN_REQ,
|
||||
SELECT_FOR_ASSIGNMENT,
|
||||
SELECT_FOR_HANDOVER,
|
||||
SELECT_FOR_VGCS,
|
||||
};
|
||||
|
||||
extern const struct value_string lchan_select_reason_names[];
|
||||
|
|
|
@ -35,9 +35,12 @@ enum meas_feed_msgtype {
|
|||
};
|
||||
|
||||
#define MEAS_FEED_VERSION 1
|
||||
#define MEAS_FEED_TXQUEUE_MAX_LEN_DEFAULT 100
|
||||
|
||||
int meas_feed_cfg_set(const char *dst_host, uint16_t dst_port);
|
||||
void meas_feed_scenario_set(const char *name);
|
||||
void meas_feed_txqueue_max_length_set(unsigned int max_length);
|
||||
|
||||
void meas_feed_cfg_get(char **host, uint16_t *port);
|
||||
const char *meas_feed_scenario_get(void);
|
||||
unsigned int meas_feed_txqueue_max_length_get(void);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* (C) 2009 by Holger Hans Peter Freyther <zecke@selfish.org>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPENBSCDEFINES_H
|
||||
#define OPENBSCDEFINES_H
|
||||
|
||||
#ifdef BUILDING_ON_WINDOWS
|
||||
#ifdef BUILDING_OPENBSC
|
||||
#define BSC_API __declspec(dllexport)
|
||||
#else
|
||||
#define BSC_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define BSC_API __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -26,7 +26,6 @@
|
|||
/* Allocate resources to make a new connection oriented sigtran connection
|
||||
* (not the connection ittself!) */
|
||||
enum bsc_con osmo_bsc_sigtran_new_conn(struct gsm_subscriber_connection *conn, struct bsc_msc_data *msc);
|
||||
struct gsm_subscriber_connection *bsc_conn_by_bsub(struct bsc_subscr *bsub);
|
||||
|
||||
/* Open a new connection oriented sigtran connection */
|
||||
int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
|
|
@ -150,9 +150,6 @@ void paging_request_stop(struct bsc_msc_data **msc_p, enum bsc_paging_reason *re
|
|||
struct gsm_bts *bts, struct bsc_subscr *bsub);
|
||||
void paging_request_cancel(struct bsc_subscr *bsub, enum bsc_paging_reason reasons);
|
||||
|
||||
/* update paging load */
|
||||
void paging_update_buffer_space(struct gsm_bts *bts, uint16_t);
|
||||
|
||||
/* pending paging requests */
|
||||
unsigned int paging_pending_requests_nr(const struct gsm_bts *bts);
|
||||
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
#ifndef _PCU_IF_H
|
||||
#define _PCU_IF_H
|
||||
|
||||
#include <osmocom/core/write_queue.h>
|
||||
#include <osmocom/gsm/l1sap.h>
|
||||
|
||||
extern int pcu_direct;
|
||||
|
||||
#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u))
|
||||
|
||||
#define BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT 100
|
||||
|
||||
struct pcu_sock_state {
|
||||
struct gsm_network *net;
|
||||
struct gsm_network *net; /* backpointer to GSM network */
|
||||
struct osmo_fd listen_bfd; /* fd for listen socket */
|
||||
struct osmo_fd conn_bfd; /* fd for connection to lcr */
|
||||
struct llist_head upqueue; /* queue for sending messages */
|
||||
struct osmo_wqueue upqueue; /* For sending messages; has fd for conn. to PCU */
|
||||
};
|
||||
|
||||
/* Check if BTS has a PCU connection */
|
||||
bool pcu_connected(const struct gsm_network *net);
|
||||
|
||||
/* PCU relevant information has changed; Inform PCU (if connected) */
|
||||
void pcu_info_update(struct gsm_bts *bts);
|
||||
|
||||
|
@ -21,17 +26,13 @@ void pcu_info_update(struct gsm_bts *bts);
|
|||
int pcu_tx_rach_ind(struct gsm_bts *bts, int16_t qta, uint16_t ra, uint32_t fn,
|
||||
uint8_t is_11bit, enum ph_burst_type burst_type);
|
||||
|
||||
/* Confirm the sending of an immediate assignment to the pcu */
|
||||
int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
|
||||
|
||||
|
||||
/* Confirm the sending of an immediate assignment to the pcu */
|
||||
int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli);
|
||||
/* Confirm the sending of an AGCH or PCH MAC block to the pcu */
|
||||
int pcu_tx_data_cnf(struct gsm_bts *bts, uint32_t msg_id, uint8_t sapi);
|
||||
|
||||
/* Open connection to PCU */
|
||||
int pcu_sock_init(const char *path, struct gsm_bts *bts);
|
||||
int pcu_sock_init(struct gsm_network *net);
|
||||
|
||||
/* Close connection to PCU */
|
||||
void pcu_sock_exit(struct gsm_bts *bts);
|
||||
void pcu_sock_exit(struct gsm_network *net);
|
||||
|
||||
#endif /* _PCU_IF_H */
|
||||
|
|
|
@ -3,20 +3,21 @@
|
|||
|
||||
#include <osmocom/gsm/l1sap.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <osmocom/gsm/protocol/gsm_04_08.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_E1_CCU_IND 0x33 /* retrieve E1 CCU comm. parameters */
|
||||
|
@ -33,17 +34,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)
|
||||
|
@ -63,6 +63,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
|
||||
|
||||
|
@ -91,19 +102,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 {
|
||||
|
@ -185,6 +187,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));
|
||||
|
||||
/* E1 CCU connection parameters */
|
||||
|
@ -269,6 +272,32 @@ struct gsm_pcu_if_neigh_addr_cnf {
|
|||
} cgi_ps;
|
||||
} __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 */
|
||||
|
@ -277,8 +306,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;
|
||||
|
|
|
@ -5,18 +5,24 @@
|
|||
|
||||
#include <osmocom/gsm/gsm48_arfcn_range_encode.h>
|
||||
|
||||
/* Complete length of SYSTEM INFORMATION 10 (SACCH) */
|
||||
#define SI10_LENGTH 21
|
||||
|
||||
struct gsm_bts;
|
||||
|
||||
int band_compatible(const struct gsm_bts *bts, int arfcn);
|
||||
int generate_cell_chan_alloc(struct gsm_bts *bts);
|
||||
int generate_cell_chan_list(uint8_t *chan_list, struct gsm_bts *bts);
|
||||
int gsm_generate_si(struct gsm_bts *bts, enum osmo_sysinfo_type type);
|
||||
int gsm_generate_si10(struct gsm48_system_information_type_10 *si10, size_t len,
|
||||
const struct gsm_subscriber_connection *conn);
|
||||
size_t si2q_earfcn_count(const struct osmo_earfcn_si2q *e);
|
||||
unsigned range1024_p(unsigned n);
|
||||
unsigned range512_q(unsigned m);
|
||||
int range_encode(enum osmo_gsm48_range r, int *arfcns, int arfcns_used, int *w,
|
||||
int f0, uint8_t *chan_list);
|
||||
uint8_t si2q_num(struct gsm_bts *bts);
|
||||
int bts_earfcn_del(struct gsm_bts *bts, uint16_t earfcn);
|
||||
int bts_earfcn_add(struct gsm_bts *bts, uint16_t earfcn, uint8_t thresh_hi, uint8_t thresh_lo, uint8_t prio,
|
||||
uint8_t qrx, uint8_t meas_bw);
|
||||
int bts_uarfcn_del(struct gsm_bts *bts, uint16_t arfcn, uint16_t scramble);
|
||||
|
|
|
@ -36,10 +36,18 @@ enum ts_fsm_event {
|
|||
TS_EV_RSL_DOWN,
|
||||
TS_EV_LCHAN_REQUESTED,
|
||||
TS_EV_LCHAN_UNUSED,
|
||||
|
||||
/* RSL responses received from the BTS: */
|
||||
TS_EV_PDCH_ACT_ACK,
|
||||
TS_EV_PDCH_ACT_NACK,
|
||||
TS_EV_PDCH_DEACT_ACK,
|
||||
TS_EV_PDCH_DEACT_NACK,
|
||||
TS_EV_PDCH_ACT_NACK,
|
||||
TS_EV_PDCH_DEACT_ACK,
|
||||
TS_EV_PDCH_DEACT_NACK,
|
||||
|
||||
/* BSC co-located PCU disconnects from PCU socket, deactivate PDCH */
|
||||
TS_EV_PDCH_DEACT,
|
||||
|
||||
/* BSC co-located PCU (re)connects to PCU socket, activate PDCH */
|
||||
TS_EV_PDCH_ACT,
|
||||
};
|
||||
|
||||
void ts_fsm_alloc(struct gsm_bts_trx_ts *ts);
|
||||
|
@ -52,3 +60,6 @@ bool ts_is_pchan_switching(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config
|
|||
bool ts_usable_as_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan, bool allow_pchan_switch);
|
||||
|
||||
void ts_set_pchan_is(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan_is);
|
||||
|
||||
void ts_pdch_act(struct gsm_bts_trx_ts *ts);
|
||||
void ts_pdch_deact(struct gsm_bts_trx_ts *ts);
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* Handle a call via VGCS/VBCS (Voice Group/Broadcast Call Service). */
|
||||
/*
|
||||
* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0+
|
||||
*
|
||||
* Author: Andreas Eversberg
|
||||
*
|
||||
* 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
|
||||
|
||||
/* Events for both VGCS/VBS state machines. */
|
||||
enum vgcs_fsm_event {
|
||||
/* The BSC sets up a VGCS/VBS call. */
|
||||
VGCS_EV_SETUP,
|
||||
/* The BSC wants to assign a VGCS/VBS channel. */
|
||||
VGCS_EV_ASSIGN_REQ,
|
||||
/* The BTS detects a talker on a channel. */
|
||||
VGCS_EV_TALKER_DET,
|
||||
/* The BTS detects a listener on a channel. */
|
||||
VGCS_EV_LISTENER_DET,
|
||||
/* The MSC accepts a talker. */
|
||||
VGCS_EV_MSC_ACK,
|
||||
/* The MSC rejects a talker. */
|
||||
VGCS_EV_MSC_REJECT,
|
||||
/* The MSC seizes all channels. (blocking for calls) */
|
||||
VGCS_EV_MSC_SEIZE,
|
||||
/* The MSC releases all channels. (unblocking for calls) */
|
||||
VGCS_EV_MSC_RELEASE,
|
||||
/* The MSC sends message to talker. (E.g. CONNECT) */
|
||||
VGCS_EV_MSC_DTAP,
|
||||
/* Channel is now active. Waiting for Talker. */
|
||||
VGCS_EV_LCHAN_ACTIVE,
|
||||
/* Channel activation error. */
|
||||
VGCS_EV_LCHAN_ERROR,
|
||||
/* MGW connection is now active. Waiting for Talker. */
|
||||
VGCS_EV_MGW_OK,
|
||||
/* MGW connection error. */
|
||||
VGCS_EV_MGW_FAIL,
|
||||
/* Channel link established. (Talker establised.) */
|
||||
VGCS_EV_TALKER_EST,
|
||||
/* Channel link data. (Talker sends data.) */
|
||||
VGCS_EV_TALKER_DATA,
|
||||
/* Channel link released. (Talker released.) */
|
||||
VGCS_EV_TALKER_REL,
|
||||
/* Channel link failed. (Talker failed.) */
|
||||
VGCS_EV_TALKER_FAIL,
|
||||
/* Channel is blocked by BSC. */
|
||||
VGCS_EV_BLOCK,
|
||||
/* Channel is rejected by BSC. */
|
||||
VGCS_EV_REJECT,
|
||||
/* Channel is unblocked by BSC. */
|
||||
VGCS_EV_UNBLOCK,
|
||||
/* The connection will be destroyed. (free VGCS resources) */
|
||||
VGCS_EV_CLEANUP,
|
||||
/* The calling subscriber has been assigned to the group channel. */
|
||||
VGCS_EV_CALLING_ASSIGNED,
|
||||
};
|
||||
|
||||
|
||||
/* States of the VGCS/VBS call state machine */
|
||||
enum vgcs_call_fsm_state {
|
||||
/* Call is not setup. Initial state when instance is created. */
|
||||
VGCS_CALL_ST_NULL = 0,
|
||||
/* Call is idle. */
|
||||
VGCS_CALL_ST_IDLE,
|
||||
/* Call is busy, due to a talker in this BSC. */
|
||||
VGCS_CALL_ST_BUSY,
|
||||
/* Call is blocked, due to a talker in a different BSC. */
|
||||
VGCS_CALL_ST_BLOCKED,
|
||||
};
|
||||
|
||||
/* States of the VGCS/VBS channel state machine */
|
||||
enum vgcs_chan_fsm_state {
|
||||
/* Channel not assigned. Initial state when instance is created. */
|
||||
VGCS_CHAN_ST_NULL = 0,
|
||||
/* Wait for establishment of VGCS/VBS channel at BTS. */
|
||||
VGCS_CHAN_ST_WAIT_EST,
|
||||
/* Channel active and idle. Channel is marked as uplink busy. */
|
||||
VGCS_CHAN_ST_ACTIVE_BLOCKED,
|
||||
/* Channel active and idle. Channel is marked as uplink free. */
|
||||
VGCS_CHAN_ST_ACTIVE_FREE,
|
||||
/* Channel active and talker was detected, L2 must be established. */
|
||||
VGCS_CHAN_ST_ACTIVE_INIT,
|
||||
/* Channel active and talker established L2. */
|
||||
VGCS_CHAN_ST_ACTIVE_EST,
|
||||
/* Channel active and wait for talker to release L2. */
|
||||
VGCS_CHAN_ST_ACTIVE_REL,
|
||||
};
|
||||
|
||||
int vgcs_vbs_chan_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
int vgcs_vbs_call_start(struct gsm_subscriber_connection *conn, struct msgb *msg);
|
||||
|
||||
int bssmap_handle_ass_req_ct_speech(struct gsm_subscriber_connection *conn, struct gsm_bts *bts,
|
||||
struct tlv_parsed *tp, struct gsm0808_channel_type *ct,
|
||||
struct assignment_request *req, uint8_t *cause);
|
||||
void bsc_tx_setup_ack(struct gsm_subscriber_connection *conn, struct gsm0808_vgcs_feature_flags *ff);
|
||||
void bsc_tx_setup_refuse(struct gsm_subscriber_connection *conn, uint8_t cause);
|
||||
void bsc_tx_vgcs_vbs_assignment_result(struct gsm_subscriber_connection *conn, struct gsm0808_channel_type *ct,
|
||||
struct gsm0808_cell_id *ci, uint32_t call_id);
|
||||
void bsc_tx_vgcs_vbs_assignment_fail(struct gsm_subscriber_connection *conn, uint8_t cause);
|
||||
void bsc_tx_uplink_req(struct gsm_subscriber_connection *conn);
|
||||
void bsc_tx_uplink_req_conf(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
|
||||
uint8_t length);
|
||||
void bsc_tx_uplink_app_data(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info,
|
||||
uint8_t length);
|
||||
void bsc_tx_uplink_release_ind(struct gsm_subscriber_connection *conn, uint8_t cause);
|
||||
struct gsm_lchan *vgcs_vbs_find_lchan(struct gsm_bts *bts, struct gsm0808_group_callref *gc);
|
|
@ -51,6 +51,7 @@ struct gsm_network *gsmnet_from_vty(struct vty *vty);
|
|||
|
||||
int bts_vty_init(void);
|
||||
void bts_dump_vty(struct vty *vty, struct gsm_bts *bts);
|
||||
void bts_dump_vty_oml_link_state(struct vty *vty, struct gsm_bts *bts);
|
||||
void trx_dump_vty(struct vty *vty, struct gsm_bts_trx *trx, bool print_rsl, bool show_connected);
|
||||
void ts_dump_vty(struct vty *vty, struct gsm_bts_trx_ts *ts);
|
||||
void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan);
|
||||
|
|
|
@ -15,7 +15,10 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
app_configs = {
|
||||
# TODO: doc/examples/osmo-bsc/{ericsson,nokia,siemens}
|
||||
"osmo-bsc": ["doc/examples/osmo-bsc/osmo-bsc.cfg",
|
||||
"doc/examples/osmo-bsc/osmo-bsc-minimal.cfg",
|
||||
"doc/examples/osmo-bsc/osmo-bsc-4trx.cfg",
|
||||
"doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg"]
|
||||
}
|
||||
|
||||
|
|
|
@ -13,12 +13,6 @@ AM_CFLAGS = \
|
|||
$(COVERAGE_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
AM_LDFLAGS = \
|
||||
$(LIBOSMOCORE_LIBS) \
|
||||
$(LIBOSMOGSM_LIBS) \
|
||||
$(COVERAGE_LDFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
SUBDIRS = \
|
||||
osmo-bsc \
|
||||
utils \
|
||||
|
|
|
@ -46,6 +46,8 @@ libbsc_la_SOURCES = \
|
|||
bts.c \
|
||||
bts_trx.c \
|
||||
bts_trx_ctrl.c \
|
||||
bts_trx_ts_ctrl.c \
|
||||
bts_trx_ts_lchan_ctrl.c \
|
||||
bts_ericsson_rbs2000.c \
|
||||
bts_init.c \
|
||||
bts_ipaccess_nanobts.c \
|
||||
|
@ -62,6 +64,7 @@ libbsc_la_SOURCES = \
|
|||
chan_alloc.c \
|
||||
chan_counts.c \
|
||||
codec_pref.c \
|
||||
data_rate_pref.c \
|
||||
e1_config.c \
|
||||
gsm_04_08_rr.c \
|
||||
gsm_data.c \
|
||||
|
@ -72,6 +75,7 @@ libbsc_la_SOURCES = \
|
|||
handover_fsm.c \
|
||||
handover_logic.c \
|
||||
handover_vty.c \
|
||||
vgcs_fsm.c \
|
||||
lb.c \
|
||||
lchan.c \
|
||||
lchan_fsm.c \
|
||||
|
|
|
@ -42,7 +42,7 @@ static void a_reset_tx_reset_ack(void *data)
|
|||
static void a_reset_link_up(void *data)
|
||||
{
|
||||
struct bsc_msc_data *msc = data;
|
||||
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP assocation is up\n", msc->nr);
|
||||
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP association is up\n", msc->nr);
|
||||
osmo_stat_item_inc(osmo_stat_item_group_get_item(msc->msc_statg, MSC_STAT_MSC_LINKS_ACTIVE), 1);
|
||||
osmo_stat_item_inc(osmo_stat_item_group_get_item(msc->network->bsc_statg, BSC_STAT_NUM_MSC_CONNECTED), 1);
|
||||
osmo_signal_dispatch(SS_MSC, S_MSC_CONNECTED, msc);
|
||||
|
@ -51,7 +51,7 @@ static void a_reset_link_up(void *data)
|
|||
static void a_reset_link_lost(void *data)
|
||||
{
|
||||
struct bsc_msc_data *msc = data;
|
||||
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP assocation is down\n", msc->nr);
|
||||
LOGP(DMSC, LOGL_NOTICE, "(msc%d) BSSMAP association is down\n", msc->nr);
|
||||
osmo_stat_item_dec(osmo_stat_item_group_get_item(msc->msc_statg, MSC_STAT_MSC_LINKS_ACTIVE), 1);
|
||||
osmo_stat_item_dec(osmo_stat_item_group_get_item(msc->network->bsc_statg, BSC_STAT_NUM_MSC_CONNECTED), 1);
|
||||
osmo_signal_dispatch(SS_MSC, S_MSC_LOST, msc);
|
||||
|
|
|
@ -52,11 +52,15 @@
|
|||
#include <osmocom/bsc/nm_common_fsm.h>
|
||||
#include <osmocom/gsm/bts_features.h>
|
||||
#include <osmocom/bsc/ipaccess.h>
|
||||
#include <osmocom/bsc/bts_ipaccess_nanobts_omlattr.h>
|
||||
|
||||
#define OM_ALLOC_SIZE 1024
|
||||
#define OM_HEADROOM_SIZE 128
|
||||
#define IPACC_SEGMENT_SIZE 245
|
||||
|
||||
/* max number of SW Description IEs we can parse */
|
||||
#define SW_DESCR_MAX 5
|
||||
|
||||
#define LOGPMO(mo, ss, lvl, fmt, args ...) \
|
||||
LOGP(ss, lvl, "OC=%s(%02x) INST=(%02x,%02x,%02x): " fmt, \
|
||||
get_value_string(abis_nm_obj_class_names, (mo)->obj_class), \
|
||||
|
@ -560,6 +564,45 @@ static inline const uint8_t *parse_attr_resp_info_unreported(const struct abis_o
|
|||
return ari + num_unreported + 1; /* we have to account for 1st byte with number of unreported attributes */
|
||||
}
|
||||
|
||||
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.30 Manufacturer Id */
|
||||
static void parse_osmo_bts_features(struct gsm_bts *bts,
|
||||
const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
/* log potential BTS feature vector overflow */
|
||||
if (data_len > sizeof(bts->_features_data)) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
|
||||
"Get Attributes Response: feature vector is truncated "
|
||||
"(from %u to %zu bytes)\n", data_len, sizeof(bts->_features_data));
|
||||
data_len = sizeof(bts->_features_data);
|
||||
}
|
||||
|
||||
/* check that max. expected BTS attribute is above given feature vector length */
|
||||
if (data_len > OSMO_BYTES_FOR_BITS(_NUM_BTS_FEAT)) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
|
||||
"Get Attributes Response: reported unexpectedly long (%u bytes) "
|
||||
"feature vector - most likely it was compiled against newer BSC headers. "
|
||||
"Consider upgrading your BSC to later version.\n", data_len);
|
||||
}
|
||||
|
||||
memcpy(bts->_features_data, data, data_len);
|
||||
bts->features_known = true;
|
||||
|
||||
/* Log each BTS feature in the reported vector */
|
||||
for (unsigned int i = 0; i < data_len * 8; i++) {
|
||||
if (!osmo_bts_has_feature(&bts->features, i))
|
||||
continue;
|
||||
|
||||
if (i >= _NUM_BTS_FEAT) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
|
||||
"Get Attributes Response: unknown feature 0x%02x is supported\n", i);
|
||||
} else {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE,
|
||||
"Get Attributes Response: feature '%s' is supported\n",
|
||||
osmo_bts_features_name(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle 3GPP TS 52.021 §8.11.3 Get Attribute Response (with nanoBTS specific attribute formatting) */
|
||||
static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_trx *trx, struct abis_om_fom_hdr *foh, struct tlv_parsed *tp)
|
||||
{
|
||||
|
@ -570,55 +613,22 @@ static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_t
|
|||
uint16_t port;
|
||||
struct in_addr ia = {0};
|
||||
char unit_id[40];
|
||||
struct abis_nm_sw_desc sw_descr[MAX_BTS_ATTR];
|
||||
|
||||
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.30 Manufacturer Id */
|
||||
if (TLVP_PRES_LEN(tp, NM_ATT_MANUF_ID, 2)) {
|
||||
len = TLVP_LEN(tp, NM_ATT_MANUF_ID);
|
||||
|
||||
/* log potential BTS feature vector overflow */
|
||||
if (len > sizeof(bts->_features_data)) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature vector is truncated "
|
||||
"(from %u to %zu bytes)\n", len, sizeof(bts->_features_data));
|
||||
len = sizeof(bts->_features_data);
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
if (TLVP_PRES_LEN(tp, NM_ATT_MANUF_ID, 2)) {
|
||||
parse_osmo_bts_features(bts, TLVP_VAL(tp, NM_ATT_MANUF_ID),
|
||||
TLVP_LEN(tp, NM_ATT_MANUF_ID));
|
||||
}
|
||||
|
||||
/* check that max. expected BTS attribute is above given feature vector length */
|
||||
if (len > OSMO_BYTES_FOR_BITS(_NUM_BTS_FEAT)) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: reported unexpectedly long (%u bytes) "
|
||||
"feature vector - most likely it was compiled against newer BSC headers. "
|
||||
"Consider upgrading your BSC to later version.\n", len);
|
||||
}
|
||||
|
||||
memcpy(bts->_features_data, TLVP_VAL(tp, NM_ATT_MANUF_ID), len);
|
||||
bts->features_known = true;
|
||||
|
||||
/* Log each BTS feature in the reported vector */
|
||||
for (i = 0; i < len * 8; i++) {
|
||||
if (!osmo_bts_has_feature(&bts->features, i))
|
||||
continue;
|
||||
|
||||
if (i >= _NUM_BTS_FEAT)
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: unknown feature 0x%02x is"
|
||||
" supported\n", i);
|
||||
else
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature '%s' is"
|
||||
" supported\n", osmo_bts_features_name(i));
|
||||
}
|
||||
|
||||
/* Add features from the BTS model: nanobts may support more
|
||||
* features than it reports, since we extend the enum of
|
||||
* features for osmo-bts. */
|
||||
if (bts->type == GSM_BTS_TYPE_NANOBTS) {
|
||||
for (i = 0; i < _NUM_BTS_FEAT; i++) {
|
||||
if (osmo_bts_has_feature(&bts->model->features, i) /* intentional check against bts model */
|
||||
&& !osmo_bts_has_feature(&bts->features, i)) {
|
||||
LOGPMO(&bts->mo, DNM, LOGL_NOTICE, "Get Attributes Response: feature '%s' is"
|
||||
" assumed to be supported\n", osmo_bts_features_name(i));
|
||||
osmo_bts_set_feature(&bts->features, i);
|
||||
}
|
||||
}
|
||||
/* fall-through */
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
if (TLVP_PRESENT(tp, NM_ATT_IPACC_SUPP_FEATURES)) {
|
||||
ipacc_parse_supp_features(bts, foh, TLVP_VAL(tp, NM_ATT_IPACC_SUPP_FEATURES),
|
||||
TLVP_LEN(tp, NM_ATT_IPACC_SUPP_FEATURES));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.28 Manufacturer Dependent State */
|
||||
|
@ -630,6 +640,7 @@ static int parse_attr_resp_info_attr(struct gsm_bts *bts, const struct gsm_bts_t
|
|||
|
||||
/* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.61 SW Configuration */
|
||||
if (TLVP_PRESENT(tp, NM_ATT_SW_CONFIG)) {
|
||||
struct abis_nm_sw_desc sw_descr[SW_DESCR_MAX];
|
||||
data = TLVP_VAL(tp, NM_ATT_SW_CONFIG);
|
||||
len = TLVP_LEN(tp, NM_ATT_SW_CONFIG);
|
||||
/* after parsing manufacturer-specific attributes there's list of replies in form of sw-conf structure: */
|
||||
|
@ -741,15 +752,20 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
|
|||
struct tlv_parsed tp;
|
||||
const uint8_t *sw_config;
|
||||
int ret, sw_config_len, len;
|
||||
struct abis_nm_sw_desc sw_descr[MAX_BTS_ATTR];
|
||||
struct abis_nm_sw_desc sw_descr[SW_DESCR_MAX];
|
||||
|
||||
DEBUGPFOH(DNM, foh, "Software Activate Request, ACKing and Activating\n");
|
||||
|
||||
if (oh->length < sizeof(*foh)) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Software Activate Request with length too small: %u\n", oh->length);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = abis_nm_sw_act_req_ack(sign_link->trx->bts, foh->obj_class,
|
||||
foh->obj_inst.bts_nr,
|
||||
foh->obj_inst.trx_nr,
|
||||
foh->obj_inst.ts_nr, 0,
|
||||
foh->data, oh->length-sizeof(*foh));
|
||||
foh->data, oh->length - sizeof(*foh));
|
||||
if (ret != 0) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Sending SW ActReq ACK failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -1682,7 +1698,7 @@ int abis_nm_software_load(struct gsm_bts *bts, int trx_nr, const char *fname,
|
|||
break;
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
sw->obj_class = NM_OC_BASEB_TRANSC;
|
||||
sw->obj_instance[0] = sw->bts->nr;
|
||||
sw->obj_instance[0] = sw->bts->bts_nr;
|
||||
sw->obj_instance[1] = sw->trx_nr;
|
||||
sw->obj_instance[2] = 0xff;
|
||||
break;
|
||||
|
@ -2153,12 +2169,13 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb)
|
|||
}
|
||||
|
||||
int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
|
||||
uint8_t i2, uint8_t i3, int nack, uint8_t *attr, int att_len)
|
||||
uint8_t i2, uint8_t i3, int nack,
|
||||
const uint8_t *attr, unsigned int attr_len)
|
||||
{
|
||||
struct abis_om_hdr *oh;
|
||||
struct msgb *msg = nm_msgb_alloc();
|
||||
uint8_t msgtype = NM_MT_SW_ACT_REQ_ACK;
|
||||
uint8_t len = att_len;
|
||||
uint8_t len = attr_len;
|
||||
|
||||
if (nack) {
|
||||
len += 2;
|
||||
|
@ -2166,12 +2183,10 @@ int abis_nm_sw_act_req_ack(struct gsm_bts *bts, uint8_t obj_class, uint8_t i1,
|
|||
}
|
||||
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
fill_om_fom_hdr(oh, att_len, msgtype, obj_class, i1, i2, i3);
|
||||
fill_om_fom_hdr(oh, len, msgtype, obj_class, i1, i2, i3);
|
||||
|
||||
if (attr) {
|
||||
uint8_t *ptr = msgb_put(msg, att_len);
|
||||
memcpy(ptr, attr, att_len);
|
||||
}
|
||||
if (attr != NULL && attr_len > 0)
|
||||
memcpy(msgb_put(msg, attr_len), attr, attr_len);
|
||||
if (nack)
|
||||
msgb_tv_put(msg, NM_ATT_NACK_CAUSES, NM_NACK_OBJCLASS_NOTSUPP);
|
||||
|
||||
|
@ -2645,8 +2660,8 @@ struct file_list_entry *fl_dequeue(struct llist_head *queue)
|
|||
|
||||
static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw)
|
||||
{
|
||||
struct file_list_entry *fle;
|
||||
char linebuf[255];
|
||||
struct llist_head *lh, *lh2;
|
||||
FILE *swl;
|
||||
int rc = 0;
|
||||
|
||||
|
@ -2655,10 +2670,8 @@ static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw)
|
|||
return -ENODEV;
|
||||
|
||||
/* zero the stale file list, if any */
|
||||
llist_for_each_safe(lh, lh2, &bs11_sw->file_list) {
|
||||
llist_del(lh);
|
||||
talloc_free(lh);
|
||||
}
|
||||
while ((fle = fl_dequeue(&bs11_sw->file_list)))
|
||||
talloc_free(fle);
|
||||
|
||||
while (fgets(linebuf, sizeof(linebuf), swl)) {
|
||||
char file_id[12+1];
|
||||
|
@ -3093,7 +3106,7 @@ int abis_nm_ipaccess_restart(struct gsm_bts_trx *trx)
|
|||
|
||||
oh = (struct abis_om_hdr *) msgb_put(msg, ABIS_OM_FOM_HDR_SIZE);
|
||||
fill_om_fom_hdr(oh, 0, NM_MT_IPACC_RESTART, NM_OC_BASEB_TRANSC,
|
||||
trx->bts->nr, trx->nr, 0xff);
|
||||
trx->bts->bts_nr, trx->nr, 0xff);
|
||||
|
||||
return abis_nm_sendmsg_direct(trx->bts, msg);
|
||||
}
|
||||
|
|
|
@ -68,20 +68,11 @@ struct osmo_fsm_inst *osmo_fsm_inst_alloc_child_id(struct osmo_fsm *fsm,
|
|||
{
|
||||
struct osmo_fsm_inst *fi;
|
||||
|
||||
fi = osmo_fsm_inst_alloc(fsm, parent, NULL, parent->log_level,
|
||||
id ? id : parent->id);
|
||||
if (!fi) {
|
||||
/* indicate immediate termination to caller */
|
||||
osmo_fsm_inst_dispatch(parent, parent_term_event, NULL);
|
||||
fi = osmo_fsm_inst_alloc_child(fsm, parent, parent_term_event);
|
||||
if (!fi)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOGPFSM(fi, "is child of %s\n", osmo_fsm_inst_name(parent));
|
||||
|
||||
fi->proc.parent = parent;
|
||||
fi->proc.parent_term_event = parent_term_event;
|
||||
llist_add(&fi->proc.child, &parent->proc.children);
|
||||
|
||||
if (id)
|
||||
osmo_fsm_inst_update_id_f_sanitize(fi, '-', id);
|
||||
return fi;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include <osmocom/gsm/rsl.h>
|
||||
#include <osmocom/core/talloc.h>
|
||||
#include <osmocom/bsc/pcu_if.h>
|
||||
#include <osmocom/bsc/pcuif_proto.h>
|
||||
#include <osmocom/bsc/gsm_08_08.h>
|
||||
#include <osmocom/netif/rtp.h>
|
||||
#include <osmocom/core/tdef.h>
|
||||
|
@ -58,6 +59,7 @@
|
|||
#include <osmocom/bsc/power_control.h>
|
||||
#include <osmocom/bsc/chan_counts.h>
|
||||
#include <osmocom/bsc/lchan.h>
|
||||
#include <osmocom/bsc/vgcs_fsm.h>
|
||||
|
||||
static void send_lchan_signal(int sig_no, struct gsm_lchan *lchan,
|
||||
struct gsm_meas_rep *resp)
|
||||
|
@ -405,12 +407,11 @@ int rsl_chan_ms_power_ctrl(struct gsm_lchan *lchan)
|
|||
static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
|
||||
struct gsm_lchan *lchan,
|
||||
const struct channel_mode_and_rate *ch_mode_rate,
|
||||
bool vamos)
|
||||
enum lchan_type_for type_for)
|
||||
{
|
||||
int rc;
|
||||
memset(cm, 0, sizeof(*cm));
|
||||
|
||||
/* FIXME: what to do with data calls ? */
|
||||
cm->dtx_dtu = 0;
|
||||
if (lchan->ts->trx->bts->dtxu != GSM48_DTX_SHALL_NOT_BE_USED)
|
||||
cm->dtx_dtu |= RSL_CMOD_DTXu;
|
||||
|
@ -430,10 +431,34 @@ static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
|
|||
cm->chan_rt = RSL_CMOD_CRT_SDCCH;
|
||||
break;
|
||||
case GSM_LCHAN_TCH_F:
|
||||
cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm : RSL_CMOD_CRT_TCH_Bm;
|
||||
switch (type_for) {
|
||||
case LCHAN_TYPE_FOR_VAMOS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm;
|
||||
break;
|
||||
case LCHAN_TYPE_FOR_VGCS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_GROUP_Bm;
|
||||
break;
|
||||
case LCHAN_TYPE_FOR_VBS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_BCAST_Bm;
|
||||
break;
|
||||
default:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_Bm;
|
||||
}
|
||||
break;
|
||||
case GSM_LCHAN_TCH_H:
|
||||
cm->chan_rt = vamos ? RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm : RSL_CMOD_CRT_TCH_Lm;
|
||||
switch (type_for) {
|
||||
case LCHAN_TYPE_FOR_VAMOS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm;
|
||||
break;
|
||||
case LCHAN_TYPE_FOR_VGCS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_GROUP_Lm;
|
||||
break;
|
||||
case LCHAN_TYPE_FOR_VBS:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_BCAST_Lm;
|
||||
break;
|
||||
default:
|
||||
cm->chan_rt = RSL_CMOD_CRT_TCH_Lm;
|
||||
}
|
||||
break;
|
||||
case GSM_LCHAN_NONE:
|
||||
case GSM_LCHAN_UNKNOWN:
|
||||
|
@ -460,54 +485,13 @@ static int channel_mode_from_lchan(struct rsl_ie_chan_mode *cm,
|
|||
case GSM48_CMODE_DATA_14k5:
|
||||
case GSM48_CMODE_DATA_12k0:
|
||||
case GSM48_CMODE_DATA_6k0:
|
||||
switch (ch_mode_rate->csd_mode) {
|
||||
case LCHAN_CSD_M_NT:
|
||||
/* non-transparent CSD with RLP */
|
||||
switch (ch_mode_rate->chan_mode) {
|
||||
case GSM48_CMODE_DATA_14k5:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_14k5;
|
||||
break;
|
||||
case GSM48_CMODE_DATA_12k0:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_12k0;
|
||||
break;
|
||||
case GSM48_CMODE_DATA_6k0:
|
||||
cm->chan_rate = RSL_CMOD_SP_NT_6k0;
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_ERROR,
|
||||
"unsupported lchan->tch_mode %u\n",
|
||||
ch_mode_rate->chan_mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
/* transparent data services below */
|
||||
case LCHAN_CSD_M_T_1200_75:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_1200_75;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_600:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_600;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_1200:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_1200;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_2400:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_2400;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_9600:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_9600;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_14400:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_14400;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_29000:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_29000;
|
||||
break;
|
||||
case LCHAN_CSD_M_T_32000:
|
||||
cm->chan_rate = RSL_CMOD_CSD_T_32000;
|
||||
break;
|
||||
default:
|
||||
LOGP(DRSL, LOGL_ERROR, "unsupported csd_mode %u\n", ch_mode_rate->csd_mode);
|
||||
return -EINVAL;
|
||||
case GSM48_CMODE_DATA_3k6:
|
||||
/* 3GPP TS 48.058 § 9.3.6 Channel Mode octet 6 */
|
||||
if (ch_mode_rate->data_transparent) {
|
||||
cm->chan_rate = ch_mode_rate->data_rate.t;
|
||||
} else {
|
||||
cm->chan_rate = ch_mode_rate->data_rate.nt;
|
||||
cm->chan_rate |= 0x40;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -616,7 +600,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
|
|||
/* PDCH activation is a job for rsl_tx_dyn_ts_pdch_act_deact(); */
|
||||
OSMO_ASSERT(act_type != RSL_ACT_OSMO_PDCH);
|
||||
|
||||
rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.ch_mode_rate, lchan->activate.info.vamos);
|
||||
rc = channel_mode_from_lchan(&cm, lchan, &lchan->activate.ch_mode_rate, lchan->activate.info.type_for);
|
||||
if (rc < 0) {
|
||||
LOGP(DRSL, LOGL_ERROR,
|
||||
"%s Cannot find channel mode from lchan type\n",
|
||||
|
@ -718,7 +702,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref)
|
|||
put_top_acch_cap_ie(lchan, &cm, msg);
|
||||
|
||||
/* Selecting a specific TSC Set is only applicable to VAMOS mode */
|
||||
if (lchan->activate.info.vamos && lchan->activate.tsc_set >= 1)
|
||||
if (lchan->activate.info.type_for == LCHAN_TYPE_FOR_VAMOS && lchan->activate.tsc_set >= 1)
|
||||
put_osmo_training_sequence_ie(msg, lchan->activate.tsc_set, lchan->activate.tsc);
|
||||
|
||||
msg->dst = rsl_chan_link(lchan);
|
||||
|
@ -753,7 +737,7 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
|
|||
if (chan_nr < 0)
|
||||
return chan_nr;
|
||||
|
||||
rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.ch_mode_rate, lchan->modify.info.vamos);
|
||||
rc = channel_mode_from_lchan(&cm, lchan, &lchan->modify.ch_mode_rate, lchan->modify.info.type_for);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
@ -791,7 +775,8 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan)
|
|||
|
||||
/* Selecting a specific TSC Set is only applicable to VAMOS mode. Send this Osmocom specific IE only to OsmoBTS
|
||||
* types. */
|
||||
if (lchan->modify.info.vamos && lchan->modify.tsc_set >= 1 && bts->model->type == GSM_BTS_TYPE_OSMOBTS)
|
||||
if (lchan->modify.info.type_for == LCHAN_TYPE_FOR_VAMOS && lchan->modify.tsc_set >= 1 &&
|
||||
bts->model->type == GSM_BTS_TYPE_OSMOBTS)
|
||||
put_osmo_training_sequence_ie(msg, lchan->modify.tsc_set, lchan->modify.tsc);
|
||||
|
||||
msg->dst = rsl_chan_link(lchan);
|
||||
|
@ -912,6 +897,45 @@ int rsl_paging_cmd(struct gsm_bts *bts, uint8_t paging_group,
|
|||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
/* Chapter 8.5.10: NOTIFICATION COMMAND */
|
||||
int rsl_notification_cmd(struct gsm_bts *bts, struct gsm_lchan *lchan, struct gsm0808_group_callref *gc, uint8_t *drx)
|
||||
{
|
||||
struct abis_rsl_cchan_hdr *cch;
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct gsm48_chan_desc cd;
|
||||
uint8_t sti = (lchan) ? RSL_CMD_INDICATOR_START : RSL_CMD_INDICATOR_STOP;
|
||||
uint8_t *t;
|
||||
int rc;
|
||||
|
||||
cch = (struct abis_rsl_cchan_hdr *) msgb_put(msg, sizeof(*cch));
|
||||
rsl_init_cchan_hdr(cch, RSL_MT_NOT_CMD);
|
||||
cch->chan_nr = RSL_CHAN_PCH_AGCH;
|
||||
|
||||
msgb_tlv_put(msg, RSL_IE_CMD_INDICATOR, 1, &sti);
|
||||
|
||||
/* Use TLV encoding from TS 08.08. Change different IE type. */
|
||||
t = msg->tail;
|
||||
gsm0808_enc_group_callref(msg, gc);
|
||||
*t = RSL_IE_GROUP_CALL_REF;
|
||||
|
||||
if (lchan) {
|
||||
memset(&cd, 0, sizeof(cd));
|
||||
rc = gsm48_lchan2chan_desc(&cd, lchan, lchan->activate.tsc, true);
|
||||
if (rc) {
|
||||
LOG_LCHAN(lchan, LOGL_ERROR, "Error encoding Channel Number\n");
|
||||
msgb_free(msg);
|
||||
return rc;
|
||||
}
|
||||
msgb_tlv_put(msg, RSL_IE_CHAN_DESC, sizeof(cd), (const uint8_t *)&cd);
|
||||
|
||||
if (drx)
|
||||
msgb_tlv_put(msg, RSL_IE_NCH_DRX_INFO, 1, drx);
|
||||
}
|
||||
|
||||
msg->dst = bts->c0->rsl_link_primary;
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uint8_t l3_info_len)
|
||||
{
|
||||
struct msgb *msg;
|
||||
|
@ -928,12 +952,20 @@ int rsl_forward_layer3_info(struct gsm_lchan *lchan, const uint8_t *l3_info, uin
|
|||
}
|
||||
|
||||
/* Chapter 8.5.6 */
|
||||
struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t *val)
|
||||
struct msgb *rsl_imm_assign_cmd_common(const struct gsm_bts *bts, uint8_t len, const uint8_t *val)
|
||||
{
|
||||
struct msgb *msg = rsl_msgb_alloc();
|
||||
struct msgb *msg;
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
uint8_t buf[GSM_MACBLOCK_LEN];
|
||||
|
||||
if (len > sizeof(buf)) {
|
||||
LOGP(DRSL, LOGL_ERROR,
|
||||
"Cannot send IMMEDIATE ASSIGNMENT message with excessive length (%u)\n", len);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
msg = rsl_msgb_alloc();
|
||||
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
init_dchan_hdr(dh, RSL_MT_IMMEDIATE_ASSIGN_CMD);
|
||||
dh->chan_nr = RSL_CHAN_PCH_AGCH;
|
||||
|
@ -955,7 +987,7 @@ struct msgb *rsl_imm_assign_cmd_common(struct gsm_bts *bts, uint8_t len, uint8_t
|
|||
}
|
||||
|
||||
/* Chapter 8.5.6 */
|
||||
int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
|
||||
int rsl_imm_assign_cmd(const struct gsm_bts *bts, uint8_t len, const uint8_t *val)
|
||||
{
|
||||
struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
|
||||
if (!msg)
|
||||
|
@ -964,16 +996,23 @@ int rsl_imm_assign_cmd(struct gsm_bts *bts, uint8_t len, uint8_t *val)
|
|||
}
|
||||
|
||||
/* Chapter 8.5.6 Immediate Assignment Command (with Ericcson vendor specific RSL extension) */
|
||||
int rsl_ericsson_imm_assign_cmd(struct gsm_bts *bts, uint32_t tlli, uint8_t len, uint8_t *val)
|
||||
int rsl_ericsson_imm_assign_cmd(const struct gsm_bts *bts, uint32_t msg_id, uint8_t len,
|
||||
const uint8_t *val, uint8_t pag_grp, bool confirm)
|
||||
{
|
||||
struct msgb *msg = rsl_imm_assign_cmd_common(bts, len, val);
|
||||
if (!msg)
|
||||
return 1;
|
||||
|
||||
/* Append ericsson proprietary paging group IE, this will instruct the BTS to
|
||||
* send this immediate assignment through PCH instead of AGCH. */
|
||||
msgb_tv_put(msg, RSL_IE_ERIC_PAGING_GROUP, pag_grp);
|
||||
|
||||
/* ericsson can handle a reference at the end of the message which is used in
|
||||
* the confirm message. The confirm message is only sent if the trailer is present */
|
||||
msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
|
||||
msgb_put_u32(msg, tlli);
|
||||
if (confirm) {
|
||||
msgb_put_u8(msg, RSL_IE_ERIC_MOBILE_ID);
|
||||
msgb_put_u32(msg, msg_id);
|
||||
}
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
@ -1132,6 +1171,31 @@ int rsl_data_request(struct msgb *msg, uint8_t link_id)
|
|||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
/* Send "UNIT DATA REQUEST" message with given L3 Info payload */
|
||||
/* Chapter 8.3.11 */
|
||||
int rsl_unit_data_request(struct msgb *msg, uint8_t link_id)
|
||||
{
|
||||
int chan_nr;
|
||||
|
||||
if (msg->lchan == NULL) {
|
||||
LOGP(DRSL, LOGL_ERROR, "cannot send UNIT DATA REQUEST to unknown lchan\n");
|
||||
msgb_free(msg);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chan_nr = gsm_lchan2chan_nr(msg->lchan, true);
|
||||
if (chan_nr < 0) {
|
||||
msgb_free(msg);
|
||||
return chan_nr;
|
||||
}
|
||||
|
||||
rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, chan_nr, link_id, 1);
|
||||
|
||||
msg->dst = rsl_chan_link(msg->lchan);
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
||||
/* Send "ESTABLISH REQUEST" message with given L3 Info payload */
|
||||
/* Chapter 8.3.1 */
|
||||
int rsl_establish_request(struct gsm_lchan *lchan, uint8_t link_id)
|
||||
|
@ -1253,6 +1317,15 @@ static int rsl_rx_conn_fail(struct msgb *msg)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Report to VGCS FSM */
|
||||
if (lchan_is_asci(lchan)) {
|
||||
if (lchan->conn && lchan->conn->vgcs_chan.fi) {
|
||||
uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the lchan is associated with a conn, we shall notify the MSC of the RSL Conn Failure, and
|
||||
* the connection will presumably be torn down and lead to an lchan release. During initial
|
||||
* Channel Request from the MS, an lchan has no conn yet, so in that case release now. */
|
||||
|
@ -1484,6 +1557,66 @@ static int rsl_rx_hando_det(struct msgb *msg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Chapter 8.4.21: TALKER DETECTION */
|
||||
static int rsl_rx_talker_det(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
/* We use this struct, because it has same data. */
|
||||
struct handover_rr_detect_data d = {
|
||||
.msg = msg,
|
||||
};
|
||||
|
||||
if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
|
||||
LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
|
||||
rsl_or_ipac_msg_name(dh->c.msg_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
|
||||
d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
|
||||
|
||||
if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
|
||||
LOGP(DRSL, LOGL_ERROR, "%s TALKER DETECTION but no VGCS channel\n",
|
||||
gsm_lchan_name(msg->lchan));
|
||||
return 0;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DET, &d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Chapter 8.4.22: LISTENER DETECTION */
|
||||
static int rsl_rx_listener_det(struct msgb *msg)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
struct tlv_parsed tp;
|
||||
/* We use this struct, because it has same data. */
|
||||
struct handover_rr_detect_data d = {
|
||||
.msg = msg,
|
||||
};
|
||||
|
||||
if (rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg) - sizeof(*dh)) < 0) {
|
||||
LOG_LCHAN(msg->lchan, LOGL_ERROR, "Failed to parse RSL %s\n",
|
||||
rsl_or_ipac_msg_name(dh->c.msg_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (TLVP_PRESENT(&tp, RSL_IE_ACCESS_DELAY))
|
||||
d.access_delay = TLVP_VAL(&tp, RSL_IE_ACCESS_DELAY);
|
||||
|
||||
if (!msg->lchan->conn || !msg->lchan->conn->vgcs_chan.fi) {
|
||||
LOGP(DRSL, LOGL_ERROR, "%s LISTENER DETECTION but no VGCS channel\n",
|
||||
gsm_lchan_name(msg->lchan));
|
||||
return 0;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_LISTENER_DET, &d);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rsl_rx_ipacc_pdch(struct msgb *msg, char *name, uint32_t ts_ev)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = msg->lchan->ts;
|
||||
|
@ -1532,6 +1665,10 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
|||
|
||||
switch (rslh->c.msg_type) {
|
||||
case RSL_MT_CHAN_ACTIV_ACK:
|
||||
/* Ignore acknowlegement of channel reactivation, if a VGCS/VBS channel was reactivated to assign
|
||||
* the calling subscriber to it. */
|
||||
if (msg->lchan->conn && msg->lchan->conn->assignment.req.vgcs)
|
||||
break;
|
||||
if (msg_for_osmocom_dyn_ts(msg))
|
||||
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_ACT_ACK, NULL);
|
||||
else {
|
||||
|
@ -1551,6 +1688,12 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
|||
case RSL_MT_HANDO_DET:
|
||||
rc = rsl_rx_hando_det(msg);
|
||||
break;
|
||||
case RSL_MT_TALKER_DET:
|
||||
rc = rsl_rx_talker_det(msg);
|
||||
break;
|
||||
case RSL_MT_LISTENER_DET:
|
||||
rc = rsl_rx_listener_det(msg);
|
||||
break;
|
||||
case RSL_MT_RF_CHAN_REL_ACK:
|
||||
if (msg_for_osmocom_dyn_ts(msg))
|
||||
osmo_fsm_inst_dispatch(msg->lchan->ts->fi, TS_EV_PDCH_DEACT_ACK, NULL);
|
||||
|
@ -1581,8 +1724,6 @@ static int abis_rsl_rx_dchan(struct msgb *msg)
|
|||
break;
|
||||
case RSL_MT_PHY_CONTEXT_CONF:
|
||||
case RSL_MT_PREPROC_MEAS_RES:
|
||||
case RSL_MT_TALKER_DET:
|
||||
case RSL_MT_LISTENER_DET:
|
||||
case RSL_MT_REMOTE_CODEC_CONF_REP:
|
||||
case RSL_MT_MR_CODEC_MOD_ACK:
|
||||
case RSL_MT_MR_CODEC_MOD_NACK:
|
||||
|
@ -1834,7 +1975,6 @@ static int rsl_rx_pchan_rqd(struct chan_rqd *rqd)
|
|||
* requests from the queue to prevent the queue from growing indefinetly. */
|
||||
static void reduce_rach_dos(struct gsm_bts *bts)
|
||||
{
|
||||
int rlt = gsm_bts_get_radio_link_timeout(bts);
|
||||
time_t timestamp_current = time(NULL);
|
||||
struct chan_rqd *rqd;
|
||||
struct chan_rqd *rqd_tmp;
|
||||
|
@ -1842,9 +1982,9 @@ static void reduce_rach_dos(struct gsm_bts *bts)
|
|||
|
||||
/* Drop all expired channel requests in the list */
|
||||
llist_for_each_entry_safe(rqd, rqd_tmp, &bts->chan_rqd_queue, entry) {
|
||||
/* If the channel request is older than the radio link timeout we drop it. This also means that the
|
||||
/* If the channel request is older than the rach expiry timeout we drop it. This also means that the
|
||||
* queue is under its overflow limit again. */
|
||||
if (timestamp_current - rqd->timestamp > rlt) {
|
||||
if (timestamp_current - rqd->timestamp > bts->rach_expiry_timeout) {
|
||||
LOG_BTS(bts, DRSL, LOGL_INFO, "CHAN RQD: tossing expired channel request"
|
||||
"(ra=0x%02x, neci=0x%02x, chreq_reason=0x%02x)\n",
|
||||
rqd->ref.ra, bts->network->neci, rqd->reason);
|
||||
|
@ -2025,12 +2165,12 @@ static bool force_free_lchan_for_emergency(struct chan_rqd *rqd)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* No free TCH/F or TCH/H was found, we now select one of the busy lchans and initate a release on that lchan.
|
||||
* This will take a short amount of time. We need to come back and check regulary to see if we managed to
|
||||
/* No free TCH/F or TCH/H was found, we now select one of the busy lchans and initiate a release on that lchan.
|
||||
* This will take a short amount of time. We need to come back and check regularly to see if we managed to
|
||||
* free up another lchan. */
|
||||
if (!rqd->release_lchan) {
|
||||
struct gsm_lchan *release_lchan;
|
||||
/* Pick any busy TCH/F or TCH/H lchan and inititate a channel
|
||||
/* Pick any busy TCH/F or TCH/H lchan and initiate a channel
|
||||
* release to make room for the incoming emergency call */
|
||||
rqd->release_lchan = release_lchan = get_any_lchan(rqd->bts);
|
||||
if (!release_lchan) {
|
||||
|
@ -2325,7 +2465,7 @@ int rsl_tx_imm_assignment(struct gsm_lchan *lchan)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* current load on the CCCH */
|
||||
/* 5.4 and 8.5.2 Rx CCCH Load Ind */
|
||||
static int rsl_rx_ccch_load(struct msgb *msg)
|
||||
{
|
||||
struct e1inp_sign_link *sign_link = msg->dst;
|
||||
|
@ -2340,10 +2480,9 @@ static int rsl_rx_ccch_load(struct msgb *msg)
|
|||
switch (rslh->data[0]) {
|
||||
case RSL_IE_PAGING_LOAD:
|
||||
sd.pg_buf_space = rslh->data[1] << 8 | rslh->data[2];
|
||||
if (is_ipaccess_bts(sign_link->trx->bts) && sd.pg_buf_space == UINT16_MAX) {
|
||||
if (is_ipa_abisip_bts(sd.bts) && sd.pg_buf_space == UINT16_MAX) {
|
||||
sd.pg_buf_space = paging_estimate_available_slots(sd.bts, sd.bts->ccch_load_ind_period);
|
||||
}
|
||||
paging_update_buffer_space(sign_link->trx->bts, sd.pg_buf_space);
|
||||
osmo_signal_dispatch(SS_CCCH, S_CCCH_PAGING_LOAD, &sd);
|
||||
break;
|
||||
case RSL_IE_RACH_LOAD:
|
||||
|
@ -2415,7 +2554,7 @@ static int rsl_rx_ericsson_imm_assign_sent(struct msgb *msg)
|
|||
{
|
||||
struct e1inp_sign_link *sign_link = msg->dst;
|
||||
struct abis_rsl_dchan_hdr *dh = msgb_l2(msg);
|
||||
uint32_t tlli;
|
||||
uint32_t msg_id;
|
||||
|
||||
LOGP(DRSL, LOGL_INFO, "IMM.ass sent\n");
|
||||
msgb_pull(msg, sizeof(*dh));
|
||||
|
@ -2427,8 +2566,8 @@ static int rsl_rx_ericsson_imm_assign_sent(struct msgb *msg)
|
|||
LOGP(DRSL, LOGL_ERROR, "unsupported IMM.ass message format! (please fix)\n");
|
||||
else {
|
||||
msgb_pull(msg, 1); /* drop previous data to use msg_pull_u32 */
|
||||
tlli = msgb_pull_u32(msg);
|
||||
pcu_tx_imm_ass_sent(sign_link->trx->bts, tlli);
|
||||
msg_id = msgb_pull_u32(msg);
|
||||
pcu_tx_data_cnf(sign_link->trx->bts, msg_id, PCU_IF_SAPI_PCH_2);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -2503,6 +2642,13 @@ static int rsl_rx_rll_err_ind(struct msgb *msg)
|
|||
|
||||
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ERR_IND, &rlm_cause);
|
||||
|
||||
/* Report to VGCS FSM */
|
||||
if (lchan_is_asci(msg->lchan)) {
|
||||
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
|
||||
uint8_t cause = GSM0808_CAUSE_RADIO_INTERFACE_FAILURE;
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_FAIL, &cause);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2530,10 +2676,17 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
switch (rllh->c.msg_type) {
|
||||
case RSL_MT_DATA_IND:
|
||||
LOG_LCHAN(msg->lchan, LOGL_DEBUG, "SAPI=%u DATA INDICATION\n", sapi);
|
||||
if (msgb_l2len(msg) >
|
||||
sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
|
||||
|
||||
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
|
||||
rllh->data[0] == RSL_IE_L3_INFO) {
|
||||
msg->l3h = &rllh->data[3];
|
||||
/* Data message on a VGCS channel is handled by VGCS FSM only. */
|
||||
if (lchan_is_asci(msg->lchan)) {
|
||||
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_DATA,
|
||||
msg);
|
||||
return 0;
|
||||
}
|
||||
return gsm0408_rcvmsg(msg, rllh->link_id);
|
||||
}
|
||||
break;
|
||||
|
@ -2573,8 +2726,14 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
msg->lchan->sapis[sapi] = LCHAN_SAPI_MS;
|
||||
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_ESTABLISH_IND, msg);
|
||||
|
||||
if (msgb_l2len(msg) >
|
||||
sizeof(struct abis_rsl_common_hdr) + sizeof(*rllh) &&
|
||||
/* Establishment message on a VGCS channel is handled by VGCS FSM only. */
|
||||
if (lchan_is_asci(msg->lchan)) {
|
||||
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi)
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_EST, msg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (msgb_l2len(msg) > (sizeof(*rllh) + 3) &&
|
||||
rllh->data[0] == RSL_IE_L3_INFO) {
|
||||
msg->l3h = &rllh->data[3];
|
||||
return gsm0408_rcvmsg(msg, rllh->link_id);
|
||||
|
@ -2589,6 +2748,14 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
case RSL_MT_REL_IND:
|
||||
/* BTS informs us of having received DISC from MS */
|
||||
osmo_fsm_inst_dispatch(msg->lchan->fi, LCHAN_EV_RLL_REL_IND, &rllh->link_id);
|
||||
|
||||
/* Report to VGCS FSM */
|
||||
if (lchan_is_asci(msg->lchan)) {
|
||||
if (msg->lchan->conn && msg->lchan->conn->vgcs_chan.fi) {
|
||||
uint8_t cause = GSM0808_CAUSE_CALL_CONTROL;
|
||||
osmo_fsm_inst_dispatch(msg->lchan->conn->vgcs_chan.fi, VGCS_EV_TALKER_REL, &cause);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RSL_MT_REL_CONF:
|
||||
/* BTS informs us of having received UA from MS,
|
||||
|
@ -2611,6 +2778,68 @@ static int abis_rsl_rx_rll(struct msgb *msg)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Return an ip.access RTP CSD FMT value (uint8_t) or negative on error. */
|
||||
int ipacc_rtp_csd_fmt_transp(const struct channel_mode_and_rate *ch_mode_rate,
|
||||
const enum rsl_ipac_rtp_csd_format_d format_d)
|
||||
{
|
||||
uint8_t ret = format_d;
|
||||
|
||||
switch (ch_mode_rate->data_rate.t) {
|
||||
case RSL_CMOD_CSD_T_32k0:
|
||||
case RSL_CMOD_CSD_T_29k0:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_32k << 4;
|
||||
break;
|
||||
case RSL_CMOD_CSD_T_14k4:
|
||||
case RSL_CMOD_CSD_T_9k6:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_16k << 4;
|
||||
break;
|
||||
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:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_8k << 4;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return an ip.access RTP CSD FMT value (uint8_t) or negative on error. */
|
||||
int ipacc_rtp_csd_fmt_non_transp(const struct channel_mode_and_rate *ch_mode_rate,
|
||||
const enum rsl_ipac_rtp_csd_format_d format_d)
|
||||
{
|
||||
uint8_t ret = format_d;
|
||||
|
||||
switch (ch_mode_rate->data_rate.nt) {
|
||||
case RSL_CMOD_CSD_NTA_43k5_14k5:
|
||||
case RSL_CMOD_CSD_NTA_43k5_29k0:
|
||||
case RSL_CMOD_CSD_NTA_14k5_43k5:
|
||||
case RSL_CMOD_CSD_NTA_29k0_43k5:
|
||||
case RSL_CMOD_CSD_NT_43k5:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_64k << 4;
|
||||
break;
|
||||
case RSL_CMOD_CSD_NTA_29k0_14k5:
|
||||
case RSL_CMOD_CSD_NTA_14k5_29k0:
|
||||
case RSL_CMOD_CSD_NT_28k8:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_32k << 4;
|
||||
break;
|
||||
case RSL_CMOD_CSD_NT_14k5:
|
||||
case RSL_CMOD_CSD_NT_12k0:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_16k << 4;
|
||||
break;
|
||||
case RSL_CMOD_CSD_NT_6k0:
|
||||
ret |= RSL_IPAC_RTP_CSD_IR_8k << 4;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Return an ip.access BTS speech mode value (uint8_t) or negative on error. */
|
||||
int ipacc_speech_mode(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type)
|
||||
{
|
||||
|
@ -2663,6 +2892,11 @@ void ipacc_speech_mode_set_direction(uint8_t *speech_mode, bool send)
|
|||
int ipacc_payload_type(enum gsm48_chan_mode tch_mode, enum gsm_chan_t type)
|
||||
{
|
||||
switch (gsm48_chan_mode_to_non_vamos(tch_mode)) {
|
||||
case GSM48_CMODE_DATA_14k5:
|
||||
case GSM48_CMODE_DATA_12k0:
|
||||
case GSM48_CMODE_DATA_6k0:
|
||||
case GSM48_CMODE_DATA_3k6:
|
||||
return RTP_PT_CSDATA;
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
switch (type) {
|
||||
case GSM_LCHAN_TCH_F:
|
||||
|
@ -2778,16 +3012,27 @@ int rsl_tx_ipacc_crcx(const struct gsm_lchan *lchan)
|
|||
dh->c.msg_discr = ABIS_RSL_MDISC_IPACCESS;
|
||||
dh->chan_nr = chan_nr;
|
||||
|
||||
/* 0x1- == receive-only, 0x-1 == EFR codec */
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
|
||||
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA) {
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_CSD_FMT, lchan->abis_ip.rtp_csd_fmt);
|
||||
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG,
|
||||
"Sending IPACC CRCX to BTS: rtp_csd_fmt=0x%02x RTP_PAYLOAD=%d (CSD) osmux_use=%d osmux_loc_cid=%d\n",
|
||||
lchan->abis_ip.rtp_csd_fmt, lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
|
||||
} else {
|
||||
/* 0x1- == receive-only, 0x-1 == EFR codec */
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
|
||||
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG,
|
||||
"Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d osmux_use=%d osmux_loc_cid=%d\n",
|
||||
lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
|
||||
}
|
||||
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
|
||||
if (lchan->abis_ip.osmux.use)
|
||||
msgb_tlv_put(msg, RSL_IE_OSMO_OSMUX_CID, 1, &lchan->abis_ip.osmux.local_cid);
|
||||
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG,
|
||||
"Sending IPACC CRCX to BTS: speech_mode=0x%02x RTP_PAYLOAD=%d osmux_use=%d osmux_loc_cid=%d\n",
|
||||
lchan->abis_ip.speech_mode, lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.osmux.use, lchan->abis_ip.osmux.local_cid);
|
||||
|
||||
msg->dst = rsl_chan_link(lchan);
|
||||
|
||||
|
@ -2821,7 +3066,12 @@ struct msgb *rsl_make_ipacc_mdcx(const struct gsm_lchan *lchan, uint32_t dest_ip
|
|||
att_ip = (uint32_t *)msgb_put(msg, sizeof(uint32_t));
|
||||
*att_ip = htonl(dest_ip);
|
||||
msgb_tv16_put(msg, RSL_IE_IPAC_REMOTE_PORT, dest_port);
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
|
||||
|
||||
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA)
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_CSD_FMT, lchan->abis_ip.rtp_csd_fmt);
|
||||
else
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_SPEECH_MODE, lchan->abis_ip.speech_mode);
|
||||
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD, lchan->abis_ip.rtp_payload);
|
||||
if (lchan->abis_ip.rtp_payload2)
|
||||
msgb_tv_put(msg, RSL_IE_IPAC_RTP_PAYLOAD2, lchan->abis_ip.rtp_payload2);
|
||||
|
@ -2844,14 +3094,24 @@ int rsl_tx_ipacc_mdcx(const struct gsm_lchan *lchan)
|
|||
if (!msg)
|
||||
return -EINVAL;
|
||||
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
|
||||
" %s:%u rtp_payload=%u rtp_payload2=%u conn_id=%u speech_mode=0x%02x\n",
|
||||
ip_to_a(lchan->abis_ip.connect_ip),
|
||||
lchan->abis_ip.connect_port,
|
||||
lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.rtp_payload2,
|
||||
lchan->abis_ip.conn_id,
|
||||
lchan->abis_ip.speech_mode);
|
||||
if (lchan->current_ch_indctr == GSM0808_CHAN_DATA)
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
|
||||
" %s:%u rtp_payload=%u (CSD) rtp_payload2=%u conn_id=%u rtp_csd_fmt=0x%02x\n",
|
||||
ip_to_a(lchan->abis_ip.connect_ip),
|
||||
lchan->abis_ip.connect_port,
|
||||
lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.rtp_payload2,
|
||||
lchan->abis_ip.conn_id,
|
||||
lchan->abis_ip.rtp_csd_fmt);
|
||||
else
|
||||
LOG_LCHAN(lchan, LOGL_DEBUG, "Sending IPACC MDCX to BTS:"
|
||||
" %s:%u rtp_payload=%u rtp_payload2=%u conn_id=%u speech_mode=0x%02x\n",
|
||||
ip_to_a(lchan->abis_ip.connect_ip),
|
||||
lchan->abis_ip.connect_port,
|
||||
lchan->abis_ip.rtp_payload,
|
||||
lchan->abis_ip.rtp_payload2,
|
||||
lchan->abis_ip.conn_id,
|
||||
lchan->abis_ip.speech_mode);
|
||||
|
||||
return abis_rsl_sendmsg(msg);
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
static struct osmo_fsm assignment_fsm;
|
||||
|
||||
struct gsm_subscriber_connection *assignment_fi_conn(struct osmo_fsm_inst *fi)
|
||||
static struct gsm_subscriber_connection *assignment_fi_conn(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
OSMO_ASSERT(fi);
|
||||
OSMO_ASSERT(fi->fsm == &assignment_fsm);
|
||||
|
@ -54,7 +54,7 @@ static const struct osmo_tdef_state_timeout assignment_fsm_timeouts[32] = {
|
|||
[ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE] = { .T = 10 },
|
||||
[ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE] = { .keep_timer = true },
|
||||
[ASSIGNMENT_ST_WAIT_LCHAN_ESTABLISHED] = { .keep_timer = true },
|
||||
[ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = 23042 },
|
||||
[ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC] = { .T = -9 },
|
||||
};
|
||||
|
||||
/* Transition to a state, using the T timer defined in assignment_fsm_timeouts.
|
||||
|
@ -152,7 +152,8 @@ static void on_assignment_failure(struct gsm_subscriber_connection *conn)
|
|||
if (!resp) {
|
||||
LOG_ASSIGNMENT(conn, LOGL_ERROR, "Unable to compose BSSMAP Assignment Failure message\n");
|
||||
} else {
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE));
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs,
|
||||
MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_FAILURE));
|
||||
gscon_sigtran_send(conn, resp);
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +165,7 @@ static void on_assignment_failure(struct gsm_subscriber_connection *conn)
|
|||
}
|
||||
}
|
||||
|
||||
static void _gsm0808_ass_compl_extend_osmux(struct msgb *msg, uint8_t cid)
|
||||
void bssap_extend_osmux(struct msgb *msg, uint8_t cid)
|
||||
{
|
||||
OSMO_ASSERT(msg->l3h[1] == msgb_l3len(msg) - 2); /*TL not in len */
|
||||
msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid);
|
||||
|
@ -185,6 +186,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
|||
struct gsm_lchan *lchan = conn->lchan;
|
||||
struct osmo_fsm_inst *fi = conn->fi;
|
||||
|
||||
if (!lchan) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE, "Assignment interrupted: primary lchan lost");
|
||||
return;
|
||||
}
|
||||
|
||||
chosen_channel = gsm0808_chosen_channel(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
||||
if (!chosen_channel) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
|
||||
|
@ -194,21 +200,26 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Generate voice related fields */
|
||||
if (conn->assignment.requires_voice_stream) {
|
||||
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr)) {
|
||||
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(conn->user_plane.mgw_endpoint_ci_msc,
|
||||
&addr_local)) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
|
||||
"Unable to compose RTP address of MGW -> MSC");
|
||||
return;
|
||||
}
|
||||
addr_local_p = &addr_local;
|
||||
}
|
||||
|
||||
/* Generate rtp related fields */
|
||||
switch (conn->assignment.ch_indctr) {
|
||||
case GSM0808_CHAN_SPEECH:
|
||||
perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode);
|
||||
|
||||
if (gscon_is_aoip(conn)) {
|
||||
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(conn->user_plane.mgw_endpoint_ci_msc,
|
||||
&addr_local)) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
|
||||
"Unable to compose RTP address of MGW -> MSC");
|
||||
return;
|
||||
}
|
||||
addr_local_p = &addr_local;
|
||||
}
|
||||
/* below is AoIP specific logic */
|
||||
if (!gscon_is_aoip(conn))
|
||||
break;
|
||||
|
||||
if (gscon_is_aoip(conn) && conn->assignment.req.use_osmux) {
|
||||
if (conn->assignment.req.use_osmux) {
|
||||
if (!osmo_mgcpc_ep_ci_get_crcx_info_to_osmux_cid(conn->user_plane.mgw_endpoint_ci_msc,
|
||||
&osmux_cid)) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
|
||||
|
@ -217,14 +228,28 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
|||
}
|
||||
}
|
||||
|
||||
/* Only AoIP networks include a speech codec (choosen) in the
|
||||
* assignment complete message. */
|
||||
if (gscon_is_aoip(conn)) {
|
||||
/* Extrapolate speech codec from speech mode */
|
||||
gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
|
||||
sc.cfg = conn->lchan->current_ch_mode_rate.s15_s0;
|
||||
sc_ptr = ≻
|
||||
}
|
||||
/* Extrapolate speech codec from speech mode */
|
||||
gsm0808_speech_codec_from_chan_type(&sc, perm_spch);
|
||||
sc.cfg = conn->lchan->current_ch_mode_rate.s15_s0;
|
||||
sc_ptr = ≻
|
||||
break;
|
||||
case GSM0808_CHAN_DATA:
|
||||
/* below is AoIP specific logic */
|
||||
if (!gscon_is_aoip(conn))
|
||||
break;
|
||||
|
||||
/* The coding of Speech Codec Element for the CSData Codec Type
|
||||
* is defined in 3GPP TS 48.008 section 3.2.2.103 */
|
||||
sc = (struct gsm0808_speech_codec) {
|
||||
.pi = true, /* PI indicates CSDoIP support */
|
||||
.pt = false, /* PT indicates CSDoTDM support */
|
||||
.type = GSM0808_SCT_CSD,
|
||||
.cfg = 0, /* R2/R3 not set (redundancy not supported) */
|
||||
};
|
||||
sc_ptr = ≻
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
resp = gsm0808_create_ass_compl2(lchan->abis_ip.ass_compl.rr_cause,
|
||||
|
@ -238,11 +263,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
if (gscon_is_aoip(conn) && conn->assignment.requires_voice_stream &&
|
||||
if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr) &&
|
||||
conn->assignment.req.use_osmux)
|
||||
_gsm0808_ass_compl_extend_osmux(resp, osmux_cid);
|
||||
bssap_extend_osmux(resp, osmux_cid);
|
||||
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE));
|
||||
rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_COMPLETE));
|
||||
rc = gscon_sigtran_send(conn, resp);
|
||||
if (rc) {
|
||||
assignment_fail(GSM0808_CAUSE_EQUIPMENT_FAILURE,
|
||||
|
@ -255,9 +280,11 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn)
|
|||
static void assignment_success(struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
struct gsm_bts *bts;
|
||||
bool lchan_changed = (conn->assignment.new_lchan != NULL);
|
||||
bool lchan_changed = (conn->assignment.new_lchan != NULL && !conn->assignment.req.vgcs);
|
||||
|
||||
/* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on. */
|
||||
/* Take on the new lchan. If there only was a Channel Mode Modify, then there is no new lchan to take on.
|
||||
* In case of VGCS/VBS channel, the assignment is handled by its state machine. This subscriber connection will
|
||||
* be released by MSC. */
|
||||
if (lchan_changed) {
|
||||
gscon_change_primary_lchan(conn, conn->assignment.new_lchan);
|
||||
|
||||
|
@ -303,7 +330,7 @@ static void assignment_success(struct gsm_subscriber_connection *conn)
|
|||
osmo_fsm_inst_term(conn->assignment.fi, OSMO_FSM_TERM_REGULAR, 0);
|
||||
}
|
||||
|
||||
static void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
|
||||
void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
/* Assignment can do a new channel activation, in which case new_lchan points at the new lchan.
|
||||
* Or assignment can Channel Mode Modify the already used lchan, in which case new_lchan == NULL. */
|
||||
|
@ -313,15 +340,16 @@ static void assignment_fsm_update_id(struct gsm_subscriber_connection *conn)
|
|||
return;
|
||||
}
|
||||
|
||||
osmo_fsm_inst_update_id_f(conn->assignment.fi, "%s_%u-%u-%u-%s%s%s-%s%u",
|
||||
conn->fi->id,
|
||||
new_lchan->ts->trx->bts->nr, new_lchan->ts->trx->nr, new_lchan->ts->nr,
|
||||
gsm_pchan_id(new_lchan->ts->pchan_on_init),
|
||||
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is)? "" : "as",
|
||||
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is)? ""
|
||||
: gsm_pchan_id(new_lchan->ts->pchan_is),
|
||||
new_lchan->vamos.is_secondary ? "shadow" : "",
|
||||
new_lchan->nr - (new_lchan->vamos.is_secondary ? new_lchan->ts->max_primary_lchans : 0));
|
||||
osmo_fsm_inst_update_id_f_sanitize(conn->assignment.fi, '_', "%s_%u-%u-%u-%s%s%s-%s%u",
|
||||
conn->fi->id,
|
||||
new_lchan->ts->trx->bts->nr, new_lchan->ts->trx->nr, new_lchan->ts->nr,
|
||||
gsm_pchan_name(new_lchan->ts->pchan_on_init),
|
||||
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is) ? "" : "as",
|
||||
(new_lchan->ts->pchan_on_init == new_lchan->ts->pchan_is) ?
|
||||
"" : gsm_pchan_name(new_lchan->ts->pchan_is),
|
||||
new_lchan->vamos.is_secondary ? "shadow" : "",
|
||||
new_lchan->nr - (new_lchan->vamos.is_secondary ?
|
||||
new_lchan->ts->max_primary_lchans : 0));
|
||||
}
|
||||
|
||||
static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct channel_mode_and_rate *ch_mode_rate)
|
||||
|
@ -364,48 +392,42 @@ static bool lchan_type_compat_with_mode(enum gsm_chan_t type, const struct chann
|
|||
}
|
||||
}
|
||||
|
||||
void assignment_fsm_init(void)
|
||||
static __attribute__((constructor)) void assignment_fsm_init(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&assignment_fsm) == 0);
|
||||
}
|
||||
|
||||
static int check_requires_voice(bool *requires_voice, enum gsm48_chan_mode chan_mode)
|
||||
static int chan_mode_to_ch_indctr(enum gsm48_chan_mode chan_mode)
|
||||
{
|
||||
*requires_voice = false;
|
||||
|
||||
switch (gsm48_chan_mode_to_non_vamos(chan_mode)) {
|
||||
case GSM48_CMODE_DATA_14k5:
|
||||
case GSM48_CMODE_DATA_12k0:
|
||||
case GSM48_CMODE_DATA_6k0:
|
||||
case GSM48_CMODE_DATA_3k6:
|
||||
return GSM0808_CHAN_DATA;
|
||||
case GSM48_CMODE_SPEECH_V1:
|
||||
case GSM48_CMODE_SPEECH_EFR:
|
||||
case GSM48_CMODE_SPEECH_AMR:
|
||||
*requires_voice = true;
|
||||
break;
|
||||
return GSM0808_CHAN_SPEECH;
|
||||
case GSM48_CMODE_SIGN:
|
||||
*requires_voice = false;
|
||||
break;
|
||||
return GSM0808_CHAN_SIGN;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if the incoming assignment requests requires a voice stream or not,
|
||||
* we will look at the preferred and the alternate channel mode and also make
|
||||
* sure that both are consistent. */
|
||||
static int check_requires_voice_stream(struct gsm_subscriber_connection *conn)
|
||||
/* Check if the incoming assignment request has a channel mode that is
|
||||
* inconsistent with ch_indctr, e.g. GSM48_CMODE_DATA_14k5 and
|
||||
* GSM0808_CHAN_SPEECH */
|
||||
static int check_chan_mode_rate_against_ch_indctr(struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
bool requires_voice_pref = false, requires_voice_alt;
|
||||
struct assignment_request *req = &conn->assignment.req;
|
||||
struct osmo_fsm_inst *fi = conn->fi;
|
||||
int i, rc;
|
||||
|
||||
/* When the assignment request indicates that there is an alternate
|
||||
* rate available (e.g. "Full or Half rate channel, Half rate
|
||||
* preferred..."), then both must be either voice or either signalling,
|
||||
* a mismatch is not permitted */
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
for (i = 0; i < req->n_ch_mode_rate; i++) {
|
||||
rc = check_requires_voice(&requires_voice_alt, req->ch_mode_rate_list[i].chan_mode);
|
||||
rc = chan_mode_to_ch_indctr(req->ch_mode_rate_list[i].chan_mode);
|
||||
if (rc < 0) {
|
||||
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
|
||||
"Channel mode not supported (prev level %d): %s", i,
|
||||
|
@ -413,18 +435,15 @@ static int check_requires_voice_stream(struct gsm_subscriber_connection *conn)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (i==0)
|
||||
requires_voice_pref = requires_voice_alt;
|
||||
else if (requires_voice_alt != requires_voice_pref) {
|
||||
if (rc != req->ch_indctr) {
|
||||
assignment_fail(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP,
|
||||
"Requested a mix of Signalling and non-Signalling channel modes: %s != %s",
|
||||
gsm48_chan_mode_name(req->ch_mode_rate_list[0].chan_mode),
|
||||
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode));
|
||||
"Channel mode %s has ch_indctr %d, channel type has ch_indctr %d",
|
||||
gsm48_chan_mode_name(req->ch_mode_rate_list[i].chan_mode),
|
||||
rc, req->ch_indctr);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
conn->assignment.requires_voice_stream = requires_voice_pref;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -470,6 +489,8 @@ static int _reassignment_request(enum assign_for assign_for, struct gsm_lchan *l
|
|||
.present = (tsc >= 0),
|
||||
.val = tsc,
|
||||
},
|
||||
|
||||
.ch_indctr = chan_mode_to_ch_indctr(lchan->current_ch_mode_rate.chan_mode),
|
||||
};
|
||||
|
||||
if (to_lchan)
|
||||
|
@ -528,10 +549,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
|
|||
|
||||
assignment_count(CTR_ASSIGNMENT_ATTEMPTED);
|
||||
|
||||
/* Check if we need a voice stream. If yes, set the appropriate struct
|
||||
* members in conn */
|
||||
if (check_requires_voice_stream(conn) < 0)
|
||||
if (check_chan_mode_rate_against_ch_indctr(conn) < 0)
|
||||
return;
|
||||
conn->assignment.ch_indctr = req->ch_indctr;
|
||||
|
||||
if (!req->target_lchan && reuse_existing_lchan(conn)) {
|
||||
/* The already existing lchan is suitable for this mode */
|
||||
|
@ -570,7 +590,10 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
|
|||
return;
|
||||
}
|
||||
|
||||
if (req->target_lchan) {
|
||||
if (req->vgcs) {
|
||||
/* When assigning to a VGCS/VBS, the target lchan is already defined. */
|
||||
conn->assignment.new_lchan = req->target_lchan;
|
||||
} else if (req->target_lchan) {
|
||||
bool matching_mode;
|
||||
|
||||
/* The caller already picked a target lchan to assign to. No need to try re-using the current lchan or
|
||||
|
@ -644,7 +667,9 @@ void assignment_fsm_start(struct gsm_subscriber_connection *conn, struct gsm_bts
|
|||
req->aoip ? "yes" : "no", req->msc_rtp_addr, req->msc_rtp_port,
|
||||
req->use_osmux ? "yes" : "no");
|
||||
|
||||
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
|
||||
/* Wait for lchan to become active before send assignment. In case of VGCS/VBS directly send assignment,
|
||||
* because the channel is already active. */
|
||||
assignment_fsm_state_chg(req->vgcs ? ASSIGNMENT_ST_WAIT_RR_ASS_COMPLETE : ASSIGNMENT_ST_WAIT_LCHAN_ACTIVE);
|
||||
}
|
||||
|
||||
static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
|
||||
|
@ -656,15 +681,16 @@ static void assignment_fsm_wait_lchan_active_onenter(struct osmo_fsm_inst *fi, u
|
|||
.for_conn = conn,
|
||||
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
||||
.encr = conn->lchan->encr,
|
||||
.requires_voice_stream = conn->assignment.requires_voice_stream,
|
||||
.ch_indctr = conn->assignment.ch_indctr,
|
||||
.msc_assigned_cic = req->msc_assigned_cic,
|
||||
.re_use_mgw_endpoint_from_lchan = conn->lchan,
|
||||
.ta = conn->lchan->last_ta,
|
||||
.ta_known = true,
|
||||
.tsc_set = req->tsc_set,
|
||||
.tsc = req->tsc,
|
||||
.vamos = conn->assignment.new_lchan->vamos.is_secondary,
|
||||
};
|
||||
if (conn->assignment.new_lchan->vamos.is_secondary)
|
||||
activ_info.type_for = LCHAN_TYPE_FOR_VAMOS;
|
||||
lchan_activate(conn->assignment.new_lchan, &activ_info);
|
||||
}
|
||||
|
||||
|
@ -772,7 +798,7 @@ static void assignment_fsm_wait_lchan_established(struct osmo_fsm_inst *fi, uint
|
|||
static void assignment_fsm_post_lchan_established(struct osmo_fsm_inst *fi)
|
||||
{
|
||||
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
||||
if (conn->assignment.requires_voice_stream)
|
||||
if (bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr))
|
||||
assignment_fsm_state_chg(ASSIGNMENT_ST_WAIT_MGW_ENDPOINT_TO_MSC);
|
||||
else
|
||||
assignment_success(conn);
|
||||
|
@ -782,7 +808,7 @@ static void assignment_fsm_wait_mgw_endpoint_to_msc_onenter(struct osmo_fsm_inst
|
|||
{
|
||||
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
||||
|
||||
OSMO_ASSERT(conn->assignment.requires_voice_stream);
|
||||
OSMO_ASSERT(bsc_chan_ind_requires_rtp_stream(conn->assignment.ch_indctr));
|
||||
|
||||
LOG_ASSIGNMENT(conn, LOGL_DEBUG,
|
||||
"Connecting MGW endpoint to the MSC's RTP port: %s:%u\n",
|
||||
|
@ -846,7 +872,7 @@ static void assignment_fsm_wait_lchan_modified_onenter(struct osmo_fsm_inst *fi,
|
|||
struct lchan_modify_info modif_info = {
|
||||
.modify_for = MODIFY_FOR_ASSIGNMENT,
|
||||
.ch_mode_rate = conn->assignment.selected_ch_mode_rate,
|
||||
.requires_voice_stream = conn->assignment.requires_voice_stream,
|
||||
.ch_indctr = conn->assignment.ch_indctr,
|
||||
.msc_assigned_cic = req->msc_assigned_cic,
|
||||
/* keep previous training sequence code. TSC is always present, TSC Set may or may not be an explicit
|
||||
* value. */
|
||||
|
@ -987,7 +1013,7 @@ static int assignment_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void assignment_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
|
||||
static void assignment_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
|
||||
{
|
||||
struct gsm_subscriber_connection *conn = assignment_fi_conn(fi);
|
||||
assignment_reset(conn);
|
||||
|
|
|
@ -187,7 +187,7 @@ static int set_net_apply_config(struct ctrl_cmd *cmd, void *data)
|
|||
struct gsm_bts *bts;
|
||||
|
||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||
if (!is_ipaccess_bts(bts))
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -332,7 +332,7 @@ static int set_net_rf_lock(struct ctrl_cmd *cmd, void *data)
|
|||
|
||||
cmd->reply = talloc_asprintf(cmd, "%u", locked);
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM.";
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
|
@ -367,7 +367,7 @@ static int get_net_rf_states(struct ctrl_cmd *cmd, void *data)
|
|||
{
|
||||
cmd->reply = bsc_rf_states_c(cmd);
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM.";
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
return CTRL_CMD_REPLY;
|
||||
|
@ -686,7 +686,7 @@ static int sccplite_asp_ctrl_cmd_send(struct osmo_ss7_asp *asp, struct ctrl_cmd
|
|||
struct msgb *msg;
|
||||
|
||||
/* don't attempt to send CTRL on a non-SCCPlite ASP */
|
||||
if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA)
|
||||
if (osmo_ss7_asp_get_proto(asp) != OSMO_SS7_ASP_PROT_IPA)
|
||||
return 0;
|
||||
|
||||
msg = ctrl_cmd_make(cmd);
|
||||
|
@ -820,6 +820,45 @@ static int set_net_inform_msc(struct ctrl_cmd *cmd, void *data)
|
|||
return CTRL_CMD_HANDLED;
|
||||
}
|
||||
|
||||
/* Return full information about all logical channels.
|
||||
* format: show-lchan.full
|
||||
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
|
||||
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
|
||||
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
|
||||
*/
|
||||
static int get_net_show_lchan_full(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_network *net = cmd->node;
|
||||
int bts_nr;
|
||||
bool first_bts = true;
|
||||
char *bts_dump;
|
||||
|
||||
cmd->reply = talloc_strdup(cmd, "");
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {
|
||||
bts_dump = bts_lchan_dump_full_ctrl(cmd, gsm_bts_num(net, bts_nr));
|
||||
if (!bts_dump) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
if (!strlen(bts_dump))
|
||||
continue;
|
||||
cmd->reply = talloc_asprintf_append(cmd->reply, first_bts ? "%s" : "\n%s", bts_dump);
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
first_bts = false;
|
||||
}
|
||||
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
CTRL_CMD_DEFINE_RO(net_show_lchan_full, "show-lchan full");
|
||||
|
||||
static int bsc_base_ctrl_cmds_install(struct gsm_network *net)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -837,8 +876,9 @@ static int bsc_base_ctrl_cmds_install(struct gsm_network *net)
|
|||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_msc0_connection_status);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_notification);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_inform_msc);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_net_show_lchan_full);
|
||||
|
||||
rc = ctrl_cmd_install(CTRL_NODE_MSC, &cmd_msc_connection_status);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_MSC, &cmd_msc_connection_status);
|
||||
|
||||
rc |= osmo_signal_register_handler(SS_L_INPUT, &bts_connection_status_trap_cb, net);
|
||||
rc |= osmo_signal_register_handler(SS_MSC, &msc_connection_status_trap_cb, net);
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -43,6 +43,7 @@ static int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
|||
struct gsm_bts *bts = NULL;
|
||||
struct gsm_bts_trx *trx = NULL;
|
||||
struct gsm_bts_trx_ts *ts = NULL;
|
||||
struct gsm_lchan *lchan = NULL;
|
||||
struct bsc_msc_data *msc = NULL;
|
||||
char *token = vector_slot(vline, *i);
|
||||
long num;
|
||||
|
@ -89,6 +90,20 @@ static int bsc_ctrl_node_lookup(void *data, vector vline, int *node_type,
|
|||
goto err_missing;
|
||||
*node_data = ts;
|
||||
*node_type = CTRL_NODE_TS;
|
||||
} else if (!strcmp(token, "lchan")) {
|
||||
if (*node_type != CTRL_NODE_TS || !*node_data)
|
||||
goto err_missing;
|
||||
ts = *node_data;
|
||||
(*i)++;
|
||||
if (!ctrl_parse_get_num(vline, *i, &num))
|
||||
goto err_index;
|
||||
|
||||
if ((num >= 0) && (num < TS_MAX_LCHAN))
|
||||
lchan = &ts->lchan[num];
|
||||
if (!lchan)
|
||||
goto err_missing;
|
||||
*node_data = lchan;
|
||||
*node_type = CTRL_NODE_LCHAN;
|
||||
} else if (!strcmp(token, "msc")) {
|
||||
if (*node_type != CTRL_NODE_ROOT || !net)
|
||||
goto err_missing;
|
||||
|
|
|
@ -204,6 +204,7 @@ static struct gsm_network *bsc_network_init(void *ctx)
|
|||
net->cbc->client.remote_addr = (struct osmo_sockaddr_str){ .port = CBSP_TCP_PORT, };
|
||||
net->cbc->client.local_addr = (struct osmo_sockaddr_str){};
|
||||
|
||||
net->pcu_sock_wqueue_len_max = BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT;
|
||||
return net;
|
||||
|
||||
err_free_all:
|
||||
|
|
|
@ -303,7 +303,7 @@ static void rf_check_cb(void *_data)
|
|||
struct gsm_bts_trx *trx;
|
||||
|
||||
/* don't bother to check a booting or missing BTS */
|
||||
if (!bts->oml_link || !is_ipaccess_bts(bts))
|
||||
if (!bts->oml_link || !is_ipa_abisip_bts(bts))
|
||||
continue;
|
||||
|
||||
/* Exclude the BTS from the global lock */
|
||||
|
|
|
@ -21,44 +21,120 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <osmocom/core/utils.h>
|
||||
|
||||
#include <osmocom/bsc/gsm_data.h>
|
||||
#include <osmocom/bsc/bsc_msc_data.h>
|
||||
#include <osmocom/bsc/lb.h>
|
||||
|
||||
/* We need an unused SCCP conn_id across all SCCP users. */
|
||||
int bsc_sccp_inst_next_conn_id(struct osmo_sccp_instance *sccp)
|
||||
void bscp_sccp_conn_node_init(struct bscp_sccp_conn_node *sccp_conn, struct gsm_subscriber_connection *gscon)
|
||||
{
|
||||
static uint32_t next_id = 1;
|
||||
int i;
|
||||
|
||||
/* This looks really suboptimal, but in most cases the static next_id should indicate exactly the next unused
|
||||
* conn_id, and we only iterate all conns once to make super sure that it is not already in use. */
|
||||
|
||||
for (i = 0; i < 0xFFFFFF; i++) {
|
||||
struct gsm_subscriber_connection *conn;
|
||||
uint32_t conn_id = next_id;
|
||||
bool conn_id_already_used = false;
|
||||
next_id = (next_id + 1) & 0xffffff;
|
||||
|
||||
llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) {
|
||||
if (conn->sccp.msc && conn->sccp.msc->a.sccp == sccp) {
|
||||
if (conn_id == conn->sccp.conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bsc_gsmnet->smlc->sccp == sccp
|
||||
&& conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE) {
|
||||
if (conn_id == conn->lcs.lb.conn_id) {
|
||||
conn_id_already_used = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!conn_id_already_used)
|
||||
return conn_id;
|
||||
}
|
||||
return -1;
|
||||
sccp_conn->conn_id = SCCP_CONN_ID_UNSET;
|
||||
sccp_conn->gscon = gscon;
|
||||
}
|
||||
|
||||
struct bsc_sccp_inst *bsc_sccp_inst_alloc(void *ctx)
|
||||
{
|
||||
struct bsc_sccp_inst *bsc_sccp;
|
||||
|
||||
bsc_sccp = talloc_zero(ctx, struct bsc_sccp_inst);
|
||||
OSMO_ASSERT(bsc_sccp);
|
||||
bsc_sccp->next_id = 1;
|
||||
|
||||
return bsc_sccp;
|
||||
}
|
||||
|
||||
int bsc_sccp_inst_register_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn)
|
||||
{
|
||||
struct rb_node **n = &(bsc_sccp->connections.rb_node);
|
||||
struct rb_node *parent = NULL;
|
||||
uint32_t conn_id = sccp_conn->conn_id;
|
||||
|
||||
OSMO_ASSERT(conn_id != SCCP_CONN_ID_UNSET);
|
||||
|
||||
while (*n) {
|
||||
struct bscp_sccp_conn_node *it = container_of(*n, struct bscp_sccp_conn_node, node);
|
||||
|
||||
parent = *n;
|
||||
if (conn_id < it->conn_id) {
|
||||
n = &((*n)->rb_left);
|
||||
} else if (conn_id > it->conn_id) {
|
||||
n = &((*n)->rb_right);
|
||||
} else {
|
||||
LOGP(DMSC, LOGL_ERROR,
|
||||
"Trying to reserve already reserved conn_id %u\n", conn_id);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&sccp_conn->node, parent, n);
|
||||
rb_insert_color(&sccp_conn->node, &bsc_sccp->connections);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bsc_sccp_inst_unregister_gscon(struct bsc_sccp_inst *bsc_sccp, struct bscp_sccp_conn_node *sccp_conn)
|
||||
{
|
||||
OSMO_ASSERT(sccp_conn->conn_id != SCCP_CONN_ID_UNSET);
|
||||
rb_erase(&sccp_conn->node, &bsc_sccp->connections);
|
||||
}
|
||||
|
||||
/* Helper function to Check if the given connection id is already assigned */
|
||||
struct gsm_subscriber_connection *bsc_sccp_inst_get_gscon_by_conn_id(const struct bsc_sccp_inst *bsc_sccp, uint32_t conn_id)
|
||||
{
|
||||
const struct rb_node *node = bsc_sccp->connections.rb_node;
|
||||
|
||||
OSMO_ASSERT(conn_id != SCCP_CONN_ID_UNSET);
|
||||
/* Range (0..SCCP_CONN_ID_MAX) expected, see bsc_sccp_inst_next_conn_id() */
|
||||
OSMO_ASSERT(conn_id <= SCCP_CONN_ID_MAX);
|
||||
|
||||
while (node) {
|
||||
struct bscp_sccp_conn_node *sccp_conn = container_of(node, struct bscp_sccp_conn_node, node);
|
||||
if (conn_id < sccp_conn->conn_id)
|
||||
node = node->rb_left;
|
||||
else if (conn_id > sccp_conn->conn_id)
|
||||
node = node->rb_right;
|
||||
else
|
||||
return sccp_conn->gscon;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We need an unused SCCP conn_id across all SCCP users. */
|
||||
uint32_t bsc_sccp_inst_next_conn_id(struct bsc_sccp_inst *bsc_sccp)
|
||||
{
|
||||
uint32_t first_id, test_id;
|
||||
|
||||
first_id = test_id = bsc_sccp->next_id;
|
||||
|
||||
/* SUA: RFC3868 sec 3.10.4:
|
||||
* The source reference number is a 4 octet long integer.
|
||||
* This is allocated by the source SUA instance.
|
||||
* M3UA/SCCP: ITU-T Q.713 sec 3.3:
|
||||
* The "source local reference" parameter field is a three-octet field containing a
|
||||
* reference number which is generated and used by the local node to identify the
|
||||
* connection section after the connection section is set up.
|
||||
* The coding "all ones" is reserved for future use.
|
||||
*Hence, as we currently use the connection ID also as local reference,
|
||||
*let's simply use 24 bit ids to fit all link types (excluding 0x00ffffff).
|
||||
*/
|
||||
|
||||
while (bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, test_id)) {
|
||||
/* Optimized modulo operation (% SCCP_CONN_ID_MAX) using bitwise AND plus CMP: */
|
||||
test_id = (test_id + 1) & 0x00FFFFFF;
|
||||
if (OSMO_UNLIKELY(test_id == 0x00FFFFFF))
|
||||
test_id = 0;
|
||||
|
||||
/* Did a whole loop, all used, fail */
|
||||
if (OSMO_UNLIKELY(test_id == first_id))
|
||||
return SCCP_CONN_ID_UNSET;
|
||||
}
|
||||
|
||||
bsc_sccp->next_id = test_id;
|
||||
/* Optimized modulo operation (% SCCP_CONN_ID_MAX) using bitwise AND plus CMP: */
|
||||
bsc_sccp->next_id = (bsc_sccp->next_id + 1) & 0x00FFFFFF;
|
||||
if (OSMO_UNLIKELY(bsc_sccp->next_id == 0x00FFFFFF))
|
||||
bsc_sccp->next_id = 0;
|
||||
|
||||
return test_id;
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include <osmocom/core/byteswap.h>
|
||||
#include <osmocom/bsc/lb.h>
|
||||
#include <osmocom/bsc/lcs_loc_req.h>
|
||||
#include <osmocom/bsc/vgcs_fsm.h>
|
||||
|
||||
#define S(x) (1 << (x))
|
||||
|
||||
|
@ -80,7 +81,7 @@ static const struct value_string gscon_fsm_event_names[] = {
|
|||
{GSCON_EV_MO_COMPL_L3, "MO_COMPL_L3"},
|
||||
{GSCON_EV_A_CONN_CFM, "MO-CONNECT.cfm"},
|
||||
{GSCON_EV_A_CLEAR_CMD, "CLEAR_CMD"},
|
||||
{GSCON_EV_A_DISC_IND, "DISCONNET.ind"},
|
||||
{GSCON_EV_A_DISC_IND, "DISCONNECT.ind"},
|
||||
{GSCON_EV_A_COMMON_ID_IND, "COMMON_ID.ind"},
|
||||
{GSCON_EV_ASSIGNMENT_START, "ASSIGNMENT_START"},
|
||||
{GSCON_EV_ASSIGNMENT_END, "ASSIGNMENT_END"},
|
||||
|
@ -212,6 +213,12 @@ void gscon_fsm_wait_sccp_rlsd_onenter(struct osmo_fsm_inst *fi, uint32_t prev_st
|
|||
if (conn->lcs.loc_req)
|
||||
osmo_fsm_inst_dispatch(conn->lcs.loc_req->fi, LCS_LOC_REQ_EV_CONN_CLEAR, NULL);
|
||||
|
||||
if (conn->vgcs_call.fi)
|
||||
osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
|
||||
|
||||
if (conn->vgcs_chan.fi)
|
||||
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
|
||||
|
||||
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
|
||||
osmo_mgcpc_ep_clear(conn->user_plane.mgw_endpoint);
|
||||
|
||||
|
@ -246,6 +253,8 @@ static void gscon_release_lchan(struct gsm_subscriber_connection *conn, struct g
|
|||
conn->lchan = NULL;
|
||||
if (conn->ho.fi && conn->ho.new_lchan == lchan)
|
||||
conn->ho.new_lchan = NULL;
|
||||
if (conn->vgcs_chan.new_lchan == lchan)
|
||||
conn->vgcs_chan.new_lchan = NULL;
|
||||
if (conn->assignment.new_lchan == lchan)
|
||||
conn->assignment.new_lchan = NULL;
|
||||
lchan_release(lchan, do_rr_release, err, cause_rr,
|
||||
|
@ -303,6 +312,8 @@ static int validate_initial_user_data(struct osmo_fsm_inst *fi, struct msgb *msg
|
|||
switch (bssmap_type) {
|
||||
case BSS_MAP_MSG_HANDOVER_RQST:
|
||||
case BSS_MAP_MSG_PERFORM_LOCATION_RQST:
|
||||
case BSS_MAP_MSG_VGCS_VBS_SETUP:
|
||||
case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
|
@ -343,6 +354,20 @@ static void handle_initial_user_data(struct osmo_fsm_inst *fi, struct msgb *msg)
|
|||
lcs_loc_req_start(conn, msg);
|
||||
return;
|
||||
|
||||
case BSS_MAP_MSG_VGCS_VBS_SETUP:
|
||||
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP]);
|
||||
/* VGCS: MSC asks vor voice group/bcast call. */
|
||||
conn_fsm_state_chg(ST_ACTIVE);
|
||||
vgcs_vbs_call_start(conn, msg);
|
||||
return;
|
||||
|
||||
case BSS_MAP_MSG_VGCS_VBS_ASSIGNMENT_RQST:
|
||||
rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctr[MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST]);
|
||||
/* VGCS: MSC asks vor resource (channel) for voice group/bcast call. */
|
||||
conn_fsm_state_chg(ST_ACTIVE);
|
||||
vgcs_vbs_chan_start(conn, msg);
|
||||
return;
|
||||
|
||||
default:
|
||||
LOGPFSML(fi, LOGL_ERROR, "No support for initial BSSMAP: %s: %s\n",
|
||||
gsm0808_bssap_name(bs->type), gsm0808_bssmap_name(bssmap_type));
|
||||
|
@ -717,13 +742,19 @@ struct osmo_mgcpc_ep *gscon_ensure_mgw_endpoint(struct gsm_subscriber_connection
|
|||
msc_assigned_cic, osmo_mgcpc_ep_name(conn->user_plane.mgw_endpoint));
|
||||
|
||||
} else if (gscon_is_aoip(conn)) {
|
||||
if (is_ipaccess_bts(for_lchan->ts->trx->bts))
|
||||
if (is_ipa_abisip_bts(for_lchan->ts->trx->bts))
|
||||
/* use dynamic RTPBRIDGE endpoint allocation in MGW */
|
||||
epname = mgcp_client_rtpbridge_wildcard(mgcp_client);
|
||||
else {
|
||||
uint8_t i460_bit_offs;
|
||||
if (for_lchan->ts->e1_link.e1_ts_ss == E1_SUBSLOT_FULL)
|
||||
i460_bit_offs = 0;
|
||||
else
|
||||
i460_bit_offs = for_lchan->ts->e1_link.e1_ts_ss * 2;
|
||||
|
||||
epname = mgcp_client_e1_epname(conn, mgcp_client, for_lchan->ts->e1_link.e1_nr,
|
||||
for_lchan->ts->e1_link.e1_ts, 16,
|
||||
for_lchan->ts->e1_link.e1_ts_ss*2);
|
||||
i460_bit_offs);
|
||||
}
|
||||
|
||||
conn->user_plane.mgw_endpoint =
|
||||
|
@ -763,7 +794,7 @@ bool gscon_connect_mgw_to_msc(struct gsm_subscriber_connection *conn,
|
|||
|
||||
mgw_info = (struct mgcp_conn_peer){
|
||||
.port = port,
|
||||
.call_id = conn->sccp.conn_id,
|
||||
.call_id = conn->sccp.conn.conn_id,
|
||||
.ptime = 20,
|
||||
.x_osmo_osmux_use = conn->assignment.req.use_osmux,
|
||||
.x_osmo_osmux_cid = conn->assignment.req.osmux_cid,
|
||||
|
@ -930,6 +961,10 @@ void gscon_lchan_releasing(struct gsm_subscriber_connection *conn, struct gsm_lc
|
|||
if (conn->ho.fi)
|
||||
osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_LCHAN_ERROR, lchan);
|
||||
}
|
||||
if (conn->vgcs_chan.new_lchan == lchan) {
|
||||
if (conn->vgcs_chan.fi)
|
||||
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_LCHAN_ERROR, lchan);
|
||||
}
|
||||
if (conn->lchan == lchan) {
|
||||
lchan_forget_conn(conn->lchan);
|
||||
conn->lchan = NULL;
|
||||
|
@ -966,6 +1001,10 @@ void gscon_forget_lchan(struct gsm_subscriber_connection *conn, struct gsm_lchan
|
|||
conn->ho.new_lchan = NULL;
|
||||
detach_label = "ho.new_lchan";
|
||||
}
|
||||
if (conn->vgcs_chan.new_lchan == lchan) {
|
||||
conn->vgcs_chan.new_lchan = NULL;
|
||||
detach_label = "vgcs.new_lchan";
|
||||
}
|
||||
if (conn->lchan == lchan) {
|
||||
conn->lchan = NULL;
|
||||
detach_label = "primary lchan";
|
||||
|
@ -984,6 +1023,7 @@ void gscon_forget_lchan(struct gsm_subscriber_connection *conn, struct gsm_lchan
|
|||
if (!conn->lchan
|
||||
&& !conn->ho.new_lchan
|
||||
&& !conn->assignment.new_lchan
|
||||
&& !conn->vgcs_chan.new_lchan
|
||||
&& !conn->lcs.loc_req)
|
||||
gscon_bssmap_clear(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE);
|
||||
}
|
||||
|
@ -1005,6 +1045,7 @@ static void gscon_forget_mgw_endpoint(struct gsm_subscriber_connection *conn)
|
|||
conn->ho.created_ci_for_msc = NULL;
|
||||
lchan_forget_mgw_endpoint(conn->lchan);
|
||||
lchan_forget_mgw_endpoint(conn->assignment.new_lchan);
|
||||
lchan_forget_mgw_endpoint(conn->vgcs_chan.new_lchan);
|
||||
lchan_forget_mgw_endpoint(conn->ho.new_lchan);
|
||||
}
|
||||
|
||||
|
@ -1094,6 +1135,7 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
|
|||
|
||||
lchan_forget_conn(conn->lchan);
|
||||
lchan_forget_conn(conn->assignment.new_lchan);
|
||||
lchan_forget_conn(conn->vgcs_chan.new_lchan);
|
||||
lchan_forget_conn(conn->ho.new_lchan);
|
||||
|
||||
lb_close_conn(conn);
|
||||
|
@ -1102,9 +1144,14 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
|
|||
LOGPFSML(fi, LOGL_DEBUG, "Disconnecting SCCP\n");
|
||||
struct bsc_msc_data *msc = conn->sccp.msc;
|
||||
/* FIXME: include a proper cause value / error message? */
|
||||
osmo_sccp_tx_disconn(msc->a.sccp_user, conn->sccp.conn_id, &msc->a.bsc_addr, 0);
|
||||
osmo_sccp_tx_disconn(msc->a.sccp_user, conn->sccp.conn.conn_id, &msc->a.bsc_addr, 0);
|
||||
conn->sccp.state = SUBSCR_SCCP_ST_NONE;
|
||||
}
|
||||
if (conn->sccp.conn.conn_id != SCCP_CONN_ID_UNSET && conn->sccp.msc) {
|
||||
struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(conn->sccp.msc->a.sccp);
|
||||
bsc_sccp_inst_unregister_gscon(bsc_sccp, &conn->sccp.conn);
|
||||
conn->sccp.conn.conn_id = SCCP_CONN_ID_UNSET;
|
||||
}
|
||||
|
||||
if (conn->bsub) {
|
||||
LOGPFSML(fi, LOGL_DEBUG, "Putting bsc_subscr\n");
|
||||
|
@ -1141,6 +1188,12 @@ static void gscon_pre_term(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause ca
|
|||
conn->lcls.fi = NULL;
|
||||
}
|
||||
|
||||
if (conn->vgcs_call.fi)
|
||||
osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_CLEANUP, NULL);
|
||||
|
||||
if (conn->vgcs_chan.fi)
|
||||
osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_CLEANUP, NULL);
|
||||
|
||||
LOGPFSML(fi, LOGL_DEBUG, "Releasing all lchans (if any) because this conn is terminating\n");
|
||||
gscon_release_lchans(conn, true, bsc_gsm48_rr_cause_from_gsm0808_cause(conn->clear_cause));
|
||||
|
||||
|
@ -1202,7 +1255,7 @@ static struct osmo_fsm gscon_fsm = {
|
|||
.event_names = gscon_fsm_event_names,
|
||||
};
|
||||
|
||||
void bsc_subscr_conn_fsm_init(void)
|
||||
static __attribute__((constructor)) void bsc_subscr_conn_fsm_init(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&gscon_fsm) == 0);
|
||||
OSMO_ASSERT(osmo_fsm_register(&lcls_fsm) == 0);
|
||||
|
@ -1220,8 +1273,8 @@ struct gsm_subscriber_connection *bsc_subscr_con_allocate(struct gsm_network *ne
|
|||
conn->network = net;
|
||||
INIT_LLIST_HEAD(&conn->dtap_queue);
|
||||
INIT_LLIST_HEAD(&conn->hodec2.penalty_timers);
|
||||
conn->sccp.conn_id = -1;
|
||||
|
||||
bscp_sccp_conn_node_init(&conn->sccp.conn, conn);
|
||||
bscp_sccp_conn_node_init(&conn->lcs.lb.conn, conn);
|
||||
/* Default clear cause (on RR translates to GSM48_RR_CAUSE_ABNORMAL_UNSPEC) */
|
||||
conn->clear_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE;
|
||||
|
||||
|
@ -1394,7 +1447,7 @@ void gscon_update_id(struct gsm_subscriber_connection *conn)
|
|||
{
|
||||
osmo_fsm_inst_update_id_f(conn->fi, "msc%u-conn%u%s%s",
|
||||
conn->sccp.msc ? conn->sccp.msc->nr : UINT_MAX,
|
||||
conn->sccp.conn_id,
|
||||
conn->sccp.conn.conn_id,
|
||||
conn->bsub? "_" : "",
|
||||
conn->bsub? bsc_subscr_id(conn->bsub) : "");
|
||||
}
|
||||
|
|
|
@ -65,14 +65,27 @@ static int bsub_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, co
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
|
||||
struct bsc_subscr_store *bsc_subscr_store_alloc(void *ctx)
|
||||
{
|
||||
struct bsc_subscr_store *bsubst;
|
||||
|
||||
bsubst = talloc_zero(ctx, struct bsc_subscr_store);
|
||||
if (!bsubst)
|
||||
return NULL;
|
||||
|
||||
INIT_LLIST_HEAD(&bsubst->bsub_list);
|
||||
return bsubst;
|
||||
}
|
||||
|
||||
static struct bsc_subscr *bsc_subscr_alloc(struct bsc_subscr_store *bsubst)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
bsub = talloc_zero(list, struct bsc_subscr);
|
||||
bsub = talloc_zero(bsubst, struct bsc_subscr);
|
||||
if (!bsub)
|
||||
return NULL;
|
||||
|
||||
bsub->store = bsubst;
|
||||
bsub->tmsi = GSM_RESERVED_TMSI;
|
||||
bsub->use_count = (struct osmo_use_count){
|
||||
.talloc_object = bsub,
|
||||
|
@ -80,12 +93,12 @@ static struct bsc_subscr *bsc_subscr_alloc(struct llist_head *list)
|
|||
};
|
||||
INIT_LLIST_HEAD(&bsub->active_paging_requests);
|
||||
|
||||
llist_add_tail(&bsub->entry, list);
|
||||
llist_add_tail(&bsub->entry, &bsubst->bsub_list);
|
||||
|
||||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_by_imsi(struct bsc_subscr_store *bsubst,
|
||||
const char *imsi,
|
||||
const char *use_token)
|
||||
{
|
||||
|
@ -94,7 +107,7 @@ struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
|||
if (!imsi || !*imsi)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(bsub, list, entry) {
|
||||
llist_for_each_entry(bsub, &bsubst->bsub_list, entry) {
|
||||
if (!strcmp(bsub->imsi, imsi)) {
|
||||
bsc_subscr_get(bsub, use_token);
|
||||
return bsub;
|
||||
|
@ -103,16 +116,16 @@ struct bsc_subscr *bsc_subscr_find_by_imsi(struct llist_head *list,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
|
||||
const char *imei,
|
||||
const char *use_token)
|
||||
static struct bsc_subscr *bsc_subscr_find_by_imei(struct bsc_subscr_store *bsubst,
|
||||
const char *imei,
|
||||
const char *use_token)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
if (!imei || !*imei)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(bsub, list, entry) {
|
||||
llist_for_each_entry(bsub, &bsubst->bsub_list, entry) {
|
||||
if (!strcmp(bsub->imei, imei)) {
|
||||
bsc_subscr_get(bsub, use_token);
|
||||
return bsub;
|
||||
|
@ -121,39 +134,83 @@ struct bsc_subscr *bsc_subscr_find_by_imei(struct llist_head *list,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_tmsi(struct llist_head *list,
|
||||
uint32_t tmsi,
|
||||
const char *use_token)
|
||||
static struct bsc_subscr *bsc_subscr_find_by_tmsi(struct bsc_subscr_store *bsubst,
|
||||
uint32_t tmsi,
|
||||
const char *use_token)
|
||||
{
|
||||
const struct rb_node *node = bsubst->bsub_tree_tmsi.rb_node;
|
||||
struct bsc_subscr *bsub;
|
||||
|
||||
if (tmsi == GSM_RESERVED_TMSI)
|
||||
return NULL;
|
||||
|
||||
llist_for_each_entry(bsub, list, entry) {
|
||||
if (bsub->tmsi == tmsi) {
|
||||
while (node) {
|
||||
bsub = container_of(node, struct bsc_subscr, node_tmsi);
|
||||
if (tmsi < bsub->tmsi)
|
||||
node = node->rb_left;
|
||||
else if (tmsi > bsub->tmsi)
|
||||
node = node->rb_right;
|
||||
else {
|
||||
bsc_subscr_get(bsub, use_token);
|
||||
return bsub;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
|
||||
const char *use_token)
|
||||
static int bsc_subscr_store_insert_bsub_tmsi(struct bsc_subscr *bsub)
|
||||
{
|
||||
if (!mi)
|
||||
return NULL;
|
||||
switch (mi->type) {
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
return bsc_subscr_find_by_imsi(list, mi->imsi, use_token);
|
||||
case GSM_MI_TYPE_IMEI:
|
||||
return bsc_subscr_find_by_imei(list, mi->imei, use_token);
|
||||
case GSM_MI_TYPE_TMSI:
|
||||
return bsc_subscr_find_by_tmsi(list, mi->tmsi, use_token);
|
||||
default:
|
||||
return NULL;
|
||||
struct bsc_subscr_store *bsubst = bsub->store;
|
||||
struct rb_node **n = &(bsubst->bsub_tree_tmsi.rb_node);
|
||||
struct rb_node *parent = NULL;
|
||||
|
||||
OSMO_ASSERT(bsub->tmsi != GSM_RESERVED_TMSI);
|
||||
|
||||
while (*n) {
|
||||
struct bsc_subscr *it;
|
||||
|
||||
it = container_of(*n, struct bsc_subscr, node_tmsi);
|
||||
|
||||
parent = *n;
|
||||
if (bsub->tmsi < it->tmsi) {
|
||||
n = &((*n)->rb_left);
|
||||
} else if (bsub->tmsi > it->tmsi) {
|
||||
n = &((*n)->rb_right);
|
||||
} else {
|
||||
LOGP(DMSC, LOGL_ERROR, "Trying to reserve already reserved tmsi %u\n", bsub->tmsi);
|
||||
return -EEXIST;
|
||||
}
|
||||
}
|
||||
|
||||
rb_link_node(&bsub->node_tmsi, parent, n);
|
||||
rb_insert_color(&bsub->node_tmsi, &bsubst->bsub_tree_tmsi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bsc_subscr_set_tmsi(struct bsc_subscr *bsub, uint32_t tmsi)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!bsub)
|
||||
return -EINVAL;
|
||||
|
||||
if (bsub->tmsi == tmsi)
|
||||
return 0;
|
||||
|
||||
/* bsub was already inserted, remove and re-insert with new tmsi */
|
||||
if (bsub->tmsi != GSM_RESERVED_TMSI)
|
||||
rb_erase(&bsub->node_tmsi, &bsub->store->bsub_tree_tmsi);
|
||||
|
||||
bsub->tmsi = tmsi;
|
||||
|
||||
/* If new tmsi is set, insert bsub into rbtree: */
|
||||
if (bsub->tmsi != GSM_RESERVED_TMSI) {
|
||||
if ((rc = bsc_subscr_store_insert_bsub_tmsi(bsub)) < 0)
|
||||
bsub->tmsi = GSM_RESERVED_TMSI;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void bsc_subscr_set_imsi(struct bsc_subscr *bsub, const char *imsi)
|
||||
|
@ -170,15 +227,15 @@ void bsc_subscr_set_imei(struct bsc_subscr *bsub, const char *imei)
|
|||
osmo_strlcpy(bsub->imei, imei, sizeof(bsub->imei));
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct bsc_subscr_store *bsubst,
|
||||
const char *imsi,
|
||||
const char *use_token)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
bsub = bsc_subscr_find_by_imsi(list, imsi, use_token);
|
||||
bsub = bsc_subscr_find_by_imsi(bsubst, imsi, use_token);
|
||||
if (bsub)
|
||||
return bsub;
|
||||
bsub = bsc_subscr_alloc(list);
|
||||
bsub = bsc_subscr_alloc(bsubst);
|
||||
if (!bsub)
|
||||
return NULL;
|
||||
bsc_subscr_set_imsi(bsub, imsi);
|
||||
|
@ -186,15 +243,15 @@ struct bsc_subscr *bsc_subscr_find_or_create_by_imsi(struct llist_head *list,
|
|||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
|
||||
const char *imei,
|
||||
const char *use_token)
|
||||
static struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct bsc_subscr_store *bsubst,
|
||||
const char *imei,
|
||||
const char *use_token)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
bsub = bsc_subscr_find_by_imei(list, imei, use_token);
|
||||
bsub = bsc_subscr_find_by_imei(bsubst, imei, use_token);
|
||||
if (bsub)
|
||||
return bsub;
|
||||
bsub = bsc_subscr_alloc(list);
|
||||
bsub = bsc_subscr_alloc(bsubst);
|
||||
if (!bsub)
|
||||
return NULL;
|
||||
bsc_subscr_set_imei(bsub, imei);
|
||||
|
@ -202,34 +259,37 @@ struct bsc_subscr *bsc_subscr_find_or_create_by_imei(struct llist_head *list,
|
|||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct llist_head *list,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_tmsi(struct bsc_subscr_store *bsubst,
|
||||
uint32_t tmsi,
|
||||
const char *use_token)
|
||||
{
|
||||
struct bsc_subscr *bsub;
|
||||
bsub = bsc_subscr_find_by_tmsi(list, tmsi, use_token);
|
||||
bsub = bsc_subscr_find_by_tmsi(bsubst, tmsi, use_token);
|
||||
if (bsub)
|
||||
return bsub;
|
||||
bsub = bsc_subscr_alloc(list);
|
||||
bsub = bsc_subscr_alloc(bsubst);
|
||||
if (!bsub)
|
||||
return NULL;
|
||||
bsub->tmsi = tmsi;
|
||||
if (bsc_subscr_set_tmsi(bsub, tmsi) < 0) {
|
||||
bsc_subscr_free(bsub);
|
||||
return NULL;
|
||||
}
|
||||
bsc_subscr_get(bsub, use_token);
|
||||
return bsub;
|
||||
}
|
||||
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct llist_head *list, const struct osmo_mobile_identity *mi,
|
||||
struct bsc_subscr *bsc_subscr_find_or_create_by_mi(struct bsc_subscr_store *bsubst, const struct osmo_mobile_identity *mi,
|
||||
const char *use_token)
|
||||
{
|
||||
if (!mi)
|
||||
return NULL;
|
||||
switch (mi->type) {
|
||||
case GSM_MI_TYPE_IMSI:
|
||||
return bsc_subscr_find_or_create_by_imsi(list, mi->imsi, use_token);
|
||||
return bsc_subscr_find_or_create_by_imsi(bsubst, mi->imsi, use_token);
|
||||
case GSM_MI_TYPE_IMEI:
|
||||
return bsc_subscr_find_or_create_by_imei(list, mi->imei, use_token);
|
||||
return bsc_subscr_find_or_create_by_imei(bsubst, mi->imei, use_token);
|
||||
case GSM_MI_TYPE_TMSI:
|
||||
return bsc_subscr_find_or_create_by_tmsi(list, mi->tmsi, use_token);
|
||||
return bsc_subscr_find_or_create_by_tmsi(bsubst, mi->tmsi, use_token);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -272,6 +332,10 @@ const char *bsc_subscr_id(struct bsc_subscr *bsub)
|
|||
static void bsc_subscr_free(struct bsc_subscr *bsub)
|
||||
{
|
||||
OSMO_ASSERT(llist_empty(&bsub->active_paging_requests));
|
||||
|
||||
if (bsub->tmsi != GSM_RESERVED_TMSI)
|
||||
rb_erase(&bsub->node_tmsi, &bsub->store->bsub_tree_tmsi);
|
||||
|
||||
llist_del(&bsub->entry);
|
||||
talloc_free(bsub);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include <osmocom/bsc/bssmap_reset.h>
|
||||
#include <osmocom/bsc/bsc_msc_data.h>
|
||||
#include <osmocom/bsc/lchan.h>
|
||||
#include <osmocom/bsc/pcu_if.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
|
@ -218,6 +219,9 @@ static void net_dump_vty(struct vty *vty, struct gsm_network *net)
|
|||
vty_out(vty, " Last RF Lock Command: %s%s",
|
||||
net->rf_ctrl->last_rf_lock_ctrl_command,
|
||||
VTY_NEWLINE);
|
||||
|
||||
if (net->pcu_sock_path)
|
||||
vty_out(vty, " PCU Socket Path: %s%s", net->pcu_sock_path, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
DEFUN(bsc_show_net, bsc_show_net_cmd, "show network",
|
||||
|
@ -253,6 +257,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]",
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(show_bts_brief, show_bts_brief_cmd, "show bts brief",
|
||||
SHOW_STR "Display information about a BTS\n"
|
||||
"Display availability status of all BTS\n")
|
||||
{
|
||||
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||
struct gsm_bts *bts;
|
||||
|
||||
/* Print OML state of BTSs. */
|
||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||
vty_out(vty, "BTS %d:", bts->nr);
|
||||
bts_dump_vty_oml_link_state(vty, bts);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(show_bts_fail_rep, show_bts_fail_rep_cmd, "show bts <0-255> fail-rep [reset]",
|
||||
SHOW_STR "Display information about a BTS\n"
|
||||
"BTS number\n" "OML failure reports\n"
|
||||
|
@ -381,6 +401,7 @@ static int config_write_net(struct vty *vty)
|
|||
uint16_t meas_port;
|
||||
char *meas_host;
|
||||
const char *meas_scenario;
|
||||
unsigned int max_len = meas_feed_txqueue_max_length_get();
|
||||
|
||||
meas_feed_cfg_get(&meas_host, &meas_port);
|
||||
meas_scenario = meas_feed_scenario_get();
|
||||
|
@ -391,6 +412,9 @@ static int config_write_net(struct vty *vty)
|
|||
if (strlen(meas_scenario) > 0)
|
||||
vty_out(vty, " meas-feed scenario %s%s",
|
||||
meas_scenario, VTY_NEWLINE);
|
||||
if (max_len != MEAS_FEED_TXQUEUE_MAX_LEN_DEFAULT)
|
||||
vty_out(vty, " meas-feed write-queue-max-length %u%s",
|
||||
max_len, VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (gsmnet->allow_unusable_timeslots)
|
||||
|
@ -406,6 +430,12 @@ static int config_write_net(struct vty *vty)
|
|||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
}
|
||||
|
||||
if (gsmnet->pcu_sock_path)
|
||||
vty_out(vty, " pcu-socket %s%s", gsmnet->pcu_sock_path, VTY_NEWLINE);
|
||||
if (gsmnet->pcu_sock_wqueue_len_max != BSC_PCU_SOCK_WQUEUE_LEN_DEFAULT)
|
||||
vty_out(vty, " pcu-socket-wqueue-length %u%s", gsmnet->pcu_sock_wqueue_len_max,
|
||||
VTY_NEWLINE);
|
||||
|
||||
neighbor_ident_vty_write_network(vty, " ");
|
||||
mgcp_client_pool_config_write(vty, " ");
|
||||
|
||||
|
@ -727,7 +757,7 @@ DEFUN(show_lchan_summary_all,
|
|||
static void dump_one_subscr_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)
|
||||
{
|
||||
vty_out(vty, "conn ID=%u, MSC=%u, hodec2_fail=%d, mgw_ep=%s%s",
|
||||
conn->sccp.conn_id, conn->sccp.msc->nr, conn->hodec2.failures,
|
||||
conn->sccp.conn.conn_id, conn->sccp.msc->nr, conn->hodec2.failures,
|
||||
osmo_mgcpc_ep_name(conn->user_plane.mgw_endpoint), VTY_NEWLINE);
|
||||
if (conn->lcls.global_call_ref_len) {
|
||||
vty_out(vty, " LCLS GCR: %s%s",
|
||||
|
@ -753,14 +783,12 @@ DEFUN(show_subscr_conn,
|
|||
struct gsm_subscriber_connection *conn;
|
||||
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||
bool no_conns = true;
|
||||
unsigned int count = 0;
|
||||
|
||||
vty_out(vty, "Active subscriber connections: %s", VTY_NEWLINE);
|
||||
|
||||
llist_for_each_entry(conn, &net->subscr_conns, entry) {
|
||||
dump_one_subscr_conn(vty, conn);
|
||||
no_conns = false;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (no_conns)
|
||||
|
@ -862,8 +890,7 @@ static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, b
|
|||
struct lchan_modify_info info = {
|
||||
.modify_for = MODIFY_FOR_VTY,
|
||||
.ch_mode_rate = lchan->current_ch_mode_rate,
|
||||
.requires_voice_stream = (lchan->fi_rtp != NULL),
|
||||
.vamos = vamos,
|
||||
.ch_indctr = lchan->current_ch_indctr,
|
||||
.tsc_set = {
|
||||
.present = (tsc_set >= 0),
|
||||
.val = tsc_set,
|
||||
|
@ -873,6 +900,8 @@ static int trigger_vamos_mode_modify(struct vty *vty, struct gsm_lchan *lchan, b
|
|||
.val = tsc,
|
||||
},
|
||||
};
|
||||
if (vamos)
|
||||
info.type_for = LCHAN_TYPE_FOR_VAMOS;
|
||||
|
||||
lchan_mode_modify(lchan, &info);
|
||||
return CMD_SUCCESS;
|
||||
|
@ -1261,8 +1290,8 @@ DEFUN(drop_bts,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!is_ipaccess_bts(bts)) {
|
||||
vty_out(vty, "%% This command only works for ipaccess.%s", VTY_NEWLINE);
|
||||
if (!is_ipa_abisip_bts(bts)) {
|
||||
vty_out(vty, "%% This command only works for IPA Abis/IP.%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -1308,8 +1337,8 @@ DEFUN(restart_bts, restart_bts_cmd,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!is_ipaccess_bts(bts) || is_osmobts(bts)) {
|
||||
vty_out(vty, "%% This command only works for ipaccess nanoBTS.%s",
|
||||
if (!is_ipa_abisip_bts(bts)) {
|
||||
vty_out(vty, "%% This command only works for IPA Abis/IP.%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -1419,18 +1448,22 @@ DEFUN(bts_c0_power_red,
|
|||
}
|
||||
|
||||
rc = gsm_bts_set_c0_power_red(bts, red);
|
||||
if (rc == -ENOTSUP) {
|
||||
switch (rc) {
|
||||
case 0: /* success */
|
||||
return CMD_SUCCESS;
|
||||
case -ENOTCONN:
|
||||
vty_out(vty, "%% BTS%u is offline%s", bts_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
case -ENOTSUP:
|
||||
vty_out(vty, "%% BCCH carrier power reduction operation mode "
|
||||
"is not supported for BTS%u%s", bts_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
} else if (rc != 0) {
|
||||
default:
|
||||
vty_out(vty, "%% Failed to %sable BCCH carrier power reduction "
|
||||
"operation mode for BTS%u%s", red ? "en" : "dis",
|
||||
bts_nr, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* this command is now hidden, as it's a low-level debug hack, and people should
|
||||
|
@ -1521,8 +1554,8 @@ DEFUN(pdch_act, pdch_act_cmd,
|
|||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!is_ipaccess_bts(ts->trx->bts)) {
|
||||
vty_out(vty, "%% This command only works for ipaccess BTS%s",
|
||||
if (!is_ipa_abisip_bts(ts->trx->bts)) {
|
||||
vty_out(vty, "%% This command only works for IPA Abis/IP BTS%s",
|
||||
VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
@ -1625,11 +1658,11 @@ static int lchan_act_single(struct vty *vty, struct gsm_lchan *lchan, const char
|
|||
}
|
||||
|
||||
info.activ_for = ACTIVATE_FOR_VTY;
|
||||
info.requires_voice_stream = false;
|
||||
info.ch_indctr = GSM0808_CHAN_SIGN;
|
||||
info.ch_mode_rate.chan_rate = chan_t_to_chan_rate(lchan_t);
|
||||
|
||||
if (activate == 2 || lchan->vamos.is_secondary) {
|
||||
info.vamos = true;
|
||||
info.type_for = LCHAN_TYPE_FOR_VAMOS;
|
||||
if (lchan->vamos.is_secondary) {
|
||||
info.tsc_set.present = true;
|
||||
info.tsc_set.val = 1;
|
||||
|
@ -2055,8 +2088,8 @@ DEFUN(lchan_mdcx, lchan_mdcx_cmd,
|
|||
|
||||
lchan = &ts->lchan[ss_nr];
|
||||
|
||||
if (!is_ipaccess_bts(lchan->ts->trx->bts)) {
|
||||
vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE);
|
||||
if (!is_ipa_abisip_bts(lchan->ts->trx->bts)) {
|
||||
vty_out(vty, "%% BTS is not of IPA Abis/IP type%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
|
@ -2404,6 +2437,16 @@ DEFUN_ATTR(cfg_net_meas_feed_scenario, cfg_net_meas_feed_scenario_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_net_meas_feed_wqueue_max_len, cfg_net_meas_feed_wqueue_max_len_cmd,
|
||||
"meas-feed write-queue-max-length <1-65535>",
|
||||
MEAS_FEED_STR "Set the maximum length of the message write queue towards the UDP socket\n"
|
||||
"Maximum number of messages to be queued waiting for transmission\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
meas_feed_txqueue_max_length_set(atoi(argv[0]));
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static void legacy_timers(struct vty *vty, const char **T_arg)
|
||||
{
|
||||
if (!strcmp((*T_arg), "T993111") || !strcmp((*T_arg), "t993111")) {
|
||||
|
@ -2460,6 +2503,63 @@ DEFUN(cfg_net_allow_unusable_timeslots, cfg_net_allow_unusable_timeslots_cmd,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_bts_pcu_sock_wqueue_len, cfg_bts_pcu_sock_wqueue_len_cmd,
|
||||
"pcu-socket-wqueue-length <1-2147483646>",
|
||||
"Configure the PCU socket queue length\n"
|
||||
"Queue length\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
size_t dropped_msgs = 0;
|
||||
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||
size_t old = net->pcu_sock_wqueue_len_max;
|
||||
net->pcu_sock_wqueue_len_max = atoi(argv[0]);
|
||||
if (net->pcu_state)
|
||||
dropped_msgs = osmo_wqueue_set_maxlen(&net->pcu_state->upqueue, net->pcu_sock_wqueue_len_max);
|
||||
if (dropped_msgs) {
|
||||
LOGP(DPCU, LOGL_INFO, "Have dropped %zu messages due to shortened max. message queue size (from: %zu to %u)\n",
|
||||
dropped_msgs, old, net->pcu_sock_wqueue_len_max);
|
||||
vty_out(vty, "Have dropped %zu messages due to shortened max. message queue size (from: %zu to %u)%s",
|
||||
dropped_msgs, old, net->pcu_sock_wqueue_len_max, VTY_NEWLINE);
|
||||
}
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_net_pcu_sock_path,
|
||||
cfg_net_pcu_sock_path_cmd,
|
||||
"pcu-socket PATH",
|
||||
"PCU Socket Path for using OsmoPCU co-located with BSC\n"
|
||||
"Path in the file system for the unix-domain PCU socket\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||
int rc;
|
||||
|
||||
osmo_talloc_replace_string(net, &net->pcu_sock_path, argv[0]);
|
||||
pcu_sock_exit(net);
|
||||
rc = pcu_sock_init(net);
|
||||
if (rc < 0) {
|
||||
vty_out(vty, "%% Error creating PCU socket `%s'%s",
|
||||
net->pcu_sock_path, VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_net_no_pcu_sock,
|
||||
cfg_net_no_pcu_sock_cmd,
|
||||
"no pcu-socket",
|
||||
NO_STR "Disable BSC co-located PCU\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
{
|
||||
struct gsm_network *net = gsmnet_from_vty(vty);
|
||||
|
||||
pcu_sock_exit(net);
|
||||
talloc_free(net->pcu_sock_path);
|
||||
net->pcu_sock_path = NULL;
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct bsc_msc_data *bsc_msc_data(struct vty *vty)
|
||||
{
|
||||
return vty->index;
|
||||
|
@ -2550,10 +2650,10 @@ static void write_msc(struct vty *vty, struct bsc_msc_data *msc)
|
|||
if (i != 0)
|
||||
vty_out(vty, " ");
|
||||
|
||||
if (msc->audio_support[i]->hr)
|
||||
vty_out(vty, "hr%.1u", msc->audio_support[i]->ver);
|
||||
if (msc->audio_support[i].hr)
|
||||
vty_out(vty, "hr%u", msc->audio_support[i].ver);
|
||||
else
|
||||
vty_out(vty, "fr%.1u", msc->audio_support[i]->ver);
|
||||
vty_out(vty, "fr%u", msc->audio_support[i].ver);
|
||||
}
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
|
||||
|
@ -2640,8 +2740,8 @@ static int config_write_bsc(struct vty *vty)
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_net_bsc_ncc,
|
||||
cfg_net_bsc_ncc_cmd,
|
||||
DEFUN_ATTR(cfg_net_msc_ncc,
|
||||
cfg_net_msc_ncc_cmd,
|
||||
"core-mobile-network-code <1-999>",
|
||||
"Use this network code for the core network\n" "MNC value\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
|
@ -2659,8 +2759,8 @@ DEFUN_ATTR(cfg_net_bsc_ncc,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_ATTR(cfg_net_bsc_mcc,
|
||||
cfg_net_bsc_mcc_cmd,
|
||||
DEFUN_ATTR(cfg_net_msc_mcc,
|
||||
cfg_net_msc_mcc_cmd,
|
||||
"core-mobile-country-code <1-999>",
|
||||
"Use this country code for the core network\n" "MCC value\n",
|
||||
CMD_ATTR_IMMEDIATE)
|
||||
|
@ -2675,8 +2775,8 @@ DEFUN_ATTR(cfg_net_bsc_mcc,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_DEPRECATED(cfg_net_bsc_lac,
|
||||
cfg_net_bsc_lac_cmd,
|
||||
DEFUN_DEPRECATED(cfg_net_msc_lac,
|
||||
cfg_net_msc_lac_cmd,
|
||||
"core-location-area-code <0-65535>",
|
||||
"Legacy configuration that no longer has any effect\n-\n")
|
||||
{
|
||||
|
@ -2684,8 +2784,8 @@ DEFUN_DEPRECATED(cfg_net_bsc_lac,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_DEPRECATED(cfg_net_bsc_ci,
|
||||
cfg_net_bsc_ci_cmd,
|
||||
DEFUN_DEPRECATED(cfg_net_msc_ci,
|
||||
cfg_net_msc_ci_cmd,
|
||||
"core-cell-identity <0-65535>",
|
||||
"Legacy configuration that no longer has any effect\n-\n")
|
||||
{
|
||||
|
@ -2693,8 +2793,8 @@ DEFUN_DEPRECATED(cfg_net_bsc_ci,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_DEPRECATED(cfg_net_bsc_rtp_base,
|
||||
cfg_net_bsc_rtp_base_cmd,
|
||||
DEFUN_DEPRECATED(cfg_net_msc_rtp_base,
|
||||
cfg_net_msc_rtp_base_cmd,
|
||||
"ip.access rtp-base <1-65000>",
|
||||
"deprecated\n" "deprecated, RTP is handled by the MGW\n" "deprecated\n")
|
||||
{
|
||||
|
@ -2702,56 +2802,64 @@ DEFUN_DEPRECATED(cfg_net_bsc_rtp_base,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN_USRATTR(cfg_net_bsc_codec_list,
|
||||
cfg_net_bsc_codec_list_cmd,
|
||||
DEFUN_USRATTR(cfg_net_msc_codec_list,
|
||||
cfg_net_msc_codec_list_cmd,
|
||||
BSC_VTY_ATTR_NEW_LCHAN,
|
||||
"codec-list .LIST",
|
||||
"Set the allowed audio codecs\n"
|
||||
"List of audio codecs, e.g. fr3 fr1 hr3\n")
|
||||
"Set the allowed audio codecs and their order of preference\n"
|
||||
"List of audio codecs in order of preference, e.g. 'codec-list fr3 fr2 fr1 hr3 hr1'."
|
||||
" (fr3: AMR-FR, hr3: AMR-HR, fr2: GSM-EFR, fr1: GSM-FR, hr1: GSM-HR)\n")
|
||||
{
|
||||
struct bsc_msc_data *data = bsc_msc_data(vty);
|
||||
struct gsm_audio_support tmp[ARRAY_SIZE(data->audio_support)];
|
||||
const char *arg = NULL;
|
||||
int i;
|
||||
|
||||
/* Nr of arguments must fit in the array */
|
||||
if (argc > ARRAY_SIZE(data->audio_support)) {
|
||||
vty_out(vty, "Too many items in 'msc' / 'codec-list': %d. There can be at most %zu entries.%s",
|
||||
argc, ARRAY_SIZE(data->audio_support), VTY_NEWLINE);
|
||||
return CMD_ERR_EXEED_ARGC_MAX;
|
||||
}
|
||||
|
||||
/* check all given arguments first */
|
||||
for (i = 0; i < argc; ++i) {
|
||||
/* check for hrX or frX */
|
||||
if (strlen(argv[i]) != 3
|
||||
|| argv[i][1] != 'r'
|
||||
|| (argv[i][0] != 'h' && argv[i][0] != 'f')
|
||||
|| argv[i][2] < 0x30
|
||||
|| argv[i][2] > 0x39)
|
||||
goto error;
|
||||
for (i = 0; i < argc; i++) {
|
||||
int j;
|
||||
int ver;
|
||||
arg = argv[i];
|
||||
|
||||
if (strncmp("hr", arg, 2) == 0)
|
||||
tmp[i].hr = 1;
|
||||
else if (strncmp("fr", arg, 2) == 0)
|
||||
tmp[i].hr = 0;
|
||||
else
|
||||
goto invalid_arg;
|
||||
|
||||
ver = atoi(arg + 2);
|
||||
if (ver < 1 || ver > 7)
|
||||
goto invalid_arg;
|
||||
tmp[i].ver = ver;
|
||||
|
||||
if (tmp[i].hr == 1 && ver == 2)
|
||||
goto invalid_arg;
|
||||
|
||||
/* prevent duplicate entries */
|
||||
for (j = 0; j < i; j++) {
|
||||
if (gsm_audio_support_cmp(&tmp[j], &tmp[i]) == 0) {
|
||||
vty_out(vty, "duplicate entry in 'msc' / 'codec-list': %s%s", argv[i], VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the old list... if it exists */
|
||||
if (data->audio_support) {
|
||||
talloc_free(data->audio_support);
|
||||
data->audio_support = NULL;
|
||||
data->audio_length = 0;
|
||||
}
|
||||
|
||||
/* create a new array */
|
||||
data->audio_support =
|
||||
talloc_zero_array(bsc_gsmnet, struct gsm_audio_support *, argc);
|
||||
memcpy(data->audio_support, tmp, sizeof(data->audio_support));
|
||||
data->audio_length = argc;
|
||||
|
||||
for (i = 0; i < argc; ++i) {
|
||||
data->audio_support[i] = talloc_zero(data->audio_support,
|
||||
struct gsm_audio_support);
|
||||
data->audio_support[i]->ver = atoi(argv[i] + 2);
|
||||
|
||||
if (strncmp("hr", argv[i], 2) == 0)
|
||||
data->audio_support[i]->hr = 1;
|
||||
else if (strncmp("fr", argv[i], 2) == 0)
|
||||
data->audio_support[i]->hr = 0;
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
||||
error:
|
||||
vty_out(vty, "Codec name must be hrX or frX. Was '%s'%s",
|
||||
argv[i], VTY_NEWLINE);
|
||||
return CMD_ERR_INCOMPLETE;
|
||||
invalid_arg:
|
||||
vty_out(vty, "%s is not a valid codec version%s", osmo_quote_cstr_c(OTC_SELECT, arg, -1), VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
#define LEGACY_STR "This command has no effect, it is kept to support legacy config files\n"
|
||||
|
@ -3158,13 +3266,19 @@ DEFUN(show_mscs,
|
|||
{
|
||||
struct bsc_msc_data *msc;
|
||||
llist_for_each_entry(msc, &bsc_gsmnet->mscs, entry) {
|
||||
vty_out(vty, "%d %s %s ",
|
||||
vty_out(vty, "MSC %d: %s <-> ",
|
||||
msc->a.cs7_instance,
|
||||
osmo_ss7_asp_protocol_name(msc->a.asp_proto),
|
||||
osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.bsc_addr));
|
||||
vty_out(vty, "%s%s",
|
||||
osmo_sccp_inst_addr_name(msc->a.sccp, &msc->a.msc_addr),
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " ASP protocol: %s%s",
|
||||
osmo_ss7_asp_protocol_name(msc->a.asp_proto),
|
||||
VTY_NEWLINE);
|
||||
vty_out(vty, " BSSMAP state: %s%s",
|
||||
msc->a.bssmap_reset ? osmo_fsm_inst_state_name(msc->a.bssmap_reset->fi) : "",
|
||||
VTY_NEWLINE);
|
||||
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -3275,7 +3389,7 @@ DEFUN(show_subscr_all,
|
|||
vty_out(vty, " IMSI TMSI Use%s", VTY_NEWLINE);
|
||||
/* " 001010123456789 ffffffff 1" */
|
||||
|
||||
llist_for_each_entry(bsc_subscr, bsc_gsmnet->bsc_subscribers, entry)
|
||||
llist_for_each_entry(bsc_subscr, &bsc_gsmnet->bsc_subscribers->bsub_list, entry)
|
||||
dump_one_sub(vty, bsc_subscr);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
|
@ -3524,14 +3638,19 @@ int bsc_vty_init(struct gsm_network *network)
|
|||
install_element(GSMNET_NODE, &cfg_net_dyn_ts_allow_tch_f_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_meas_feed_dest_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_meas_feed_scenario_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_meas_feed_wqueue_max_len_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_timer_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_allow_unusable_timeslots_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_pcu_sock_path_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_bts_pcu_sock_wqueue_len_cmd);
|
||||
install_element(GSMNET_NODE, &cfg_net_no_pcu_sock_cmd);
|
||||
|
||||
/* Timer configuration commands (generic osmo_tdef API) */
|
||||
osmo_tdef_vty_groups_init(GSMNET_NODE, bsc_tdef_group);
|
||||
|
||||
install_element_ve(&bsc_show_net_cmd);
|
||||
install_element_ve(&show_bts_cmd);
|
||||
install_element_ve(&show_bts_brief_cmd);
|
||||
install_element_ve(&show_bts_fail_rep_cmd);
|
||||
install_element_ve(&show_rejected_bts_cmd);
|
||||
install_element_ve(&show_trx_cmd);
|
||||
|
@ -3614,12 +3733,12 @@ int bsc_vty_init(struct gsm_network *network)
|
|||
install_element(BSC_NODE, &cfg_bsc_bts_setup_ramping_step_interval_cmd);
|
||||
|
||||
install_node(&msc_node, config_write_msc);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_ncc_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_mcc_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_lac_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_ci_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_rtp_base_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_bsc_codec_list_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_ncc_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_mcc_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_lac_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_ci_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_rtp_base_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_codec_list_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_dest_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_no_dest_cmd);
|
||||
install_element(MSC_NODE, &cfg_net_msc_welcome_ussd_cmd);
|
||||
|
|
|
@ -198,7 +198,7 @@ static int bssmap_reset_fsm_timer_cb(struct osmo_fsm_inst *fi)
|
|||
|
||||
static struct osmo_fsm_state bssmap_reset_fsm_states[] = {
|
||||
[BSSMAP_RESET_ST_DISC] = {
|
||||
.name = "DISC",
|
||||
.name = "DISCONNECTED",
|
||||
.in_event_mask = 0
|
||||
| S(BSSMAP_RESET_EV_RX_RESET)
|
||||
| S(BSSMAP_RESET_EV_RX_RESET_ACK)
|
||||
|
@ -213,7 +213,7 @@ static struct osmo_fsm_state bssmap_reset_fsm_states[] = {
|
|||
.action = bssmap_reset_disc_action,
|
||||
},
|
||||
[BSSMAP_RESET_ST_CONN] = {
|
||||
.name = "CONN",
|
||||
.name = "CONNECTED",
|
||||
.in_event_mask = 0
|
||||
| S(BSSMAP_RESET_EV_RX_RESET)
|
||||
| S(BSSMAP_RESET_EV_RX_RESET_ACK)
|
||||
|
@ -251,6 +251,12 @@ void bssmap_reset_resend_reset(struct bssmap_reset *bssmap_reset)
|
|||
osmo_fsm_inst_state_chg_ms(bssmap_reset->fi, BSSMAP_RESET_ST_DISC, 1, 0);
|
||||
}
|
||||
|
||||
void bssmap_reset_set_disconnected(struct bssmap_reset *bssmap_reset)
|
||||
{
|
||||
/* Go to disconnected state, with the normal RESET timeout to re-send RESET. */
|
||||
bssmap_reset_fsm_state_chg(bssmap_reset->fi, BSSMAP_RESET_ST_DISC);
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void bssmap_reset_fsm_init(void)
|
||||
{
|
||||
OSMO_ASSERT(osmo_fsm_register(&bssmap_reset_fsm) == 0);
|
||||
|
|
|
@ -49,7 +49,7 @@ const struct value_string osmo_bts_variant_names[_NUM_BTS_VARIANT + 1] = {
|
|||
{ BTS_OSMO_LITECELL15, "osmo-bts-lc15" },
|
||||
{ BTS_OSMO_OCTPHY, "osmo-bts-octphy" },
|
||||
{ BTS_OSMO_SYSMO, "osmo-bts-sysmo" },
|
||||
{ BTS_OSMO_TRX, "omso-bts-trx" },
|
||||
{ BTS_OSMO_TRX, "osmo-bts-trx" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -117,8 +117,20 @@ int gsm_bts_model_register(struct gsm_bts_model *model)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const uint8_t bts_cell_timer_default[] =
|
||||
{ 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 };
|
||||
static const uint8_t bts_cell_timer_default[11] = {
|
||||
3, /* blocking timer (T1) */
|
||||
3, /* blocking retries */
|
||||
3, /* unblocking retries */
|
||||
3, /* reset timer (T2) */
|
||||
3, /* reset retries */
|
||||
10, /* suspend timer (T3) in 100ms */
|
||||
3, /* suspend retries */
|
||||
10, /* resume timer (T4) in 100ms */
|
||||
3, /* resume retries */
|
||||
10, /* capability update timer (T5) */
|
||||
3, /* capability update retries */
|
||||
};
|
||||
|
||||
static const struct gprs_rlc_cfg rlc_cfg_default = {
|
||||
.parameter = {
|
||||
[RLC_T3142] = 20,
|
||||
|
@ -458,6 +470,7 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, struct gsm_bts_sm *bts_sm
|
|||
bts->interf_meas_params_cfg = interf_meas_params_def;
|
||||
|
||||
bts->rach_max_delay = 63;
|
||||
bts->rach_expiry_timeout = 32;
|
||||
|
||||
/* SRVCC is enabled by default */
|
||||
bts->srvcc_fast_return_allowed = true;
|
||||
|
@ -753,7 +766,8 @@ struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num)
|
|||
|
||||
void bts_store_uptime(struct gsm_bts *bts)
|
||||
{
|
||||
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_UPTIME_SECONDS), bts_uptime(bts));
|
||||
osmo_stat_item_set(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_UPTIME_SECONDS),
|
||||
bts->oml_link ? bts_updowntime(bts) : 0);
|
||||
}
|
||||
|
||||
void bts_store_lchan_durations(struct gsm_bts *bts)
|
||||
|
@ -811,20 +825,20 @@ void bts_store_lchan_durations(struct gsm_bts *bts)
|
|||
rate_ctr_add(rate_ctr_group_get_ctr(bts->bts_ctrs, BTS_CTR_CHAN_SDCCH_ACTIVE_MILLISECONDS_TOTAL), elapsed_sdcch_ms);
|
||||
}
|
||||
|
||||
unsigned long long bts_uptime(const struct gsm_bts *bts)
|
||||
unsigned long long bts_updowntime(const struct gsm_bts *bts)
|
||||
{
|
||||
struct timespec tp;
|
||||
|
||||
if (!bts->uptime || !bts->oml_link)
|
||||
if (!bts->updowntime)
|
||||
return 0;
|
||||
|
||||
if (osmo_clock_gettime(CLOCK_MONOTONIC, &tp) != 0) {
|
||||
LOGP(DNM, LOGL_ERROR, "BTS %u uptime computation failure: %s\n", bts->nr, strerror(errno));
|
||||
LOGP(DNM, LOGL_ERROR, "BTS %u uptime/downtime computation failure: %s\n", bts->nr, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* monotonic clock helps to ensure that the conversion is valid */
|
||||
return difftime(tp.tv_sec, bts->uptime);
|
||||
return difftime(tp.tv_sec, bts->updowntime);
|
||||
}
|
||||
|
||||
char *get_model_oml_status(const struct gsm_bts *bts)
|
||||
|
@ -888,14 +902,14 @@ int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
|
|||
return (base->depends_on[idx] & (1U << bit)) > 0;
|
||||
}
|
||||
|
||||
static int bts_is_online(struct gsm_bts *bts)
|
||||
static bool bts_is_online(const struct gsm_bts *bts)
|
||||
{
|
||||
/* TODO: support E1 BTS too */
|
||||
if (!is_ipaccess_bts(bts))
|
||||
return 1;
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return true;
|
||||
|
||||
if (!bts->oml_link)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
|
||||
}
|
||||
|
@ -978,21 +992,32 @@ int gsm_bts_set_system_infos(struct gsm_bts *bts)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Send the given C0 power reduction value to the BTS */
|
||||
int gsm_bts_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red)
|
||||
{
|
||||
if (!bts_is_online(bts))
|
||||
return -ENOTCONN;
|
||||
if (!osmo_bts_has_feature(&bts->features, BTS_FEAT_BCCH_POWER_RED))
|
||||
return -ENOTSUP;
|
||||
if (bts->model->power_ctrl_send_c0_power_red == NULL)
|
||||
return -ENOTSUP;
|
||||
return bts->model->power_ctrl_send_c0_power_red(bts, red);
|
||||
}
|
||||
|
||||
/* Send the given C0 power reduction value to the BTS and update the internal state */
|
||||
int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red)
|
||||
{
|
||||
struct gsm_bts_trx *c0 = bts->c0;
|
||||
unsigned int tn;
|
||||
int rc;
|
||||
|
||||
if (!osmo_bts_has_feature(&bts->features, BTS_FEAT_BCCH_POWER_RED))
|
||||
return -ENOTSUP;
|
||||
if (bts->model->power_ctrl_set_c0_power_red == NULL)
|
||||
return -ENOTSUP;
|
||||
|
||||
rc = bts->model->power_ctrl_set_c0_power_red(bts, red);
|
||||
rc = gsm_bts_send_c0_power_red(bts, red);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
LOG_BTS(bts, DRSL, LOGL_NOTICE, "%sabling BCCH carrier power reduction "
|
||||
"operation mode (maximum %u dB)\n", red ? "En" : "Dis", red);
|
||||
|
||||
/* Timeslot 0 is always transmitting BCCH/CCCH */
|
||||
c0->ts[0].c0_max_power_red_db = 0;
|
||||
|
||||
|
@ -1003,7 +1028,7 @@ int gsm_bts_set_c0_power_red(struct gsm_bts *bts, const uint8_t red)
|
|||
switch (ts->pchan_is) {
|
||||
/* Not allowed on CCCH/BCCH */
|
||||
case GSM_PCHAN_CCCH:
|
||||
/* Preceeding timeslot shall not exceed 2 dB */
|
||||
/* Preceding timeslot shall not exceed 2 dB */
|
||||
if (prev->c0_max_power_red_db > 0)
|
||||
prev->c0_max_power_red_db = 2;
|
||||
/* fall-through */
|
||||
|
@ -1632,12 +1657,12 @@ const struct osmo_stat_item_desc bts_stat_desc[] = {
|
|||
"Number of SDCCH8 channels total",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_CHAN_TCH_F_PDCH_USED] = \
|
||||
{ "chan_tch_f_pdch:used",
|
||||
"Number of TCH/F_PDCH channels used",
|
||||
{ "chan_dynamic_ipaccess:used",
|
||||
"Number of DYNAMIC/IPACCESS channels used",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_CHAN_TCH_F_PDCH_TOTAL] = \
|
||||
{ "chan_tch_f_pdch:total",
|
||||
"Number of TCH/F_PDCH channels total",
|
||||
{ "chan_dynamic_ipaccess:total",
|
||||
"Number of DYNAMIC/IPACCESS channels total",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_CHAN_CCCH_SDCCH4_CBCH_USED] = \
|
||||
{ "chan_ccch_sdcch4_cbch:used",
|
||||
|
@ -1656,12 +1681,12 @@ const struct osmo_stat_item_desc bts_stat_desc[] = {
|
|||
"Number of SDCCH8+CBCH channels total",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_CHAN_OSMO_DYN_USED] = \
|
||||
{ "chan_osmo_dyn:used",
|
||||
"Number of TCH/F_TCH/H_SDCCH8_PDCH channels used",
|
||||
{ "chan_dynamic_osmocom:used",
|
||||
"Number of DYNAMIC/OSMOCOM channels used",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_CHAN_OSMO_DYN_TOTAL] = \
|
||||
{ "chan_osmo_dyn:total",
|
||||
"Number of TCH/F_TCH/H_SDCCH8_PDCH channels total",
|
||||
{ "chan_dynamic_osmocom:total",
|
||||
"Number of DYNAMIC/OSMOCOM channels total",
|
||||
"", 60, 0 },
|
||||
[BTS_STAT_T3122] = \
|
||||
{ "T3122",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -131,7 +131,7 @@ struct gsm_bts_model bts_model_nanobts = {
|
|||
[NM_ATT_IPACC_REVOC_DATE] = { TLV_TYPE_TL16V },
|
||||
},
|
||||
},
|
||||
.features_get_reported = true,
|
||||
.features_get_reported = false,
|
||||
};
|
||||
|
||||
|
||||
|
@ -150,7 +150,7 @@ static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd)
|
|||
struct gsm_gprs_nse *nse;
|
||||
struct gsm_gprs_cell *cell;
|
||||
|
||||
if (!is_ipaccess_bts(nsd->bts))
|
||||
if (!is_ipa_abisip_bts(nsd->bts))
|
||||
return 0;
|
||||
|
||||
switch (obj_class) {
|
||||
|
@ -195,157 +195,78 @@ static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd)
|
|||
/* Callback function to be called every time we receive a 12.21 SW activated report */
|
||||
static int sw_activ_rep(struct msgb *mb)
|
||||
{
|
||||
struct abis_om_fom_hdr *foh = msgb_l3(mb);
|
||||
const struct abis_om_fom_hdr *foh = msgb_l3(mb);
|
||||
struct e1inp_sign_link *sign_link = mb->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_gprs_nsvc *nsvc;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
struct gsm_abis_mo *mo;
|
||||
struct tlv_parsed tp;
|
||||
|
||||
if (!is_ipaccess_bts(bts))
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return 0;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_SITE_MANAGER:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_BTS:
|
||||
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return -EINVAL;
|
||||
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_RADIO_CARRIER:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return -EINVAL;
|
||||
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_CHANNEL:
|
||||
if (!(ts = abis_nm_get_ts(mb)))
|
||||
return -EINVAL;
|
||||
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_NSE:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_CELL:
|
||||
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_NSVC:
|
||||
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
|
||||
return -EINVAL;
|
||||
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_SW_ACT_REP, NULL);
|
||||
break;
|
||||
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
|
||||
if (mo == NULL) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx SW activated report for non-existent MO\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nm_rx_opstart_ack_chan(struct msgb *oml_msg)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
ts = abis_nm_get_ts(oml_msg);
|
||||
if (!ts)
|
||||
/* error already logged in abis_nm_get_ts() */
|
||||
return;
|
||||
if (!ts->fi) {
|
||||
LOG_TS(ts, LOGL_ERROR, "Channel OPSTART ACK for uninitialized TS\n");
|
||||
return;
|
||||
if (abis_nm_tlv_parse(&tp, bts, &foh->data[0], msgb_l3len(mb) - sizeof(*foh)) < 0) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_READY, NULL);
|
||||
|
||||
mo->ipaccess.obj_version = 0; /* implicit default */
|
||||
if (TLVP_PRES_LEN(&tp, NM_ATT_IPACC_OBJ_VERSION, 1)) {
|
||||
const uint8_t *versions = TLVP_VAL(&tp, NM_ATT_IPACC_OBJ_VERSION);
|
||||
char buf[256];
|
||||
struct osmo_strbuf sb = { .buf = buf, .len = sizeof(buf) };
|
||||
|
||||
/* nanoBTS may report several Object Versions; the first one will
|
||||
* be used by default unless requested explicitly before OPSTARTing. */
|
||||
mo->ipaccess.obj_version = versions[0];
|
||||
|
||||
OSMO_STRBUF_PRINTF(sb, "%u (default)", versions[0]);
|
||||
for (uint16_t i = 1; i < TLVP_LEN(&tp, NM_ATT_IPACC_OBJ_VERSION); i++)
|
||||
OSMO_STRBUF_PRINTF(sb, ", %u", versions[i]);
|
||||
LOGPFOH(DNM, LOGL_INFO, foh, "IPA Object Versions supported: %s\n", buf);
|
||||
}
|
||||
|
||||
osmo_fsm_inst_dispatch(mo->fi, NM_EV_SW_ACT_REP, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nm_rx_opstart_ack(struct msgb *oml_msg)
|
||||
{
|
||||
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
const struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_gprs_nsvc *nsvc;
|
||||
struct gsm_abis_mo *mo;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_SITE_MANAGER:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_BTS:
|
||||
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_RADIO_CARRIER:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_CHANNEL:
|
||||
nm_rx_opstart_ack_chan(oml_msg);
|
||||
break;
|
||||
case NM_OC_GPRS_NSE:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_CELL:
|
||||
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_NSVC:
|
||||
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
|
||||
if (mo == NULL)
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx OPSTART ACK for non-existent MO\n");
|
||||
else
|
||||
osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL);
|
||||
}
|
||||
|
||||
static void nm_rx_opstart_nack(struct msgb *oml_msg)
|
||||
{
|
||||
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
const struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
struct gsm_gprs_nsvc *nsvc;
|
||||
struct gsm_abis_mo *mo;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_SITE_MANAGER:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_BTS:
|
||||
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
|
||||
break;
|
||||
case NM_OC_RADIO_CARRIER:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_CHANNEL:
|
||||
if (!(ts = abis_nm_get_ts(oml_msg)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_NSE:
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nse.mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_CELL:
|
||||
osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
case NM_OC_GPRS_NSVC:
|
||||
if (!(nsvc = gsm_bts_sm_nsvc_num(bts->site_mgr, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_OPSTART_NACK, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
|
||||
if (mo == NULL)
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx OPSTART NACK for non-existent MO\n");
|
||||
else
|
||||
osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_NACK, NULL);
|
||||
}
|
||||
|
||||
static void nm_rx_get_attr_rep(struct msgb *oml_msg)
|
||||
|
@ -353,20 +274,16 @@ static void nm_rx_get_attr_rep(struct msgb *oml_msg)
|
|||
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx *trx;
|
||||
struct gsm_abis_mo *mo;
|
||||
|
||||
switch (foh->obj_class) {
|
||||
case NM_OC_BTS:
|
||||
osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_GET_ATTR_REP, NULL);
|
||||
break;
|
||||
case NM_OC_BASEB_TRANSC:
|
||||
if (!(trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr)))
|
||||
return;
|
||||
osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_GET_ATTR_REP, NULL);
|
||||
break;
|
||||
default:
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Get Attributes Response received on incorrect object class %d!\n", foh->obj_class);
|
||||
}
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
|
||||
if (mo == NULL)
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Rx Get Attribute Report for non-existent MO\n");
|
||||
else
|
||||
osmo_fsm_inst_dispatch(mo->fi, NM_EV_GET_ATTR_REP, NULL);
|
||||
}
|
||||
|
||||
static void nm_rx_set_bts_attr_ack(struct msgb *oml_msg)
|
||||
|
@ -375,6 +292,9 @@ static void nm_rx_set_bts_attr_ack(struct msgb *oml_msg)
|
|||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
if (foh->obj_class != NM_OC_BTS) {
|
||||
LOG_BTS(bts, DNM, LOGL_ERROR, "Set BTS Attr Ack received on non BTS object!\n");
|
||||
return;
|
||||
|
@ -388,8 +308,12 @@ static void nm_rx_set_radio_attr_ack(struct msgb *oml_msg)
|
|||
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
|
||||
if (!trx || foh->obj_class != NM_OC_RADIO_CARRIER) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Set Radio Carrier Attr Ack received on non Radio Carrier object!\n");
|
||||
return;
|
||||
|
@ -400,8 +324,14 @@ static void nm_rx_set_radio_attr_ack(struct msgb *oml_msg)
|
|||
static void nm_rx_set_chan_attr_ack(struct msgb *oml_msg)
|
||||
{
|
||||
struct abis_om_fom_hdr *foh = msgb_l3(oml_msg);
|
||||
struct gsm_bts_trx_ts *ts = abis_nm_get_ts(oml_msg);
|
||||
struct e1inp_sign_link *sign_link = oml_msg->dst;
|
||||
struct gsm_bts *bts = sign_link->trx->bts;
|
||||
struct gsm_bts_trx_ts *ts;
|
||||
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
return;
|
||||
|
||||
ts = abis_nm_get_ts(oml_msg);
|
||||
if (!ts || foh->obj_class != NM_OC_CHANNEL) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "Set Channel Attr Ack received on non Radio Channel object!\n");
|
||||
return;
|
||||
|
@ -565,7 +495,7 @@ find_bts_by_unitid(struct gsm_network *net, uint16_t site_id, uint16_t bts_id)
|
|||
struct gsm_bts *bts;
|
||||
|
||||
llist_for_each_entry(bts, &net->bts_list, list) {
|
||||
if (!is_ipaccess_bts(bts))
|
||||
if (!is_ipa_abisip_bts(bts))
|
||||
continue;
|
||||
|
||||
if (bts->ip_access.site_id == site_id &&
|
||||
|
@ -597,6 +527,8 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
|
|||
struct gsm_bts_trx_ts *ts ;
|
||||
uint8_t tn;
|
||||
uint8_t i;
|
||||
struct timespec tp;
|
||||
int rc;
|
||||
|
||||
/* First of all, remove deferred drop if enabled */
|
||||
osmo_timer_del(&bts->oml_drop_link_timer);
|
||||
|
@ -607,7 +539,8 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
|
|||
LOG_BTS(bts, DLINP, LOGL_NOTICE, "Dropping OML link: %s\n", reason);
|
||||
e1inp_sign_link_destroy(bts->oml_link);
|
||||
bts->oml_link = NULL;
|
||||
bts->uptime = 0;
|
||||
rc = osmo_clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
bts->updowntime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for downtime */
|
||||
osmo_stat_item_dec(osmo_stat_item_group_get_item(bts->bts_statg, BTS_STAT_OML_CONNECTED), 1);
|
||||
gsm_bts_stats_reset(bts);
|
||||
|
||||
|
@ -637,10 +570,14 @@ void ipaccess_drop_oml(struct gsm_bts *bts, const char *reason)
|
|||
for (i = 0; i < ARRAY_SIZE(bts->site_mgr->gprs.nsvc); i++)
|
||||
osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nsvc[i].mo.fi, NM_EV_OML_DOWN, NULL);
|
||||
|
||||
gsm_bts_all_ts_dispatch(bts, TS_EV_OML_DOWN, NULL);
|
||||
|
||||
bts->ip_access.flags = 0;
|
||||
|
||||
if (bts->model->features_get_reported) {
|
||||
/* Reset the feature vector */
|
||||
memset(bts->_features_data, 0, sizeof(bts->_features_data));
|
||||
bts->features_known = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through the list and see if we are the depndency of a BTS
|
||||
* and then drop the BTS. This can lead to some recursion but it
|
||||
|
@ -776,7 +713,7 @@ ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
|
|||
E1INP_SIGN_OML, bts->c0,
|
||||
bts->oml_tei, 0);
|
||||
rc = osmo_clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
bts->uptime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for uptime */
|
||||
bts->updowntime = (rc < 0) ? 0 : tp.tv_sec; /* we don't need sub-second precision for uptime */
|
||||
if (!(sign_link->trx->bts->ip_access.flags & OML_UP)) {
|
||||
e1inp_event(sign_link->ts, S_L_INP_TEI_UP,
|
||||
sign_link->tei, sign_link->sapi);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* ip.access nanoBTS specific code, OML attribute table generator */
|
||||
|
||||
/* (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
/* (C) 2016-2023 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* Author: Philipp Maier
|
||||
|
@ -26,13 +26,81 @@
|
|||
#include <osmocom/bsc/bts.h>
|
||||
#include <osmocom/gsm/bts_features.h>
|
||||
|
||||
const struct tlv_definition ipacc_eie_tlv_def = {
|
||||
.def = {
|
||||
/* TODO: add more values from enum ipac_eie */
|
||||
[NM_IPAC_EIE_FREQ_BANDS] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_MAX_TA] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_CIPH_ALGOS] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_CHAN_TYPES] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_CHAN_MODES] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_GPRS_CODING] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_RTP_FEATURES] = { TLV_TYPE_TL16V },
|
||||
[NM_IPAC_EIE_RSL_FEATURES] = { TLV_TYPE_TL16V },
|
||||
}
|
||||
};
|
||||
|
||||
static inline uint32_t ipacc_parse_supp_flags(const struct abis_om_fom_hdr *foh,
|
||||
const struct value_string *flags,
|
||||
const struct tlv_p_entry *e,
|
||||
const char *text)
|
||||
{
|
||||
uint32_t u32 = 0;
|
||||
|
||||
for (unsigned int i = 0; i < OSMO_MAX(e->len, 4); i++)
|
||||
u32 |= e->val[i] << (i * 8);
|
||||
for (const struct value_string *vs = flags; vs->value && vs->str; vs++) {
|
||||
if (u32 & vs->value)
|
||||
LOGPFOH(DNM, LOGL_INFO, foh, "%s '%s' is supported\n", text, vs->str);
|
||||
}
|
||||
|
||||
return u32;
|
||||
}
|
||||
|
||||
/* Parse ip.access Supported Features IE */
|
||||
int ipacc_parse_supp_features(const struct gsm_bts *bts,
|
||||
const struct abis_om_fom_hdr *foh,
|
||||
const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
const struct tlv_p_entry *e;
|
||||
struct tlv_parsed tp;
|
||||
|
||||
if (tlv_parse(&tp, &ipacc_eie_tlv_def, data, data_len, 0, 0) < 0) {
|
||||
LOGPFOH(DNM, LOGL_ERROR, foh, "%s(): tlv_parse failed\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: store the flags in the respective MO state */
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_FREQ_BANDS)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_freq_band_desc, e, "Freq. band");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CIPH_ALGOS)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_ciph_algo_desc, e, "Ciphering algorithm");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_TYPES)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_chant_desc, e, "Channel type");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_CHAN_MODES)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_chanm_desc, e, "Channel mode");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_GPRS_CODING)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_gprs_coding_desc, e, "GPRS Coding Scheme");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RTP_FEATURES)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_rtp_feat_desc, e, "RTP Feature");
|
||||
if ((e = TLVP_GET(&tp, NM_IPAC_EIE_RSL_FEATURES)) != NULL)
|
||||
ipacc_parse_supp_flags(foh, abis_nm_ipacc_rsl_feat_desc, e, "RSL Feature");
|
||||
if (TLVP_PRES_LEN(&tp, NM_IPAC_EIE_MAX_TA, 1)) {
|
||||
uint8_t u8 = *TLVP_VAL(&tp, NM_IPAC_EIE_MAX_TA);
|
||||
LOGPFOH(DNM, LOGL_DEBUG, foh, "Max Timing Advance %u\n", u8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 3GPP TS 52.021 section 8.6.1 Set BTS Attributes */
|
||||
struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts)
|
||||
{
|
||||
struct msgb *msgb;
|
||||
uint8_t buf[256];
|
||||
int rlt;
|
||||
msgb = msgb_alloc(1024, "nanobts_attr_bts");
|
||||
|
||||
msgb = msgb_alloc(1024, __func__);
|
||||
if (!msgb)
|
||||
return NULL;
|
||||
|
||||
|
@ -112,9 +180,12 @@ struct msgb *nanobts_gen_set_bts_attr(struct gsm_bts *bts)
|
|||
struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm)
|
||||
{
|
||||
struct msgb *msgb;
|
||||
uint8_t buf[256];
|
||||
uint8_t buf[2];
|
||||
struct abis_nm_ipacc_att_ns_cfg ns_cfg;
|
||||
struct abis_nm_ipacc_att_bssgp_cfg bssgp_cfg;
|
||||
struct gsm_bts *bts = gsm_bts_sm_get_bts(bts_sm);
|
||||
msgb = msgb_alloc(1024, "nanobts_attr_bts");
|
||||
|
||||
msgb = msgb_alloc(1024, __func__);
|
||||
if (!msgb)
|
||||
return NULL;
|
||||
|
||||
|
@ -123,36 +194,45 @@ struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm)
|
|||
buf[1] = bts_sm->gprs.nse.nsei & 0xff;
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_NSEI, 2, buf);
|
||||
|
||||
/* all timers in seconds */
|
||||
OSMO_ASSERT(ARRAY_SIZE(bts_sm->gprs.nse.timer) < sizeof(buf));
|
||||
memcpy(buf, bts_sm->gprs.nse.timer, ARRAY_SIZE(bts_sm->gprs.nse.timer));
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, 7, buf);
|
||||
osmo_static_assert(ARRAY_SIZE(bts_sm->gprs.nse.timer) == 7, nse_timer_array_wrong_size);
|
||||
ns_cfg = (struct abis_nm_ipacc_att_ns_cfg){
|
||||
.un_blocking_timer = bts_sm->gprs.nse.timer[0],
|
||||
.un_blocking_retries = bts_sm->gprs.nse.timer[1],
|
||||
.reset_timer = bts_sm->gprs.nse.timer[2],
|
||||
.reset_retries = bts_sm->gprs.nse.timer[3],
|
||||
.test_timer = bts_sm->gprs.nse.timer[4],
|
||||
.alive_timer = bts_sm->gprs.nse.timer[5],
|
||||
.alive_retries = bts_sm->gprs.nse.timer[6],
|
||||
};
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, sizeof(ns_cfg), (const uint8_t *)&ns_cfg);
|
||||
|
||||
/* all timers in seconds */
|
||||
buf[0] = 3; /* blockimg timer (T1) */
|
||||
buf[1] = 3; /* blocking retries */
|
||||
buf[2] = 3; /* unblocking retries */
|
||||
buf[3] = 3; /* reset timer (T2) */
|
||||
buf[4] = 3; /* reset retries */
|
||||
buf[5] = 10; /* suspend timer (T3) in 100ms */
|
||||
buf[6] = 3; /* suspend retries */
|
||||
buf[7] = 10; /* resume timer (T4) in 100ms */
|
||||
buf[8] = 3; /* resume retries */
|
||||
buf[9] = 10; /* capability update timer (T5) */
|
||||
buf[10] = 3; /* capability update retries */
|
||||
|
||||
OSMO_ASSERT(ARRAY_SIZE(bts->gprs.cell.timer) < sizeof(buf));
|
||||
memcpy(buf, bts->gprs.cell.timer, ARRAY_SIZE(bts->gprs.cell.timer));
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, 11, buf);
|
||||
osmo_static_assert(ARRAY_SIZE(bts->gprs.cell.timer) == 11, cell_timer_array_wrong_size);
|
||||
bssgp_cfg = (struct abis_nm_ipacc_att_bssgp_cfg){
|
||||
.t1_s = bts->gprs.cell.timer[0],
|
||||
.t1_blocking_retries = bts->gprs.cell.timer[1],
|
||||
.t1_unblocking_retries = bts->gprs.cell.timer[2],
|
||||
.t2_s = bts->gprs.cell.timer[3],
|
||||
.t2_retries = bts->gprs.cell.timer[4],
|
||||
.t3_100ms = bts->gprs.cell.timer[5],
|
||||
.t3_retries = bts->gprs.cell.timer[6],
|
||||
.t4_100ms = bts->gprs.cell.timer[7],
|
||||
.t4_retries = bts->gprs.cell.timer[8],
|
||||
.t5_s = bts->gprs.cell.timer[9],
|
||||
.t5_retries = bts->gprs.cell.timer[10],
|
||||
};
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, sizeof(bssgp_cfg), (const uint8_t *)&bssgp_cfg);
|
||||
|
||||
return msgb;
|
||||
}
|
||||
|
||||
struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts)
|
||||
{
|
||||
const struct gsm_gprs_cell *cell = &bts->gprs.cell;
|
||||
const struct gprs_rlc_cfg *rlcc = &cell->rlc_cfg;
|
||||
struct msgb *msgb;
|
||||
uint8_t buf[256];
|
||||
msgb = msgb_alloc(1024, "nanobts_attr_bts");
|
||||
uint8_t buf[2];
|
||||
|
||||
msgb = msgb_alloc(1024, __func__);
|
||||
if (!msgb)
|
||||
return NULL;
|
||||
|
||||
|
@ -160,49 +240,88 @@ struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts)
|
|||
buf[0] = bts->gprs.rac;
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RAC, 1, buf);
|
||||
|
||||
buf[0] = 5; /* repeat time (50ms) */
|
||||
buf[1] = 3; /* repeat count */
|
||||
buf[0] = rlcc->paging.repeat_time / 50; /* units of 50ms */
|
||||
buf[1] = rlcc->paging.repeat_count;
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_GPRS_PAGING_CFG, 2, buf);
|
||||
|
||||
/* BVCI 925 */
|
||||
buf[0] = bts->gprs.cell.bvci >> 8;
|
||||
buf[1] = bts->gprs.cell.bvci & 0xff;
|
||||
buf[0] = cell->bvci >> 8;
|
||||
buf[1] = cell->bvci & 0xff;
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf);
|
||||
|
||||
/* all timers in seconds, unless otherwise stated */
|
||||
buf[0] = 20; /* T3142 */
|
||||
buf[1] = 5; /* T3169 */
|
||||
buf[2] = 5; /* T3191 */
|
||||
buf[3] = 160; /* T3193 (units of 10ms) */
|
||||
buf[4] = 5; /* T3195 */
|
||||
buf[5] = 10; /* N3101 */
|
||||
buf[6] = 4; /* N3103 */
|
||||
buf[7] = 8; /* N3105 */
|
||||
buf[8] = 15; /* RLC CV countdown */
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf);
|
||||
const struct abis_nm_ipacc_att_rlc_cfg rlc_cfg = {
|
||||
.t3142 = rlcc->parameter[RLC_T3142],
|
||||
.t3169 = rlcc->parameter[RLC_T3169],
|
||||
.t3191 = rlcc->parameter[RLC_T3191],
|
||||
.t3193_10ms = rlcc->parameter[RLC_T3193],
|
||||
.t3195 = rlcc->parameter[RLC_T3195],
|
||||
.n3101 = rlcc->parameter[RLC_N3101],
|
||||
.n3103 = rlcc->parameter[RLC_N3103],
|
||||
.n3105 = rlcc->parameter[RLC_N3105],
|
||||
.rlc_cv_countdown = rlcc->parameter[CV_COUNTDOWN],
|
||||
};
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, sizeof(rlc_cfg), (const uint8_t *)&rlc_cfg);
|
||||
|
||||
if (bts->gprs.mode == BTS_GPRS_EGPRS) {
|
||||
buf[0] = 0x8f;
|
||||
buf[1] = 0xff;
|
||||
} else {
|
||||
buf[0] = 0x0f;
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
if (cell->mo.ipaccess.obj_version < 4)
|
||||
break;
|
||||
/* fall-through */
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
/* CS1..CS4 flags encoded in the first octet */
|
||||
buf[0] = rlcc->cs_mask & 0x0f;
|
||||
/* MCS1..MSC8 flags encoded in the second octet */
|
||||
buf[1] = 0x00;
|
||||
if (bts->gprs.mode == BTS_GPRS_EGPRS) {
|
||||
/* MSC9 is special and also goes to the first octet */
|
||||
if (rlcc->cs_mask & (1 << GPRS_MCS9))
|
||||
buf[0] |= (1 << 7);
|
||||
buf[1] = (rlcc->cs_mask >> 4) & 0xff;
|
||||
}
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf);
|
||||
|
||||
buf[0] = 0; /* T downlink TBF extension (0..500, high byte) */
|
||||
buf[1] = 250; /* T downlink TBF extension (0..500, low byte) */
|
||||
buf[2] = 0; /* T uplink TBF extension (0..500, high byte) */
|
||||
buf[3] = 250; /* T uplink TBF extension (0..500, low byte) */
|
||||
buf[4] = 2; /* CS2 */
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf);
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
if (cell->mo.ipaccess.obj_version < 20)
|
||||
break;
|
||||
/* fall-through */
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
{
|
||||
const struct abis_nm_ipacc_att_rlc_cfg_2 rlc_cfg_2 = {
|
||||
.t_dl_tbf_ext_10ms = htons(rlcc->parameter[T_DL_TBF_EXT] / 10),
|
||||
.t_ul_tbf_ext_10ms = htons(rlcc->parameter[T_UL_TBF_EXT] / 10),
|
||||
.initial_cs = rlcc->initial_cs,
|
||||
};
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2,
|
||||
sizeof(rlc_cfg_2), (const uint8_t *)&rlc_cfg_2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* EDGE model only, breaks older models.
|
||||
* Should inquire the BTS capabilities */
|
||||
buf[0] = 2; /* MCS2 */
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf);
|
||||
#endif
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
if (cell->mo.ipaccess.obj_version < 30)
|
||||
break;
|
||||
/* fall-through */
|
||||
case GSM_BTS_TYPE_OSMOBTS:
|
||||
{
|
||||
const struct abis_nm_ipacc_att_rlc_cfg_3 rlc_cfg_3 = {
|
||||
.initial_mcs = rlcc->initial_mcs,
|
||||
};
|
||||
msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3,
|
||||
sizeof(rlc_cfg_3), (const uint8_t *)&rlc_cfg_3);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return msgb;
|
||||
}
|
||||
|
@ -211,7 +330,8 @@ struct msgb *nanobts_gen_set_nsvc_attr(struct gsm_gprs_nsvc *nsvc)
|
|||
{
|
||||
struct msgb *msgb;
|
||||
uint8_t buf[256];
|
||||
msgb = msgb_alloc(1024, "nanobts_attr_bts");
|
||||
|
||||
msgb = msgb_alloc(1024, __func__);
|
||||
if (!msgb)
|
||||
return NULL;
|
||||
|
||||
|
@ -256,7 +376,8 @@ struct msgb *nanobts_gen_set_radio_attr(struct gsm_bts *bts,
|
|||
{
|
||||
struct msgb *msgb;
|
||||
uint8_t buf[256];
|
||||
msgb = msgb_alloc(1024, "nanobts_attr_bts");
|
||||
|
||||
msgb = msgb_alloc(1024, __func__);
|
||||
if (!msgb)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -1338,7 +1338,7 @@ static int find_element(uint8_t * data, int len, uint16_t id, uint8_t * value,
|
|||
|
||||
GET_NEXT_BYTE;
|
||||
|
||||
/* encoding bit, construced means that other elements are contained */
|
||||
/* encoding bit, constructed means that other elements are contained */
|
||||
constructed = ((ub & 0x20) ? 1 : 0);
|
||||
|
||||
if ((ub & 0x1F) == 0x1F) {
|
||||
|
@ -1397,7 +1397,7 @@ static int dump_elements(uint8_t * data, int len)
|
|||
|
||||
GET_NEXT_BYTE;
|
||||
|
||||
/* encoding bit, construced means that other elements are contained */
|
||||
/* encoding bit, constructed means that other elements are contained */
|
||||
constructed = ((ub & 0x20) ? 1 : 0);
|
||||
|
||||
if ((ub & 0x1F) == 0x1F) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Osmocom OsmoBTS specific code */
|
||||
|
||||
/* (C) 2010-2012 by Harald Welte <laforge@gnumonks.org>
|
||||
* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
|
||||
* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
*
|
||||
* All Rights Reserved
|
||||
*
|
||||
|
@ -159,8 +159,7 @@ void osmobts_enc_power_params_osmo_ext(struct msgb *msg, const struct gsm_power_
|
|||
*ie_len = msg->tail - (ie_len + 1);
|
||||
}
|
||||
|
||||
static int power_ctrl_set_c0_power_red(const struct gsm_bts *bts,
|
||||
const uint8_t red)
|
||||
static int power_ctrl_send_c0_power_red(const struct gsm_bts *bts, const uint8_t red)
|
||||
{
|
||||
struct abis_rsl_dchan_hdr *dh;
|
||||
struct msgb *msg;
|
||||
|
@ -169,10 +168,6 @@ static int power_ctrl_set_c0_power_red(const struct gsm_bts *bts,
|
|||
if (msg == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
LOGP(DRSL, LOGL_NOTICE, "%sabling BCCH carrier power reduction "
|
||||
"operation mode for BTS%u (maximum %u dB)\n",
|
||||
red ? "En" : "Dis", bts->nr, red);
|
||||
|
||||
/* Abuse the standard BS POWER CONTROL message by specifying 'Common Channel'
|
||||
* in the Protocol Discriminator field and 'BCCH' in the Channel Number IE. */
|
||||
dh = (struct abis_rsl_dchan_hdr *) msgb_put(msg, sizeof(*dh));
|
||||
|
@ -193,12 +188,13 @@ int bts_model_osmobts_init(void)
|
|||
model_osmobts = bts_model_nanobts;
|
||||
model_osmobts.name = "osmo-bts";
|
||||
model_osmobts.type = GSM_BTS_TYPE_OSMOBTS;
|
||||
model_osmobts.features_get_reported = true;
|
||||
|
||||
/* Unlike nanoBTS, osmo-bts does support SI2bis and SI2ter fine */
|
||||
model_osmobts.force_combined_si = false;
|
||||
|
||||
/* Power control API */
|
||||
model_osmobts.power_ctrl_set_c0_power_red = &power_ctrl_set_c0_power_red;
|
||||
model_osmobts.power_ctrl_send_c0_power_red = &power_ctrl_send_c0_power_red;
|
||||
|
||||
model_osmobts.features.data = &model_osmobts._features_data[0];
|
||||
model_osmobts.features.data_len =
|
||||
|
|
|
@ -401,7 +401,7 @@ static void nm_reconfig_ts(struct gsm_bts_trx_ts *ts)
|
|||
|
||||
abis_nm_set_channel_attr(ts, ccomb);
|
||||
|
||||
if (is_ipaccess_bts(ts->trx->bts))
|
||||
if (is_ipa_abisip_bts(ts->trx->bts))
|
||||
return;
|
||||
|
||||
switch (ts->pchan_from_config) {
|
||||
|
@ -423,57 +423,35 @@ static void nm_reconfig_trx(struct gsm_bts_trx *trx)
|
|||
|
||||
patch_nm_tables(trx->bts);
|
||||
|
||||
switch (trx->bts->type) {
|
||||
case GSM_BTS_TYPE_BS11:
|
||||
/* FIXME: discover this by fetching an attribute */
|
||||
/* FIXME: discover this by fetching an attribute */
|
||||
#if 0
|
||||
trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
|
||||
trx->nominal_power = 15; /* 15dBm == 30mW PA configuration */
|
||||
#else
|
||||
trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
|
||||
trx->nominal_power = 24; /* 24dBm == 250mW PA configuration */
|
||||
#endif
|
||||
abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
|
||||
e1l->e1_ts_ss);
|
||||
abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
|
||||
e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei_primary);
|
||||
abis_nm_conn_terr_sign(trx, e1l->e1_nr, e1l->e1_ts,
|
||||
e1l->e1_ts_ss);
|
||||
abis_nm_establish_tei(trx->bts, trx->nr, e1l->e1_nr,
|
||||
e1l->e1_ts, e1l->e1_ts_ss, trx->rsl_tei_primary);
|
||||
|
||||
/* Set Radio Attributes */
|
||||
if (trx == trx->bts->c0)
|
||||
abis_nm_set_radio_attr(trx, bs11_attr_radio,
|
||||
sizeof(bs11_attr_radio));
|
||||
else {
|
||||
uint8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
|
||||
uint8_t arfcn_low = trx->arfcn & 0xff;
|
||||
uint8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
|
||||
memcpy(trx1_attr_radio, bs11_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
/* Set Radio Attributes */
|
||||
if (trx == trx->bts->c0)
|
||||
abis_nm_set_radio_attr(trx, bs11_attr_radio,
|
||||
sizeof(bs11_attr_radio));
|
||||
else {
|
||||
uint8_t trx1_attr_radio[sizeof(bs11_attr_radio)];
|
||||
uint8_t arfcn_low = trx->arfcn & 0xff;
|
||||
uint8_t arfcn_high = (trx->arfcn >> 8) & 0x0f;
|
||||
memcpy(trx1_attr_radio, bs11_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
|
||||
/* patch ARFCN into TRX Attributes */
|
||||
trx1_attr_radio[2] &= 0xf0;
|
||||
trx1_attr_radio[2] |= arfcn_high;
|
||||
trx1_attr_radio[3] = arfcn_low;
|
||||
/* patch ARFCN into TRX Attributes */
|
||||
trx1_attr_radio[2] &= 0xf0;
|
||||
trx1_attr_radio[2] |= arfcn_high;
|
||||
trx1_attr_radio[3] = arfcn_low;
|
||||
|
||||
abis_nm_set_radio_attr(trx, trx1_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
}
|
||||
break;
|
||||
case GSM_BTS_TYPE_NANOBTS:
|
||||
switch (trx->bts->band) {
|
||||
case GSM_BAND_850:
|
||||
case GSM_BAND_900:
|
||||
trx->nominal_power = 20;
|
||||
break;
|
||||
case GSM_BAND_1800:
|
||||
case GSM_BAND_1900:
|
||||
trx->nominal_power = 23;
|
||||
break;
|
||||
default:
|
||||
LOGP(DNM, LOGL_ERROR, "Unsupported nanoBTS GSM band %s\n",
|
||||
gsm_band_name(trx->bts->band));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
abis_nm_set_radio_attr(trx, trx1_attr_radio,
|
||||
sizeof(trx1_attr_radio));
|
||||
}
|
||||
|
||||
for (i = 0; i < TRX_NR_TS; i++)
|
||||
|
@ -484,17 +462,11 @@ static void nm_reconfig_bts(struct gsm_bts *bts)
|
|||
{
|
||||
struct gsm_bts_trx *trx;
|
||||
|
||||
switch (bts->type) {
|
||||
case GSM_BTS_TYPE_BS11:
|
||||
patch_nm_tables(bts);
|
||||
abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
|
||||
abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
|
||||
abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
|
||||
abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
patch_nm_tables(bts);
|
||||
abis_nm_raw_msg(bts, sizeof(msg_1), msg_1); /* set BTS SiteMgr attr*/
|
||||
abis_nm_set_bts_attr(bts, bs11_attr_bts, sizeof(bs11_attr_bts));
|
||||
abis_nm_raw_msg(bts, sizeof(msg_3), msg_3); /* set BTS handover attr */
|
||||
abis_nm_raw_msg(bts, sizeof(msg_4), msg_4); /* set BTS power control attr */
|
||||
|
||||
llist_for_each_entry(trx, &bts->trx_list, list)
|
||||
nm_reconfig_trx(trx);
|
||||
|
|
|
@ -264,7 +264,7 @@ void gsm_trx_lock_rf(struct gsm_bts_trx *trx, bool locked, const char *reason)
|
|||
bool trx_is_usable(const struct gsm_bts_trx *trx)
|
||||
{
|
||||
/* FIXME: How does this behave for BS-11 ? */
|
||||
if (is_ipaccess_bts(trx->bts)) {
|
||||
if (is_ipa_abisip_bts(trx->bts)) {
|
||||
if (!nm_is_running(&trx->mo.nm_state) ||
|
||||
!nm_is_running(&trx->bb_transc.mo.nm_state))
|
||||
return false;
|
||||
|
|
|
@ -19,112 +19,11 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <osmocom/ctrl/control_cmd.h>
|
||||
|
||||
#include <osmocom/vty/command.h>
|
||||
#include <osmocom/vty/misc.h>
|
||||
|
||||
#include <osmocom/bsc/ctrl.h>
|
||||
#include <osmocom/bsc/osmo_bsc_rf.h>
|
||||
#include <osmocom/bsc/bts.h>
|
||||
#include <osmocom/bsc/ipaccess.h>
|
||||
#include <osmocom/bsc/chan_alloc.h>
|
||||
#include <osmocom/bsc/abis_nm.h>
|
||||
#include <osmocom/bsc/neighbor_ident.h>
|
||||
#include <osmocom/bsc/system_information.h>
|
||||
|
||||
/*********************
|
||||
* TS_NODE
|
||||
*********************/
|
||||
|
||||
static int verify_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, const char *value, void *_data)
|
||||
{
|
||||
int64_t arfcn;
|
||||
enum gsm_band unused;
|
||||
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
|
||||
return 1;
|
||||
if (gsm_arfcn2band_rc(arfcn, &unused) < 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int set_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = cmd->node;
|
||||
int arfcn = atoi(cmd->value);
|
||||
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE);
|
||||
|
||||
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
|
||||
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO); /* roll-back */
|
||||
cmd->reply = "Failed to re-generate Cell Allocation";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
/* Parameter format: "<arfcn>" */
|
||||
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_add, "hopping-arfcn-add");
|
||||
|
||||
static int verify_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, const char *value, void *_data)
|
||||
{
|
||||
int64_t arfcn;
|
||||
enum gsm_band unused;
|
||||
if (strcmp(value, "all") == 0)
|
||||
return 0;
|
||||
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
|
||||
return 1;
|
||||
if (gsm_arfcn2band_rc(arfcn, &unused) < 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int set_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = cmd->node;
|
||||
bool all = (strcmp(cmd->value, "all") == 0);
|
||||
int arfcn;
|
||||
|
||||
if (all) {
|
||||
bitvec_zero(&ts->hopping.arfcns);
|
||||
} else {
|
||||
arfcn = atoi(cmd->value);
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO);
|
||||
}
|
||||
|
||||
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
|
||||
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
|
||||
if (!all)
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE); /* roll-back */
|
||||
cmd->reply = "Failed to re-generate Cell Allocation";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
/* Parameter format: "(<arfcn>|all)" */
|
||||
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_del, "hopping-arfcn-del");
|
||||
|
||||
|
||||
static int bsc_bts_trx_ts_ctrl_cmds_install(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_add);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_del);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*********************
|
||||
* TRX_NODE
|
||||
*********************/
|
||||
|
||||
static int get_trx_rf_locked(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
|
@ -198,6 +97,51 @@ static int set_trx_max_power(struct ctrl_cmd *cmd, void *_data)
|
|||
}
|
||||
CTRL_CMD_DEFINE(trx_max_power, "max-power-reduction");
|
||||
|
||||
char *trx_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx *trx)
|
||||
{
|
||||
int ts_nr;
|
||||
bool first_ts = true;
|
||||
char *ts_dump, *dump;
|
||||
|
||||
dump = talloc_strdup(t, "");
|
||||
if (!dump)
|
||||
return NULL;
|
||||
|
||||
for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {
|
||||
ts_dump = ts_lchan_dump_full_ctrl(t, &trx->ts[ts_nr]);
|
||||
if (!ts_dump)
|
||||
return NULL;
|
||||
if (!strlen(ts_dump))
|
||||
continue;
|
||||
dump = talloc_asprintf_append(dump, first_ts ? "%s" : "\n%s", ts_dump);
|
||||
if (!dump)
|
||||
return NULL;
|
||||
first_ts = false;
|
||||
}
|
||||
|
||||
return dump;
|
||||
}
|
||||
|
||||
/* Return full information about all logical channels in a TRX.
|
||||
* format: bts.<0-255>.trx.<0-255>.show-lchan.full
|
||||
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
|
||||
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
|
||||
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
|
||||
*/
|
||||
static int get_trx_show_lchan_full(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx *trx = cmd->node;
|
||||
|
||||
cmd->reply = trx_lchan_dump_full_ctrl(cmd, trx);
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
CTRL_CMD_DEFINE_RO(trx_show_lchan_full, "show-lchan full");
|
||||
|
||||
int bsc_bts_trx_ctrl_cmds_install(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -205,6 +149,7 @@ int bsc_bts_trx_ctrl_cmds_install(void)
|
|||
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_max_power);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_arfcn);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_rf_locked);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_trx_show_lchan_full);
|
||||
|
||||
rc |= bsc_bts_trx_ts_ctrl_cmds_install();
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* (C) 2013-2015 by Holger Hans Peter Freyther
|
||||
* (C) 2013-2022 by sysmocom s.f.m.c. GmbH
|
||||
*
|
||||
* 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/ctrl/control_cmd.h>
|
||||
|
||||
#include <osmocom/bsc/ctrl.h>
|
||||
#include <osmocom/bsc/bts.h>
|
||||
#include <osmocom/bsc/system_information.h>
|
||||
|
||||
static int verify_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, const char *value, void *_data)
|
||||
{
|
||||
int64_t arfcn;
|
||||
enum gsm_band unused;
|
||||
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
|
||||
return 1;
|
||||
if (gsm_arfcn2band_rc(arfcn, &unused) < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int set_ts_hopping_arfcn_add(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = cmd->node;
|
||||
int arfcn = atoi(cmd->value);
|
||||
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE);
|
||||
|
||||
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
|
||||
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO); /* roll-back */
|
||||
cmd->reply = "Failed to re-generate Cell Allocation";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
/* Parameter format: "<arfcn>" */
|
||||
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_add, "hopping-arfcn-add");
|
||||
|
||||
static int verify_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, const char *value, void *_data)
|
||||
{
|
||||
int64_t arfcn;
|
||||
enum gsm_band unused;
|
||||
if (strcmp(value, "all") == 0)
|
||||
return 0;
|
||||
if (osmo_str_to_int64(&arfcn, value, 10, 0, 1024) < 0)
|
||||
return 1;
|
||||
if (gsm_arfcn2band_rc(arfcn, &unused) < 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
static int set_ts_hopping_arfcn_del(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = cmd->node;
|
||||
bool all = (strcmp(cmd->value, "all") == 0);
|
||||
int arfcn;
|
||||
|
||||
if (all) {
|
||||
bitvec_zero(&ts->hopping.arfcns);
|
||||
} else {
|
||||
arfcn = atoi(cmd->value);
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ZERO);
|
||||
}
|
||||
|
||||
/* Update Cell Allocation (list of all the frequencies allocated to a cell) */
|
||||
if (generate_cell_chan_alloc(ts->trx->bts) != 0) {
|
||||
if (!all)
|
||||
bitvec_set_bit_pos(&ts->hopping.arfcns, arfcn, ONE); /* roll-back */
|
||||
cmd->reply = "Failed to re-generate Cell Allocation";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
cmd->reply = "OK";
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
/* Parameter format: "(<arfcn>|all)" */
|
||||
CTRL_CMD_DEFINE_WO(ts_hopping_arfcn_del, "hopping-arfcn-del");
|
||||
|
||||
char *ts_lchan_dump_full_ctrl(const void *t, struct gsm_bts_trx_ts *ts)
|
||||
{
|
||||
bool first_lchan = true;
|
||||
char *lchan_dump, *dump;
|
||||
struct gsm_lchan *lchan;
|
||||
|
||||
dump = talloc_strdup(t, "");
|
||||
if (!dump)
|
||||
return NULL;
|
||||
|
||||
ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
|
||||
lchan_dump = lchan_dump_full_ctrl(t, lchan);
|
||||
if (!lchan_dump)
|
||||
return NULL;
|
||||
dump = talloc_asprintf_append(dump, first_lchan ? "%s" : "\n%s", lchan_dump);
|
||||
if (!dump)
|
||||
return NULL;
|
||||
first_lchan = false;
|
||||
}
|
||||
|
||||
return dump;
|
||||
}
|
||||
|
||||
/* Return full information about all logical channels in a timeslot.
|
||||
* format: bts.<0-255>.trx.<0-255>.ts.<0-8>.show-lchan.full
|
||||
* result format: New line delimited list of <bts>,<trx>,<ts>,<lchan>,<type>,<connection>,<state>,<last error>,<bs power>,
|
||||
* <ms power>,<interference dbm>, <interference band>,<channel mode>,<imsi>,<tmsi>,<ipa bound ip>,<ipa bound port>,
|
||||
* <ipa bound conn id>,<ipa conn ip>,<ipa conn port>,<ipa conn speech mode>
|
||||
*/
|
||||
static int get_ts_show_lchan_full(struct ctrl_cmd *cmd, void *data)
|
||||
{
|
||||
struct gsm_bts_trx_ts *ts = cmd->node;
|
||||
|
||||
cmd->reply = ts_lchan_dump_full_ctrl(cmd, ts);
|
||||
if (!cmd->reply) {
|
||||
cmd->reply = "OOM";
|
||||
return CTRL_CMD_ERROR;
|
||||
}
|
||||
|
||||
return CTRL_CMD_REPLY;
|
||||
}
|
||||
CTRL_CMD_DEFINE_RO(ts_show_lchan_full, "show-lchan full");
|
||||
|
||||
int bsc_bts_trx_ts_ctrl_cmds_install(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_add);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_hopping_arfcn_del);
|
||||
rc |= ctrl_cmd_install(CTRL_NODE_TS, &cmd_ts_show_lchan_full);
|
||||
|
||||
rc |= bsc_bts_trx_ts_lchan_ctrl_cmds_install();
|
||||
|
||||
return rc;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue