Projects
osmocom:latest
osmo-bsc
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 5
View file
osmo-bsc.spec
Changed
@@ -18,13 +18,13 @@ Name: osmo-bsc Requires: osmocom-latest -Version: 1.10.0 +Version: 1.11.0 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: osmo-bsc_1.10.0.tar.xz +Source: osmo-bsc_1.11.0.tar.xz Source1: rpmlintrc BuildRequires: automake >= 1.9 BuildRequires: libtool >= 2 @@ -33,15 +33,15 @@ 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(libosmo-mgcp-client) >= 1.12.0 +BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0 +BuildRequires: pkgconfig(libosmo-sigtran) >= 1.8.0 +BuildRequires: pkgconfig(libosmoabis) >= 1.5.0 +BuildRequires: pkgconfig(libosmocore) >= 1.9.0 +BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0 +BuildRequires: pkgconfig(libosmogb) >= 1.9.0 +BuildRequires: pkgconfig(libosmogsm) >= 1.9.0 +BuildRequires: pkgconfig(libosmovty) >= 1.9.0 BuildRequires: pkgconfig(talloc) %{?systemd_requires}
View file
osmo-bsc_1.10.0.tar.xz/tests/gprs_bvci_default.vty
Deleted
@@ -1,13 +0,0 @@ -OsmoBSC> enable -OsmoBSC# configure terminal -OsmoBSC(config)# network -OsmoBSC(config-net)# bts 0 -OsmoBSC(config-net-bts)# gprs mode gprs -OsmoBSC(config-net-bts)# exit - -OsmoBSC(config-net)# show running-config -... - bts 0 -... - gprs cell bvci 2 -...
View file
osmo-bsc_1.10.0.dsc -> osmo-bsc_1.11.0.dsc
Changed
@@ -2,13 +2,13 @@ Source: osmo-bsc Binary: osmo-bsc, osmo-bsc-dbg, abisip-find, osmo-bsc-ipaccess-utils, osmo-bsc-bs11-utils, osmo-bsc-meas-utils, osmo-bsc-doc Architecture: any all -Version: 1.10.0 +Version: 1.11.0 Maintainer: Osmocom team <openbsc@lists.osmocom.org> Homepage: https://projects.osmocom.org/projects/osmo-bsc Standards-Version: 3.9.8 Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bsc -Build-Depends: debhelper (>= 9), dh-autoreconf, autotools-dev, autoconf, automake, libtool, pkg-config, 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) +Build-Depends: debhelper (>= 10), dh-autoreconf, autotools-dev, autoconf, automake, libtool, pkg-config, python3-minimal, libcdk5-dev, libtalloc-dev, 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) Package-List: abisip-find deb net extra arch=any osmo-bsc deb net extra arch=any @@ -18,8 +18,8 @@ osmo-bsc-ipaccess-utils deb net extra arch=any osmo-bsc-meas-utils deb net extra arch=any Checksums-Sha1: - 2909746d5138851e61c7effd671daa08a0c7e9aa 588396 osmo-bsc_1.10.0.tar.xz + a09d63142aa52451b05081f75275f1ca0fce427e 616788 osmo-bsc_1.11.0.tar.xz Checksums-Sha256: - 3c2d1f3e67905bb9851a26b399247c6955ecfe10a9a41018d0ae2b70bb6dd46b 588396 osmo-bsc_1.10.0.tar.xz + 5f8fee07b7bbd3ad3115b19d75552cba50cd698ba9780e840b41e795291c2427 616788 osmo-bsc_1.11.0.tar.xz Files: - 9fd06989074d737bd2b0afd6fe826fc1 588396 osmo-bsc_1.10.0.tar.xz + a13ff42ac8182b8c59f9b60501ea7bb4 616788 osmo-bsc_1.11.0.tar.xz
View file
osmo-bsc_1.10.0.tar.xz/.tarball-version -> osmo-bsc_1.11.0.tar.xz/.tarball-version
Changed
@@ -1 +1 @@ -1.10.0 +1.11.0
View file
osmo-bsc_1.10.0.tar.xz/configure.ac -> osmo-bsc_1.11.0.tar.xz/configure.ac
Changed
@@ -36,38 +36,52 @@ 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 @@ 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 @@ ), 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 @@ 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 @@ 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)"
View file
osmo-bsc_1.10.0.tar.xz/contrib/jenkins.sh -> osmo-bsc_1.11.0.tar.xz/contrib/jenkins.sh
Changed
@@ -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 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 @@ 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
View file
osmo-bsc_1.10.0.tar.xz/contrib/osmo-bsc.spec.in -> osmo-bsc_1.11.0.tar.xz/contrib/osmo-bsc.spec.in
Changed
@@ -32,15 +32,15 @@ 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(libosmo-mgcp-client) >= 1.12.0 +BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0 +BuildRequires: pkgconfig(libosmo-sigtran) >= 1.8.0 +BuildRequires: pkgconfig(libosmoabis) >= 1.5.0 +BuildRequires: pkgconfig(libosmocore) >= 1.9.0 +BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0 +BuildRequires: pkgconfig(libosmogb) >= 1.9.0 +BuildRequires: pkgconfig(libosmogsm) >= 1.9.0 +BuildRequires: pkgconfig(libosmovty) >= 1.9.0 BuildRequires: pkgconfig(talloc) %{?systemd_requires}
View file
osmo-bsc_1.10.0.tar.xz/contrib/systemd/osmo-bsc.service -> osmo-bsc_1.11.0.tar.xz/contrib/systemd/osmo-bsc.service
Changed
@@ -1,6 +1,8 @@ Unit Description=Osmocom Base Station Controller (BSC) Wants=osmo-mgw.service +After=network-online.target +Wants=network-online.target Service Type=simple
View file
osmo-bsc_1.10.0.tar.xz/debian/changelog -> osmo-bsc_1.11.0.tar.xz/debian/changelog
Changed
@@ -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 EUARFCNs + * 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
View file
osmo-bsc_1.10.0.tar.xz/debian/compat -> osmo-bsc_1.11.0.tar.xz/debian/compat
Changed
@@ -1 +1 @@ -9 +10
View file
osmo-bsc_1.10.0.tar.xz/debian/control -> osmo-bsc_1.11.0.tar.xz/debian/control
Changed
@@ -2,7 +2,7 @@ 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 @@ 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
View file
osmo-bsc_1.10.0.tar.xz/debian/rules -> osmo-bsc_1.11.0.tar.xz/debian/rules
Changed
@@ -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:
View file
osmo-bsc_1.10.0.tar.xz/doc/Makefile.am -> osmo-bsc_1.11.0.tar.xz/doc/Makefile.am
Changed
@@ -14,6 +14,7 @@ $(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 @@ $(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
View file
osmo-bsc_1.11.0.tar.xz/doc/codec_resolution.msc
Added
@@ -0,0 +1,48 @@ +msc { + hscale="1.7"; + mslabel="MS/BTS",cfglabel="osmo-bsc.cfg",bsclabel="osmo-bsc",__msclabel="MSC",siplabel="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"; +}
View file
osmo-bsc_1.11.0.tar.xz/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-1trx-1pdch-16kbps.cfg
Added
@@ -0,0 +1,111 @@ +! +! 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 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
View file
osmo-bsc_1.11.0.tar.xz/doc/examples/osmo-bsc/ericsson/osmo-bsc.dug20-rus02-1trx-1pdch-64kbps.cfg
Added
@@ -0,0 +1,100 @@ +! +! OpenBSC (0.9.11.308-62d46) configuration saved from vty +!! +password foo +! +line vty + no login +! +log stderr + 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
View file
osmo-bsc_1.10.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg -> osmo-bsc_1.11.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc-4trx.cfg
Changed
@@ -46,22 +46,22 @@ 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 +71,28 @@ 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 +102,28 @@ 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 +133,28 @@ 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
View file
osmo-bsc_1.10.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc-minimal.cfg -> osmo-bsc_1.11.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc-minimal.cfg
Changed
@@ -30,4 +30,3 @@ e1_line 0 driver ipa msc 0 allow-emergency deny - codec-list fr1
View file
osmo-bsc_1.10.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg -> osmo-bsc_1.11.0.tar.xz/doc/examples/osmo-bsc/osmo-bsc_custom-sccp.cfg
Changed
@@ -74,6 +74,8 @@ 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
View file
osmo-bsc_1.10.0.tar.xz/doc/lchan.msc -> osmo-bsc_1.11.0.tar.xz/doc/lchan.msc
Changed
@@ -15,7 +15,7 @@ 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 @@ 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 @@ 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 @@ ...; 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 @@ 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 @@ 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"; ...; ...;
View file
osmo-bsc_1.11.0.tar.xz/doc/location_services_fsm_bsc.dot
Added
@@ -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 +}
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/bts-examples.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/bts-examples.adoc
Changed
@@ -175,6 +175,7 @@ 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 @@ <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 @@ <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
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/bts.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/bts.adoc
Changed
@@ -47,7 +47,7 @@ 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 @@ 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 @@ .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 @@ 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 @@ 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) + +`DYNAMIC/IPACCESS` is an alias for `TCH/F_PDCH`. -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 +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 @@ ==== 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 @@ 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 @@ 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 @@ <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. \ No newline at end of file
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/control.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/control.adoc
Changed
@@ -20,8 +20,6 @@ |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 @@ |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 @@ |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 @@ |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
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/interf_meas.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/interf_meas.adoc
Changed
@@ -63,7 +63,7 @@ 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;
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/overview.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/overview.adoc
Changed
@@ -135,11 +135,13 @@ 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.
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/chapters/running.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/chapters/running.adoc
Changed
@@ -87,6 +87,7 @@ 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 +219,47 @@ ---- 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 +----
View file
osmo-bsc_1.10.0.tar.xz/doc/manuals/osmobsc-usermanual.adoc -> osmo-bsc_1.11.0.tar.xz/doc/manuals/osmobsc-usermanual.adoc
Changed
@@ -16,6 +16,10 @@ 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
View file
osmo-bsc_1.10.0.tar.xz/doc/timeslot.msc -> osmo-bsc_1.11.0.tar.xz/doc/timeslot.msc
Changed
@@ -1,5 +1,5 @@ msc { - bts label="MS/BTS", bsclabel="BSC", bsc_tslabel="BSC timeslot FSM", bsc_lchanlabel="BSC lchan FSM"; + bts label="MS/BTS", bsclabel="BSC", bsc_tslabel="BSC timeslot FSM", bsc_lchanlabel="BSC lchan FSM", pcu_socklabel="PCU socket"; bsc_ts abox bsc_ts label="NOT_INITIALIZED"; @@ -88,6 +88,24 @@ 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";
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/Makefile.am -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/Makefile.am
Changed
@@ -19,6 +19,7 @@ chan_alloc.h \ chan_counts.h \ codec_pref.h \ + data_rate_pref.h \ ctrl.h \ debug.h \ e1_config.h \ @@ -66,4 +67,5 @@ osmo_bsc_lcls.h \ smscb.h \ power_control.h \ + vgcs_fsm.h \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/abis_rsl.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/abis_rsl.h
Changed
@@ -55,17 +55,20 @@ 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_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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/assignment_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/assignment_fsm.h
Changed
@@ -40,7 +40,7 @@ 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 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bsc_msc_data.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bsc_msc_data.h
Changed
@@ -71,6 +71,15 @@ 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 @@ 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 @@ 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 @@ /* 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_support16; int audio_length; + enum bsc_lcls_mode lcls_mode; bool lcls_codec_mismatch_allow;
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bsc_subscr_conn_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bsc_subscr_conn_fsm.h
Changed
@@ -57,8 +57,6 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bsc_subscriber.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bsc_subscriber.h
Changed
@@ -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 imsiGSM23003_IMSI_MAX_DIGITS+1; @@ -28,30 +40,21 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bssmap_reset.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bssmap_reset.h
Changed
@@ -28,4 +28,5 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bts.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bts.h
Changed
@@ -300,7 +300,7 @@ /* (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); @@ -523,6 +523,7 @@ 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 @@ uint16_t scramble_listMAX_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 @@ /* 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; @@ -678,77 +680,89 @@ #define GSM_BTS_SI(bts, i) (void *)((bts)->si_bufi0) /* 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_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 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 0; + return false; } static inline const struct osmo_location_area_id *bts_lai(struct gsm_bts *bts) @@ -814,6 +828,7 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/bts_sm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/bts_sm.h
Changed
@@ -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
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/codec_pref.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/codec_pref.h
Changed
@@ -17,6 +17,10 @@ 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,
View file
osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/data_rate_pref.h
Added
@@ -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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/debug.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/debug.h
Changed
@@ -28,6 +28,7 @@ DAS, DCBS, DLCS, + DASCI, DRESET, DLOOP, Debug_LastEntry,
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/gsm_04_08_rr.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/gsm_04_08_rr.h
Changed
@@ -18,7 +18,7 @@ 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,6 +33,9 @@ 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 gsm48_parse_meas_rep(struct gsm_meas_rep *rep, struct msgb *msg);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/gsm_08_08.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/gsm_08_08.h
Changed
@@ -13,3 +13,4 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/gsm_data.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/gsm_data.h
Changed
@@ -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 @@ enum assign_for assign_for; bool aoip; + bool vgcs; uint16_t msc_assigned_cic; @@ -163,6 +169,9 @@ /* 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_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 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 @@ /* 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 @@ /* 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 @@ } 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_str16; + /* 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_addrINET6_ADDRSTRLEN; + uint16_t msc_rtp_port; + } vgcs_chan; }; @@ -495,9 +571,9 @@ * * 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 @@ -806,10 +882,7 @@ 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); @@ -863,6 +936,19 @@ 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 +985,10 @@ /* 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 +1014,8 @@ * 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 +1058,10 @@ struct chan_counts chan_counts; struct all_allocated all_allocated; + + /* PCU socket state */ + char *pcu_sock_path; + struct pcu_sock_state *pcu_state; }; struct gsm_audio_support { @@ -984,6 +1069,8 @@ 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 +1107,6 @@ 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) */
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/handover_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/handover_fsm.h
Changed
@@ -55,8 +55,6 @@ 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,
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/lchan.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/lchan.h
Changed
@@ -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 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 @@ 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 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 @@ * 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 @@ 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 @@ * 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 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 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 @@ 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 @@ * 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. */
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/lchan_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/lchan_fsm.h
Changed
@@ -56,8 +56,6 @@ 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 +78,8 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/lchan_select.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/lchan_select.h
Changed
@@ -5,6 +5,7 @@ SELECT_FOR_MS_CHAN_REQ, SELECT_FOR_ASSIGNMENT, SELECT_FOR_HANDOVER, + SELECT_FOR_VGCS, }; extern const struct value_string lchan_select_reason_names;
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/meas_feed.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/meas_feed.h
Changed
@@ -35,9 +35,12 @@ }; #define MEAS_FEED_VERSION 1 +#define MEAS_FEED_WQUEUE_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_wqueue_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_wqueue_max_length_get(void);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/nm_common_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/nm_common_fsm.h
Changed
@@ -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
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/osmo_bsc_sigtran.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/osmo_bsc_sigtran.h
Changed
@@ -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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/paging.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/paging.h
Changed
@@ -150,9 +150,6 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/pcu_if.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/pcu_if.h
Changed
@@ -8,12 +8,15 @@ #define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u)) 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 */ }; +/* 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 +24,13 @@ 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 */
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/pcuif_proto.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/pcuif_proto.h
Changed
@@ -3,10 +3,12 @@ #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 0x0b #define TXT_MAX_LEN 128 /* msg_type */ @@ -16,7 +18,7 @@ #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 */ @@ -39,7 +41,8 @@ #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 */ @@ -91,19 +94,10 @@ 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 { @@ -269,6 +263,32 @@ } 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 imsiOSMO_IMSI_BUF_SIZE; + /* GSM mac-block (with immediate assignment message) */ + uint8_t dataGSM_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 dataGSM_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 */ @@ -278,7 +298,7 @@ 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;
View file
osmo-bsc_1.10.0.tar.xz/include/osmocom/bsc/timeslot_fsm.h -> osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/timeslot_fsm.h
Changed
@@ -36,10 +36,18 @@ 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_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);
View file
osmo-bsc_1.11.0.tar.xz/include/osmocom/bsc/vgcs_fsm.h
Added
@@ -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);
View file
osmo-bsc_1.10.0.tar.xz/osmoappdesc.py -> osmo-bsc_1.11.0.tar.xz/osmoappdesc.py
Changed
@@ -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" }
View file
osmo-bsc_1.10.0.tar.xz/src/Makefile.am -> osmo-bsc_1.11.0.tar.xz/src/Makefile.am
Changed
@@ -13,12 +13,6 @@ $(COVERAGE_CFLAGS) \ $(NULL) -AM_LDFLAGS = \ - $(LIBOSMOCORE_LIBS) \ - $(LIBOSMOGSM_LIBS) \ - $(COVERAGE_LDFLAGS) \ - $(NULL) - SUBDIRS = \ osmo-bsc \ utils \
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/Makefile.am -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/Makefile.am
Changed
@@ -62,6 +62,7 @@ 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 +73,7 @@ handover_fsm.c \ handover_logic.c \ handover_vty.c \ + vgcs_fsm.c \ lb.c \ lchan.c \ lchan_fsm.c \
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/a_reset.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/a_reset.c
Changed
@@ -42,7 +42,7 @@ 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_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);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/abis_nm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/abis_nm.c
Changed
@@ -573,7 +573,7 @@ struct abis_nm_sw_desc sw_descrMAX_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)) { + if (bts->type == GSM_BTS_TYPE_OSMOBTS && TLVP_PRES_LEN(tp, NM_ATT_MANUF_ID, 2)) { len = TLVP_LEN(tp, NM_ATT_MANUF_ID); /* log potential BTS feature vector overflow */ @@ -606,19 +606,6 @@ " 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); - } - } - } } /* Parse Attribute Response Info content for 3GPP TS 52.021 §9.4.28 Manufacturer Dependent State */ @@ -2645,8 +2632,8 @@ static int bs11_read_swl_file(struct abis_nm_bs11_sw *bs11_sw) { + struct file_list_entry *fle; char linebuf255; - struct llist_head *lh, *lh2; FILE *swl; int rc = 0; @@ -2655,10 +2642,8 @@ 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_id12+1;
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/abis_om2000.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/abis_om2000.c
Changed
@@ -68,20 +68,11 @@ { 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; }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/abis_rsl.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/abis_rsl.c
Changed
@@ -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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ 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 @@ /* 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 @@ 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 @@ } /* 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 bufGSM_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 @@ } /* 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 @@ } /* 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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: @@ -2025,12 +2166,12 @@ 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 +2466,7 @@ 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 +2481,9 @@ switch (rslh->data0) { case RSL_IE_PAGING_LOAD: sd.pg_buf_space = rslh->data1 << 8 | rslh->data2; - 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 +2555,7 @@ { 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 +2567,8 @@ 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 +2643,13 @@ 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 +2677,17 @@ 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->data0 == RSL_IE_L3_INFO) { msg->l3h = &rllh->data3; + /* 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 +2727,14 @@ msg->lchan->sapissapi = 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->data0 == RSL_IE_L3_INFO) { msg->l3h = &rllh->data3; return gsm0408_rcvmsg(msg, rllh->link_id); @@ -2589,6 +2749,14 @@ 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 +2779,68 @@ 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 +2893,11 @@ 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 +3013,27 @@ 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 +3067,12 @@ 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 +3095,24 @@ 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); }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/assignment_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/assignment_fsm.c
Changed
@@ -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 @@ 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 @@ 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 _gsm0808_ass_compl_extend_osmux(struct msgb *msg, uint8_t cid) +void bssap_extend_osmux(struct msgb *msg, uint8_t cid) { OSMO_ASSERT(msg->l3h1 == msgb_l3len(msg) - 2); /*TL not in len */ msgb_tv_put(msg, GSM0808_IE_OSMO_OSMUX_CID, cid); @@ -185,6 +186,11 @@ 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 @@ 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 @@ } } - /* 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 @@ 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 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 @@ 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 @@ 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 @@ } } -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_listi.chan_mode); + rc = chan_mode_to_ch_indctr(req->ch_mode_rate_listi.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 @@ 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_list0.chan_mode), - gsm48_chan_mode_name(req->ch_mode_rate_listi.chan_mode)); + "Channel mode %s has ch_indctr %d, channel type has ch_indctr %d", + gsm48_chan_mode_name(req->ch_mode_rate_listi.chan_mode), + rc, req->ch_indctr); return -EINVAL; } } - conn->assignment.requires_voice_stream = requires_voice_pref; return 0; } @@ -470,6 +489,8 @@ .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 @@ 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 @@ 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 @@ 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 @@ .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_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 @@ { 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 @@ 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 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_ctrl.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_ctrl.c
Changed
@@ -187,7 +187,7 @@ 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 @@ cmd->reply = talloc_asprintf(cmd, "%u", locked); if (!cmd->reply) { - cmd->reply = "OOM."; + cmd->reply = "OOM"; return CTRL_CMD_ERROR; } @@ -367,7 +367,7 @@ { 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 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_rf_ctrl.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_rf_ctrl.c
Changed
@@ -303,7 +303,7 @@ 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 */
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_sccp.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_sccp.c
Changed
@@ -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; + sccp_conn->conn_id = SCCP_CONN_ID_UNSET; + sccp_conn->gscon = gscon; +} - /* 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. */ +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; +} - 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; - } - } +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; - if (!conn_id_already_used) - return conn_id; + 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 -1; + + 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; }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_subscr_conn_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_subscr_conn_fsm.c
Changed
@@ -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 @@ {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 @@ 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 @@ 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 @@ 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 @@ lcs_loc_req_start(conn, msg); return; + case BSS_MAP_MSG_VGCS_VBS_SETUP: + rate_ctr_inc(&conn->sccp.msc->msc_ctrs->ctrMSC_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->ctrMSC_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ .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 @@ 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 @@ { 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) : ""); }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_subscriber.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_subscriber.c
Changed
@@ -65,14 +65,27 @@ 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 @@ }; 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bsc_vty.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bsc_vty.c
Changed
@@ -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 @@ 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", @@ -381,6 +385,7 @@ uint16_t meas_port; char *meas_host; const char *meas_scenario; + unsigned int max_len = meas_feed_wqueue_max_length_get(); meas_feed_cfg_get(&meas_host, &meas_port); meas_scenario = meas_feed_scenario_get(); @@ -391,6 +396,9 @@ if (strlen(meas_scenario) > 0) vty_out(vty, " meas-feed scenario %s%s", meas_scenario, VTY_NEWLINE); + if (max_len != MEAS_FEED_WQUEUE_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 +414,9 @@ vty_out(vty, "%s", VTY_NEWLINE); } + if (gsmnet->pcu_sock_path) + vty_out(vty, " pcu-socket %s%s", gsmnet->pcu_sock_path, VTY_NEWLINE); + neighbor_ident_vty_write_network(vty, " "); mgcp_client_pool_config_write(vty, " "); @@ -727,7 +738,7 @@ 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", @@ -862,8 +873,7 @@ 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 +883,8 @@ .val = tsc, }, }; + if (vamos) + info.type_for = LCHAN_TYPE_FOR_VAMOS; lchan_mode_modify(lchan, &info); return CMD_SUCCESS; @@ -1261,8 +1273,8 @@ 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 +1320,8 @@ 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 +1431,22 @@ } 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 +1537,8 @@ 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 +1641,11 @@ } 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 +2071,8 @@ lchan = &ts->lchanss_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 +2420,16 @@ 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_wqueue_max_length_set(atoi(argv0)); + 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 +2486,42 @@ return CMD_SUCCESS; } +DEFUN_ATTR(cfg_net_pcu_sock, + cfg_net_pcu_sock_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, argv0); + 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 +2612,10 @@ if (i != 0) vty_out(vty, " "); - if (msc->audio_supporti->hr) - vty_out(vty, "hr%.1u", msc->audio_supporti->ver); + if (msc->audio_supporti.hr) + vty_out(vty, "hr%u", msc->audio_supporti.ver); else - vty_out(vty, "fr%.1u", msc->audio_supporti->ver); + vty_out(vty, "fr%u", msc->audio_supporti.ver); } vty_out(vty, "%s", VTY_NEWLINE); @@ -2640,8 +2702,8 @@ 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 +2721,8 @@ 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 +2737,8 @@ 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 +2746,8 @@ 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 +2755,8 @@ 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 +2764,64 @@ 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 tmpARRAY_SIZE(data->audio_support); + const char *arg = NULL; int i; - /* check all given arguments first */ - for (i = 0; i < argc; ++i) { - /* check for hrX or frX */ - if (strlen(argvi) != 3 - || argvi1 != 'r' - || (argvi0 != 'h' && argvi0 != 'f') - || argvi2 < 0x30 - || argvi2 > 0x39) - goto error; - } - - /* 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); - data->audio_length = argc; + /* 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; + } - for (i = 0; i < argc; ++i) { - data->audio_supporti = talloc_zero(data->audio_support, - struct gsm_audio_support); - data->audio_supporti->ver = atoi(argvi + 2); + /* check all given arguments first */ + for (i = 0; i < argc; i++) { + int j; + int ver; + arg = argvi; + + if (strncmp("hr", arg, 2) == 0) + tmpi.hr = 1; + else if (strncmp("fr", arg, 2) == 0) + tmpi.hr = 0; + else + goto invalid_arg; - if (strncmp("hr", argvi, 2) == 0) - data->audio_supporti->hr = 1; - else if (strncmp("fr", argvi, 2) == 0) - data->audio_supporti->hr = 0; + ver = atoi(arg + 2); + if (ver < 1 || ver > 7) + goto invalid_arg; + tmpi.ver = ver; + + if (tmpi.hr == 1 && ver == 2) + goto invalid_arg; + + /* prevent duplicate entries */ + for (j = 0; j < i; j++) { + if (gsm_audio_support_cmp(&tmpj, &tmpi) == 0) { + vty_out(vty, "duplicate entry in 'msc' / 'codec-list': %s%s", argvi, VTY_NEWLINE); + return CMD_WARNING; + } + } } + memcpy(data->audio_support, tmp, sizeof(data->audio_support)); + data->audio_length = argc; + return CMD_SUCCESS; -error: - vty_out(vty, "Codec name must be hrX or frX. Was '%s'%s", - argvi, 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" @@ -3275,7 +3345,7 @@ 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,8 +3594,11 @@ 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_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); @@ -3614,12 +3687,12 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bssmap_reset.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bssmap_reset.c
Changed
@@ -251,6 +251,12 @@ 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);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts.c
Changed
@@ -117,8 +117,20 @@ 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_default11 = { + 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, @@ -888,14 +900,14 @@ return (base->depends_onidx & (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 +990,32 @@ 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->ts0.c0_max_power_red_db = 0; @@ -1003,7 +1026,7 @@ 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 +1655,12 @@ "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 +1679,12 @@ "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",
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_ctrl.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_ctrl.c
Changed
@@ -34,6 +34,9 @@ #include <osmocom/bsc/chan_alloc.h> #include <osmocom/bsc/abis_nm.h> #include <osmocom/bsc/neighbor_ident.h> +#include <osmocom/bsc/system_information.h> + +#include <osmocom/gsm/sysinfo.h> static int location_equal(struct bts_location *a, struct bts_location *b) { @@ -247,13 +250,15 @@ /* BTS related commands below */ CTRL_CMD_DEFINE_RANGE(bts_lac, "location-area-code", struct gsm_bts, location_area_code, 0, 65535); CTRL_CMD_DEFINE_RANGE(bts_ci, "cell-identity", struct gsm_bts, cell_identity, 0, 65535); +CTRL_CMD_DEFINE_RANGE(bts_bsic, "bsic", struct gsm_bts, bsic, 0, 63); +CTRL_CMD_DEFINE_RANGE(bts_rach_max_delay, "rach-max-delay", struct gsm_bts, rach_max_delay, 1, 127); static int set_bts_apply_config(struct ctrl_cmd *cmd, void *data) { struct gsm_bts *bts = cmd->node; - if (!is_ipaccess_bts(bts)) { - cmd->reply = "BTS is not IP based"; + if (!is_ipa_abisip_bts(bts)) { + cmd->reply = "BTS is not IPA Abis/IP based"; return CTRL_CMD_ERROR; } @@ -430,7 +435,7 @@ cmd->reply = talloc_asprintf(cmd, "%s,%s,%s", oper, admin, policy); if (!cmd->reply) { - cmd->reply = "OOM."; + cmd->reply = "OOM"; return CTRL_CMD_ERROR; } @@ -453,7 +458,7 @@ cmd->reply = bsc_rf_states_of_bts_c(cmd, bts); if (!cmd->reply) { - cmd->reply = "OOM."; + cmd->reply = "OOM"; return CTRL_CMD_ERROR; } @@ -482,7 +487,7 @@ cmd->reply = talloc_asprintf(cmd, "%u", bts->c0_max_power_red_db); if (!cmd->reply) { - cmd->reply = "OOM."; + cmd->reply = "OOM"; return CTRL_CMD_ERROR; } @@ -496,19 +501,65 @@ int rc; rc = gsm_bts_set_c0_power_red(bts, red); - if (rc == -ENOTSUP) { + switch (rc) { + case 0: /* success */ + return get_bts_c0_power_red(cmd, data); + case -ENOTCONN: + cmd->reply = "BTS is offline"; + return CTRL_CMD_ERROR; + case -ENOTSUP: cmd->reply = "BCCH carrier power reduction is not supported"; return CTRL_CMD_ERROR; - } else if (rc != 0) { + default: cmd->reply = "Failed to enable BCCH carrier power reduction"; return CTRL_CMD_ERROR; } - - return get_bts_c0_power_red(cmd, data); } CTRL_CMD_DEFINE(bts_c0_power_red, "c0-power-reduction"); +static int get_bts_neighbor_list(struct ctrl_cmd *cmd, const struct bitvec *neigh_list) +{ + int i; + char *pos; + + /* The length of "1 2 3 ... 1023" is 4009, so 4096 is enough */ + cmd->reply = talloc_size(cmd, 4096); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + cmd->reply0 = '\0'; + + pos = cmd->reply; + + for (i = 0; i < neigh_list->data_len * 8; i++) { + if (!bitvec_get_bit_pos(neigh_list, i)) + continue; + + pos += sprintf(pos, i == 0 ? "%u" : " %u", i); + } + + return CTRL_CMD_REPLY; +} + +static int get_bts_neighbor_list_si2(struct ctrl_cmd *cmd, void *data) +{ + const struct gsm_bts *bts = cmd->node; + return get_bts_neighbor_list(cmd, &bts->si_common.neigh_list); +} + +CTRL_CMD_DEFINE_RO(bts_neighbor_list_si2, "neighbor-list si2"); + +static int get_bts_neighbor_list_si5(struct ctrl_cmd *cmd, void *data) +{ + const struct gsm_bts *bts = cmd->node; + return get_bts_neighbor_list(cmd, &bts->si_common.si5_neigh_list); +} + +CTRL_CMD_DEFINE_RO(bts_neighbor_list_si5, "neighbor-list si5"); + static int verify_bts_neighbor_list_add_del(struct ctrl_cmd *cmd, const char *value, void *_data) { int arfcn; @@ -521,10 +572,8 @@ return 0; } -static int set_bts_neighbor_list_add_del(struct ctrl_cmd *cmd, void *data, bool add) +static int set_bts_neighbor_list_add_del(struct ctrl_cmd *cmd, void *data, bool add, struct bitvec *neigh_list) { - struct gsm_bts *bts = cmd->node; - struct bitvec *bv = &bts->si_common.neigh_list; int arfcn_int; uint16_t arfcn; enum gsm_band unused; @@ -535,20 +584,15 @@ } arfcn = (uint16_t) arfcn_int; - if (bts->neigh_list_manual_mode == NL_MODE_AUTOMATIC) { - cmd->reply = "Neighbor list not in manual mode"; - return CTRL_CMD_ERROR; - } - if (gsm_arfcn2band_rc(arfcn, &unused) < 0) { cmd->reply = "Invalid arfcn detected"; return CTRL_CMD_ERROR; } if (add) - bitvec_set_bit_pos(bv, arfcn, 1); + bitvec_set_bit_pos(neigh_list, arfcn, 1); else - bitvec_set_bit_pos(bv, arfcn, 0); + bitvec_set_bit_pos(neigh_list, arfcn, 0); cmd->reply = "OK"; return CTRL_CMD_REPLY; @@ -561,7 +605,12 @@ static int set_bts_neighbor_list_add(struct ctrl_cmd *cmd, void *data) { - return set_bts_neighbor_list_add_del(cmd, data, true); + struct gsm_bts *bts = cmd->node; + if (bts->neigh_list_manual_mode == NL_MODE_AUTOMATIC) { + cmd->reply = "Neighbor list not in manual mode"; + return CTRL_CMD_ERROR; + } + return set_bts_neighbor_list_add_del(cmd, data, true, &bts->si_common.neigh_list); } CTRL_CMD_DEFINE_WO(bts_neighbor_list_add, "neighbor-list add"); @@ -573,11 +622,50 @@ static int set_bts_neighbor_list_del(struct ctrl_cmd *cmd, void *data) { - return set_bts_neighbor_list_add_del(cmd, data, false); + struct gsm_bts *bts = cmd->node; + if (bts->neigh_list_manual_mode == NL_MODE_AUTOMATIC) { + cmd->reply = "Neighbor list not in manual mode"; + return CTRL_CMD_ERROR; + } + return set_bts_neighbor_list_add_del(cmd, data, false, &bts->si_common.neigh_list); } CTRL_CMD_DEFINE_WO(bts_neighbor_list_del, "neighbor-list del"); +static int verify_bts_neighbor_list_si5_add(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + return verify_bts_neighbor_list_add_del(cmd, value, _data); +} + +static int set_bts_neighbor_list_si5_add(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + if (bts->neigh_list_manual_mode != NL_MODE_MANUAL_SI5SEP) { + cmd->reply = "Neighbor list not in manual mode with separate SI5"; + return CTRL_CMD_ERROR; + } + return set_bts_neighbor_list_add_del(cmd, data, true, &bts->si_common.si5_neigh_list); +} + +CTRL_CMD_DEFINE_WO(bts_neighbor_list_si5_add, "neighbor-list si5-add"); + +static int verify_bts_neighbor_list_si5_del(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + return verify_bts_neighbor_list_add_del(cmd, value, _data); +} + +static int set_bts_neighbor_list_si5_del(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + if (bts->neigh_list_manual_mode != NL_MODE_MANUAL_SI5SEP) { + cmd->reply = "Neighbor list not in manual mode with separate SI5"; + return CTRL_CMD_ERROR; + } + return set_bts_neighbor_list_add_del(cmd, data, false, &bts->si_common.si5_neigh_list); +} + +CTRL_CMD_DEFINE_WO(bts_neighbor_list_si5_del, "neighbor-list si5-del"); + static int verify_bts_neighbor_list_mode(struct ctrl_cmd *cmd, const char *value, void *_data) { if (!strcmp(value, "automatic")) @@ -623,6 +711,625 @@ CTRL_CMD_DEFINE_WO(bts_neighbor_list_mode, "neighbor-list mode"); +/* si2quater neighbor management: delete an EARFCN. + * Format: bts.<0-255>.si2quater-neighbor-list.del.earfcn EARFCN + * EARFCN is in range 0..65535 */ +static int set_bts_si2quater_neighbor_list_del_earfcn(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)cmd->node; + struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; + int earfcn; + + if (osmo_str_to_int(&earfcn, cmd->value, 10, 0, 65535) < 0) { + cmd->reply = "Failed to parse neighbor EARFCN value"; + return CTRL_CMD_ERROR; + } + + if (osmo_earfcn_del(e, earfcn) < 0) { + cmd->reply = "Failed to delete a (not existent?) neighbor EARFCN"; + return CTRL_CMD_ERROR; + } + + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_WO_NOVRF(bts_si2quater_neighbor_list_del_earfcn, + "si2quater-neighbor-list del earfcn"); + +/* si2quater neighbor management: delete an UARFCN + * Format: bts.<0-255>.si2quater-neighbor-list.del.uarfcn UARFCN,SCRAMBLE + * UARFCN is in range 0..16383, SCRAMBLE is in range 0..511 */ +static int set_bts_si2quater_neighbor_list_del_uarfcn(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)cmd->node; + char *uarfcn_str, *scramble_str; + char *tmp, *saveptr; + int uarfcn, scramble; + + tmp = talloc_strdup(OTC_SELECT, cmd->value); + if (!tmp) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + uarfcn_str = strtok_r(tmp, ",", &saveptr); + scramble_str = strtok_r(NULL, ",", &saveptr); + + if (!uarfcn_str || osmo_str_to_int(&uarfcn, uarfcn_str, 10, 0, 16383) < 0) { + cmd->reply = "Failed to parse neighbor UARFCN value"; + return CTRL_CMD_ERROR; + } + + if (!scramble_str || osmo_str_to_int(&scramble, scramble_str, 10, 0, 511) < 0) { + cmd->reply = "Failed to parse neighbor scrambling code"; + return CTRL_CMD_ERROR; + } + + if (bts_uarfcn_del(bts, uarfcn, scramble) < 0) { + cmd->reply = "Failed to delete a (not existent?) neighbor UARFCN"; + return CTRL_CMD_ERROR; + } + + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_WO_NOVRF(bts_si2quater_neighbor_list_del_uarfcn, + "si2quater-neighbor-list del uarfcn"); + +static int verify_bts_si2quater_neighbor_list_add_earfcn(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + char *earfcn_str, *thresh_hi_str, *thresh_lo_str, *prio_str, *qrxlv_str, *meas_str, *saveptr, *tmp; + int earfcn, thresh_hi, thresh_lo, prio, qrxlv, meas; + + tmp = talloc_strdup(cmd, value); + if (!tmp) + return 1; + + earfcn_str = strtok_r(tmp, ",", &saveptr); + thresh_hi_str = strtok_r(NULL, ",", &saveptr); + thresh_lo_str = strtok_r(NULL, ",", &saveptr); + prio_str = strtok_r(NULL, ",", &saveptr); + qrxlv_str = strtok_r(NULL, ",", &saveptr); + meas_str = strtok_r(NULL, "\0", &saveptr); + + + if (!earfcn_str || osmo_str_to_int(&earfcn, earfcn_str, 10, 0, 65535) < 0) { + cmd->reply = "Failed to parse neighbor EARFCN value"; + return 1; + } + + if (!thresh_hi_str || osmo_str_to_int(&thresh_hi, thresh_hi_str, 10, 0, 31) < 0) { + cmd->reply = "Failed to parse neighbor threshold high bits value"; + return 1; + } + + if (!thresh_lo_str || osmo_str_to_int(&thresh_lo, thresh_lo_str, 10, 0, 32) < 0) { + cmd->reply = "Failed to parse neighbor threshold low bits value"; + return 1; + } + + if (!prio_str || osmo_str_to_int(&prio, prio_str, 10, 0, 8) < 0) { + cmd->reply = "Failed to parse neighbor priority value"; + return 1; + } + + if (!qrxlv_str || osmo_str_to_int(&qrxlv, qrxlv_str, 10, 0, 32) < 0) { + cmd->reply = "Failed to parse neighbor QRXLEVMIN value"; + return 1; + } + + if (!meas_str || osmo_str_to_int(&meas, meas_str, 10, 0, 8) < 0) { + cmd->reply = "Failed to parse neighbor measurement bandwidth"; + return 1; + } + + return 0; +} + +/* si2quater neighbor management: add an EARFCN + * Format: bts.<0-255>.si2quater-neighbor-list.add.earfcn <EARFCN>,<thresh-hi>,<thresh-lo>,<priority>,<QRXLEVMIN>,<measurement bandwidth> + * EARFCN is in range 0..65535, thresh-hi is in range 0..31, thresh-hi is in range 0..32, + * priority is in range 0..8, QRXLEVMIN is in range 0..32, measurement bandwidth is in range 0..8 */ +static int set_bts_si2quater_neighbor_list_add_earfcn(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)cmd->node; + struct osmo_earfcn_si2q *neighbors = &bts->si_common.si2quater_neigh_list; + char *earfcn_str, *thresh_hi_str, *thresh_lo_str, *prio_str, *qrxlv_str, *meas_str, *saveptr, *tmp; + int earfcn, thresh_hi, thresh_lo, prio, qrxlv, meas, result; + + tmp = talloc_strdup(cmd, cmd->value); + if (!tmp) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + earfcn_str = strtok_r(tmp, ",", &saveptr); + thresh_hi_str = strtok_r(NULL, ",", &saveptr); + thresh_lo_str = strtok_r(NULL, ",", &saveptr); + prio_str = strtok_r(NULL, ",", &saveptr); + qrxlv_str = strtok_r(NULL, ",", &saveptr); + meas_str = strtok_r(NULL, "\0", &saveptr); + + + if (!earfcn_str || osmo_str_to_int(&earfcn, earfcn_str, 10, 0, 65535) < 0) { + cmd->reply = "Failed to parse neighbor EARFCN value"; + return CTRL_CMD_ERROR; + } + + if (!thresh_hi_str || osmo_str_to_int(&thresh_hi, thresh_hi_str, 10, 0, 31) < 0) { + cmd->reply = "Failed to parse neighbor threshold high bits value"; + return CTRL_CMD_ERROR; + } + + if (!thresh_lo_str || osmo_str_to_int(&thresh_lo, thresh_lo_str, 10, 0, 32) < 0) { + cmd->reply = "Failed to parse neighbor threshold low bits value"; + return CTRL_CMD_ERROR; + } + + if (!prio_str || osmo_str_to_int(&prio, prio_str, 10, 0, 8) < 0) { + cmd->reply = "Failed to parse neighbor priority value"; + return CTRL_CMD_ERROR; + } + + if (!qrxlv_str || osmo_str_to_int(&qrxlv, qrxlv_str, 10, 0, 32) < 0) { + cmd->reply = "Failed to parse neighbor QRXLEVMIN value"; + return CTRL_CMD_ERROR; + } + + if (!meas_str || osmo_str_to_int(&meas, meas_str, 10, 0, 8) < 0) { + cmd->reply = "Failed to parse neighbor measurement bandwidth"; + return CTRL_CMD_ERROR; + } + + result = bts_earfcn_add(bts, earfcn, thresh_hi, thresh_lo, prio, qrxlv, meas); + + if ((result == 0) && (si2q_num(bts) <= SI2Q_MAX_NUM)) { + cmd->reply = "OK"; + return CTRL_CMD_REPLY; + } + + switch (result) { + case 0: + cmd->reply = talloc_asprintf(cmd, "Not enough space in SI2quater (%u/%u used)", bts->si2q_count, SI2Q_MAX_NUM); + if (!cmd->reply) + cmd->reply = "OOM"; + break; + case 1: + cmd->reply = "Multiple threshold-high are not supported"; + break; + case EARFCN_THRESH_LOW_INVALID: + cmd->reply = "Multiple threshold-low are not supported"; + break; + case EARFCN_QRXLV_INVALID + 1: + cmd->reply = "Multiple QRXLEVMIN are not supported"; + break; + case EARFCN_PRIO_INVALID: + cmd->reply = "Multiple priorities are not supported"; + break; + default: + cmd->reply = talloc_asprintf(cmd, "Unable to add EARFCN: %s", strerror(-result)); + if (!cmd->reply) + cmd->reply = "OOM"; + } + + if (osmo_earfcn_del(neighbors, earfcn) != 0) + cmd->reply = "Failed to roll-back adding EARFCN"; + + return CTRL_CMD_ERROR; +} + +CTRL_CMD_DEFINE_WO(bts_si2quater_neighbor_list_add_earfcn, + "si2quater-neighbor-list add earfcn"); + +static int verify_bts_si2quater_neighbor_list_add_uarfcn(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + char *uarfcn_str, *scramble_str, *diversity_str, *saveptr, *tmp; + int uarfcn, scramble; + + tmp = talloc_strdup(cmd, value); + if (!tmp) + return 1; + + uarfcn_str = strtok_r(tmp, ",", &saveptr); + scramble_str = strtok_r(NULL, ",", &saveptr); + diversity_str = strtok_r(NULL, "\0", &saveptr); + + if (!uarfcn_str || osmo_str_to_int(&uarfcn, uarfcn_str, 10, 0, 16383) < 0) { + cmd->reply = "Failed to parse neighbor UARFCN value"; + return 1; + } + + if (!scramble_str || osmo_str_to_int(&scramble, scramble_str, 10, 0, 511) < 0) { + cmd->reply = "Failed to parse neighbor scrambling code"; + return 1; + } + + if (!diversity_str || ((strcmp(diversity_str, "1") != 0) && (strcmp(diversity_str, "0") != 0))) { + cmd->reply = "Failed to parse neighbor diversity bit"; + return 1; + } + + return 0; +} + +/* si2quater neighbor management: add an UARFCN + * Format: bts.<0-255>.si2quater-neighbor-list.add.uarfcn <UARFCN>,<scrambling code>,<diversity bit> + * UARFCN is in range 0..16383, scrambling code is in range 0..511 */ +static int set_bts_si2quater_neighbor_list_add_uarfcn(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)cmd->node; + char *uarfcn_str, *scramble_str, *diversity_str, *saveptr, *tmp; + int uarfcn, scramble; + bool diversity; + + tmp = talloc_strdup(cmd, cmd->value); + if (!tmp) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + uarfcn_str = strtok_r(tmp, ",", &saveptr); + scramble_str = strtok_r(NULL, ",", &saveptr); + diversity_str = strtok_r(NULL, "\0", &saveptr); + + + if (!uarfcn_str || osmo_str_to_int(&uarfcn, uarfcn_str, 10, 0, 16383) < 0) { + cmd->reply = "Failed to parse neighbor UARFCN value"; + return CTRL_CMD_ERROR; + } + + if (!scramble_str || osmo_str_to_int(&scramble, scramble_str, 10, 0, 511) < 0) { + cmd->reply = "Failed to parse neighbor scrambling code"; + return CTRL_CMD_ERROR; + } + + diversity = strcmp(diversity_str, "1") == 0; + + switch (bts_uarfcn_add(bts, uarfcn, scramble, diversity)) { + case -ENOMEM: + cmd->reply = "max number of UARFCNs reached"; + return CTRL_CMD_ERROR; + case -ENOSPC: + cmd->reply = "not enough space in SI2quater"; + return CTRL_CMD_ERROR; + } + + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_WO(bts_si2quater_neighbor_list_add_uarfcn, + "si2quater-neighbor-list add uarfcn"); + +static int verify_bts_cell_reselection_offset(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + const int cell_reselection_offset = atoi(value); + + if (cell_reselection_offset < 0 || cell_reselection_offset > 126) { + cmd->reply = "Value is out of range"; + return 1; + } else if (cell_reselection_offset % 2 != 0) { + cmd->reply = "Value must be even"; + return 1; + } + + return 0; +} + +static int get_bts_cell_reselection_offset(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + + if (!bts->si_common.cell_ro_sel_par.present) { + cmd->reply = "0"; + return CTRL_CMD_REPLY; + } + + cmd->reply = talloc_asprintf(cmd, "%u", bts->si_common.cell_ro_sel_par.cell_resel_off * 2); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int set_bts_cell_reselection_offset(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + bts->si_common.cell_ro_sel_par.present = 1; + bts->si_common.cell_ro_sel_par.cell_resel_off = atoi(cmd->value) / 2; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE(bts_cell_reselection_offset, "cell-reselection-offset"); + +static int verify_bts_cell_reselection_penalty_time(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + int penalty_time; + + if (strcmp(value, "reserved") == 0) + return 0; + + penalty_time = atoi(value); + + if (penalty_time < 20 || penalty_time > 620) { + cmd->reply = "Value is out of range"; + return 1; + } else if (penalty_time % 20 != 0) { + cmd->reply = "Value must be a multiple of 20"; + return 1; + } + + return 0; +} + +/* According to 3GPP TS 45.008, PENALTY_TIME in the Control parameters section */ +static int get_bts_cell_reselection_penalty_time(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + + if (!bts->si_common.cell_ro_sel_par.present) { + cmd->reply = "0"; + return CTRL_CMD_REPLY; + } + + if (bts->si_common.cell_ro_sel_par.penalty_time == 31) { + cmd->reply = "reserved"; + return CTRL_CMD_REPLY; + } + + /* Calculate the penalty time in seconds */ + cmd->reply = talloc_asprintf(cmd, "%u", (bts->si_common.cell_ro_sel_par.penalty_time * 20) + 20); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int set_bts_cell_reselection_penalty_time(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + bts->si_common.cell_ro_sel_par.present = 1; + + if (strcmp(cmd->value, "reserved") == 0) + bts->si_common.cell_ro_sel_par.penalty_time = 31; + else + bts->si_common.cell_ro_sel_par.penalty_time = (atoi(cmd->value) - 20) / 20; + + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE(bts_cell_reselection_penalty_time, "cell-reselection-penalty-time"); + +static int verify_bts_cell_reselection_hysteresis(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + const int cell_reselection_hysteresis = atoi(value); + + if (cell_reselection_hysteresis < 0 || cell_reselection_hysteresis > 14) { + cmd->reply = "Value is out of range"; + return 1; + } else if (cell_reselection_hysteresis % 2 != 0) { + cmd->reply = "Value must be even"; + return 1; + } + + return 0; +} + +static int get_bts_cell_reselection_hysteresis(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + + cmd->reply = talloc_asprintf(cmd, "%u", bts->si_common.cell_sel_par.cell_resel_hyst * 2); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int set_bts_cell_reselection_hysteresis(struct ctrl_cmd *cmd, void *data) +{ + struct gsm_bts *bts = cmd->node; + bts->si_common.cell_sel_par.cell_resel_hyst = atoi(cmd->value) / 2; + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE(bts_cell_reselection_hysteresis, "cell-reselection-hysteresis"); + +/* Return space concatenated set of pairs <class>,<barred/allowed> */ +static int get_bts_rach_access_control_class(struct ctrl_cmd *cmd, void *data) +{ + int i; + const struct gsm_bts *bts = cmd->node; + + cmd->reply = talloc_strdup(cmd, ""); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + for (i = 0; i < 8; i++) { + cmd->reply = talloc_asprintf_append(cmd->reply, + i == 0 ? "%u,%s" : " %u,%s", + i, bts->si_common.rach_control.t3 & (0x1 << i) ? "barred" : "allowed"); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + } + + for (i = 0; i < 8; i++) { + if (i != 2) + cmd->reply = talloc_asprintf_append(cmd->reply, + " %u,%s", + i + 8, bts->si_common.rach_control.t2 & (0x1 << i) ? "barred" : "allowed"); + else + cmd->reply = talloc_asprintf_append(cmd->reply, + " emergency,%s", + bts->si_common.rach_control.t2 & (0x1 << i) ? "barred" : "allowed"); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(bts_rach_access_control_class, "rach-access-control-classes"); + +static int verify_access_control_class(struct ctrl_cmd *cmd, const char *value) +{ + int acc; + + if (strcmp(value, "emergency") == 0) + return 0; + + acc = atoi(value); + + if (acc < 0 || acc > 15) { + cmd->reply = "Value is out of range"; + return 1; + } else if (acc == 10) { + cmd->reply = "Access control class 10 does not exist, consider using \"emergency\" instead"; + return 1; + } + + return 0; +} + +static int set_access_control_class(struct ctrl_cmd *cmd, bool allow) +{ + int acc; + struct gsm_bts *bts = cmd->node; + + if (strcmp(cmd->value, "emergency") == 0) { + if (allow) + bts->si_common.rach_control.t2 &= ~0x4; + else + bts->si_common.rach_control.t2 |= 0x4; + cmd->reply = "OK"; + return CTRL_CMD_REPLY; + } + + acc = atoi(cmd->value); + if (acc < 8) + if (allow) + bts->si_common.rach_control.t3 &= ~(0x1 << acc); + else + bts->si_common.rach_control.t3 |= (0x1 << acc); + else + if (allow) + bts->si_common.rach_control.t2 &= ~(0x1 << (acc - 8)); + else + bts->si_common.rach_control.t2 |= (0x1 << (acc - 8)); + + if (acc < 10) + acc_mgr_perm_subset_changed(&bts->acc_mgr, &bts->si_common.rach_control); + + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +static int verify_bts_rach_access_control_class_bar(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + return verify_access_control_class(cmd, value); +} + +static int set_bts_rach_access_control_class_bar(struct ctrl_cmd *cmd, void *data) +{ + return set_access_control_class(cmd, false); +} + +CTRL_CMD_DEFINE_WO(bts_rach_access_control_class_bar, "rach-access-control-class bar"); + +static int verify_bts_rach_access_control_class_allow(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + return verify_access_control_class(cmd, value); +} + +static int set_bts_rach_access_control_class_allow(struct ctrl_cmd *cmd, void *data) +{ + return set_access_control_class(cmd, true); +} + +CTRL_CMD_DEFINE_WO(bts_rach_access_control_class_allow, "rach-access-control-class allow"); + +/* Return space concatenated set of tuples <UARFCN>,<scrambling code>,<diversity bit> */ +static int get_bts_neighbor_list_si2quater_uarfcn(struct ctrl_cmd *cmd, void *data) +{ + int i; + const struct gsm_bts *bts = cmd->node; + + cmd->reply = talloc_strdup(cmd, ""); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + for (i = 0; i < bts->si_common.uarfcn_length; i++) { + cmd->reply = talloc_asprintf_append(cmd->reply, + i == 0 ? "%u,%u,%u" : " %u,%u,%u", + bts->si_common.data.uarfcn_listi, + bts->si_common.data.scramble_listi & ~(1 << 9), + (bts->si_common.data.scramble_listi >> 9) & 1); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(bts_neighbor_list_si2quater_uarfcn, "neighbor-list si2quater uarfcns"); + +/* Return space concatenated set of tuples <EARFCN>,<thresh-hi>,<thresh-lo>,<prio>,<qrxlv>,<meas> */ +static int get_bts_neighbor_list_si2quater_earfcn(struct ctrl_cmd *cmd, void *data) +{ + int i; + bool first_earfcn = true; + const struct gsm_bts *bts = cmd->node; + const struct osmo_earfcn_si2q *neighbors = &bts->si_common.si2quater_neigh_list; + + cmd->reply = talloc_strdup(cmd, ""); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + for (i = 0; i < MAX_EARFCN_LIST; i++) { + if (neighbors->arfcni == OSMO_EARFCN_INVALID) + continue; + cmd->reply = talloc_asprintf_append(cmd->reply, + first_earfcn ? "%u,%u,%u,%u,%u,%u" : " %u,%u,%u,%u,%u,%u", + neighbors->arfcni, + neighbors->thresh_hi, + neighbors->thresh_lo_valid ? neighbors->thresh_lo : 32, + neighbors->prio_valid ? neighbors->prio : 8, + neighbors->qrxlm_valid ? neighbors->qrxlm : 32, + (neighbors->meas_bwi != OSMO_EARFCN_MEAS_INVALID) ? neighbors->meas_bwi : 8); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + first_earfcn = false; + } + + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE_RO(bts_neighbor_list_si2quater_earfcn, "neighbor-list si2quater earfcns"); + int bsc_bts_ctrl_cmds_install(void) { int rc = 0; @@ -630,6 +1337,8 @@ rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_loc); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_lac); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_ci); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_bsic); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rach_max_delay); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_apply_config); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_power_ctrl_defs); @@ -640,9 +1349,25 @@ rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rf_state); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rf_states); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_c0_power_red); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si2); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si5); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_add); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_del); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si5_add); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si5_del); rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_mode); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si2quater_neighbor_list_del_earfcn); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si2quater_neighbor_list_del_uarfcn); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si2quater_neighbor_list_add_earfcn); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_si2quater_neighbor_list_add_uarfcn); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_cell_reselection_offset); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_cell_reselection_penalty_time); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_cell_reselection_hysteresis); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rach_access_control_class); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rach_access_control_class_bar); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rach_access_control_class_allow); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si2quater_uarfcn); + rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_si2quater_earfcn); rc |= neighbor_ident_ctrl_init();
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_ipaccess_nanobts.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_ipaccess_nanobts.c
Changed
@@ -131,7 +131,7 @@ NM_ATT_IPACC_REVOC_DATE = { TLV_TYPE_TL16V }, }, }, - .features_get_reported = true, + .features_get_reported = false, }; @@ -150,7 +150,7 @@ 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) { @@ -202,7 +202,7 @@ struct gsm_gprs_nsvc *nsvc; struct gsm_bts_trx_ts *ts; - if (!is_ipaccess_bts(bts)) + if (!is_ipa_abisip_bts(bts)) return 0; switch (foh->obj_class) { @@ -254,7 +254,6 @@ return; } osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL); - osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_READY, NULL); } static void nm_rx_opstart_ack(struct msgb *oml_msg) @@ -565,7 +564,7 @@ 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 && @@ -637,10 +636,14 @@ for (i = 0; i < ARRAY_SIZE(bts->site_mgr->gprs.nsvc); i++) osmo_fsm_inst_dispatch(bts->site_mgr->gprs.nsvci.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
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_ipaccess_nanobts_omlattr.c
Changed
@@ -112,7 +112,9 @@ struct msgb *nanobts_gen_set_nse_attr(struct gsm_bts_sm *bts_sm) { struct msgb *msgb; - uint8_t buf256; + uint8_t buf2; + 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"); if (!msgb) @@ -123,27 +125,33 @@ buf1 = 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); - - /* all timers in seconds */ - buf0 = 3; /* blockimg timer (T1) */ - buf1 = 3; /* blocking retries */ - buf2 = 3; /* unblocking retries */ - buf3 = 3; /* reset timer (T2) */ - buf4 = 3; /* reset retries */ - buf5 = 10; /* suspend timer (T3) in 100ms */ - buf6 = 3; /* suspend retries */ - buf7 = 10; /* resume timer (T4) in 100ms */ - buf8 = 3; /* resume retries */ - buf9 = 10; /* capability update timer (T5) */ - buf10 = 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_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.timer0, + .un_blocking_retries = bts_sm->gprs.nse.timer1, + .reset_timer = bts_sm->gprs.nse.timer2, + .reset_retries = bts_sm->gprs.nse.timer3, + .test_timer = bts_sm->gprs.nse.timer4, + .alive_timer = bts_sm->gprs.nse.timer5, + .alive_retries = bts_sm->gprs.nse.timer6, + }; + msgb_tl16v_put(msgb, NM_ATT_IPACC_NS_CFG, sizeof(ns_cfg), (const uint8_t *)&ns_cfg); + + 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.timer0, + .t1_blocking_retries = bts->gprs.cell.timer1, + .t1_unblocking_retries = bts->gprs.cell.timer2, + .t2_s = bts->gprs.cell.timer3, + .t2_retries = bts->gprs.cell.timer4, + .t3_100ms = bts->gprs.cell.timer5, + .t3_retries = bts->gprs.cell.timer6, + .t4_100ms = bts->gprs.cell.timer7, + .t4_retries = bts->gprs.cell.timer8, + .t5_s = bts->gprs.cell.timer9, + .t5_retries = bts->gprs.cell.timer10, + }; + msgb_tl16v_put(msgb, NM_ATT_IPACC_BSSGP_CFG, sizeof(bssgp_cfg), (const uint8_t *)&bssgp_cfg); return msgb; } @@ -151,7 +159,9 @@ struct msgb *nanobts_gen_set_cell_attr(struct gsm_bts *bts) { struct msgb *msgb; - uint8_t buf256; + struct abis_nm_ipacc_att_rlc_cfg rlc_cfg; + struct abis_nm_ipacc_att_rlc_cfg_2 rlc_cfg_2; + uint8_t buf2; msgb = msgb_alloc(1024, "nanobts_attr_bts"); if (!msgb) return NULL; @@ -170,16 +180,18 @@ msgb_tl16v_put(msgb, NM_ATT_IPACC_BVCI, 2, buf); /* all timers in seconds, unless otherwise stated */ - buf0 = 20; /* T3142 */ - buf1 = 5; /* T3169 */ - buf2 = 5; /* T3191 */ - buf3 = 160; /* T3193 (units of 10ms) */ - buf4 = 5; /* T3195 */ - buf5 = 10; /* N3101 */ - buf6 = 4; /* N3103 */ - buf7 = 8; /* N3105 */ - buf8 = 15; /* RLC CV countdown */ - msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG, 9, buf); + rlc_cfg = (struct abis_nm_ipacc_att_rlc_cfg){ + .t3142 = 20, /* T3142 */ + .t3169 = 5, /* T3169 */ + .t3191 = 5, /* T3191 */ + .t3193_10ms = 160, /* T3193 (units of 10ms) */ + .t3195 = 5, /* T3195 */ + .n3101 = 10, /* N3101 */ + .n3103 = 4, /* N3103 */ + .n3105 = 8, /* N3105 */ + .rlc_cv_countdown = 15, /* RLC 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) { buf0 = 0x8f; @@ -190,18 +202,21 @@ } msgb_tl16v_put(msgb, NM_ATT_IPACC_CODING_SCHEMES, 2, buf); - buf0 = 0; /* T downlink TBF extension (0..500, high byte) */ - buf1 = 250; /* T downlink TBF extension (0..500, low byte) */ - buf2 = 0; /* T uplink TBF extension (0..500, high byte) */ - buf3 = 250; /* T uplink TBF extension (0..500, low byte) */ - buf4 = 2; /* CS2 */ - msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, 5, buf); + rlc_cfg_2 = (struct abis_nm_ipacc_att_rlc_cfg_2){ + .t_dl_tbf_ext_10ms = htons(250), /* 0..500 */ + .t_ul_tbf_ext_10ms = htons(250), /* 0..500 */ + .initial_cs = 2, /* CS2 */ + }; + msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_2, sizeof(rlc_cfg_2), (const uint8_t *)&rlc_cfg_2); #if 0 /* EDGE model only, breaks older models. * Should inquire the BTS capabilities */ - buf0 = 2; /* MCS2 */ - msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, 1, buf); + struct abis_nm_ipacc_att_rlc_cfg_3 rlc_cfg_3; + rlc_cfg_3 = (struct abis_nm_ipacc_att_rlc_cfg_3){ + .initial_mcs = 2, /* MCS2 */ + }; + msgb_tl16v_put(msgb, NM_ATT_IPACC_RLC_CFG_3, sizeof(rlc_cfg_3), (const uint8_t *)&rlc_cfg_3); #endif return msgb;
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_nokia_site.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_nokia_site.c
Changed
@@ -1338,7 +1338,7 @@ 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 @@ 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) {
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_osmobts.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_osmobts.c
Changed
@@ -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 @@ *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 @@ 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 @@ 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_data0; model_osmobts.features.data_len =
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_siemens_bs11.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_siemens_bs11.c
Changed
@@ -401,7 +401,7 @@ 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) {
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_trx.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_trx.c
Changed
@@ -264,7 +264,7 @@ 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;
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_trx_vty.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_trx_vty.c
Changed
@@ -69,7 +69,7 @@ e1_link->e1_nr = atoi(line); e1_link->e1_ts = atoi(ts); if (!strcmp(ss, "full")) - e1_link->e1_ts_ss = 255; + e1_link->e1_ts_ss = E1_SUBSLOT_FULL; else e1_link->e1_ts_ss = atoi(ss); } @@ -609,7 +609,7 @@ } else { vty_out(vty, " No Subscriber%s", VTY_NEWLINE); } - if (is_ipaccess_bts(lchan->ts->trx->bts)) { + if (is_ipa_abisip_bts(lchan->ts->trx->bts)) { struct in_addr ia; if (lchan->abis_ip.bound_ip) { ia.s_addr = htonl(lchan->abis_ip.bound_ip); @@ -694,7 +694,7 @@ vty_out(vty, ", TSC %u%s NM State: ", gsm_ts_tsc(ts), VTY_NEWLINE); vty_out_dyn_ts_details(vty, ts); net_dump_nmstate(vty, &ts->mo.nm_state); - if (!is_ipaccess_bts(ts->trx->bts)) + if (!is_ipa_abisip_bts(ts->trx->bts)) vty_out(vty, " E1 Line %u, Timeslot %u, Subslot %u%s", ts->e1_link.e1_nr, ts->e1_link.e1_ts, ts->e1_link.e1_ts_ss, VTY_NEWLINE); @@ -753,8 +753,8 @@ vty_out(vty, " %sBaseband Transceiver NM State: ", is_ericsson_bts(trx->bts) ? "Virtual " : ""); net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state); - if (is_ipaccess_bts(trx->bts)) { - vty_out(vty, " ip.access stream ID: 0x%02x ", trx->rsl_tei_primary); + if (is_ipa_abisip_bts(trx->bts)) { + vty_out(vty, " IPA Abis/IP stream ID: 0x%02x ", trx->rsl_tei_primary); e1isl_dump_vty_tcp(vty, trx->rsl_link_primary); } else { vty_out(vty, " E1 Signalling Link:%s", VTY_NEWLINE); @@ -773,7 +773,7 @@ if (!e1_link->e1_ts) return; - if (e1_link->e1_ts_ss == 255) + if (e1_link->e1_ts_ss == E1_SUBSLOT_FULL) vty_out(vty, "%se1 line %u timeslot %u sub-slot full%s", prefix, e1_link->e1_nr, e1_link->e1_ts, VTY_NEWLINE); else
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/bts_vty.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/bts_vty.c
Changed
@@ -204,7 +204,7 @@ struct gsm_bts *bts = vty->index; bts->dtxu = (argc > 0) ? GSM48_DTX_SHALL_BE_USED : GSM48_DTX_MAY_BE_USED; - if (!is_ipaccess_bts(bts)) + if (!is_ipa_abisip_bts(bts)) vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration " "neither supported nor tested!%s", VTY_NEWLINE); return CMD_SUCCESS; @@ -234,7 +234,7 @@ struct gsm_bts *bts = vty->index; bts->dtxd = true; - if (!is_ipaccess_bts(bts)) + if (!is_ipa_abisip_bts(bts)) vty_out(vty, "%% DTX enabled on non-IP BTS: this configuration " "neither supported nor tested!%s", VTY_NEWLINE); return CMD_SUCCESS; @@ -340,8 +340,8 @@ int site_id = atoi(argv0); int bts_id = atoi(argv1); - if (!is_ipaccess_bts(bts)) { - vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE); + if (!is_ipa_abisip_bts(bts)) { + vty_out(vty, "%% BTS is not of IPA Abis/IP type%s", VTY_NEWLINE); return CMD_WARNING; } @@ -370,8 +370,8 @@ struct gsm_bts *bts = vty->index; struct in_addr ia; - if (!is_ipaccess_bts(bts)) { - vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE); + if (!is_ipa_abisip_bts(bts)) { + vty_out(vty, "%% BTS is not of IPA Abis/IP type%s", VTY_NEWLINE); return CMD_WARNING; } @@ -466,8 +466,8 @@ struct gsm_bts *bts = vty->index; int stream_id = atoi(argv0), linenr = atoi(argv1); - if (!is_ipaccess_bts(bts)) { - vty_out(vty, "%% BTS is not of ip.access type%s", VTY_NEWLINE); + if (!is_ipa_abisip_bts(bts)) { + vty_out(vty, "%% BTS is not of IPA Abis/IP type%s", VTY_NEWLINE); return CMD_WARNING; } @@ -549,6 +549,7 @@ bts->chan_alloc_chan_req_reverse = reverse; bts->chan_alloc_assignment_reverse = reverse; bts->chan_alloc_handover_reverse = reverse; + bts->chan_alloc_vgcs_reverse = reverse; bts->chan_alloc_assignment_dynamic = false; return CMD_SUCCESS; @@ -557,7 +558,7 @@ DEFUN_ATTR(cfg_bts_challoc_mode, cfg_bts_challoc_mode_cmd, CHAN_ALLOC_CMD - " mode (set-all|chan-req|assignment|handover) " + " mode (set-all|chan-req|assignment|handover|vgcs-vbs) " CHAN_ALLOC_ASC_DSC, CHAN_ALLOC_DESC "Channel allocation mode\n" @@ -565,6 +566,7 @@ "Channel allocation for CHANNEL REQUEST (RACH)\n" "Channel allocation for assignment\n" "Channel allocation for handover\n" + "Channel allocation for VGCS/VBS\n" CHAN_ALLOC_ASC_DSC_DESC, CMD_ATTR_IMMEDIATE) { @@ -580,6 +582,8 @@ } if (set_all || !strcmp(argv0, "handover")) bts->chan_alloc_handover_reverse = reverse; + if (set_all || !strcmp(argv0, "vgcs-vbs")) + bts->chan_alloc_vgcs_reverse = reverse; return CMD_SUCCESS; } @@ -1107,6 +1111,46 @@ return CMD_SUCCESS; } +DEFUN_USRATTR(cfg_bts_nch_position, + cfg_bts_nch_position_cmd, + X(BSC_VTY_ATTR_RESTART_ABIS_RSL_LINK), + "nch-position num-blocks <1-7> first-block <0-6>", + "NCH (Notification Channel) position within CCCH\n" + "Number of blocks reserved for NCH\n" + "Number of blocks reserved for NCH\n" + "First block reserved for NCH\n" + "First block reserved for NCH\n") +{ + struct gsm_bts *bts = vty->index; + int num_blocks = atoi(argv0); + int first_block = atoi(argv1); + + if (osmo_gsm48_si1ro_nch_pos_encode(num_blocks, first_block)) { + vty_out(vty, "num-blocks %u first-block %u is not permitted by 3GPP TS 44.010 Table 10.5.2.32.1b%s", + num_blocks, first_block, VTY_NEWLINE); + return CMD_WARNING; + } + + bts->nch.num_blocks = num_blocks; + bts->nch.first_block = first_block; + + return CMD_SUCCESS; +} + +DEFUN_USRATTR(cfg_bts_no_nch_position, + cfg_bts_no_nch_position_cmd, + X(BSC_VTY_ATTR_RESTART_ABIS_RSL_LINK), + "no nch-position", + NO_STR "Disable NCH in this BTS\n") +{ + struct gsm_bts *bts = vty->index; + + bts->nch.num_blocks = 0; + bts->nch.first_block = 0; + + return CMD_SUCCESS; +} + DEFUN_USRATTR(cfg_bts_cell_barred, cfg_bts_cell_barred_cmd, X(BSC_VTY_ATTR_RESTART_ABIS_RSL_LINK), @@ -1581,7 +1625,7 @@ "Tbvc-block timeout\n" \ "Tbvc-block retries\n" \ "Tbvc-unblock retries\n" \ - "Tbvcc-reset timeout\n" \ + "Tbvc-reset timeout\n" \ "Tbvc-reset retries\n" \ "Tbvc-suspend timeout\n" \ "Tbvc-suspend retries\n" \ @@ -1919,8 +1963,8 @@ { struct gsm_bts *bts = vty->index; - if (!is_ipaccess_bts(bts) || is_osmobts(bts)) { - vty_out(vty, "%% This command is only intended for ipaccess nanoBTS. See OS#3707.%s", + if (!is_ipa_abisip_bts(bts)) { + vty_out(vty, "%% This command is only intended for IPA Abis/IP BTS. See OS#3707.%s", VTY_NEWLINE); return CMD_WARNING; } @@ -2078,7 +2122,9 @@ vty_out(vty, "%% Warning: not enough space in SI2quater (%u/%u used) for a given EARFCN %u%s", bts->si2q_count, SI2Q_MAX_NUM, arfcn, VTY_NEWLINE); - osmo_earfcn_del(e, arfcn); + + if (osmo_earfcn_del(e, arfcn) != 0) + vty_out(vty, "%% Failed to roll-back adding EARFCN %u%s", arfcn, VTY_NEWLINE); return CMD_WARNING; } @@ -2118,7 +2164,7 @@ struct gsm_bts *bts = vty->index; uint16_t arfcn = atoi(argv0), scramble = atoi(argv1); - switch(bts_uarfcn_add(bts, arfcn, scramble, atoi(argv2))) { + switch (bts_uarfcn_add(bts, arfcn, scramble, atoi(argv2))) { case -ENOMEM: vty_out(vty, "%% Unable to add UARFCN: max number of UARFCNs (%u) reached%s", MAX_EARFCN_LIST, VTY_NEWLINE); @@ -2127,10 +2173,6 @@ vty_out(vty, "%% Warning: not enough space in SI2quater for a given UARFCN (%u, %u)%s", arfcn, scramble, VTY_NEWLINE); return CMD_WARNING; - case -EADDRINUSE: - vty_out(vty, "%% Unable to add UARFCN: (%u, %u) is already added%s", - arfcn, scramble, VTY_NEWLINE); - return CMD_WARNING; } return CMD_SUCCESS; @@ -2191,28 +2233,6 @@ return CMD_SUCCESS; } -DEFUN_ATTR(cfg_bts_pcu_sock, - cfg_bts_pcu_sock_cmd, - "pcu-socket PATH", - "PCU Socket Path for using OsmoPCU co-located with BSC (legacy BTS)\n" - "Path in the file system for the unix-domain PCU socket\n", - CMD_ATTR_IMMEDIATE) -{ - struct gsm_bts *bts = vty->index; - int rc; - - osmo_talloc_replace_string(bts, &bts->pcu_sock_path, argv0); - pcu_sock_exit(bts); - rc = pcu_sock_init(bts->pcu_sock_path, bts); - if (rc < 0) { - vty_out(vty, "%% Error creating PCU socket `%s' for BTS %u%s", - bts->pcu_sock_path, bts->nr, VTY_NEWLINE); - return CMD_WARNING; - } - - return CMD_SUCCESS; -} - DEFUN_ATTR(cfg_bts_acc_rotate, cfg_bts_acc_rotate_cmd, "access-control-class-rotate <0-10>", @@ -2500,14 +2520,14 @@ int dep = atoi(argv0); - if (!is_ipaccess_bts(bts)) { + if (!is_ipa_abisip_bts(bts)) { vty_out(vty, "%% This feature is only available for IP systems.%s", VTY_NEWLINE); return CMD_WARNING; } other_bts = gsm_bts_num(bts->network, dep); - if (!other_bts || !is_ipaccess_bts(other_bts)) { + if (!other_bts || !is_ipa_abisip_bts(other_bts)) { vty_out(vty, "%% This feature is only available for IP systems.%s", VTY_NEWLINE); return CMD_WARNING; @@ -3979,9 +3999,7 @@ bts->early_classmark_allowed_3g && !bts->early_classmark_allowed ? " (forbidden by 2G bit)" : "", VTY_NEWLINE); - if (bts->pcu_sock_path) - vty_out(vty, " PCU Socket Path: %s%s", bts->pcu_sock_path, VTY_NEWLINE); - if (is_ipaccess_bts(bts)) + if (is_ipa_abisip_bts(bts)) vty_out(vty, " Unit ID: %u/%u/0, OML Stream ID 0x%02x%s", bts->ip_access.site_id, bts->ip_access.bts_id, bts->oml_tei, VTY_NEWLINE); @@ -4008,7 +4026,7 @@ vty_out(vty, " Paging: %u pending requests, %u free slots%s", paging_pending_requests_nr(bts), bts->paging.available_slots, VTY_NEWLINE); - if (is_ipaccess_bts(bts)) { + if (is_ipa_abisip_bts(bts)) { vty_out(vty, " OML Link: "); e1isl_dump_vty_tcp(vty, bts->oml_link); vty_out(vty, " OML Link state: %s", get_model_oml_status(bts)); @@ -4228,7 +4246,7 @@ vty_out(vty, "auto%s", VTY_NEWLINE); } -/* TODO: generalize and move indention handling to libosmocore */ +/* TODO: generalize and move indentation handling to libosmocore */ #define cfg_out(fmt, args...) \ vty_out(vty, "%*s" fmt, indent, "", ##args); @@ -4410,6 +4428,9 @@ vty_out(vty, " channel allocator mode handover %s%s", bts->chan_alloc_handover_reverse ? "descending" : "ascending", VTY_NEWLINE); + vty_out(vty, " channel allocator mode vgcs-vbs %s%s", + bts->chan_alloc_vgcs_reverse ? "descending" : "ascending", + VTY_NEWLINE); if (bts->chan_alloc_avoid_interf) vty_out(vty, " channel allocator avoid-interference 1%s", VTY_NEWLINE); if (bts->chan_alloc_tch_signalling_policy == BTS_TCH_SIGNALLING_NEVER) @@ -4431,6 +4452,12 @@ bts->si_common.chan_desc.bs_pa_mfrms + 2, VTY_NEWLINE); vty_out(vty, " channel-description bs-ag-blks-res %u%s", bts->si_common.chan_desc.bs_ag_blks_res, VTY_NEWLINE); + if (bts->nch.num_blocks) { + vty_out(vty, " nch-position num-blocks %u first-block %u%s", + bts->nch.num_blocks, bts->nch.first_block, VTY_NEWLINE); + } else { + vty_out(vty, " no nch-position%s", VTY_NEWLINE); + } if (bts->ccch_load_ind_thresh != 10) vty_out(vty, " ccch load-indication-threshold %u%s", @@ -4618,8 +4645,6 @@ vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE); } } - if (bts->pcu_sock_path) - vty_out(vty, " pcu-socket %s%s", bts->pcu_sock_path, VTY_NEWLINE); ho_vty_write_bts(vty, bts); @@ -4857,7 +4882,6 @@ install_element(BTS_NODE, &cfg_bts_osmux_cmd); install_element(BTS_NODE, &cfg_bts_mgw_pool_target_cmd); install_element(BTS_NODE, &cfg_bts_no_mgw_pool_target_cmd); - install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd); install_element(BTS_NODE, &cfg_bts_acc_rotate_cmd); install_element(BTS_NODE, &cfg_bts_acc_rotate_quantum_cmd); install_element(BTS_NODE, &cfg_bts_acc_ramping_cmd); @@ -4880,6 +4904,8 @@ install_element(BTS_NODE, &cfg_bts_interf_meas_level_bounds_cmd); install_element(BTS_NODE, &cfg_bts_srvcc_fast_return_cmd); install_element(BTS_NODE, &cfg_bts_immediate_assignment_cmd); + install_element(BTS_NODE, &cfg_bts_nch_position_cmd); + install_element(BTS_NODE, &cfg_bts_no_nch_position_cmd); neighbor_ident_vty_init(); /* See also handover commands added on bts level from handover_vty.c */
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/chan_alloc.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/chan_alloc.c
Changed
@@ -63,7 +63,7 @@ if (!nm_is_running(&ts->mo.nm_state)) continue; - /* A dynamic timeslot currently in PDCH mode are available as TCH or SDCCH8, beause they can be switched + /* A dynamic timeslot currently in PDCH mode are available as TCH or SDCCH8, because they can be switched * to TCH or SDCCH mode at any moment. Count TCH/F_TCH/H_SDCCH8_PDCH as one total timeslot, even though it may * be switched to TCH/H and would then count as two -- hence opt for pessimistic load. */ if ((ts->pchan_on_init == GSM_PCHAN_OSMO_DYN ||
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/codec_pref.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/codec_pref.c
Changed
@@ -61,8 +61,7 @@ return 0; } -/* Helper function for match_codec_pref(), looks up a matching chan mode for - * a given permitted speech value */ +/* Look up a matching chan mode for a given permitted speech value */ static enum gsm48_chan_mode gsm88_to_chan_mode(enum gsm0808_permitted_speech speech) { switch (speech) { @@ -88,8 +87,7 @@ } } -/* Helper function for match_codec_pref(), looks up a matching permitted speech - * value for a given msc audio codec pref */ +/* Look up a matching permitted speech value for a given msc audio codec pref */ static enum gsm0808_permitted_speech audio_support_to_gsm88(const struct gsm_audio_support *audio) { if (audio->hr) { @@ -125,10 +123,9 @@ } } -/* Helper function for match_codec_pref(), tests if a given audio support - * matches one of the permitted speech settings of the channel type element. - * The matched permitted speech value is then also compared against the - * speech codec list. (optional, only relevant for AoIP) */ +/* Test if a given audio support matches one of the permitted speech settings + * of the channel type element. The matched permitted speech value is then also + * compared against the speech codec list. (optional, only relevant for AoIP) */ static bool test_codec_pref(const struct gsm0808_speech_codec **sc_match, const struct gsm0808_speech_codec_list *scl, const struct gsm0808_channel_type *ct, @@ -177,37 +174,48 @@ return false; } -/* Helper function to check if the given permitted speech value is supported - * by the BTS. (vty option bts->codec-support). */ -static bool test_codec_support_bts(const struct gsm_bts *bts, uint8_t perm_spch) +static bool test_codec_support_bts_rate(const struct gsm_bts *bts, const bool full_rate) { + unsigned int i; struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + for (i = 0; i < TRX_NR_TS; i++) { + switch (trx->tsi.pchan_from_config) { + case GSM_PCHAN_OSMO_DYN: + return true; + case GSM_PCHAN_TCH_F: + case GSM_PCHAN_TCH_F_PDCH: + if (full_rate) + return true; + break; + case GSM_PCHAN_TCH_H: + if (!full_rate) + return true; + break; + default: + continue; + } + } + } + + return false; +} + +/* Check if the given permitted speech value is supported by the BTS + * (vty option bts->codec-support). */ +static bool test_codec_support_bts(const struct gsm_bts *bts, uint8_t perm_spch) +{ const struct bts_codec_conf *bts_codec = &bts->codec; - unsigned int i; bool full_rate; int rc; - enum gsm_phys_chan_config pchan; - bool rate_match = false; /* Check if the BTS provides a physical channel that matches the * bandwidth of the desired codec. */ rc = full_rate_from_perm_spch(&full_rate, perm_spch); if (rc < 0) return false; - llist_for_each_entry(trx, &bts->trx_list, list) { - for (i = 0; i < TRX_NR_TS; i++) { - pchan = trx->tsi.pchan_from_config; - if (pchan == GSM_PCHAN_OSMO_DYN) - rate_match = true; - else if (full_rate && pchan == GSM_PCHAN_TCH_F) - rate_match = true; - else if (full_rate && pchan == GSM_PCHAN_TCH_F_PDCH) - rate_match = true; - else if (!full_rate && pchan == GSM_PCHAN_TCH_H) - rate_match = true; - } - } - if (!rate_match) + if (!test_codec_support_bts_rate(bts, full_rate)) return false; /* Check codec support */ @@ -217,21 +225,12 @@ * selectively disable GSM-RF per BTS via VTY. */ return true; case GSM0808_PERM_FR2: - if (bts_codec->efr) - return true; - break; + return (bool)bts_codec->efr; case GSM0808_PERM_FR3: - if (bts_codec->amr) - return true; - break; - case GSM0808_PERM_HR1: - if (bts_codec->hr) - return true; - break; case GSM0808_PERM_HR3: - if (bts_codec->amr) - return true; - break; + return (bool)bts_codec->amr; + case GSM0808_PERM_HR1: + return (bool)bts_codec->hr; default: return false; } @@ -308,8 +307,8 @@ return 0; } -/*! Match the codec preferences from local config with a received codec preferences IEs received from the - * MSC and the BTS' codec configuration. +/*! Match the codec preferences from local config with codec preference IEs + * received from the MSC and the BTS' codec configuration. * \paramout ch_mode_rate resulting codec and rate information * \paramin ct GSM 08.08 channel type received from MSC. * \paramin scl GSM 08.08 speech codec list received from MSC (optional). @@ -336,7 +335,7 @@ * indeed available with the current BTS and MSC configuration */ for (i = 0; i < msc->audio_length; i++) { /* Pick a permitted speech value from the global codec configuration list */ - perm_spch = audio_support_to_gsm88(msc->audio_supporti); + perm_spch = audio_support_to_gsm88(&msc->audio_supporti); /* Determine if the result is a half or full rate codec */ rc = full_rate_from_perm_spch(&full_rate, perm_spch); @@ -376,7 +375,7 @@ break; } - /* Exit without result, in case no match can be deteched */ + /* Exit without result, in case no match can be detected */ if (!match) { ch_mode_rate->chan_mode = GSM48_CMODE_SIGN; ch_mode_rate->chan_rate = CH_RATE_SDCCH; @@ -407,7 +406,7 @@ for (i = 0; i < msc->audio_length; i++) { /* Pick a permitted speech value from the global codec configuration list */ - perm_spch = audio_support_to_gsm88(msc->audio_supporti); + perm_spch = audio_support_to_gsm88(&msc->audio_supporti); /* Check this permitted speech value against the BTS specific parameters. * if the BTS does not support the codec, try the next one */ @@ -422,8 +421,8 @@ /* AMR (HR/FR version 3) is the only codec that requires a codec * configuration (S0-S15). Determine the current configuration and update * the cfg flag. */ - if (msc->audio_supporti->ver == 3) - scl->codecscl->len.cfg = gen_bss_supported_amr_s15_s0(msc, bts, msc->audio_supporti->hr); + if (msc->audio_supporti.ver == 3) + scl->codecscl->len.cfg = gen_bss_supported_amr_s15_s0(msc, bts, msc->audio_supporti.hr); scl->len++; }
View file
osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/data_rate_pref.c
Added
@@ -0,0 +1,165 @@ +/* + * (C) 2023 by sysmocom s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * Author: Oliver Smith + * + * 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/gsm/protocol/gsm_08_08.h> +#include <osmocom/gsm/protocol/gsm_08_58.h> +#include <osmocom/bsc/data_rate_pref.h> +#include <osmocom/bsc/debug.h> +#include <osmocom/bsc/lchan.h> + +static int gsm0808_data_rate_transp_to_gsm0858(enum gsm0808_data_rate_transp rate) +{ + switch (rate) { + case GSM0808_DATA_RATE_TRANSP_32k0: + return RSL_CMOD_CSD_T_32k0; + case GSM0808_DATA_RATE_TRANSP_28k8: + return RSL_CMOD_CSD_T_29k0; + case GSM0808_DATA_RATE_TRANSP_14k4: + return RSL_CMOD_CSD_T_14k4; + case GSM0808_DATA_RATE_TRANSP_9k6: + return RSL_CMOD_CSD_T_9k6; + case GSM0808_DATA_RATE_TRANSP_4k8: + return RSL_CMOD_CSD_T_4k8; + case GSM0808_DATA_RATE_TRANSP_2k4: + return RSL_CMOD_CSD_T_2k4; + case GSM0808_DATA_RATE_TRANSP_1k2: + return RSL_CMOD_CSD_T_1k2; + case GSM0808_DATA_RATE_TRANSP_600: + return RSL_CMOD_CSD_T_600; + case GSM0808_DATA_RATE_TRANSP_1200_75: + return RSL_CMOD_CSD_T_1200_75; + default: + LOGP(DMSC, LOGL_ERROR, "Unsupported transparent data rate 0x%x\n", rate); + return -1; + } +} + +static int gsm0808_data_rate_transp_to_gsm0408(enum gsm0808_data_rate_transp rate) +{ + switch (rate) { + case GSM0808_DATA_RATE_TRANSP_14k4: + return GSM48_CMODE_DATA_14k5; + case GSM0808_DATA_RATE_TRANSP_9k6: + return GSM48_CMODE_DATA_12k0; + case GSM0808_DATA_RATE_TRANSP_4k8: + return GSM48_CMODE_DATA_6k0; + case GSM0808_DATA_RATE_TRANSP_2k4: + case GSM0808_DATA_RATE_TRANSP_1k2: + case GSM0808_DATA_RATE_TRANSP_600: + case GSM0808_DATA_RATE_TRANSP_1200_75: + return GSM48_CMODE_DATA_3k6; + default: + LOGP(DMSC, LOGL_ERROR, "Unsupported transparent data rate 0x%x\n", rate); + return -1; + } +} + +static int gsm0808_data_rate_non_transp_to_gsm0408(enum gsm0808_data_rate_non_transp rate, bool full_rate) +{ + switch (rate) { + case GSM0808_DATA_RATE_NON_TRANSP_12000_6000: + if (full_rate) + return GSM48_CMODE_DATA_12k0; + return GSM48_CMODE_DATA_6k0; + case GSM0808_DATA_RATE_NON_TRANSP_14k5: + return GSM48_CMODE_DATA_14k5; + case GSM0808_DATA_RATE_NON_TRANSP_12k0: + return GSM48_CMODE_DATA_12k0; + case GSM0808_DATA_RATE_NON_TRANSP_6k0: + return GSM48_CMODE_DATA_6k0; + default: + LOGP(DMSC, LOGL_ERROR, "Unsupported non-transparent data rate 0x%x\n", rate); + return -1; + } +} + +static int gsm0808_data_rate_non_transp_to_gsm0858(enum gsm0808_data_rate_non_transp rate, bool full_rate) +{ + switch (rate) { + case GSM0808_DATA_RATE_NON_TRANSP_12000_6000: + if (full_rate) + return RSL_CMOD_CSD_NT_12k0; + return RSL_CMOD_CSD_NT_6k0; + case GSM0808_DATA_RATE_NON_TRANSP_14k5: + return RSL_CMOD_CSD_NT_14k5; + case GSM0808_DATA_RATE_NON_TRANSP_12k0: + return RSL_CMOD_CSD_NT_12k0; + case GSM0808_DATA_RATE_NON_TRANSP_6k0: + return RSL_CMOD_CSD_NT_6k0; + case GSM0808_DATA_RATE_NON_TRANSP_43k5: + return RSL_CMOD_CSD_NT_43k5; + case GSM0808_DATA_RATE_NON_TRANSP_29k0: + return RSL_CMOD_CSD_NT_28k8; + default: + LOGP(DMSC, LOGL_ERROR, "Unsupported non-transparent data rate 0x%x\n", rate); + return -1; + } +} + +static enum gsm48_chan_mode match_non_transp_data_rate(const struct gsm0808_channel_type *ct, bool full_rate) +{ + /* FIXME: Handle ct->data_rate_allowed too if it is set. Find the best + * match by comparing the preferred ct->data_rate + all allowed + * ct->data_rate_allowed against what's most suitable for the BTS. */ + + return gsm0808_data_rate_non_transp_to_gsm0858(ct->data_rate, full_rate); +} + +/*! Match the GSM 08.08 channel type received from the MSC to suitable data for + * the BTS, the GSM 04.08 channel mode, channel rate (FR/HR) and GSM 08.58 + * data rate. + * \paramout ch_mode_rate resulting channel rate, channel mode and data rate + * \paramin ct GSM 08.08 channel type received from MSC. + * \paramin full_rate true means FR is preferred, false means HR + * \returns 0 on success, -1 in case no match was found */ +int match_data_rate_pref(struct channel_mode_and_rate *ch_mode_rate, + const struct gsm0808_channel_type *ct, + const bool full_rate) +{ + int rc; + *ch_mode_rate = (struct channel_mode_and_rate){}; + ch_mode_rate->chan_rate = full_rate ? CH_RATE_FULL : CH_RATE_HALF; + ch_mode_rate->data_transparent = ct->data_transparent; + + if (ct->data_transparent) { + rc = gsm0808_data_rate_transp_to_gsm0858(ct->data_rate); + if (rc == -1) + return -1; + ch_mode_rate->data_rate.t = rc; + + rc = gsm0808_data_rate_transp_to_gsm0408(ct->data_rate); + if (rc == -1) + return -1; + ch_mode_rate->chan_mode = rc; + } else { + rc = match_non_transp_data_rate(ct, full_rate); + if (rc == -1) + return -1; + ch_mode_rate->data_rate.nt = rc; + + rc = gsm0808_data_rate_non_transp_to_gsm0408(ct->data_rate, full_rate); + if (rc == -1) + return -1; + ch_mode_rate->chan_mode = rc; + } + + return 0; +}
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/gsm_04_08_rr.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/gsm_04_08_rr.c
Changed
@@ -57,6 +57,15 @@ return rsl_data_request(msg, 0); } +int gsm48_sendmsg_unit(struct msgb *msg) +{ + if (msg->lchan) + msg->dst = rsl_chan_link(msg->lchan); + + msg->l3h = msg->data; + return rsl_unit_data_request(msg, 0); +} + /* Section 9.1.8 / Table 9.9 */ struct chreq { uint8_t val; @@ -299,12 +308,15 @@ } } +#define REPEAT_RR_RELEASE_UI 3 + /* 7.1.7 and 9.1.7: RR CHANnel RELease */ -int gsm48_send_rr_release(struct gsm_lchan *lchan) +int gsm48_send_rr_release(struct gsm_lchan *lchan, bool ui) { - struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL"); + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 RR REL"), *msgc; struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); uint8_t *cause; + int n; msg->lchan = lchan; gh->proto_discr = GSM48_PDISC_RR; @@ -329,8 +341,17 @@ gsm_lchan_name(lchan), lchan->release.rr_cause, rr_cause_name(lchan->release.rr_cause)); - /* Send actual release request to MS */ - return gsm48_sendmsg(msg); + /* Send actual release request to MS (dedicated channel) */ + if (!ui) + return gsm48_sendmsg(msg); + + /* Send actual release request to MS (VGCS channel) */ + for (n = 1; n < REPEAT_RR_RELEASE_UI; n++) { + msgc = msgb_copy(msg, "CHAN RELEASE copy"); + msgc->lchan = lchan; + gsm48_sendmsg_unit(msgc); + } + return gsm48_sendmsg_unit(msg); } int send_siemens_mrpci(struct gsm_lchan *lchan, @@ -565,7 +586,7 @@ * TODO: NCI (Normal cell indication), currently 0. */ const uint8_t sync_ind = async ? 0x00 : 0x01; /* T (4 bit) + V (4 bit), see 3GPP TS 44.018, 10.5.2.39 */ - msgb_v_put(msg, GSM48_IE_SYNC_IND | (sync_ind & 0x0f)); + msgb_v_put(msg, (GSM48_IE_SYNC_IND_HO << 4) | (sync_ind & 0x0f)); } if (new_lchan->ts->hopping.enabled) { @@ -595,7 +616,7 @@ if (new_lchan->encr.alg_a5_n > 0) cms = (new_lchan->encr.alg_a5_n - 1) << 1 | 1; /* T (4 bit) + V (4 bit), see 3GPP TS 44.018, 10.5.2.9 */ - msgb_v_put(msg, GSM48_IE_CIP_MODE_SET | (cms & 0x0f)); + msgb_v_put(msg, (GSM48_IE_CIP_MODE_SET_HO << 4) | (cms & 0x0f)); } /* in case of multi rate we need to attach a config */ @@ -737,7 +758,7 @@ } } - if (lchan->modify.info.vamos && lchan->modify.tsc_set > 0) { + if (lchan->modify.info.type_for == LCHAN_TYPE_FOR_VAMOS && lchan->modify.tsc_set > 0) { /* Add the Extended TSC Set IE. So far we only need a TSC Set sent for VAMOS. * Convert from spec conforming "human readable" TSC Set 1-4 to 0-3 on the wire */ msgb_tv_put(msg, GSM48_IE_EXTENDED_TSC_SET, (lchan->modify.tsc_set - 1) & 0x3); @@ -746,6 +767,66 @@ return gsm48_sendmsg(msg); } +/* TS 44.018 section 9.1.48 */ +int gsm48_send_uplink_release(struct gsm_lchan *lchan, uint8_t cause) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UL RELEASE"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + msg->lchan = lchan; + gh->proto_discr = GSM48_PDISC_RR; + gh->msg_type = GSM48_MT_RR_UPLINK_RELEASE; + + msgb_put_u8(msg, cause); + + return gsm48_sendmsg(msg); +} + +/* TS 44.018 section 9.1.46 */ +int gsm48_send_uplink_busy(struct gsm_lchan *lchan) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UL BUSY"); + struct gsm48_hdr *gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); + + msg->lchan = lchan; + gh->proto_discr = GSM48_PDISC_RR; + gh->msg_type = GSM48_MT_RR_UPLINK_BUSY; + + return gsm48_sendmsg_unit(msg); +} + +/* TS 44.018 section 9.1.47 */ +int gsm48_send_uplink_free(struct gsm_lchan *lchan, uint8_t acc_bit, uint8_t *uic) +{ + struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 UL FREE"); + struct gsm48_hdr_sh *sh = (struct gsm48_hdr_sh *) msgb_put(msg, sizeof(*sh) + 22); + struct bitvec *bv = bitvec_alloc(22, NULL); + + msg->lchan = lchan; + sh->rr_short_pd = GSM48_PDISC_SH_RR; + sh->msg_type = GSM48_MT_RR_SH_UL_FREE; + sh->l2_header = 0; + + /* < Uplink Access Request bit > */ + bitvec_set_bit(bv, (acc_bit) ? H : L); + + /* { L | H <Uplink Identity Code bit(6) > } */ + if (uic) { + bitvec_set_bit(bv, H); + sh->data0 = 0x40 | *uic; + } else + bitvec_set_bit(bv, L); + + /* Emergency mode not supported */ + + /* Padding the rest with 0x2B and apply to msg. */ + bitvec_spare_padding(bv, 175); + bitvec_pack(bv, sh->data); + bitvec_free(bv); + + return gsm48_sendmsg_unit(msg); +} + int gsm48_rx_rr_modif_ack(struct msgb *msg) { struct gsm48_hdr *gh = msgb_l3(msg); @@ -1101,6 +1182,12 @@ * according to spec */ bsc_dtap(conn, link_id, msg); break; + case GSM48_MT_RR_UPLINK_RELEASE: + /* When the calling phone releases the uplink before it has been assigned to the group + * channel, it will send an UPLINK RELEASE message on the dedicated channel. The MSC + * has to take care of it. (assigning the phone to the group channel) */ + bsc_dtap(conn, link_id, msg); + break; default: /* Drop unknown RR message */ LOG_LCHAN(msg->lchan, LOGL_NOTICE, "Unknown RR message: %s\n",
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/gsm_08_08.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/gsm_08_08.c
Changed
@@ -182,7 +182,7 @@ struct bsc_msc_data *msc_target = NULL; struct bsc_msc_data *msc_round_robin_next = NULL; struct bsc_msc_data *msc_round_robin_first = NULL; - uint8_t round_robin_next_nr; + unsigned int round_robin_next_nr; int16_t nri_v = -1; bool is_null_nri = false; @@ -351,6 +351,19 @@ conn_update_ms_power_class(conn, rc8); } +static struct gsm_subscriber_connection *bsc_conn_by_bsub(const struct bsc_subscr *bsub) +{ + struct gsm_subscriber_connection *conn; + if (!bsub) + return NULL; + + llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { + if (conn->bsub == bsub) + return conn; + } + return NULL; +} + /*! MS->MSC: New MM context with L3 payload. */ int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { @@ -607,3 +620,14 @@ if (rc != 0) msgb_free(resp); } + +bool bsc_chan_ind_requires_rtp_stream(enum gsm0808_chan_indicator ch_indctr) +{ + switch (ch_indctr) { + case GSM0808_CHAN_SPEECH: + case GSM0808_CHAN_DATA: + return true; + default: + return false; + } +}
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/gsm_data.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/gsm_data.c
Changed
@@ -184,31 +184,22 @@ { GSM_PCHAN_TCH_H, "TCH/H" }, { GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" }, { GSM_PCHAN_PDCH, "PDCH" }, - { GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" }, + { GSM_PCHAN_TCH_F_PDCH, "DYNAMIC/IPACCESS" }, { GSM_PCHAN_UNKNOWN, "UNKNOWN" }, { GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH+SDCCH4+CBCH" }, { GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8+CBCH" }, + { GSM_PCHAN_OSMO_DYN, "DYNAMIC/OSMOCOM" }, + /* make get_string_value() return GSM_PCHAN_TCH_F_PDCH for both "DYNAMIC/IPACCESS" and "TCH/F_PDCH" */ + { GSM_PCHAN_TCH_F_PDCH, "TCH/F_PDCH" }, + /* make get_string_value() return GSM_PCHAN_OSMO_DYN for both "DYNAMIC/OSMOCOM" and "TCH/F_TCH/H_SDCCH8_PDCH" */ { GSM_PCHAN_OSMO_DYN, "TCH/F_TCH/H_SDCCH8_PDCH" }, + /* When adding items here, you must also add matching items to gsm_pchant_descs! */ { 0, NULL } }; -const struct value_string gsm_pchan_ids = { - { GSM_PCHAN_NONE, "NONE" }, - { GSM_PCHAN_CCCH, "CCCH" }, - { GSM_PCHAN_CCCH_SDCCH4,"CCCH_SDCCH4" }, - { GSM_PCHAN_TCH_F, "TCH_F" }, - { GSM_PCHAN_TCH_H, "TCH_H" }, - { GSM_PCHAN_SDCCH8_SACCH8C, "SDCCH8" }, - { GSM_PCHAN_PDCH, "PDCH" }, - { GSM_PCHAN_TCH_F_PDCH, "TCH_F_PDCH" }, - { GSM_PCHAN_UNKNOWN, "UNKNOWN" }, - { GSM_PCHAN_CCCH_SDCCH4_CBCH, "CCCH_SDCCH4_CBCH" }, - { GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "SDCCH8_CBCH" }, - { GSM_PCHAN_OSMO_DYN, "OSMO_DYN" }, - { 0, NULL } -}; - -const struct value_string gsm_pchant_descs13 = { +/* VTY command descriptions. These have to be in the same order as gsm_pchant_names, so that the automatic VTY command + * composition in bts_trx_vty_init() works out. */ +const struct value_string gsm_pchant_descs = { { GSM_PCHAN_NONE, "Physical Channel not configured" }, { GSM_PCHAN_CCCH, "FCCH + SCH + BCCH + CCCH (Comb. IV)" }, { GSM_PCHAN_CCCH_SDCCH4, @@ -217,14 +208,24 @@ { GSM_PCHAN_TCH_H, "2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II)" }, { GSM_PCHAN_SDCCH8_SACCH8C, "8 SDCCH + 4 SACCH (Comb. VII)" }, { GSM_PCHAN_PDCH, "Packet Data Channel for GPRS/EDGE" }, - { GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" }, + { GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" + " (dynamic/ipaccess is an alias for tch/f_pdch)" }, { GSM_PCHAN_UNKNOWN, "Unknown / Unsupported channel combination" }, { GSM_PCHAN_CCCH_SDCCH4_CBCH, "FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V)" }, { GSM_PCHAN_SDCCH8_SACCH8C_CBCH, "7 SDCCH + 4 SACCH + CBCH (Comb. VII)" }, - { GSM_PCHAN_OSMO_DYN, "Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH" }, + { GSM_PCHAN_OSMO_DYN, "Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH" + " (dynamic/osmocom is an alias for tch/f_tch/h_sdcch8_pdch)" }, + /* These duplicate entries are needed to provide a description for both the DYNAMIC/... aliases and their + * explicit versions 'TCH/F_PDCH' / 'TCH/F_TCH/H_SDCCH8_PDCH', see bts_trx_vty_init() */ + { GSM_PCHAN_TCH_F_PDCH, "Dynamic TCH/F or GPRS PDCH" + " (dynamic/ipaccess is an alias for tch/f_pdch)" }, + { GSM_PCHAN_OSMO_DYN, "Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH" + " (dynamic/osmocom is an alias for tch/f_tch/h_sdcch8_pdch)" }, { 0, NULL } }; +osmo_static_assert(ARRAY_SIZE(gsm_pchant_names) == ARRAY_SIZE(gsm_pchant_descs), _pchan_vty_docs); + const char *gsm_pchan_name(enum gsm_phys_chan_config c) { return get_value_string(gsm_pchant_names, c); @@ -939,6 +940,7 @@ OSMO_VALUE_STRING(ACTIVATE_FOR_MS_CHANNEL_REQUEST), OSMO_VALUE_STRING(ACTIVATE_FOR_ASSIGNMENT), OSMO_VALUE_STRING(ACTIVATE_FOR_HANDOVER), + OSMO_VALUE_STRING(ACTIVATE_FOR_VGCS_CHANNEL), OSMO_VALUE_STRING(ACTIVATE_FOR_VTY), {} }; @@ -1042,3 +1044,18 @@ return -EINVAL; } } + +int gsm_audio_support_cmp(const struct gsm_audio_support *a, const struct gsm_audio_support *b) +{ + int rc; + if (a == b) + return 0; + if (!a) + return -1; + if (!b) + return 1; + rc = OSMO_CMP(a->hr, b->hr); + if (rc) + return rc; + return OSMO_CMP(a->ver, b->ver); +}
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/handover_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/handover_fsm.c
Changed
@@ -193,11 +193,11 @@ } static const struct osmo_tdef_state_timeout ho_fsm_timeouts32 = { - HO_ST_WAIT_LCHAN_ACTIVE = { .T = 23042 }, - HO_ST_WAIT_MGW_ENDPOINT_TO_MSC = { .T = 23042 }, - HO_ST_WAIT_RR_HO_DETECT = { .T = 23042 }, - HO_ST_WAIT_RR_HO_COMPLETE = { .T = 23042 }, - HO_ST_WAIT_LCHAN_ESTABLISHED = { .T = 23042 }, + HO_ST_WAIT_LCHAN_ACTIVE = { /* Guarded by X5 + X6 in lchan_fsm_timeouts */ }, + HO_ST_WAIT_MGW_ENDPOINT_TO_MSC = { .T = -9 }, + HO_ST_WAIT_RR_HO_DETECT = { .T = 3103 }, + HO_ST_WAIT_RR_HO_COMPLETE = { .keep_timer = true }, /* Keep T3103 */ + HO_ST_WAIT_LCHAN_ESTABLISHED = { /* Guarded by T3101 in lchan_fsm_timeouts */ }, HO_OUT_ST_WAIT_HO_COMMAND = { .T = 7 }, HO_OUT_ST_WAIT_CLEAR = { .T = 8 }, }; @@ -269,7 +269,7 @@ if (conn->fi->id) osmo_fsm_inst_update_id_f(fi, "%s_%s", label, conn->fi->id); else - osmo_fsm_inst_update_id_f(fi, "%s_conn%u", label, conn->sccp.conn_id); + osmo_fsm_inst_update_id_f(fi, "%s_conn%u", label, conn->sccp.conn.conn_id); } static void handover_reset(struct gsm_subscriber_connection *conn) @@ -293,7 +293,7 @@ }; } -void handover_fsm_init(void) +static __attribute__((constructor)) void handover_fsm_init(void) { OSMO_ASSERT(osmo_fsm_register(&ho_fsm) == 0); } @@ -409,7 +409,7 @@ .for_conn = conn, .ch_mode_rate = conn->lchan->current_ch_mode_rate, .encr = conn->lchan->encr, - .requires_voice_stream = conn->lchan->mgw_endpoint_ci_bts ? true : false, + .ch_indctr = conn->lchan->current_ch_indctr, .msc_assigned_cic = conn->ho.inter_bsc_in.msc_assigned_cic, .re_use_mgw_endpoint_from_lchan = conn->lchan, .wait_before_switching_rtp = true, @@ -630,18 +630,6 @@ return true; } -static bool chan_mode_is_tch(enum gsm48_chan_mode mode) -{ - switch (gsm48_chan_mode_to_non_vamos(mode)) { - case GSM48_CMODE_SPEECH_V1: - case GSM48_CMODE_SPEECH_EFR: - case GSM48_CMODE_SPEECH_AMR: - return true; - default: - return false; - } -} - void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn, struct msgb *ho_request_msg) { @@ -739,7 +727,7 @@ .activ_for = ACTIVATE_FOR_HANDOVER, .for_conn = conn, .ch_mode_rate = ch_mode_rate, - .requires_voice_stream = chan_mode_is_tch(ch_mode_rate.chan_mode), + .ch_indctr = req->ct.ch_indctr, .msc_assigned_cic = req->msc_assigned_cic, }; @@ -943,7 +931,7 @@ ho_perf_params.chosen_encr_alg = ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n); ho_perf_params.chosen_encr_alg_present = true; - if (ho->new_lchan->activate.info.requires_voice_stream) { + if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr)) { /* Speech Version (chosen) 3.2.2.51 */ ho_perf_params.speech_version_chosen = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode); @@ -1129,7 +1117,7 @@ * So create an MSC side endpoint CI only if a voice lchan is established for an incoming inter-BSC * handover on AoIP. Otherwise go on to send a Handover Command and wait for the Detect. */ - if (ho->new_lchan->activate.info.requires_voice_stream + if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr) && (ho->scope & HO_INTER_BSC_IN) && gscon_is_aoip(conn)) ho_fsm_state_chg(HO_ST_WAIT_MGW_ENDPOINT_TO_MSC);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lb.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lb.c
Changed
@@ -31,19 +31,7 @@ #include <osmocom/bsc/osmo_bsc_sigtran.h> #include <osmocom/bsc/lcs_loc_req.h> #include <osmocom/bsc/bssmap_reset.h> - -static struct gsm_subscriber_connection *get_bsc_conn_by_lb_conn_id(int conn_id) -{ - struct gsm_subscriber_connection *conn; - - llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { - if (conn->lcs.lb.state != SUBSCR_SCCP_ST_NONE - && conn->lcs.lb.conn_id == conn_id) - return conn; - } - - return NULL; -} +#include <osmocom/bsc/gsm_data.h> /* Send reset to SMLC */ int bssmap_le_tx_reset(void) @@ -147,6 +135,8 @@ { struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph; struct osmo_sccp_user *scu = _scu; + struct osmo_sccp_instance *sccp = osmo_sccp_get_sccp(scu); + struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(sccp); struct gsm_subscriber_connection *conn; int rc = 0; @@ -169,7 +159,7 @@ case OSMO_PRIM(OSMO_SCU_PRIM_N_CONNECT, PRIM_OP_CONFIRM): /* Handle inbound confirmation of outbound connection */ DEBUGP(DLCS, "N-CONNECT.cnf(%u)\n", scu_prim->u.connect.conn_id); - conn = get_bsc_conn_by_lb_conn_id(scu_prim->u.connect.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.connect.conn_id); if (conn) { conn->lcs.lb.state = SUBSCR_SCCP_ST_CONNECTED; if (msgb_l2len(oph->msg) > 0) { @@ -185,7 +175,7 @@ /* Handle incoming connection oriented data */ DEBUGP(DLCS, "N-DATA.ind(%u)\n", scu_prim->u.data.conn_id); - conn = get_bsc_conn_by_lb_conn_id(scu_prim->u.data.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.data.conn_id); if (!conn) { LOGP(DLCS, LOGL_ERROR, "N-DATA.ind(%u) for unknown conn_id\n", scu_prim->u.data.conn_id); rc = -EINVAL; @@ -203,12 +193,14 @@ osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)), scu_prim->u.disconnect.cause); /* indication of disconnect */ - conn = get_bsc_conn_by_lb_conn_id(scu_prim->u.disconnect.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.disconnect.conn_id); if (!conn) { LOGP(DLCS, LOGL_ERROR, "N-DISCONNECT.ind for unknown conn_id %u\n", scu_prim->u.disconnect.conn_id); rc = -EINVAL; } else { + bsc_sccp_inst_unregister_gscon(bsc_sccp, &conn->lcs.lb.conn); + conn->lcs.lb.conn.conn_id = SCCP_CONN_ID_UNSET; conn->lcs.lb.state = SUBSCR_SCCP_ST_NONE; if (msgb_l2len(oph->msg) > 0) { rc = lcs_loc_req_rx_bssmap_le(conn, oph->msg); @@ -229,8 +221,9 @@ static int lb_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) { struct osmo_ss7_instance *ss7; - int conn_id; + uint32_t conn_id; int rc; + struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(bsc_gsmnet->smlc->sccp); OSMO_ASSERT(conn); OSMO_ASSERT(msg); @@ -241,35 +234,52 @@ return -EINVAL; } - conn_id = bsc_sccp_inst_next_conn_id(bsc_gsmnet->smlc->sccp); - if (conn_id < 0) { + conn_id = bsc_sccp_inst_next_conn_id(bsc_sccp); + if (conn_id == SCCP_CONN_ID_UNSET) { LOGPFSMSL(conn->fi, DLCS, LOGL_ERROR, "Unable to allocate SCCP Connection ID for BSSMAP-LE to SMLC\n"); return -ENOSPC; } - conn->lcs.lb.conn_id = conn_id; + conn->lcs.lb.conn.conn_id = conn_id; + if (bsc_sccp_inst_register_gscon(bsc_sccp, &conn->lcs.lb.conn) < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to register Lb SCCP connection (id=%u)\n", conn->lcs.lb.conn.conn_id); + return -1; + } ss7 = osmo_ss7_instance_find(bsc_gsmnet->smlc->cs7_instance); OSMO_ASSERT(ss7); - LOGPFSMSL(conn->fi, DLCS, LOGL_INFO, "Opening new SCCP connection (id=%i) to SMLC: %s\n", conn_id, + LOGPFSMSL(conn->fi, DLCS, LOGL_INFO, "Opening new SCCP connection (id=%u) to SMLC: %s\n", conn_id, osmo_sccp_addr_name(ss7, &bsc_gsmnet->smlc->smlc_addr)); rc = osmo_sccp_tx_conn_req_msg(bsc_gsmnet->smlc->sccp_user, conn_id, &bsc_gsmnet->smlc->bsc_addr, &bsc_gsmnet->smlc->smlc_addr, msg); - if (rc >= 0) + if (rc >= 0) { rate_ctr_inc(rate_ctr_group_get_ctr(bsc_gsmnet->smlc->ctrs, SMLC_CTR_BSSMAP_LE_TX_SUCCESS)); - else - rate_ctr_inc(rate_ctr_group_get_ctr(bsc_gsmnet->smlc->ctrs, SMLC_CTR_BSSMAP_LE_TX_ERR_SEND)); - if (rc >= 0) conn->lcs.lb.state = SUBSCR_SCCP_ST_WAIT_CONN_CONF; + } else { + rate_ctr_inc(rate_ctr_group_get_ctr(bsc_gsmnet->smlc->ctrs, SMLC_CTR_BSSMAP_LE_TX_ERR_SEND)); + goto failed_unregister_conn_id; + } return rc; + +failed_unregister_conn_id: + bsc_sccp_inst_unregister_gscon(bsc_sccp, &conn->lcs.lb.conn); + conn->lcs.lb.conn.conn_id = SCCP_CONN_ID_UNSET; + return rc; } void lb_close_conn(struct gsm_subscriber_connection *conn) { + struct bsc_sccp_inst *bsc_sccp; if (conn->lcs.lb.state == SUBSCR_SCCP_ST_NONE) return; - osmo_sccp_tx_disconn(bsc_gsmnet->smlc->sccp_user, conn->lcs.lb.conn_id, &bsc_gsmnet->smlc->bsc_addr, 0); + OSMO_ASSERT(conn->lcs.lb.conn.conn_id != SCCP_CONN_ID_UNSET); + + osmo_sccp_tx_disconn(bsc_gsmnet->smlc->sccp_user, conn->lcs.lb.conn.conn_id, &bsc_gsmnet->smlc->bsc_addr, 0); + conn->lcs.lb.state = SUBSCR_SCCP_ST_NONE; + bsc_sccp = osmo_sccp_get_priv(bsc_gsmnet->smlc->sccp); + bsc_sccp_inst_unregister_gscon(bsc_sccp, &conn->lcs.lb.conn); + conn->lcs.lb.conn.conn_id = SCCP_CONN_ID_UNSET; } /* Send data to SMLC, take ownership of *msg */ @@ -302,7 +312,7 @@ } LOGPFSMSL(conn->fi, DLCS, LOGL_DEBUG, "Tx %s\n", osmo_bssap_le_pdu_to_str_c(OTC_SELECT, bssap_le)); - rc = osmo_sccp_tx_data_msg(bsc_gsmnet->smlc->sccp_user, conn->lcs.lb.conn_id, msg); + rc = osmo_sccp_tx_data_msg(bsc_gsmnet->smlc->sccp_user, conn->lcs.lb.conn.conn_id, msg); if (rc >= 0) rate_ctr_inc(rate_ctr_group_get_ctr(bsc_gsmnet->smlc->ctrs, SMLC_CTR_BSSMAP_LE_TX_SUCCESS)); else @@ -418,6 +428,7 @@ enum osmo_ss7_asp_protocol used_proto = OSMO_SS7_ASP_PROT_M3UA; char inst_name32; const char *smlc_name = "smlc"; + struct bsc_sccp_inst *bsc_sccp; /* Already set up? */ if (bsc_gsmnet->smlc->sccp_user) @@ -451,6 +462,9 @@ if (!sccp) return -EINVAL; bsc_gsmnet->smlc->sccp = sccp; + bsc_sccp = bsc_sccp_inst_alloc(tall_bsc_ctx); + bsc_sccp->sccp = sccp; + osmo_sccp_set_priv(sccp, bsc_sccp); /* If unset, use default local SCCP address */ if (!bsc_gsmnet->smlc->bsc_addr.presence)
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lchan.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lchan.c
Changed
@@ -1,4 +1,4 @@ -/* (C) 2022 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * (C) 2008-2018 by Harald Welte <laforge@gnumonks.org> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lchan_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lchan_fsm.c
Changed
@@ -35,6 +35,7 @@ #include <osmocom/bsc/abis_rsl.h> #include <osmocom/bsc/bsc_rll.h> #include <osmocom/bsc/gsm_04_08_rr.h> +#include <osmocom/bsc/gsm_08_08.h> #include <osmocom/bsc/assignment_fsm.h> #include <osmocom/bsc/handover_fsm.h> #include <osmocom/bsc/bsc_msc_data.h> @@ -42,6 +43,7 @@ #include <osmocom/bsc/bts.h> #include <osmocom/bsc/bsc_stats.h> #include <osmocom/bsc/lchan.h> +#include <osmocom/bsc/vgcs_fsm.h> static struct osmo_fsm lchan_fsm; @@ -68,6 +70,14 @@ } } +bool lchan_is_asci(struct gsm_lchan *lchan) +{ + if (lchan->activate.info.type_for == LCHAN_TYPE_FOR_VGCS || + lchan->activate.info.type_for == LCHAN_TYPE_FOR_VBS) + return true; + return false; +} + static void lchan_on_mode_modify_success(struct gsm_lchan *lchan) { lchan->modify.concluded = true; @@ -183,6 +193,23 @@ _osmo_fsm_inst_dispatch(for_conn->ho.fi, HO_EV_LCHAN_ERROR, lchan, file, line); break; + case ACTIVATE_FOR_VGCS_CHANNEL: + LOG_LCHAN(lchan, LOGL_NOTICE, "Signalling VGCS Assignment FSM of error (%s)\n", + lchan->last_error ? : "unknown error"); + if (!for_conn) { + LOG_LCHAN(lchan, LOGL_ERROR, + "lchan activation for VGCS Assignment failed, but activation request has no conn\n"); + break; + } + if (!for_conn->vgcs_chan.fi) { + LOG_LCHAN(lchan, LOGL_ERROR, + "lchan activation for VGCS Assignment failed, but conn has no ongoing" + " assignment procedure\n"); + break; + } + _osmo_fsm_inst_dispatch(for_conn->vgcs_chan.fi, VGCS_EV_LCHAN_ERROR, lchan, file, line); + break; + case ACTIVATE_FOR_VTY: LOG_LCHAN(lchan, LOGL_ERROR, "VTY user invoked lchan activation failed (%s)\n", lchan->last_error ? : "unknown error"); @@ -270,6 +297,22 @@ * we will try to roll back a modified RTP connection. */ break; + case ACTIVATE_FOR_VGCS_CHANNEL: + if (!lchan->conn) { + LOG_LCHAN(lchan, LOGL_ERROR, + "lchan activation for VGCS assignment succeeded, but lchan has no conn\n"); + lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL); + break; + } + if (!lchan->conn->vgcs_chan.fi) { + LOG_LCHAN(lchan, LOGL_ERROR, + "lchan Activation for VGCS assignment requested, but conn has no VGCS resource FSM.\n"); + lchan_release(lchan, false, true, RSL_ERR_EQUIPMENT_FAIL, NULL); + break; + } + osmo_fsm_inst_dispatch(lchan->conn->vgcs_chan.fi, VGCS_EV_LCHAN_ACTIVE, lchan); + break; + case ACTIVATE_FOR_MODE_MODIFY_RTP: lchan_on_mode_modify_success(lchan); break; @@ -347,7 +390,7 @@ OSMO_ASSERT(lchan && info); - if ((info->vamos || lchan->vamos.is_secondary) + if ((info->type_for == LCHAN_TYPE_FOR_VAMOS || lchan->vamos.is_secondary) && !osmo_bts_has_feature(&lchan->ts->trx->bts->features, BTS_FEAT_VAMOS)) { lchan->last_error = talloc_strdup(lchan->ts->trx, "VAMOS related channel activation requested," " but BTS does not support VAMOS"); @@ -404,6 +447,28 @@ } break; + case ACTIVATE_FOR_VGCS_CHANNEL: + if (!info->for_conn + || !info->for_conn->fi) { + LOG_LCHAN(lchan, LOGL_ERROR, "Activation requested, but no conn\n"); + goto abort; + } + if (!info->for_conn->vgcs_chan.fi) { + LOG_LCHAN(lchan, LOGL_ERROR, + "Activation for VGCS assignment requested, but conn has no VGCS resource FSM.\n"); + goto abort; + } + if (info->for_conn->vgcs_chan.new_lchan != lchan) { + LOG_LCHAN(lchan, LOGL_ERROR, + "Activation for VGCS assignment requested, but conn's VGCS assignment state does" + " not reflect this lchan to be activated (instead: %s)\n", + info->for_conn->vgcs_chan.new_lchan ? + gsm_lchan_name(info->for_conn->vgcs_chan.new_lchan) + : "NULL"); + goto abort; + } + break; + default: break; } @@ -428,7 +493,7 @@ { OSMO_ASSERT(lchan && info); - if ((info->vamos || lchan->vamos.is_secondary) + if ((info->type_for == LCHAN_TYPE_FOR_VAMOS || lchan->vamos.is_secondary) && !osmo_bts_has_feature(&lchan->ts->trx->bts->features, BTS_FEAT_VAMOS)) { lchan->last_error = talloc_strdup(lchan->ts->trx, "VAMOS related Channel Mode Modify requested," " but BTS does not support VAMOS"); @@ -452,21 +517,18 @@ lchan_update_name(lchan); if (!lchan->fi) return; - osmo_fsm_inst_update_id_f(lchan->fi, "%u-%u-%u-%s-%s%u", - lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, - gsm_pchan_id(lchan->ts->pchan_on_init), - lchan->vamos.is_secondary ? "shadow" : "", - lchan->nr - (lchan->vamos.is_secondary ? lchan->ts->max_primary_lchans : 0)); + osmo_fsm_inst_update_id_f_sanitize(lchan->fi, '_', "%u-%u-%u-%s-%s%u", + lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr, + gsm_pchan_name(lchan->ts->pchan_on_init), + lchan->vamos.is_secondary ? "shadow" : "", + lchan->nr - (lchan->vamos.is_secondary ? lchan->ts->max_primary_lchans : 0)); if (lchan->fi_rtp) osmo_fsm_inst_update_id_f(lchan->fi_rtp, lchan->fi->id); } -extern void lchan_rtp_fsm_init(); - -void lchan_fsm_init(void) +static __attribute__((constructor)) void lchan_fsm_init(void) { OSMO_ASSERT(osmo_fsm_register(&lchan_fsm) == 0); - lchan_rtp_fsm_init(); } static void lchan_reset(struct gsm_lchan *lchan); @@ -678,9 +740,9 @@ { struct osmo_fsm_inst *fi = lchan->fi; lchan->activate.ch_mode_rate = lchan->activate.info.ch_mode_rate; - lchan->activate.ch_mode_rate.chan_mode = (lchan->activate.info.vamos + lchan->activate.ch_mode_rate.chan_mode = (lchan->activate.info.type_for == LCHAN_TYPE_FOR_VAMOS) ? gsm48_chan_mode_to_vamos(lchan->activate.info.ch_mode_rate.chan_mode) - : gsm48_chan_mode_to_non_vamos(lchan->activate.info.ch_mode_rate.chan_mode)); + : gsm48_chan_mode_to_non_vamos(lchan->activate.info.ch_mode_rate.chan_mode); if (lchan->activate.ch_mode_rate.chan_mode < 0) { lchan_fail("Invalid chan_mode: %s", gsm48_chan_mode_name(lchan->activate.info.ch_mode_rate.chan_mode)); return -EINVAL; @@ -692,6 +754,8 @@ return -EINVAL; } } + + lchan->activate.ch_indctr = lchan->activate.info.ch_indctr; return 0; } @@ -720,6 +784,7 @@ struct gsm_lchan *old_lchan = lchan->activate.info.re_use_mgw_endpoint_from_lchan; struct lchan_activate_info *info = &lchan->activate.info; int ms_power_dbm = bts->ms_max_power; + bool requires_rtp_stream; if (lchan->release.requested) { lchan_fail("Release requested while activating"); @@ -763,12 +828,13 @@ lchan->activate.tsc = lchan->activate.info.tsc.present ? lchan->activate.info.tsc.val : gsm_ts_tsc(lchan->ts); use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan); + requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr); LOG_LCHAN(lchan, LOGL_INFO, - "Activation requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s encr-alg=A5/%u ck=%s\n", + "Activation requested: %s rtp=%s MGW-ci=%s type=%s tch-mode=%s encr-alg=A5/%u ck=%s\n", lchan_activate_mode_name(lchan->activate.info.activ_for), - lchan->activate.info.requires_voice_stream ? "yes" : "no", - lchan->activate.info.requires_voice_stream ? + requires_rtp_stream ? "yes" : "no", + requires_rtp_stream ? (use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new") : "none", gsm_chan_t_name(lchan->type), @@ -782,7 +848,7 @@ osmo_fsm_inst_dispatch(lchan->ts->fi, TS_EV_LCHAN_REQUESTED, lchan); /* Prepare an MGW endpoint CI if appropriate. */ - if (lchan->activate.info.requires_voice_stream) + if (requires_rtp_stream) lchan_rtp_fsm_start(lchan); if (lchan->activate.info.imm_ass_time == IMM_ASS_TIME_PRE_TS_ACK) { @@ -847,6 +913,7 @@ ho_ref = lchan->conn->ho.ho_ref; break; case ACTIVATE_FOR_ASSIGNMENT: + case ACTIVATE_FOR_VGCS_CHANNEL: default: act_type = RSL_ACT_INTRA_NORM_ASS; break; @@ -941,7 +1008,8 @@ { lchan->current_ch_mode_rate = lchan->activate.ch_mode_rate; lchan->current_mr_conf = lchan->activate.mr_conf_filtered; - lchan->vamos.enabled = lchan->activate.info.vamos; + lchan->current_ch_indctr = lchan->activate.ch_indctr; + lchan->vamos.enabled = (lchan->activate.info.type_for == LCHAN_TYPE_FOR_VAMOS); lchan->tsc_set = lchan->activate.tsc_set; lchan->tsc = lchan->activate.tsc; } @@ -1022,16 +1090,19 @@ static void lchan_fsm_wait_rll_rtp_establish_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_lchan *lchan = lchan_fi_lchan(fi); + bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr); + if (lchan->fi_rtp) osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_LCHAN_READY, 0); /* Prepare an MGW endpoint CI if appropriate (late). */ - else if (lchan->activate.info.requires_voice_stream) + else if (requires_rtp_stream) lchan_rtp_fsm_start(lchan); - /* When activating a channel for VTY, skip waiting for activity from - * lchan_rtp_fsm, but only if no voice stream is required. */ - if (lchan->activate.info.activ_for == ACTIVATE_FOR_VTY && - !lchan->activate.info.requires_voice_stream) { + /* When activating a channel for VTY or VGCS/VBS, skip waiting for activity from + * lchan_rtp_fsm, but only if no rtp stream is required. */ + if ((lchan->activate.info.activ_for == ACTIVATE_FOR_VTY || + lchan->activate.info.activ_for == ACTIVATE_FOR_VGCS_CHANNEL) && + !requires_rtp_stream) { lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED); } } @@ -1039,21 +1110,24 @@ static void lchan_fsm_wait_rll_rtp_establish(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_lchan *lchan = lchan_fi_lchan(fi); + bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr); + switch (event) { case LCHAN_EV_RLL_ESTABLISH_IND: - if (!lchan->activate.info.requires_voice_stream - || lchan_rtp_established(lchan)) { + if (!requires_rtp_stream || lchan_rtp_established(lchan)) { LOG_LCHAN(lchan, LOGL_DEBUG, "%s\n", - (lchan->activate.info.requires_voice_stream ? + (requires_rtp_stream ? "RTP already established earlier" : "no voice stream required")); lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED); } return; case LCHAN_EV_RTP_READY: - if (lchan->sapis0 != LCHAN_SAPI_UNUSED) + /* If RLL was established or if it does not need to be establised, because of VGCS/VBS channel. */ + if (lchan->sapis0 != LCHAN_SAPI_UNUSED || + lchan->activate.info.activ_for == ACTIVATE_FOR_VGCS_CHANNEL) lchan_fsm_state_chg(LCHAN_ST_ESTABLISHED); return; @@ -1121,19 +1195,19 @@ /* The Channel Mode Modify was ACKed, now the requested values become the accepted and used values. */ lchan->current_ch_mode_rate = lchan->modify.ch_mode_rate; lchan->current_mr_conf = lchan->modify.mr_conf_filtered; + lchan->current_ch_indctr = lchan->modify.ch_indctr; lchan->tsc_set = lchan->modify.tsc_set; lchan->tsc = lchan->modify.tsc; - lchan->vamos.enabled = lchan->modify.info.vamos; + lchan->vamos.enabled = (lchan->modify.info.type_for == LCHAN_TYPE_FOR_VAMOS); - if (lchan->modify.info.requires_voice_stream - && !lchan->fi_rtp) { + if (bsc_chan_ind_requires_rtp_stream(lchan->modify.info.ch_indctr) && !lchan->fi_rtp) { /* Continue with RTP stream establishing as done in lchan_activate(). Place the requested values in * lchan->activate.info and continue with voice stream setup. */ lchan->activate.info = (struct lchan_activate_info){ .activ_for = ACTIVATE_FOR_MODE_MODIFY_RTP, .for_conn = lchan->conn, .ch_mode_rate = lchan->modify.ch_mode_rate, - .requires_voice_stream = true, + .ch_indctr = lchan->modify.info.ch_indctr, .msc_assigned_cic = lchan->modify.info.msc_assigned_cic, }; if (lchan_activate_set_ch_mode_rate_and_mr_config(lchan)) @@ -1223,8 +1297,13 @@ /* Releasing SAPI 0 means the conn becomes invalid; but not if the link_id contains a SACCH flag. */ if (lchan->conn && sapi == 0 && !(link_id & 0xc0)) { - LOG_LCHAN(lchan, LOGL_DEBUG, "lchan is releasing\n"); - gscon_lchan_releasing(lchan->conn, lchan); + /* A VGCS/VBS channel must stay active, even if all SAPIs are released. + * When a talker releases, the channel is available for the listeners and the next talker. The actual + * channel release is performed by the VGCS/VBS call control. */ + if (!lchan_is_asci(lchan)) { + LOG_LCHAN(lchan, LOGL_DEBUG, "lchan is releasing\n"); + gscon_lchan_releasing(lchan->conn, lchan); + } /* if SAPI=0 is gone, it makes no sense if other SAPIs are still around, * this is not a valid configuration and we should forget about them. @@ -1242,6 +1321,7 @@ struct gsm_lchan *lchan = lchan_fi_lchan(fi); struct lchan_modify_info *modif_info; struct osmo_mgcpc_ep_ci *use_mgwep_ci; + bool requires_rtp_stream = bsc_chan_ind_requires_rtp_stream(lchan->modify.info.ch_indctr); switch (event) { case LCHAN_EV_RLL_ESTABLISH_IND: @@ -1251,7 +1331,8 @@ case LCHAN_EV_RLL_REL_IND: case LCHAN_EV_RLL_REL_CONF: handle_rll_rel_ind_or_conf(fi, event, data); - if (!lchan_active_sapis(lchan, 0)) + /* Only release channel, if there is no SAPI and this channel is not a VGCS channel. */ + if (!lchan_active_sapis(lchan, 0) && !lchan_is_asci(lchan)) lchan_fsm_state_chg(LCHAN_ST_WAIT_RLL_RTP_RELEASED); return; @@ -1276,9 +1357,9 @@ use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan); lchan->modify.ch_mode_rate = lchan->modify.info.ch_mode_rate; - lchan->modify.ch_mode_rate.chan_mode = (lchan->modify.info.vamos - ? gsm48_chan_mode_to_vamos(lchan->modify.info.ch_mode_rate.chan_mode) - : gsm48_chan_mode_to_non_vamos(lchan->modify.info.ch_mode_rate.chan_mode)); + lchan->modify.ch_mode_rate.chan_mode = (lchan->modify.info.type_for == LCHAN_TYPE_FOR_VAMOS) + ? gsm48_chan_mode_to_vamos(lchan->modify.info.ch_mode_rate.chan_mode) + : gsm48_chan_mode_to_non_vamos(lchan->modify.info.ch_mode_rate.chan_mode); if (lchan->modify.ch_mode_rate.chan_mode < 0) { lchan_fail("Invalid chan_mode: %s", gsm48_chan_mode_name(lchan->modify.info.ch_mode_rate.chan_mode)); return; @@ -1292,6 +1373,8 @@ } } + lchan->modify.ch_indctr = lchan->modify.info.ch_indctr; + /* If enabling VAMOS mode and no specific TSC Set was selected, make sure to select a sane TSC Set by * default: Set 1 for the primary and Set 2 for the shadow lchan. For non-VAMOS lchans, TSC Set 1. */ if (lchan->modify.info.tsc_set.present) @@ -1304,10 +1387,10 @@ lchan->modify.tsc = lchan->modify.info.tsc.present ? lchan->modify.info.tsc.val : gsm_ts_tsc(lchan->ts); LOG_LCHAN(lchan, LOGL_INFO, - "Modification requested: %s voice=%s MGW-ci=%s type=%s tch-mode=%s tsc=%d/%u\n", + "Modification requested: %s rtp=%s MGW-ci=%s type=%s tch-mode=%s tsc=%d/%u\n", lchan_modify_for_name(lchan->modify.info.modify_for), - lchan->modify.info.requires_voice_stream ? "yes" : "no", - lchan->modify.info.requires_voice_stream ? + requires_rtp_stream ? "yes" : "no", + requires_rtp_stream ? (use_mgwep_ci ? osmo_mgcpc_ep_ci_name(use_mgwep_ci) : "new") : "none", gsm_chan_t_name(lchan->type), @@ -1339,8 +1422,14 @@ static void lchan_do_release(struct gsm_lchan *lchan) { - if (lchan->release.do_rr_release && lchan->sapis0 != LCHAN_SAPI_UNUSED) - gsm48_send_rr_release(lchan); + if (lchan->release.do_rr_release) { + /* To main DCCH in dedicated and group transmit mode */ + if (lchan->sapis0 != LCHAN_SAPI_UNUSED) + gsm48_send_rr_release(lchan, false); + /* As UI to all listeners in group receive mode */ + if (lchan_is_asci(lchan)) + gsm48_send_rr_release(lchan, true); + } if (lchan->fi_rtp) osmo_fsm_inst_dispatch(lchan->fi_rtp, LCHAN_RTP_EV_RELEASE, 0); @@ -1809,9 +1898,9 @@ lchan->release.rsl_error_cause = RSL_ERR_INTERWORKING; lchan->release.rr_cause = bsc_gsm48_rr_cause_from_rsl_cause(lchan->release.rsl_error_cause); if (fi->state == LCHAN_ST_WAIT_RLL_RTP_ESTABLISH) { - lchan_fail("Timeout (rll_ready=%s,voice_require=%s,voice_ready=%s)", + lchan_fail("Timeout (rll_ready=%s,rtp_require=%s,voice_ready=%s)", (lchan->sapis0 != LCHAN_SAPI_UNUSED) ? "yes" : "no", - lchan->activate.info.requires_voice_stream ? "yes" : "no", + bsc_chan_ind_requires_rtp_stream(lchan->activate.info.ch_indctr) ? "yes" : "no", lchan_rtp_established(lchan) ? "yes" : "no"); } else { lchan_fail("Timeout");
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lchan_rtp_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lchan_rtp_fsm.c
Changed
@@ -70,7 +70,7 @@ } while (0) /* Called from lchan_fsm_init(), does not need to be visible in lchan_rtp_fsm.h */ -void lchan_rtp_fsm_init(void) +static __attribute__((constructor)) void lchan_rtp_fsm_init(void) { OSMO_ASSERT(osmo_fsm_register(&lchan_rtp_fsm) == 0); } @@ -143,7 +143,7 @@ struct osmo_mgcpc_ep_ci *use_mgwep_ci = lchan_use_mgw_endpoint_ci_bts(lchan); struct mgcp_conn_peer crcx_info; - if (!is_ipaccess_bts(lchan->ts->trx->bts)) { + if (!is_ipa_abisip_bts(lchan->ts->trx->bts)) { LOG_LCHAN_RTP(lchan, LOGL_DEBUG, "Audio link to-BTS via E1, skipping IPACC\n"); lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_LCHAN_READY); return; @@ -169,7 +169,7 @@ .x_osmo_osmux_cid = -1, /* -1 is wildcard, .x_osmo_osmux_use set below */ }; if (lchan->conn) { - crcx_info.call_id = lchan->conn->sccp.conn_id; + crcx_info.call_id = lchan->conn->sccp.conn.conn_id; if (lchan->conn->sccp.msc) crcx_info.x_osmo_ign = lchan->conn->sccp.msc->x_osmo_ign; } @@ -290,7 +290,7 @@ { struct gsm_lchan *lchan = lchan_rtp_fi_lchan(fi); - if (is_ipaccess_bts(lchan->ts->trx->bts)) + if (is_ipa_abisip_bts(lchan->ts->trx->bts)) lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_IPACC_CRCX_ACK); else lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_MGW_ENDPOINT_CONFIGURED); @@ -307,14 +307,35 @@ return; } - val = ipacc_speech_mode(lchan->activate.ch_mode_rate.chan_mode, lchan->type); - if (val < 0) { - lchan_rtp_fail("Cannot determine Abis/IP speech mode for tch_mode=%s type=%s", - get_value_string(gsm48_chan_mode_names, lchan->activate.ch_mode_rate.chan_mode), - gsm_chan_t_name(lchan->type)); - return; + if (lchan->current_ch_indctr == GSM0808_CHAN_DATA) { + enum rsl_ipac_rtp_csd_format_d format_d = RSL_IPAC_RTP_CSD_TRAU_BTS; + + if (lchan->activate.ch_mode_rate.data_transparent) { + val = ipacc_rtp_csd_fmt_transp(&lchan->activate.ch_mode_rate, format_d); + if (val < 0) { + lchan_rtp_fail("Cannot determine Abis/IP RTP CSD format for rsl_cmod_csd_t=%d", + lchan->activate.ch_mode_rate.data_rate.t); + return; + } + } else { + val = ipacc_rtp_csd_fmt_non_transp(&lchan->activate.ch_mode_rate, format_d); + if (val < 0) { + lchan_rtp_fail("Cannot determine Abis/IP RTP CSD format for rsl_cmod_csd_nt=%d", + lchan->activate.ch_mode_rate.data_rate.nt); + return; + } + } + lchan->abis_ip.rtp_csd_fmt = val; + } else { + val = ipacc_speech_mode(lchan->activate.ch_mode_rate.chan_mode, lchan->type); + if (val < 0) { + lchan_rtp_fail("Cannot determine Abis/IP speech mode for tch_mode=%s type=%s", + get_value_string(gsm48_chan_mode_names, lchan->activate.ch_mode_rate.chan_mode), + gsm_chan_t_name(lchan->type)); + return; + } + lchan->abis_ip.speech_mode = val; } - lchan->abis_ip.speech_mode = val; val = ipacc_payload_type(lchan->activate.ch_mode_rate.chan_mode, lchan->type); if (val < 0) { @@ -495,7 +516,7 @@ return; } - if (!is_ipaccess_bts(lchan->ts->trx->bts)) { + if (!is_ipa_abisip_bts(lchan->ts->trx->bts)) { LOG_LCHAN_RTP(lchan, LOGL_DEBUG, "Audio link to-BTS via E1, skipping IPACC\n"); lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_READY); return; @@ -522,7 +543,7 @@ switch (event) { case LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED: - if (is_ipaccess_bts(lchan->ts->trx->bts)) + if (is_ipa_abisip_bts(lchan->ts->trx->bts)) lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_WAIT_IPACC_MDCX_ACK); else { lchan_rtp_fsm_state_chg(LCHAN_RTP_ST_READY); @@ -589,7 +610,7 @@ return; } - if (is_ipaccess_bts(lchan->ts->trx->bts)) + if (is_ipa_abisip_bts(lchan->ts->trx->bts)) connect_mgw_endpoint_to_lchan(fi, lchan->mgw_endpoint_ci_bts, old_lchan); else osmo_fsm_inst_dispatch(fi, LCHAN_RTP_EV_MGW_ENDPOINT_CONFIGURED, 0); @@ -850,6 +871,12 @@ static enum mgcp_codecs chan_mode_to_mgcp_codec(enum gsm48_chan_mode chan_mode, bool full_rate) { 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 CODEC_CLEARMODE; + case GSM48_CMODE_SPEECH_V1: if (full_rate) return CODEC_GSM_8000_1;
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lchan_select.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lchan_select.c
Changed
@@ -41,6 +41,7 @@ OSMO_VALUE_STRING(SELECT_FOR_MS_CHAN_REQ), OSMO_VALUE_STRING(SELECT_FOR_ASSIGNMENT), OSMO_VALUE_STRING(SELECT_FOR_HANDOVER), + OSMO_VALUE_STRING(SELECT_FOR_VGCS), {0, NULL} }; @@ -178,12 +179,16 @@ return GSM_LCHAN_NONE; } case GSM48_CMODE_SPEECH_EFR: - /* EFR works over FR channels only */ + case GSM48_CMODE_DATA_14k5: + case GSM48_CMODE_DATA_12k0: + /* these rates work over full-rate channels only */ if (chan_rate != CH_RATE_FULL) return GSM_LCHAN_NONE; /* fall through */ case GSM48_CMODE_SPEECH_V1: case GSM48_CMODE_SPEECH_AMR: + case GSM48_CMODE_DATA_6k0: + case GSM48_CMODE_DATA_3k6: switch (chan_rate) { case CH_RATE_HALF: return GSM_LCHAN_TCH_H; @@ -345,6 +350,9 @@ case SELECT_FOR_HANDOVER: chan_alloc_reverse = bts->chan_alloc_handover_reverse; break; + case SELECT_FOR_VGCS: + chan_alloc_reverse = bts->chan_alloc_vgcs_reverse; + break; } /* Allocate an array with pointers to all timeslots of a BTS */
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/lcs_ta_req.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/lcs_ta_req.c
Changed
@@ -89,7 +89,7 @@ struct lcs_ta_req *lcs_ta_req; if (lcs_loc_req->ta_req) { LOG_LCS_TA_REQ(lcs_loc_req->ta_req, LOGL_ERROR, - "Cannot start anoter TA Request FSM, this TA Request is still active\n"); + "Cannot start another TA Request FSM, this TA Request is still active\n"); return -ENOTSUP; } lcs_ta_req = lcs_ta_req_alloc(lcs_loc_req->fi, LCS_LOC_REQ_EV_TA_REQ_END);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/meas_feed.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/meas_feed.c
Changed
@@ -24,12 +24,16 @@ struct meas_feed_state { struct osmo_wqueue wqueue; + unsigned int wqueue_max_len; char scenario31+1; char *dst_host; uint16_t dst_port; }; -static struct meas_feed_state g_mfs = {}; +static struct meas_feed_state g_mfs = { + .wqueue.bfd.fd = -1, + .wqueue_max_len = MEAS_FEED_WQUEUE_MAX_LEN_DEFAULT, +}; static int process_meas_rep(struct gsm_meas_rep *mr) { @@ -37,6 +41,8 @@ struct meas_feed_meas *mfm; struct bsc_subscr *bsub; + OSMO_ASSERT(g_mfs.wqueue.bfd.fd != -1); + /* ignore measurements as long as we don't know who it is */ if (!mr->lchan) { LOGP(DMEAS, LOGL_DEBUG, "meas_feed: no lchan, not sending report\n"); @@ -49,7 +55,7 @@ bsub = mr->lchan->conn->bsub; - msg = msgb_alloc(sizeof(struct meas_feed_meas), "Meas. Feed"); + msg = msgb_alloc(sizeof(struct meas_feed_meas), "meas_feed_msg"); if (!msg) return 0; @@ -125,48 +131,47 @@ return rc; } +static void meas_feed_close(void) +{ + if (g_mfs.wqueue.bfd.fd == -1) + return; + osmo_signal_unregister_handler(SS_LCHAN, meas_feed_sig_cb, NULL); + osmo_wqueue_clear(&g_mfs.wqueue); + osmo_fd_unregister(&g_mfs.wqueue.bfd); + close(g_mfs.wqueue.bfd.fd); + g_mfs.wqueue.bfd.fd = -1; +} + int meas_feed_cfg_set(const char *dst_host, uint16_t dst_port) { int rc; - int already_initialized = 0; - - if (g_mfs.wqueue.bfd.fd) - already_initialized = 1; - - - if (already_initialized && - !strcmp(dst_host, g_mfs.dst_host) && - dst_port == g_mfs.dst_port) - return 0; - if (!already_initialized) { - osmo_wqueue_init(&g_mfs.wqueue, 10); - g_mfs.wqueue.write_cb = feed_write_cb; - g_mfs.wqueue.read_cb = feed_read_cb; - osmo_signal_register_handler(SS_LCHAN, meas_feed_sig_cb, NULL); - LOGP(DMEAS, LOGL_DEBUG, "meas_feed: registered signal callback\n"); + /* Already initialized */ + if (g_mfs.wqueue.bfd.fd > 0) { + /* No change needed, do nothing */ + if (!strcmp(dst_host, g_mfs.dst_host) && dst_port == g_mfs.dst_port) + return 0; + meas_feed_close(); } - if (already_initialized) { - osmo_wqueue_clear(&g_mfs.wqueue); - osmo_fd_unregister(&g_mfs.wqueue.bfd); - close(g_mfs.wqueue.bfd.fd); - /* don't set to zero, as that would mean 'not yet initialized' */ - g_mfs.wqueue.bfd.fd = -1; - } + osmo_wqueue_init(&g_mfs.wqueue, g_mfs.wqueue_max_len); + g_mfs.wqueue.write_cb = feed_write_cb; + g_mfs.wqueue.read_cb = feed_read_cb; + rc = osmo_sock_init_ofd(&g_mfs.wqueue.bfd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, dst_host, dst_port, OSMO_SOCK_F_CONNECT); - if (rc < 0) + if (rc < 0) { + g_mfs.wqueue.bfd.fd = -1; return rc; + } osmo_fd_read_disable(&g_mfs.wqueue.bfd); - - if (g_mfs.dst_host) - talloc_free(g_mfs.dst_host); - g_mfs.dst_host = talloc_strdup(NULL, dst_host); + osmo_talloc_replace_string(NULL, &g_mfs.dst_host, dst_host); g_mfs.dst_port = dst_port; - + osmo_signal_register_handler(SS_LCHAN, meas_feed_sig_cb, NULL); + LOGP(DMEAS, LOGL_DEBUG, "meas_feed: started %s\n", + osmo_sock_get_name2(g_mfs.wqueue.bfd.fd)); return 0; } @@ -176,6 +181,18 @@ *host = g_mfs.dst_host; } +void meas_feed_wqueue_max_length_set(unsigned int max_length) +{ + g_mfs.wqueue_max_len = max_length; + if (g_mfs.wqueue.bfd.fd) + g_mfs.wqueue.max_length = max_length; +} + +unsigned int meas_feed_wqueue_max_length_get(void) +{ + return g_mfs.wqueue_max_len; +} + void meas_feed_scenario_set(const char *name) { osmo_strlcpy(g_mfs.scenario, name, sizeof(g_mfs.scenario));
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/neighbor_ident.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/neighbor_ident.c
Changed
@@ -489,7 +489,7 @@ struct ctrl_handle *neighbor_controlif_setup(struct gsm_network *net) { - /* See also osmobsc-usermanual.pdf, section 14.1 Neighbor Address Resolution Service */ + /* DEPRECATED: see osmobsc-usermanual.pdf, section 16.1.1 Neighbor Address Resolution Service */ return ctrl_interface_setup_dynip2(net, net->neigh_ctrl.addr, net->neigh_ctrl.port, NULL, _LAST_CTRL_NODE_NEIGHBOR); }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/neighbor_ident_vty.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/neighbor_ident_vty.c
Changed
@@ -494,7 +494,7 @@ { vty_out(vty, "%% Warning: The CTRL interface for Neighbor Address Resolution is now deprecated." "Upgrade osmo-pcu and drop the 'neighbor-resolution bind " VTY_IPV46_CMD " <0-65535>' VTY " - "option in order to let osmo-pcu use the new resoluton method using the PCUIF over IPA " + "option in order to let osmo-pcu use the new resolution method using the PCUIF over IPA " "multiplex, which will work out of the box without required configuration.%s", VTY_NEWLINE); osmo_talloc_replace_string(bsc_gsmnet, &bsc_gsmnet->neigh_ctrl.addr, argv0); if (argc > 1)
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/net_init.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/net_init.c
Changed
@@ -36,7 +36,7 @@ { .T = 101, .default_val = 10, .desc = "inter-BSC/MSC Handover incoming, BSSMAP HO Request to HO Accept" }, { .T = 3101, .default_val = 3, .desc = "RR Immediate Assignment" }, { .T = 3103, .default_val = 5, .desc = "Handover" }, - { .T = 3105, .default_val = GSM_T3105_DEFAULT, .unit = OSMO_TDEF_MS, .desc = "Physical Information" }, + { .T = 3105, .default_val = GSM_T3105_DEFAULT, .min_val = 1, .unit = OSMO_TDEF_MS, .desc = "Physical Information" }, { .T = 3107, .default_val = 5, .desc = "(unused)" }, { .T = 3109, .default_val = 5, .desc = "RSL SACCH deactivation" }, { .T = 3111, .default_val = 2, .desc = "Wait time before RSL RF Channel Release" }, @@ -119,8 +119,7 @@ INIT_LLIST_HEAD(&net->subscr_conns); - net->bsc_subscribers = talloc_zero(net, struct llist_head); - INIT_LLIST_HEAD(net->bsc_subscribers); + net->bsc_subscribers = bsc_subscr_store_alloc(net); INIT_LLIST_HEAD(&net->bts_list); net->num_bts = 0;
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_bb_transc_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_bb_transc_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM BaseBand Transceiver FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -113,7 +113,7 @@ if (!bb_transc->mo.get_attr_sent && !bb_transc->mo.get_attr_rep_received) { bb_transc->mo.get_attr_sent = true; /* N. B: we rely on attribute order when parsing response in abis_nm_rx_get_attr_resp() */ - const uint8_t trx_attr = { NM_ATT_MANUF_STATE, NM_ATT_SW_CONFIG, }; + const uint8_t trx_attr = { NM_ATT_MANUF_STATE, NM_ATT_SW_CONFIG, NM_ATT_IPACC_SUPP_FEATURES }; /* we should not request more attributes than we're ready to handle */ OSMO_ASSERT(sizeof(trx_attr) < MAX_BTS_ATTR); abis_nm_get_attr(trx->bts, NM_OC_BASEB_TRANSC, 0, trx->nr, 0xff,
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_bts_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_bts_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM BTS FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -100,7 +100,7 @@ if (!bts->mo.get_attr_sent && !bts->mo.get_attr_rep_received) { bts->mo.get_attr_sent = true; /* N. B: we rely on attribute order when parsing response in abis_nm_rx_get_attr_resp() */ - const uint8_t bts_attr = { NM_ATT_MANUF_ID, NM_ATT_SW_CONFIG, }; + const uint8_t bts_attr = { NM_ATT_MANUF_ID, NM_ATT_SW_CONFIG, NM_ATT_IPACC_SUPP_FEATURES}; /* we should not request more attributes than we're ready to handle */ OSMO_ASSERT(sizeof(bts_attr) < MAX_BTS_ATTR); abis_nm_get_attr(bts, NM_OC_BTS, 0, 0xff, 0xff, @@ -122,7 +122,7 @@ bts->bts_nr, 0xff, 0xff, NM_STATE_UNLOCKED); /* Message containing BTS attributes, including the interference band bounds, was ACKed by the BTS. - * Store the sent bounds as the ones being used for logging and comparing intereference levels. */ + * Store the sent bounds as the ones being used for logging and comparing interference levels. */ bts->interf_meas_params_used = bts->interf_meas_params_cfg; } @@ -286,6 +286,13 @@ bts->mo.get_attr_rep_received = false; bts->mo.set_attr_sent = false; bts->mo.set_attr_ack_received = false; + + /* Resume power saving on the BCCH carrier, if was enabled */ + if (bts->c0_max_power_red_db > 0) { + LOG_BTS(bts, DRSL, LOGL_NOTICE, "Resuming BCCH carrier power reduction " + "operation mode (maximum %u dB)\n", bts->c0_max_power_red_db); + gsm_bts_send_c0_power_red(bts, bts->c0_max_power_red_db); + } } static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_bts_sm_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_bts_sm_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM BTS Site Manager FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_channel_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_channel_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM Radio Channel FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -35,6 +35,7 @@ #include <osmocom/bsc/ipaccess.h> #include <osmocom/bsc/nm_common_fsm.h> #include <osmocom/bsc/debug.h> +#include <osmocom/bsc/timeslot_fsm.h> #define X(s) (1 << (s)) @@ -239,6 +240,8 @@ ts->mo.adm_unlock_sent = false; ts->mo.set_attr_ack_received = false; ts->mo.set_attr_sent = false; + + osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_READY, NULL); } static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -283,8 +286,10 @@ ts->mo.opstart_sent = false; break; case NM_EV_OML_DOWN: - if (fi->state != NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) + if (fi->state != NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) { + osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_DOWN, NULL); nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_NOTINSTALLED); + } break; default: OSMO_ASSERT(0);
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_common_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_common_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM FSM, common bits */ -/* (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
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_gprs_cell_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_gprs_cell_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM GPRS Cell FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_gprs_nse_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_gprs_nse_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM GPRS NSE FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_gprs_nsvc_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_gprs_nsvc_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM GPRS NSVC FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Alexander Couzens <lynxis@fe80.eu> * * All Rights Reserved @@ -90,12 +90,17 @@ } } -static bool has_valid_nsvc(struct gsm_gprs_nsvc *nsvc) +static bool has_valid_nsvc(const struct gsm_gprs_nsvc *nsvc) { + /* remote address must be valid */ + if (osmo_sockaddr_is_any(&nsvc->remote)) + return false; + /* remote port must be valid */ switch (nsvc->remote.u.sa.sa_family) { case AF_INET: + return nsvc->remote.u.sin.sin_port != 0; case AF_INET6: - return (nsvc->local_port > 0 && !osmo_sockaddr_is_any(&nsvc->remote)); + return nsvc->remote.u.sin6.sin6_port != 0; default: return false; }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/nm_rcarrier_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/nm_rcarrier_fsm.c
Changed
@@ -1,6 +1,6 @@ /* NM Radio Carrier FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/osmo_bsc_bssap.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/osmo_bsc_bssap.c
Changed
@@ -29,8 +29,10 @@ #include <osmocom/bsc/bsc_subscriber.h> #include <osmocom/bsc/paging.h> #include <osmocom/bsc/gsm_04_08_rr.h> +#include <osmocom/bsc/gsm_08_08.h> #include <osmocom/bsc/bsc_subscr_conn_fsm.h> #include <osmocom/bsc/codec_pref.h> +#include <osmocom/bsc/data_rate_pref.h> #include <osmocom/bsc/abis_rsl.h> #include <osmocom/bsc/handover_fsm.h> #include <osmocom/bsc/bts.h> @@ -47,6 +49,8 @@ #include <osmocom/core/sockaddr_str.h> #include <osmocom/bsc/lcs_loc_req.h> #include <osmocom/bsc/bssmap_reset.h> +#include <osmocom/bsc/assignment_fsm.h> +#include <osmocom/bsc/vgcs_fsm.h> #define IP_V4_ADDR_LEN 4 @@ -350,8 +354,12 @@ return -EINVAL; } } - if (params->tmsi != GSM_RESERVED_TMSI) - params->bsub->tmsi = params->tmsi; + if (params->tmsi != GSM_RESERVED_TMSI) { + if (bsc_subscr_set_tmsi(params->bsub, params->tmsi) < 0) { + LOG_PAGING(params, DMSC, LOGL_ERROR, "Paging request failed: Could not set TMSI on subscriber\n"); + return -EINVAL; + } + } log_set_context(LOG_CTX_BSC_SUBSCR, params->bsub); switch (params->cil.id_discr) { @@ -667,19 +675,79 @@ return 0; } -/* Select a preferred and an alternative codec rate depending on the available +/* Select a preferred and an alternative data rate depending on the available * capabilities. This decision does not include the actual channel load yet, * this is also the reason why the result is a preferred and an alternate * setting. The final decision is made in assignment_fsm.c when the actual * lchan is requested. The preferred lchan will be requested first. If we * find an alternate setting here, this one will be tried secondly if our * primary choice fails. */ -static int select_codecs(struct assignment_request *req, struct gsm0808_channel_type *ct, - struct gsm_subscriber_connection *conn) +static int select_data_rates(struct assignment_request *req, struct gsm0808_channel_type *ct, + struct gsm_subscriber_connection *conn) +{ + int rc, i, nc = 0; + + switch (ct->ch_rate_type) { + case GSM0808_DATA_FULL_BM: + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, true); + nc += (rc == 0) ? 1 : 0; + break; + case GSM0808_DATA_HALF_LM: + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, false); + nc += (rc == 0) ? 1 : 0; + break; + case GSM0808_DATA_FULL_PREF_NO_CHANGE: + case GSM0808_DATA_FULL_PREF: + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, true); + nc += (rc == 0) ? 1 : 0; + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, false); + nc += (rc == 0) ? 1 : 0; + break; + case GSM0808_DATA_HALF_PREF_NO_CHANGE: + case GSM0808_DATA_HALF_PREF: + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, false); + nc += (rc == 0) ? 1 : 0; + rc = match_data_rate_pref(&req->ch_mode_rate_listnc, ct, true); + nc += (rc == 0) ? 1 : 0; + break; + default: + rc = -EINVAL; + break; + } + + if (!nc) { + LOGP(DMSC, LOGL_ERROR, "No supported data rate found for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch=%s }\n", + ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); + return -EINVAL; + } + + for (i = 0; i < nc; i++) { + DEBUGP(DMSC, "Found matching data rate (pref=%d): %s %s for channel_type =" + " { ch_indctr=0x%x, ch_rate_type=0x%x, perm_spch= %s }\n", + i, + req->ch_mode_rate_listi.chan_rate == CH_RATE_FULL ? "full rate" : "half rate", + get_value_string(gsm48_chan_mode_names, req->ch_mode_rate_listi.chan_mode), + ct->ch_indctr, ct->ch_rate_type, osmo_hexdump(ct->perm_spch, ct->perm_spch_len)); + } + + req->n_ch_mode_rate = nc; + + return 0; +} + +/* Select a preferred and an alternative codec rate depending on the available + * capabilities. This decision does not include the actual lchan availability yet, + * this is also the reason why the result is a preferred and an alternate + * setting. The final decision is made in assignment_fsm.c when the actual + * lchan is requested. The preferred lchan will be requested first. If we + * find an alternate setting here, this one will be tried secondly if our + * primary choice fails. */ +static int select_codecs(struct assignment_request *req, const struct gsm0808_channel_type *ct, + struct gsm_subscriber_connection *conn, struct gsm_bts *bts) { int rc, i, nc = 0; struct bsc_msc_data *msc; - struct gsm_bts *bts = conn_get_bts(conn); if (!bts) { LOGP(DMSC, LOGL_ERROR, "No lchan, cannot select codecs\n"); @@ -796,6 +864,220 @@ return nc > 0 ? 0 : -EINVAL; } +static int bssmap_handle_ass_req_tp_cic(struct tlv_parsed *tp, bool aoip, uint16_t *cic, uint8_t *cause) +{ + if (TLVP_PRESENT(tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) { + /* CIC is permitted in both AoIP and SCCPlite */ + *cic = osmo_load16be(TLVP_VAL(tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)); + return 0; + } + + if (!aoip) { + /* no CIC but SCCPlite: illegal */ + LOGP(DMSC, LOGL_ERROR, "SCCPlite MSC, but no CIC in ASSIGN REQ?\n"); + *cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + return -1; + } + + return 0; +} + +static int bssmap_handle_ass_req_tp_rtp_addr(struct tlv_parsed *tp, bool aoip, char *msc_rtp_addr, + size_t msc_rtp_addr_len, uint16_t *msc_rtp_port, uint8_t *cause) +{ + struct sockaddr_storage rtp_addr; + int rc; + unsigned int rc2; + + if (TLVP_PRESENT(tp, GSM0808_IE_AOIP_TRASP_ADDR)) { + if (!aoip) { + /* SCCPlite and AoIP transport address: illegal */ + LOGP(DMSC, LOGL_ERROR, "AoIP Transport address over IPA ?!?\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + /* Decode AoIP transport address element */ + rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr, + TLVP_VAL(tp, GSM0808_IE_AOIP_TRASP_ADDR), + TLVP_LEN(tp, GSM0808_IE_AOIP_TRASP_ADDR)); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to decode AoIP transport address.\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + + rc2 = osmo_sockaddr_to_str_and_uint(msc_rtp_addr, msc_rtp_addr_len, msc_rtp_port, + (const struct sockaddr *)&rtp_addr); + if (!rc2 || rc >= msc_rtp_addr_len) { + LOGP(DMSC, LOGL_ERROR, "Assignment request: RTP address is too long\n"); + *cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL; + return -1; + } + return 0; + } + + if (aoip) { + /* no AoIP transport level address but AoIP transport: illegal */ + LOGP(DMSC, LOGL_ERROR, "AoIP transport address missing in ASSIGN REQ, " + "audio would not work; rejecting\n"); + *cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + return -1; + } + + return 0; +} + +static int bssmap_handle_ass_req_tp_osmux(struct gsm_subscriber_connection *conn, struct tlv_parsed *tp, + bool *use_osmux, uint8_t *osmux_cid, uint8_t *cause) +{ + int rc; + + if (TLVP_PRESENT(tp, GSM0808_IE_OSMO_OSMUX_CID)) { + if (conn->sccp.msc->use_osmux == OSMUX_USAGE_OFF) { + LOGP(DMSC, LOGL_ERROR, "MSC using Osmux but we have it disabled.\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + *use_osmux = true; + rc = gsm0808_dec_osmux_cid(osmux_cid, + TLVP_VAL(tp, GSM0808_IE_OSMO_OSMUX_CID), + TLVP_LEN(tp, GSM0808_IE_OSMO_OSMUX_CID)); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to decode Osmux CID.\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + return 0; + } + + if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ONLY) { + LOGP(DMSC, LOGL_ERROR, "MSC not using Osmux but we are forced to use it.\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + + if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ON) + LOGP(DMSC, LOGL_NOTICE, "MSC not using Osmux but we have Osmux enabled.\n"); + + return 0; +} + +static int bssmap_handle_ass_req_tp_codec_list(struct gsm_subscriber_connection *conn, struct tlv_parsed *tp, bool aoip, + uint8_t *cause) +{ + int rc; + + /* Decode speech codec list. First set len = 0. */ + conn->codec_list = (struct gsm0808_speech_codec_list){}; + /* Check for speech codec list element */ + if (TLVP_PRESENT(tp, GSM0808_IE_SPEECH_CODEC_LIST)) { + /* Decode Speech Codec list */ + rc = gsm0808_dec_speech_codec_list(&conn->codec_list, + TLVP_VAL(tp, GSM0808_IE_SPEECH_CODEC_LIST), + TLVP_LEN(tp, GSM0808_IE_SPEECH_CODEC_LIST)); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to decode speech codec list\n"); + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return -1; + } + } + + if (aoip && !conn->codec_list.len) { + LOGP(DMSC, LOGL_ERROR, "%s: AoIP Assignment Request:" + " Missing or empty Speech Codec List IE\n", bsc_subscr_name(conn->bsub)); + *cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + return -1; + } + + return 0; +} + +static int bssmap_handle_ass_req_ct_data(struct gsm_subscriber_connection *conn, struct tlv_parsed *tp, + struct gsm0808_channel_type *ct, struct assignment_request *req, + uint8_t *cause) +{ + bool aoip = gscon_is_aoip(conn); + int rc; + + *req = (struct assignment_request){ + .assign_for = ASSIGN_FOR_BSSMAP_REQ, + .aoip = aoip, + }; + + if (bssmap_handle_ass_req_tp_cic(tp, aoip, &req->msc_assigned_cic, cause) < 0) + return -1; + + if (bssmap_handle_ass_req_tp_rtp_addr(tp, aoip, req->msc_rtp_addr, sizeof(req->msc_rtp_addr), &req->msc_rtp_port, cause) < 0) + return -1; + + /* According to 3GPP TS 48.008 § 3.2.1.1 note 13, the codec list IE + * shall be included for aoip unless channel type is signalling. */ + if (bssmap_handle_ass_req_tp_codec_list(conn, tp, aoip, cause) < 0) + return -1; + + rc = select_data_rates(req, ct, conn); + if (rc < 0) { + *cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL; + return -1; + } + + return 0; +} + +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) +{ + bool aoip = gscon_is_aoip(conn); + int rc; + + *req = (struct assignment_request){ + .assign_for = ASSIGN_FOR_BSSMAP_REQ, + .aoip = aoip, + }; + + if (bssmap_handle_ass_req_tp_cic(tp, aoip, &req->msc_assigned_cic, cause) < 0) + return -1; + + if (bssmap_handle_ass_req_tp_rtp_addr(tp, aoip, req->msc_rtp_addr, sizeof(req->msc_rtp_addr), &req->msc_rtp_port, cause) < 0) + return -1; + + if (bssmap_handle_ass_req_tp_osmux(conn, tp, &req->use_osmux, &req->osmux_cid, cause) < 0) + return -1; + + if (bssmap_handle_ass_req_tp_codec_list(conn, tp, aoip, cause) < 0) + return -1; + + /* Match codec information from the assignment command against the + * local preferences of the BSC and BTS */ + rc = select_codecs(req, ct, conn, bts); + if (rc < 0) { + *cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL; + return -1; + } + + return 0; +} + +static int bssmap_handle_ass_req_ct_sign(struct gsm_subscriber_connection *conn, struct gsm0808_channel_type *ct, + struct assignment_request *req, uint8_t *cause) +{ + int rc; + + *req = (struct assignment_request){ + .assign_for = ASSIGN_FOR_BSSMAP_REQ, + .aoip = gscon_is_aoip(conn), + }; + + rc = select_sign_chan(req, ct); + if (rc < 0) { + *cause = GSM0808_CAUSE_INCORRECT_VALUE; + return rc; + } + + return 0; +} + /* * Handle the assignment request message. * @@ -806,12 +1088,8 @@ { struct msgb *resp; struct tlv_parsed tp; - uint16_t cic = 0; - bool aoip = false; - bool use_osmux = false; - uint8_t osmux_cid = 0; - struct sockaddr_storage rtp_addr; struct gsm0808_channel_type ct; + struct gsm0808_group_callref gc; uint8_t cause; int rc; struct assignment_request req = {}; @@ -822,8 +1100,6 @@ return -1; } - aoip = gscon_is_aoip(conn); - if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); return -1; @@ -845,149 +1121,71 @@ goto reject; } - bssmap_handle_ass_req_lcls(conn, &tp); - - /* Currently we only support a limited subset of all - * possible channel types, such as multi-slot or CSD */ - switch (ct.ch_indctr) { - case GSM0808_CHAN_DATA: - LOGP(DMSC, LOGL_ERROR, "Unsupported channel type, currently only speech is supported!\n"); - cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_NOT_SUPP; - goto reject; - case GSM0808_CHAN_SPEECH: - if (TLVP_PRESENT(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)) { - /* CIC is permitted in both AoIP and SCCPlite */ - cic = osmo_load16be(TLVP_VAL(&tp, GSM0808_IE_CIRCUIT_IDENTITY_CODE)); - } else { - if (!aoip) { - /* no CIC but SCCPlite: illegal */ - LOGP(DMSC, LOGL_ERROR, "SCCPlite MSC, but no CIC in ASSIGN REQ?\n"); - cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; - goto reject; - } + /* Check for assignment to VGCS channel. */ + if (TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) { + struct gsm_bts *bts = conn_get_bts(conn); + + OSMO_ASSERT(bts); + /* Decode Group Call Reference. */ + rc = gsm0808_dec_group_callref(&gc, TLVP_VAL(&tp, GSM0808_IE_GROUP_CALL_REFERENCE), + TLVP_LEN(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)); + if (rc < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to decode Group Call Reference.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; } - if (TLVP_PRESENT(&tp, GSM0808_IE_AOIP_TRASP_ADDR)) { - if (!aoip) { - /* SCCPlite and AoIP transport address: illegal */ - LOGP(DMSC, LOGL_ERROR, "AoIP Transport address over IPA ?!?\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } - /* Decode AoIP transport address element */ - rc = gsm0808_dec_aoip_trasp_addr(&rtp_addr, - TLVP_VAL(&tp, GSM0808_IE_AOIP_TRASP_ADDR), - TLVP_LEN(&tp, GSM0808_IE_AOIP_TRASP_ADDR)); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Unable to decode AoIP transport address.\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } - } else if (aoip) { - /* no AoIP transport level address but AoIP transport: illegal */ - LOGP(DMSC, LOGL_ERROR, "AoIP transport address missing in ASSIGN REQ, " - "audio would not work; rejecting\n"); - cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + req.target_lchan = vgcs_vbs_find_lchan(bts, &gc); + if (!req.target_lchan) { + cause = GSM0808_CAUSE_INCORRECT_VALUE; goto reject; } + req.assign_for = ASSIGN_FOR_BSSMAP_REQ; + req.vgcs = true; - if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_CID)) { - if (conn->sccp.msc->use_osmux == OSMUX_USAGE_OFF) { - LOGP(DMSC, LOGL_ERROR, "MSC using Osmux but we have it disabled.\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } - use_osmux = true; - rc = gsm0808_dec_osmux_cid(&osmux_cid, - TLVP_VAL(&tp, GSM0808_IE_OSMO_OSMUX_CID), - TLVP_LEN(&tp, GSM0808_IE_OSMO_OSMUX_CID)); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Unable to decode Osmux CID.\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } - } else { - if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ONLY) { - LOGP(DMSC, LOGL_ERROR, "MSC not using Osmux but we are forced to use it.\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } else if (conn->sccp.msc->use_osmux == OSMUX_USAGE_ON) - LOGP(DMSC, LOGL_NOTICE, "MSC not using Osmux but we have Osmux enabled.\n"); - } - - /* Decode speech codec list. First set len = 0. */ - conn->codec_list = (struct gsm0808_speech_codec_list){}; - /* Check for speech codec list element */ - if (TLVP_PRESENT(&tp, GSM0808_IE_SPEECH_CODEC_LIST)) { - /* Decode Speech Codec list */ - rc = gsm0808_dec_speech_codec_list(&conn->codec_list, - TLVP_VAL(&tp, GSM0808_IE_SPEECH_CODEC_LIST), - TLVP_LEN(&tp, GSM0808_IE_SPEECH_CODEC_LIST)); - if (rc < 0) { - LOGP(DMSC, LOGL_ERROR, "Unable to decode speech codec list\n"); - cause = GSM0808_CAUSE_INCORRECT_VALUE; - goto reject; - } + /* Copy timing advance. */ + if (conn->lchan) { + req.target_lchan->activate.info.ta_known = conn->lchan->activate.info.ta_known; + req.target_lchan->activate.info.ta = conn->lchan->activate.info.ta; } - if (aoip && !conn->codec_list.len) { - LOGP(DMSC, LOGL_ERROR, "%s: AoIP speech mode Assignment Request:" - " Missing or empty Speech Codec List IE\n", bsc_subscr_name(conn->bsub)); - cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; - goto reject; - } + /* Send reactivation on target lchan to prepare VGCS channel for assignment. + * See patent EP 1 858 275 A1. */ + rsl_tx_chan_activ(req.target_lchan, RSL_ACT_TYPE_REACT | RSL_ACT_INTRA_NORM_ASS, 0); - req = (struct assignment_request){ - .assign_for = ASSIGN_FOR_BSSMAP_REQ, - .aoip = aoip, - .msc_assigned_cic = cic, - .use_osmux = use_osmux, - .osmux_cid = osmux_cid, - }; - - /* Match codec information from the assignment command against the - * local preferences of the BSC and BTS */ - rc = select_codecs(&req, &ct, conn); - if (rc < 0) { - cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL; - goto reject; - } + return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req); + } - if (aoip) { - unsigned int rc = osmo_sockaddr_to_str_and_uint(req.msc_rtp_addr, - sizeof(req.msc_rtp_addr), - &req.msc_rtp_port, - (const struct sockaddr*)&rtp_addr); - if (!rc || rc >= sizeof(req.msc_rtp_addr)) { - LOGP(DMSC, LOGL_ERROR, "Assignment request: RTP address is too long\n"); - cause = GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL; - goto reject; - } - } + bssmap_handle_ass_req_lcls(conn, &tp); + + /* Currently we only support a limited subset of all + * possible channel types, such as multi-slot */ + switch (ct.ch_indctr) { + case GSM0808_CHAN_DATA: + if (bssmap_handle_ass_req_ct_data(conn, &tp, &ct, &req, &cause) < 0) + goto reject; + break; + case GSM0808_CHAN_SPEECH: + if (bssmap_handle_ass_req_ct_speech(conn, conn_get_bts(conn), &tp, &ct, &req, &cause) < 0) + goto reject; break; case GSM0808_CHAN_SIGN: - req = (struct assignment_request){ - .assign_for = ASSIGN_FOR_BSSMAP_REQ, - .aoip = aoip, - }; - - rc = select_sign_chan(&req, &ct); - if (rc < 0) { - cause = GSM0808_CAUSE_INCORRECT_VALUE; + if (bssmap_handle_ass_req_ct_sign(conn, &ct, &req, &cause) < 0) goto reject; - } break; default: cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS; goto reject; } + req.ch_indctr = ct.ch_indctr; + return osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_ASSIGNMENT_START, &req); reject: resp = gsm0808_create_assignment_failure(cause, NULL); OSMO_ASSERT(resp); - 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)); osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); return -1; } @@ -1135,6 +1333,101 @@ return 0; } +/* Handle (VGCS) UPLINK REQUEST ACKNOWLEDGE: + * + * See 3GPP TS 48.008 §3.2.1.58 + */ +static int bssmap_handle_uplink_rqst_acknowledge(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -1; + } + + if (conn->vgcs_call.fi) + osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_ACK, NULL); + return 0; +} + +/* Handle (VGCS) UPLINK REJECT COMMAND message. + * + * See 3GPP TS 48.008 §3.2.1.61 + */ +static int bssmap_handle_uplink_reject_cmd(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -1; + } + + if (conn->vgcs_call.fi) + osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_REJECT, NULL); + return 0; +} + +/* Handle (VGCS) UPLINK RELEASE COMMAND message, MSC indicating an error to us: + * + * See 3GPP TS 48.008 §3.2.1.62 + */ +static int bssmap_handle_uplink_release_cmd(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -1; + } + + if (conn->vgcs_call.fi) + osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_RELEASE, NULL); + return 0; +} + +/* Handle (VGCS) UPLINK SEIZED COMMAND message: + * + * See 3GPP TS 48.008 §3.2.1.63 + */ +static int bssmap_handle_uplink_seized_cmd(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -1; + } + + if (conn->vgcs_call.fi) + osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_SEIZE, NULL); + return 0; +} + +/* Handle VGCS/VBS ADDITIONAL INFO message: + * + * See 3GPP TS 48.008 §3.2.1.78 + */ +static int bssmap_handle_vgcs_addl_info(struct gsm_subscriber_connection *conn, + struct msgb *msg, unsigned int length) +{ + struct tlv_parsed tp; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + return -1; + } + + LOGPFSML(conn->fi, LOGL_ERROR, "VGCS ADDITIONAL INFO is not supported.\n"); + + return 0; +} + static int bssmap_rcvmsg_udt(struct bsc_msc_data *msc, struct msgb *msg, unsigned int length) { @@ -1238,6 +1531,26 @@ ret = 0; } break; + case BSS_MAP_MSG_UPLINK_RQST_ACKNOWLEDGE: + rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE); + ret = bssmap_handle_uplink_rqst_acknowledge(conn, msg, length); + break; + case BSS_MAP_MSG_UPLINK_REJECT_CMD: + rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD); + ret = bssmap_handle_uplink_reject_cmd(conn, msg, length); + break; + case BSS_MAP_MSG_UPLINK_RELEASE_CMD: + rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD); + ret = bssmap_handle_uplink_release_cmd(conn, msg, length); + break; + case BSS_MAP_MSG_UPLINK_SEIZED_CMD: + rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD); + ret = bssmap_handle_uplink_seized_cmd(conn, msg, length); + break; + case BSS_MAP_MSG_VGCS_ADDL_INFO: + rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO); + ret = bssmap_handle_vgcs_addl_info(conn, msg, length); + break; default: rate_ctr_inc(&ctrsMSC_CTR_BSSMAP_RX_DT1_UNKNOWN); LOGP(DMSC, LOGL_NOTICE, "Unimplemented msg type: %s\n", @@ -1301,7 +1614,10 @@ /* convert DLCI to RSL link ID, store in msg->cb */ OBSC_LINKID_CB(gsm48) = DLCI2RSL_LINK_ID(header->link_id); - dtap_rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, gsm48); + if (conn->vgcs_call.fi) + dtap_rc = osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_MSC_DTAP, gsm48); + else + dtap_rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, gsm48); return dtap_rc; } @@ -1461,7 +1777,7 @@ new_lchan->current_ch_mode_rate.chan_mode), }; - if (gscon_is_aoip(conn) && new_lchan->activate.info.requires_voice_stream) { + if (gscon_is_aoip(conn) && bsc_chan_ind_requires_rtp_stream(new_lchan->activate.info.ch_indctr)) { struct osmo_sockaddr_str to_msc_rtp; const struct mgcp_conn_peer *rtp_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc); int rc; @@ -1536,7 +1852,7 @@ }; /* speech_codec_chosen */ - if (ho->new_lchan->activate.info.requires_voice_stream && gscon_is_aoip(conn)) { + if (bsc_chan_ind_requires_rtp_stream(ho->new_lchan->activate.info.ch_indctr) && gscon_is_aoip(conn)) { int perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode); params.speech_codec_chosen_present = true; rc = gsm0808_speech_codec_from_chan_type(¶ms.speech_codec_chosen, perm_spch); @@ -1580,3 +1896,180 @@ LOG_HO(conn, LOGL_ERROR, "Cannot send BSSMAP Handover Failure message (rc=%d %s)\n", rc, strerror(-rc)); } + +/* Send SETUP ACKNOWLEDGE to MSC. */ +void bsc_tx_setup_ack(struct gsm_subscriber_connection *conn, struct gsm0808_vgcs_feature_flags *ff) +{ + struct msgb *resp; + struct gsm0808_vgcs_vbs_setup_ack sa = {}; + + if (ff) { + sa.vgcs_feature_flags_present = true; + sa.flags = *ff; + } + resp = gsm0808_create_vgcs_vbs_setup_ack(&sa); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send SETUP REFUSE to MSC. */ +void bsc_tx_setup_refuse(struct gsm_subscriber_connection *conn, uint8_t cause) +{ + struct msgb *resp; + resp = gsm0808_create_vgcs_vbs_setup_refuse(cause); + + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send ASSIGNMENT FAILURE to MSC. */ +void bsc_tx_vgcs_vbs_assignment_fail(struct gsm_subscriber_connection *conn, uint8_t cause) +{ + struct msgb *resp; + struct gsm0808_vgcs_vbs_assign_fail af = { + .cause = cause, + }; + + resp = gsm0808_create_vgcs_vbs_assign_fail(&af); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send ASSIGNMENT RESULT to MSC. */ +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) +{ + struct gsm_lchan *lchan = conn->lchan; + struct msgb *resp; + struct gsm0808_vgcs_vbs_assign_res ar = { + .channel_type = *ct, + .cell_identifier = *ci, + }; + int perm_spch; + uint8_t osmux_cid; + + /* Chosen Channel */ + ar.chosen_channel = gsm0808_chosen_channel(lchan->type, lchan->current_ch_mode_rate.chan_mode); + if (!ar.chosen_channel) { + LOGP(DMSC, LOGL_ERROR, "Unable to compose Chosen Channel for mode=%s type=%s", + get_value_string(gsm48_chan_mode_names, lchan->current_ch_mode_rate.chan_mode), + gsm_chan_t_name(lchan->type)); + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + return; + } + ar.chosen_channel_present = true; + + /* Generate RTP related fields. */ + if (gscon_is_aoip(conn)) { + /* AoIP Transport Layer Address (BSS) */ + if (!osmo_mgcpc_ep_ci_get_crcx_info_to_sockaddr(conn->user_plane.mgw_endpoint_ci_msc, + &ar.aoip_transport_layer)) { + LOGP(DMSC, LOGL_ERROR, "Unable to compose RTP address of MGW -> MSC"); + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + return; + } + ar.aoip_transport_layer_present = true; + + /* Call Identifier */ + ar.call_id = call_id; + ar.call_id_present = true; + + /* 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)) { + LOGP(DMSC, LOGL_ERROR, "Unable to compose Osmux CID of MGW -> MSC"); + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + return; + } + } + + /* Extrapolate speech codec from speech mode */ + perm_spch = gsm0808_permitted_speech(lchan->type, lchan->current_ch_mode_rate.chan_mode); + gsm0808_speech_codec_from_chan_type(&ar.codec_msc_chosen, perm_spch); + ar.codec_msc_chosen.cfg = conn->lchan->current_ch_mode_rate.s15_s0; + ar.codec_present = true; + } + + resp = gsm0808_create_vgcs_vbs_assign_res(&ar); + OSMO_ASSERT(resp); + if (conn->assignment.req.use_osmux) + bssap_extend_osmux(resp, osmux_cid); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send UPLINK REQUEST to MSC. */ +void bsc_tx_uplink_req(struct gsm_subscriber_connection *conn) +{ + struct msgb *resp; + struct gsm0808_uplink_request ur = {}; + + resp = gsm0808_create_uplink_request(&ur); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send UPLINK REQUEST CONFIRMATION to MSC. */ +void bsc_tx_uplink_req_conf(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info, + uint8_t length) +{ + struct msgb *resp; + struct gsm0808_uplink_request_cnf ur = { + .cell_identifier = *ci, + }; + + OSMO_ASSERT(length <= LAYER_3_INFORMATION_MAXLEN); + if (length) { + memcpy(ur.l3.l3, l3_info, length); + ur.l3.l3_len = length; + } + resp = gsm0808_create_uplink_request_cnf(&ur); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send UPLINK APPLICATION DATA to MSC. */ +void bsc_tx_uplink_app_data(struct gsm_subscriber_connection *conn, struct gsm0808_cell_id *ci, uint8_t *l3_info, + uint8_t length) +{ + struct msgb *resp; + struct gsm0808_uplink_app_data ad = { + .cell_identifier = *ci, + }; + + OSMO_ASSERT(length <= LAYER_3_INFORMATION_MAXLEN); + memcpy(ad.l3.l3, l3_info, length); + ad.l3.l3_len = length; + resp = gsm0808_create_uplink_app_data(&ad); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +} + +/* Send UPLINK RELEASE INDICATION to MSC. */ +void bsc_tx_uplink_release_ind(struct gsm_subscriber_connection *conn, uint8_t cause) +{ + struct msgb *resp; + struct gsm0808_uplink_release_ind ri = { + .cause = cause, + }; + + resp = gsm0808_create_uplink_release_ind(&ri); + OSMO_ASSERT(resp); + + rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION)); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); +}
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/osmo_bsc_main.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/osmo_bsc_main.c
Changed
@@ -231,7 +231,7 @@ return 0; } - if (is_ipaccess_bts(nack->bts)) + if (is_ipa_abisip_bts(nack->bts)) ipaccess_drop_oml_deferred(nack->bts); return 0; @@ -312,16 +312,16 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx) { + struct gsm_bts *bts = trx->bts; unsigned int i; int rc; LOG_TRX(trx, DRSL, LOGL_NOTICE, "bootstrapping RSL " "on ARFCN %u using MCC-MNC %s LAC=%u CID=%u BSIC=%u\n", trx->arfcn, osmo_plmn_name(&bsc_gsmnet->plmn), - trx->bts->location_area_code, - trx->bts->cell_identity, trx->bts->bsic); + bts->location_area_code, bts->cell_identity, bts->bsic); - if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) { + if (bts->type == GSM_BTS_TYPE_NOKIA_SITE) { rsl_nokia_si_begin(trx); } @@ -338,14 +338,14 @@ return; } - if (trx->bts->type == GSM_BTS_TYPE_NOKIA_SITE) { + if (bts->type == GSM_BTS_TYPE_NOKIA_SITE) { /* channel unspecific, power reduction in 2 dB steps */ rsl_bs_power_control(trx, 0xFF, trx->max_power_red / 2); rsl_nokia_si_end(trx); } - if (trx->bts->model->power_ctrl_send_def_params != NULL) { - rc = trx->bts->model->power_ctrl_send_def_params(trx); + if (bts->model->power_ctrl_send_def_params != NULL) { + rc = bts->model->power_ctrl_send_def_params(trx); if (rc) { LOG_TRX(trx, DRSL, LOGL_ERROR, "Failed to send default " "MS/BS Power control parameters (rc=%d)\n", rc); @@ -360,7 +360,7 @@ } /* Drop all expired channel requests in the list */ - abis_rsl_chan_rqd_queue_flush(trx->bts); + abis_rsl_chan_rqd_queue_flush(bts); } struct osmo_timer_list update_connection_stats_timer; @@ -375,6 +375,28 @@ osmo_timer_schedule(&update_connection_stats_timer, 1, 0); } +static bool nch_position_compatible_with_combined_ccch(const struct gsm_bts *bts) +{ + switch (bts->nch.num_blocks) { + case 0: + /* no NCH enabled, so we are fine */ + return true; + case 1: + if (bts->nch.first_block == 0 || bts->nch.first_block == 1) + return true; + break; + case 2: + if (bts->nch.first_block == 0) + return true; + break; + default: + break; + } + + /* anything else is not permitted */ + return false; +} + static void bootstrap_bts(struct gsm_bts *bts) { unsigned int n = 0; @@ -393,6 +415,11 @@ bts->si_common.chan_desc.bs_ag_blks_res); bts->si_common.chan_desc.bs_ag_blks_res = 2; } + + if (!nch_position_compatible_with_combined_ccch(bts)) { + LOG_BTS(bts, DNM, LOGL_ERROR, "CCCH is combined with SDCCHs, but NCH position/size is " + "incompatible with that. Please fix your config!\n"); + } } else { /* Non-combined TS0/C0 configuration */ /* There can be additional CCCHs on even timeslot numbers */ n += (bts->c0->ts2.pchan_from_config == GSM_PCHAN_CCCH); @@ -401,6 +428,13 @@ bts->si_common.chan_desc.ccch_conf = (n << 1); } + if (bts->nch.first_block + bts->nch.num_blocks > bts->si_common.chan_desc.bs_ag_blks_res) { + LOG_BTS(bts, DNM, LOGL_ERROR, "Position/Number of NCH blocks (%u..%u) exceeds AGCH (%u)." + "Please fix your config!\n", bts->nch.first_block, + bts->nch.first_block + bts->nch.num_blocks - 1, + bts->si_common.chan_desc.bs_ag_blks_res); + } + bts_setup_ramp_init_bts(bts); /* ACC ramping is initialized from vty/config */ @@ -455,7 +489,7 @@ rate_ctr_inc(rate_ctr_group_get_ctr(trx->bts->bts_ctrs, BTS_CTR_BTS_OML_FAIL)); /* ip.access BTS models have a single global A-bis/OML link for all * transceivers, so once it's lost we need to notify them all. */ - if (is_ipaccess_bts(trx->bts)) + if (is_ipa_abisip_bts(trx->bts)) gsm_bts_all_ts_dispatch(trx->bts, TS_EV_OML_DOWN, NULL); else /* Other BTS models (e.g. Ericsson) have per-TRX OML links */ gsm_trx_all_ts_dispatch(trx, TS_EV_OML_DOWN, NULL); @@ -483,7 +517,7 @@ rc = vty_read_config_file(config_file, NULL); if (rc < 0) { - LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s'\n", config_file); + LOGP(DNM, LOGL_FATAL, "Failed to parse the config file: '%s' (%s)\n", config_file, strerror(-rc)); return rc; } @@ -795,6 +829,12 @@ .description = "Location Services", .enabled = 1, .loglevel = LOGL_NOTICE, }, + DASCI = { + .name = "DASCI", + .description = "Advanced Speech Call Items (VGCS/VBS)", + .color = "\0331;38m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, DRESET = { .name = "DRESET", .description = "RESET/ACK on A and Lb interfaces", @@ -830,18 +870,21 @@ extern void *tall_paging_ctx; extern void *tall_fle_ctx; extern void *tall_tqe_ctx; -extern void *tall_ctr_ctx; static int bsc_mgw_setup(void) { struct mgcp_client *mgcp_client_single; unsigned int pool_members_initalized; - /* Initialize MGW pool. This initalizes and connects all MGCP clients that are currently configured in + /* Initialize MGW pool. This initializes and connects all MGCP clients that are currently configured in * the pool. Adding additional MGCP clients to the pool is possible but the user has to configure and * (re)connect them manually from the VTY. */ - pool_members_initalized = mgcp_client_pool_connect(bsc_gsmnet->mgw.mgw_pool); - if (pool_members_initalized) { + if (!mgcp_client_pool_empty(bsc_gsmnet->mgw.mgw_pool)) { + pool_members_initalized = mgcp_client_pool_connect(bsc_gsmnet->mgw.mgw_pool); + if (!pool_members_initalized) { + LOGP(DNM, LOGL_ERROR, "MGW pool failed to initialize any pool members\n"); + return -EINVAL; + } LOGP(DNM, LOGL_NOTICE, "MGW pool with %u pool members configured, (ignoring MGW configuration in VTY node 'msc').\n", pool_members_initalized); @@ -853,7 +896,7 @@ LOGP(DNM, LOGL_NOTICE, "No MGW pool configured, using MGW configuration in VTY node 'msc'\n"); mgcp_client_single = mgcp_client_init(bsc_gsmnet, bsc_gsmnet->mgw.conf); if (!mgcp_client_single) { - LOGP(DNM, LOGL_ERROR, "MGW (single) client initalization failed\n"); + LOGP(DNM, LOGL_ERROR, "MGW (single) client initialization failed\n"); return -EINVAL; } if (mgcp_client_connect(mgcp_client_single)) { @@ -881,7 +924,6 @@ tall_paging_ctx = talloc_named_const(tall_bsc_ctx, 0, "paging_request"); tall_fle_ctx = talloc_named_const(tall_bsc_ctx, 0, "bs11_file_list_entry"); tall_tqe_ctx = talloc_named_const(tall_bsc_ctx, 0, "subch_txq_entry"); - tall_ctr_ctx = talloc_named_const(tall_bsc_ctx, 0, "counter"); osmo_init_logging2(tall_bsc_ctx, &log_info); osmo_stats_init(tall_bsc_ctx); @@ -897,9 +939,8 @@ exit(1); } - bsc_gsmnet->mgw.conf = talloc_zero(bsc_gsmnet, struct mgcp_client_conf); + bsc_gsmnet->mgw.conf = mgcp_client_conf_alloc(bsc_gsmnet); bsc_gsmnet->mgw.mgw_pool = mgcp_client_pool_alloc(bsc_gsmnet); - mgcp_client_conf_init(bsc_gsmnet->mgw.conf); bts_init(); libosmo_abis_init(tall_bsc_ctx); @@ -926,10 +967,6 @@ /* seed the PRNG */ srand(time(NULL)); - lchan_fsm_init(); - bsc_subscr_conn_fsm_init(); - assignment_fsm_init(); - handover_fsm_init(); lb_init(); acc_ramp_global_init(); paging_global_init();
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/osmo_bsc_mgcp.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/osmo_bsc_mgcp.c
Changed
@@ -33,13 +33,14 @@ static struct bsc_msc_data *msc_from_asp(struct osmo_ss7_asp *asp) { int msc_nr; + const char *asp_name = osmo_ss7_asp_get_name(asp); /* this is rather ugly, as we of course have MTP-level routing between * the local SCCP user (BSC) and the AS/ASPs. However, for the most simple * SCCPlite case, there is a 1:1 mapping between ASP and AS, and using * the libosmo-sigtran "simple client", the names are "asp-clnt-msc-%u", * as set in osmo_bsc_sigtran_init() */ - if (sscanf(asp->cfg.name, "asp-clnt-msc-%u", &msc_nr) != 1) { - LOGP(DMSC, LOGL_ERROR, "Cannot find to which MSC the ASP %s belongs\n", asp->cfg.name); + if (!asp_name || sscanf(asp_name, "asp-clnt-msc-%u", &msc_nr) != 1) { + LOGP(DMSC, LOGL_ERROR, "Cannot find to which MSC the ASP '%s' belongs\n", asp_name); return NULL; } return osmo_msc_data_find(bsc_gsmnet, msc_nr); @@ -51,7 +52,8 @@ struct bsc_msc_data *msc; int rc; - LOGP(DMSC, LOGL_NOTICE, "%s: Received IPA-encapsulated MGCP: %s\n", asp->cfg.name, msg->l2h); + LOGP(DMSC, LOGL_NOTICE, "%s: Received IPA-encapsulated MGCP: %s\n", + osmo_ss7_asp_get_name(asp), msg->l2h); msc = msc_from_asp(asp); if (msc) { /* we don't have a write queue here as we simply expect the socket buffers
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/osmo_bsc_msc.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/osmo_bsc_msc.c
Changed
@@ -48,68 +48,281 @@ static const struct rate_ctr_desc msc_ctr_description = { /* Rx message counters (per specific message) */ - MSC_CTR_BSSMAP_RX_UDT_RESET_ACKNOWLEDGE = {"bssmap:rx:udt:reset:ack", "Number of received BSSMAP UDT RESET ACKNOWLEDGE messages"}, - MSC_CTR_BSSMAP_RX_UDT_RESET = {"bssmap:rx:udt:reset:request", "Number of received BSSMAP UDT RESET messages"}, - MSC_CTR_BSSMAP_RX_UDT_PAGING = {"bssmap:rx:udt:paging", "Number of received BSSMAP UDT PAGING messages"}, - MSC_CTR_BSSMAP_RX_UDT_UNKNOWN = {"bssmap:rx:udt:err_unknown", "Number of received BSSMAP unknown UDT messages"}, - MSC_CTR_BSSMAP_RX_DT1_CLEAR_CMD = {"bssmap:rx:dt1:clear:cmd", "Number of received BSSMAP DT1 CLEAR CMD messages"}, - MSC_CTR_BSSMAP_RX_DT1_CIPHER_MODE_CMD = {"bssmap:rx:dt1:cipher_mode:cmd", "Number of received BSSMAP DT1 CIPHER MODE CMD messages"}, - MSC_CTR_BSSMAP_RX_DT1_ASSIGNMENT_RQST = {"bssmap:rx:dt1:assignment:rqst", "Number of received BSSMAP DT1 ASSIGNMENT RQST messages"}, - MSC_CTR_BSSMAP_RX_DT1_LCLS_CONNECT_CTRL = {"bssmap:rx:dt1:lcls_connect_ctrl:cmd", "Number of received BSSMAP DT1 LCLS CONNECT CTRL messages"}, - MSC_CTR_BSSMAP_RX_DT1_HANDOVER_RQST = {"bssmap:rx:dt1:handover:rqst", "Number of received BSSMAP DT1 HANDOVER RQST messages"}, - MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD = {"bssmap:rx:dt1:handover:cmd", "Number of received BSSMAP DT1 HANDOVER CMD messages"}, - MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST = {"bssmap:rx:dt1:classmark:rqst", "Number of received BSSMAP DT1 CLASSMARK RQST messages"}, - MSC_CTR_BSSMAP_RX_DT1_CONFUSION = {"bssmap:rx:dt1:confusion", "Number of received BSSMAP DT1 CONFUSION messages"}, - MSC_CTR_BSSMAP_RX_DT1_COMMON_ID = {"bssmap:rx:dt1:common_id", "Number of received BSSMAP DT1 COMMON ID messages"}, - MSC_CTR_BSSMAP_RX_DT1_UNKNOWN = {"bssmap:rx:dt1:err_unknown", "Number of received BSSMAP unknown DT1 messages"}, - MSC_CTR_BSSMAP_RX_DT1_DTAP = {"bssmap:rx:dt1:dtap:good", "Number of received BSSMAP DTAP messages"}, - MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR = {"bssmap:rx:dt1:dtap:error", "Number of received BSSMAP DTAP messages with errors"}, - MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST = {"bssmap:rx:dt1:location:request", "Number of received BSSMAP Perform Location Request messages"}, - MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT = {"bssmap:tx:dt1:location:abort", "Number of received BSSMAP Perform Location Abort messages"}, + MSC_CTR_BSSMAP_RX_UDT_RESET_ACKNOWLEDGE = { + "bssmap:rx:udt:reset:ack", + "Number of received BSSMAP UDT RESET ACKNOWLEDGE messages" + }, + MSC_CTR_BSSMAP_RX_UDT_RESET = { + "bssmap:rx:udt:reset:request", + "Number of received BSSMAP UDT RESET messages" + }, + MSC_CTR_BSSMAP_RX_UDT_PAGING = { + "bssmap:rx:udt:paging", + "Number of received BSSMAP UDT PAGING messages" + }, + MSC_CTR_BSSMAP_RX_UDT_UNKNOWN = { + "bssmap:rx:udt:err_unknown", + "Number of received BSSMAP unknown UDT messages" + }, + MSC_CTR_BSSMAP_RX_DT1_CLEAR_CMD = { + "bssmap:rx:dt1:clear:cmd", + "Number of received BSSMAP DT1 CLEAR CMD messages" + }, + MSC_CTR_BSSMAP_RX_DT1_CIPHER_MODE_CMD = { + "bssmap:rx:dt1:cipher_mode:cmd", + "Number of received BSSMAP DT1 CIPHER MODE CMD messages" + }, + MSC_CTR_BSSMAP_RX_DT1_ASSIGNMENT_RQST = { + "bssmap:rx:dt1:assignment:rqst", + "Number of received BSSMAP DT1 ASSIGNMENT RQST messages" + }, + MSC_CTR_BSSMAP_RX_DT1_LCLS_CONNECT_CTRL = { + "bssmap:rx:dt1:lcls_connect_ctrl:cmd", + "Number of received BSSMAP DT1 LCLS CONNECT CTRL messages" + }, + MSC_CTR_BSSMAP_RX_DT1_HANDOVER_RQST = { + "bssmap:rx:dt1:handover:rqst", + "Number of received BSSMAP DT1 HANDOVER RQST messages" + }, + MSC_CTR_BSSMAP_RX_DT1_HANDOVER_CMD = { + "bssmap:rx:dt1:handover:cmd", + "Number of received BSSMAP DT1 HANDOVER CMD messages" + }, + MSC_CTR_BSSMAP_RX_DT1_CLASSMARK_RQST = { + "bssmap:rx:dt1:classmark:rqst", + "Number of received BSSMAP DT1 CLASSMARK RQST messages" + }, + MSC_CTR_BSSMAP_RX_DT1_CONFUSION = { + "bssmap:rx:dt1:confusion", + "Number of received BSSMAP DT1 CONFUSION messages" + }, + MSC_CTR_BSSMAP_RX_DT1_COMMON_ID = { + "bssmap:rx:dt1:common_id", + "Number of received BSSMAP DT1 COMMON ID messages" + }, + MSC_CTR_BSSMAP_RX_DT1_UNKNOWN = { + "bssmap:rx:dt1:err_unknown", + "Number of received BSSMAP unknown DT1 messages" + }, + MSC_CTR_BSSMAP_RX_DT1_DTAP = { + "bssmap:rx:dt1:dtap:good", + "Number of received BSSMAP DTAP messages" + }, + MSC_CTR_BSSMAP_RX_DT1_DTAP_ERROR = { + "bssmap:rx:dt1:dtap:error", + "Number of received BSSMAP DTAP messages with errors" + }, + MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_REQUEST = { + "bssmap:rx:dt1:location:request", + "Number of received BSSMAP Perform Location Request messages" + }, + MSC_CTR_BSSMAP_RX_DT1_PERFORM_LOCATION_ABORT = { + "bssmap:tx:dt1:location:abort", + "Number of received BSSMAP Perform Location Abort messages" + }, + MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_SETUP = { + "bssmap:rx:dt1:vgcs_vbs_setup", + "Number of received BSSMAP DT1 VGCS/VBS SETUP messages" + }, + MSC_CTR_BSSMAP_RX_DT1_VGCS_VBS_ASSIGN_RQST = { + "bssmap:rx:dt1:vgcs_vbs_assignment:req", + "Number of received BSSMAP DT1 VGCS/VBS ASSIGNMENT messages" + }, + MSC_CTR_BSSMAP_RX_DT1_UPLINK_RQST_ACKNOWLEDGE = { + "bssmap:rx:dt1:uplink_rqst:ack", + "Number of received BSSMAP DT1 UPLINK REQUEST ACKNOWLEDGE messages" + }, + MSC_CTR_BSSMAP_RX_DT1_UPLINK_REJECT_CMD = { + "bssmap:rx:dt1:uplink_reject:cmd", + "Number of received BSSMAP DT1 UPLINK REJECT COMMAND messages" + }, + MSC_CTR_BSSMAP_RX_DT1_UPLINK_RELEASE_CMD = { + "bssmap:rx:dt1:uplink_release:cmd", + "Number of received BSSMAP DT1 UPLINK RELEASE COMMAND messages" + }, + MSC_CTR_BSSMAP_RX_DT1_UPLINK_SEIZED_CMD = { + "bssmap:rx:dt1:uplink_seized:cmd", + "Number of received BSSMAP DT1 UPLINK SEIZED COMMAND messages" + }, + MSC_CTR_BSSMAP_RX_DT1_VGCS_ADDL_INFO = { + "bssmap:rx:dt1:vgcs_addl_info", + "Number of received BSSMAP DT1 VGCS/VBS ASSITIONAL INFORMATION messages" + }, + MSC_CTR_BSSMAP_RX_DT1_VGCS_SMS = { + "bssmap:rx:dt1:vgcs_sms", + "Number of received BSSMAP DT1 VGCS SMS messages" + }, + MSC_CTR_BSSMAP_RX_DT1_NOTIFICATION_DATA = { + "bssmap:rx:dt1:notification_data", + "Number of received BSSMAP DT1 NOTIFICATION DATA messages" + }, /* Tx message counters (per message type) * * The counters here follow the logic of the osmo_bsc_sigtran_send() function * which receives DT1 messages from the upper layers and actually sends them to the MSC. * These counters cover all messages passed to the function by the upper layers: */ - MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT = {"bssmap:tx:type:bss_management", "Number of transmitted BSS MANAGEMENT messages"}, - MSC_CTR_BSSMAP_TX_DTAP = {"bssmap:tx:type:dtap", "Number of transmitted DTAP messages"}, - MSC_CTR_BSSMAP_TX_UNKNOWN = {"bssmap:tx:type:err_unknown", "Number of transmitted messages with unknown type (an error in our code?)"}, - MSC_CTR_BSSMAP_TX_SHORT = {"bssmap:tx:type:err_short", "Number of transmitted messages which are too short (an error in our code?)"}, + MSC_CTR_BSSMAP_TX_BSS_MANAGEMENT = { + "bssmap:tx:type:bss_management", + "Number of transmitted BSS MANAGEMENT messages" + }, + MSC_CTR_BSSMAP_TX_DTAP = { + "bssmap:tx:type:dtap", + "Number of transmitted DTAP messages" + }, + MSC_CTR_BSSMAP_TX_UNKNOWN = { + "bssmap:tx:type:err_unknown", + "Number of transmitted messages with unknown type (an error in our code?)" + }, + MSC_CTR_BSSMAP_TX_SHORT = { + "bssmap:tx:type:err_short", + "Number of transmitted messages which are too short (an error in our code?)" + }, /* The next counters are also counted in the osmo_bsc_sigtran_send() function and * sum up to the exactly same number as the counters above but instead of message * classes they split by the result of the sending attempt: */ - MSC_CTR_BSSMAP_TX_ERR_CONN_NOT_READY = {"bssmap:tx:result:err_conn_not_ready", "Number of BSSMAP messages we tried to send when the connection was not ready yet"}, - MSC_CTR_BSSMAP_TX_ERR_SEND = {"bssmap:tx:result:err_send", "Number of socket errors while sending BSSMAP messages"}, - MSC_CTR_BSSMAP_TX_SUCCESS = {"bssmap:tx:result:success", "Number of successfully sent BSSMAP messages"}, + MSC_CTR_BSSMAP_TX_ERR_CONN_NOT_READY = { + "bssmap:tx:result:err_conn_not_ready", + "Number of BSSMAP messages we tried to send when the connection was not ready yet" + }, + MSC_CTR_BSSMAP_TX_ERR_SEND = { + "bssmap:tx:result:err_send", + "Number of socket errors while sending BSSMAP messages" + }, + MSC_CTR_BSSMAP_TX_SUCCESS = { + "bssmap:tx:result:success", + "Number of successfully sent BSSMAP messages" + }, /* Tx message counters (per specific message) * * Theoretically, the DT1 counters should sum up to the same number as the Tx counters * above but since these counters are coming from the upper layers, there might be * some difference if we forget some code path. */ - MSC_CTR_BSSMAP_TX_UDT_RESET = {"bssmap:tx:udt:reset:request", "Number of transmitted BSSMAP UDT RESET messages"}, - MSC_CTR_BSSMAP_TX_UDT_RESET_ACK = {"bssmap:tx:udt:reset:ack", "Number of transmitted BSSMAP UDT RESET ACK messages"}, - MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST = {"bssmap:tx:dt1:clear:rqst", "Number of transmitted BSSMAP DT1 CLEAR RQSTtx messages"}, - MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE = {"bssmap:tx:dt1:clear:complete", "Number of transmitted BSSMAP DT1 CLEAR COMPLETE messages"}, - MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_FAILURE = {"bssmap:tx:dt1:assigment:failure", "Number of transmitted BSSMAP DT1 ASSIGMENT FAILURE messages"}, - MSC_CTR_BSSMAP_TX_DT1_ASSIGMENT_COMPLETE = {"bssmap:tx:dt1:assigment:complete", "Number of transmitted BSSMAP DT1 ASSIGMENT COMPLETE messages"}, - MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT = {"bssmap:tx:dt1:sapi_n:reject", "Number of transmitted BSSMAP DT1 SAPI N REJECT messages"}, - MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE = {"bssmap:tx:dt1:cipher_mode:complete", "Number of transmitted BSSMAP DT1 CIPHER COMPLETE messages"}, - MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT = {"bssmap:tx:dt1:cipher_mode:reject", "Number of transmitted BSSMAP DT1 CIPHER REJECT messages"}, - MSC_CTR_BSSMAP_TX_DT1_CLASSMARK_UPDATE = {"bssmap:tx:dt1:classmark:update", "Number of transmitted BSSMAP DT1 CLASSMARK UPDATE messages"}, - MSC_CTR_BSSMAP_TX_DT1_LCLS_CONNECT_CTRL_ACK = {"bssmap:tx:dt1:lcls_connect_ctrl:ack", "Number of transmitted BSSMAP DT1 LCLS CONNECT CTRL ACK messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_REQUIRED = {"bssmap:tx:dt1:handover:required", "Number of transmitted BSSMAP DT1 HANDOVER REQUIRED messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_PERFORMED = {"bssmap:tx:dt1:handover:performed", "Number of transmitted BSSMAP DT1 HANDOVER PERFORMED messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_RQST_ACKNOWLEDGE = {"bssmap:tx:dt1:handover:rqst_acknowledge", "Number of transmitted BSSMAP DT1 HANDOVER RQST ACKNOWLEDGE messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_DETECT = {"bssmap:tx:dt1:handover:detect", "Number of transmitted BSSMAP DT1 HANDOVER DETECT messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_COMPLETE = {"bssmap:tx:dt1:handover:complete", "Number of transmitted BSSMAP DT1 HANDOVER COMPLETE messages"}, - MSC_CTR_BSSMAP_TX_DT1_HANDOVER_FAILURE = {"bssmap:tx:dt1:handover:failure", "Number of transmitted BSSMAP DT1 HANDOVER FAILURE messages"}, - MSC_CTR_BSSMAP_TX_DT1_DTAP = {"bssmap:tx:dt1:dtap", "Number of transmitted BSSMAP DT1 DTAP messages"}, - MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS = {"bssmap:tx:dt1:location:response_success", - "Number of transmitted BSSMAP Perform Location Response messages containing a location estimate"}, - MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE = {"bssmap:tx:dt1:location:response_failure", - "Number of transmitted BSSMAP Perform Location Response messages containing a failure cause"}, + MSC_CTR_BSSMAP_TX_UDT_RESET = { + "bssmap:tx:udt:reset:request", + "Number of transmitted BSSMAP UDT RESET messages" + }, + MSC_CTR_BSSMAP_TX_UDT_RESET_ACK = { + "bssmap:tx:udt:reset:ack", + "Number of transmitted BSSMAP UDT RESET ACK messages" + }, + MSC_CTR_BSSMAP_TX_DT1_CLEAR_RQST = { + "bssmap:tx:dt1:clear:rqst", + "Number of transmitted BSSMAP DT1 CLEAR RQSTtx messages" + }, + MSC_CTR_BSSMAP_TX_DT1_CLEAR_COMPLETE = { + "bssmap:tx:dt1:clear:complete", + "Number of transmitted BSSMAP DT1 CLEAR COMPLETE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_FAILURE = { + "bssmap:tx:dt1:assignment:failure", + "Number of transmitted BSSMAP DT1 ASSIGNMENT FAILURE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_ASSIGNMENT_COMPLETE = { + "bssmap:tx:dt1:assignment:complete", + "Number of transmitted BSSMAP DT1 ASSIGNMENT COMPLETE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_SAPI_N_REJECT = { + "bssmap:tx:dt1:sapi_n:reject", + "Number of transmitted BSSMAP DT1 SAPI N REJECT messages" + }, + MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE = { + "bssmap:tx:dt1:cipher_mode:complete", + "Number of transmitted BSSMAP DT1 CIPHER COMPLETE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_CIPHER_REJECT = { + "bssmap:tx:dt1:cipher_mode:reject", + "Number of transmitted BSSMAP DT1 CIPHER REJECT messages" + }, + MSC_CTR_BSSMAP_TX_DT1_CLASSMARK_UPDATE = { + "bssmap:tx:dt1:classmark:update", + "Number of transmitted BSSMAP DT1 CLASSMARK UPDATE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_LCLS_CONNECT_CTRL_ACK = { + "bssmap:tx:dt1:lcls_connect_ctrl:ack", + "Number of transmitted BSSMAP DT1 LCLS CONNECT CTRL ACK messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_REQUIRED = { + "bssmap:tx:dt1:handover:required", + "Number of transmitted BSSMAP DT1 HANDOVER REQUIRED messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_PERFORMED = { + "bssmap:tx:dt1:handover:performed", + "Number of transmitted BSSMAP DT1 HANDOVER PERFORMED messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_RQST_ACKNOWLEDGE = { + "bssmap:tx:dt1:handover:rqst_acknowledge", + "Number of transmitted BSSMAP DT1 HANDOVER RQST ACKNOWLEDGE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_DETECT = { + "bssmap:tx:dt1:handover:detect", + "Number of transmitted BSSMAP DT1 HANDOVER DETECT messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_COMPLETE = { + "bssmap:tx:dt1:handover:complete", + "Number of transmitted BSSMAP DT1 HANDOVER COMPLETE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_HANDOVER_FAILURE = { + "bssmap:tx:dt1:handover:failure", + "Number of transmitted BSSMAP DT1 HANDOVER FAILURE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_DTAP = { + "bssmap:tx:dt1:dtap", + "Number of transmitted BSSMAP DT1 DTAP messages" + }, + MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_SUCCESS = { + "bssmap:tx:dt1:location:response_success", + "Number of transmitted BSSMAP Perform Location Response messages containing a location estimate" + }, + MSC_CTR_BSSMAP_TX_DT1_PERFORM_LOCATION_RESPONSE_FAILURE = { + "bssmap:tx:dt1:location:response_failure", + "Number of transmitted BSSMAP Perform Location Response messages containing a failure cause" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_ACK = { + "bssmap:tx:dt1:vgcs_vbs_setup:ack", + "Number of transmitted BSSMAP DT1 VGCS/VBS SETUP ACK messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_SETUP_REFUSE = { + "bssmap:tx:dt1:vgcs_vbs_setup:refuse", + "Number of transmitted BSSMAP DT1 VGCS/VBS SETUP REFUSE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_RESULT = { + "bssmap:tx:dt1:vgcs_vbs_assignment:res", + "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT RESULT messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGN_FAIL = { + "bssmap:tx:dt1:vgcs_vbs_assignment:fail", + "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT FAILURE messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_QUEUING_INDICATION = { + "bssmap:tx:dt1:vgcs_vbs_queuing:ind", + "Number of transmitted BSSMAP DT1 VGCS/VBS QUEUING INDICATION messages" + }, + MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST = { + "bssmap:tx:dt1:uplink_rqst", + "Number of transmitted BSSMAP DT1 UPLINK REQUEST messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_ASSIGNMENT_STATUS = { + "bssmap:tx:dt1:vgcs_vbs_assignment:status", + "Number of transmitted BSSMAP DT1 VGCS/VBS ASSIGNMENT STATUS messages" + }, + MSC_CTR_BSSMAP_TX_DT1_VGCS_VBS_AREA_CELL_INFO = { + "bssmap:tx:dt1:vgcs_vbs_area_cell:info", + "Number of transmitted BSSMAP DT1 VGCS/VBS AREA CELL INFO messages" + }, + MSC_CTR_BSSMAP_TX_DT1_UPLINK_RQST_CONFIRMATION = { + "bssmap:tx:dt1:uplink_rqst:cnf", + "Number of transmitted BSSMAP DT1 UPLINK REQUEST CONFIRMATION messages" + }, + MSC_CTR_BSSMAP_TX_DT1_UPLINK_RELEASE_INDICATION = { + "bssmap:tx:dt1:uplink_release:ind", + "Number of transmitted BSSMAP DT1 UPLINK RELEASE INDICATION messages" + }, + MSC_CTR_BSSMAP_TX_DT1_UPLINK_APP_DATA = { + "bssmap:tx:dt1:uplink_app_data", + "Number of transmitted BSSMAP DT1 UPLINK APPLICATION DATA messages" + }, /* Indicators for MSC pool usage */ MSC_CTR_MSCPOOL_SUBSCR_NEW = { @@ -207,7 +420,6 @@ struct bsc_msc_data *osmo_msc_data_alloc(struct gsm_network *net, int nr) { struct bsc_msc_data *msc_data; - unsigned int i; /* check if there is already one */ msc_data = osmo_msc_data_find(net, nr); @@ -251,24 +463,16 @@ /* Allow the full set of possible codecs by default */ msc_data->audio_length = 5; - msc_data->audio_support = - talloc_zero_array(msc_data, struct gsm_audio_support *, - msc_data->audio_length); - for (i = 0; i < msc_data->audio_length; i++) { - msc_data->audio_supporti = - talloc_zero(msc_data->audio_support, - struct gsm_audio_support); - } - msc_data->audio_support0->ver = 1; - msc_data->audio_support0->hr = 0; - msc_data->audio_support1->ver = 1; - msc_data->audio_support1->hr = 1; - msc_data->audio_support2->ver = 2; - msc_data->audio_support2->hr = 0; - msc_data->audio_support3->ver = 3; - msc_data->audio_support3->hr = 0; - msc_data->audio_support4->ver = 3; - msc_data->audio_support4->hr = 1; + msc_data->audio_support0.ver = 1; + msc_data->audio_support0.hr = 0; + msc_data->audio_support1.ver = 1; + msc_data->audio_support1.hr = 1; + msc_data->audio_support2.ver = 2; + msc_data->audio_support2.hr = 0; + msc_data->audio_support3.ver = 3; + msc_data->audio_support3.hr = 0; + msc_data->audio_support4.ver = 3; + msc_data->audio_support4.hr = 1; osmo_fd_setup(&msc_data->mgcp_ipa.ofd, -1, OSMO_FD_READ, &bsc_sccplite_mgcp_proxy_cb, msc_data, 0); msc_data->mgcp_ipa.local_addr = NULL; /* = INADDR(6)_ANY */
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/osmo_bsc_sigtran.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/osmo_bsc_sigtran.c
Changed
@@ -36,6 +36,7 @@ #include <osmocom/bsc/gsm_data.h> #include <osmocom/bsc/bts.h> #include <osmocom/bsc/paging.h> +#include <osmocom/bsc/bssmap_reset.h> #include <osmocom/mgcp_client/mgcp_common.h> /* A pointer to a list with all involved MSCs @@ -45,33 +46,6 @@ #define DEFAULT_ASP_LOCAL_IP "localhost" #define DEFAULT_ASP_REMOTE_IP "localhost" -/* Helper function to Check if the given connection id is already assigned */ -static struct gsm_subscriber_connection *get_bsc_conn_by_conn_id(int conn_id) -{ - conn_id &= 0xFFFFFF; - struct gsm_subscriber_connection *conn; - - llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { - if (conn->sccp.conn_id == conn_id) - return conn; - } - - return NULL; -} - -struct gsm_subscriber_connection *bsc_conn_by_bsub(struct bsc_subscr *bsub) -{ - struct gsm_subscriber_connection *conn; - if (!bsub) - return NULL; - - llist_for_each_entry(conn, &bsc_gsmnet->subscr_conns, entry) { - if (conn->bsub == bsub) - return conn; - } - return NULL; -} - /* Patch regular BSSMAP RESET to add extra T to announce Osmux support (osmocom extension) */ static void _gsm0808_extend_announce_osmux(struct msgb *msg) { @@ -119,7 +93,7 @@ &msc->a.msc_addr, msg); } -/* Find an MSC by its sigtran point code */ +/* Find an MSC by its remote SCCP address */ static struct bsc_msc_data *get_msc_by_addr(const struct osmo_sccp_addr *msc_addr) { struct osmo_ss7_instance *ss7; @@ -134,6 +108,21 @@ return NULL; } +/* Find an MSC by its remote sigtran point code on a given cs7 instance. */ +static struct bsc_msc_data *get_msc_by_pc(struct osmo_ss7_instance *cs7, uint32_t pc) +{ + struct bsc_msc_data *msc; + llist_for_each_entry(msc, msc_list, entry) { + if (msc->a.cs7_instance != cs7->cfg.id) + continue; + if ((msc->a.msc_addr.presence & OSMO_SCCP_ADDR_T_PC) == 0) + continue; + if (msc->a.msc_addr.pc == pc) + return msc; + } + return NULL; +} + /* Received data from MSC, use the connection id which MSC it is */ static int handle_data_from_msc(struct gsm_subscriber_connection *conn, struct msgb *msg) { @@ -164,10 +153,12 @@ static int handle_n_connect_from_msc(struct osmo_sccp_user *scu, struct osmo_scu_prim *scu_prim) { struct bsc_msc_data *msc = get_msc_by_addr(&scu_prim->u.connect.calling_addr); + struct osmo_sccp_instance *sccp = osmo_sccp_get_sccp(scu); + struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(sccp); struct gsm_subscriber_connection *conn; int rc = 0; - conn = get_bsc_conn_by_conn_id(scu_prim->u.connect.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.connect.conn_id); if (conn) { LOGP(DMSC, LOGL_NOTICE, "(calling_addr=%s conn_id=%u) N-CONNECT.ind with already used conn_id, ignoring\n", @@ -195,7 +186,14 @@ if (!conn) return -ENOMEM; conn->sccp.msc = msc; - conn->sccp.conn_id = scu_prim->u.connect.conn_id; + conn->sccp.conn.conn_id = scu_prim->u.connect.conn_id; + if (bsc_sccp_inst_register_gscon(bsc_sccp, &conn->sccp.conn) < 0) { + LOGP(DMSC, LOGL_NOTICE, "(calling_addr=%s conn_id=%u) N-CONNECT.ind failed registering conn\n", + osmo_sccp_addr_dump(&scu_prim->u.connect.calling_addr), scu_prim->u.connect.conn_id); + osmo_fsm_inst_term(conn->fi, OSMO_FSM_TERM_REQUEST, NULL); + rc = -ENOENT; + goto refuse; + } /* Take actions asked for by the enclosed PDU */ osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_IND, scu_prim); @@ -206,11 +204,101 @@ return rc; } +static void handle_pcstate_ind(struct osmo_ss7_instance *cs7, const struct osmo_scu_pcstate_param *pcst) +{ + struct bsc_msc_data *msc; + bool connected; + bool disconnected; + + LOGP(DMSC, LOGL_DEBUG, "N-PCSTATE ind: affected_pc=%u sp_status=%s remote_sccp_status=%s\n", + pcst->affected_pc, osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + + /* If we don't care about that point-code, ignore PCSTATE. */ + msc = get_msc_by_pc(cs7, pcst->affected_pc); + if (!msc) + return; + + /* See if this marks the point code to have become available, or to have been lost. + * + * I want to detect two events: + * - connection event (both indicators say PC is reachable). + * - disconnection event (at least one indicator says the PC is not reachable). + * + * There are two separate incoming indicators with various possible values -- the incoming events can be: + * + * - neither connection nor disconnection indicated -- just indicating congestion + * connected == false, disconnected == false --> do nothing. + * - both incoming values indicate that we are connected + * --> trigger connected + * - both indicate we are disconnected + * --> trigger disconnected + * - one value indicates 'connected', the other indicates 'disconnected' + * --> trigger disconnected + * + * Congestion could imply that we're connected, but it does not indicate that a PC's reachability changed, so no need to + * trigger on that. + */ + connected = false; + disconnected = false; + + switch (pcst->sp_status) { + case OSMO_SCCP_SP_S_ACCESSIBLE: + connected = true; + break; + case OSMO_SCCP_SP_S_INACCESSIBLE: + disconnected = true; + break; + default: + case OSMO_SCCP_SP_S_CONGESTED: + /* Neither connecting nor disconnecting */ + break; + } + + switch (pcst->remote_sccp_status) { + case OSMO_SCCP_REM_SCCP_S_AVAILABLE: + if (!disconnected) + connected = true; + break; + case OSMO_SCCP_REM_SCCP_S_UNAVAILABLE_UNKNOWN: + case OSMO_SCCP_REM_SCCP_S_UNEQUIPPED: + case OSMO_SCCP_REM_SCCP_S_INACCESSIBLE: + disconnected = true; + connected = false; + break; + default: + case OSMO_SCCP_REM_SCCP_S_CONGESTED: + /* Neither connecting nor disconnecting */ + break; + } + + if (disconnected && a_reset_conn_ready(msc)) { + LOGP(DMSC, LOGL_NOTICE, + "(msc%d) now unreachable: N-PCSTATE ind: pc=%u sp_status=%s remote_sccp_status=%s\n", + msc->nr, pcst->affected_pc, + osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + /* A previously usable MSC has disconnected. Kick the BSSMAP back to DISC state. */ + bssmap_reset_set_disconnected(msc->a.bssmap_reset); + } else if (connected && !a_reset_conn_ready(msc)) { + LOGP(DMSC, LOGL_NOTICE, + "(msc%d) now available: N-PCSTATE ind: pc=%u sp_status=%s remote_sccp_status=%s\n", + msc->nr, pcst->affected_pc, + osmo_sccp_sp_status_name(pcst->sp_status), + osmo_sccp_rem_sccp_status_name(pcst->remote_sccp_status)); + /* A previously unusable MSC has become reachable. Trigger immediate BSSMAP RESET -- we would resend a + * RESET either way, but we might as well do it now to speed up connecting. */ + bssmap_reset_resend_reset(msc->a.bssmap_reset); + } +} + /* Callback function, called by the SCCP stack when data arrives */ static int sccp_sap_up(struct osmo_prim_hdr *oph, void *_scu) { struct osmo_scu_prim *scu_prim = (struct osmo_scu_prim *)oph; struct osmo_sccp_user *scu = _scu; + struct osmo_sccp_instance *sccp = osmo_sccp_get_sccp(scu); + struct bsc_sccp_inst *bsc_sccp = osmo_sccp_get_priv(sccp); struct gsm_subscriber_connection *conn; int rc = 0; @@ -231,7 +319,7 @@ /* Handle outbound connection confirmation */ DEBUGP(DMSC, "N-CONNECT.cnf(%u, %s)\n", scu_prim->u.connect.conn_id, osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); - conn = get_bsc_conn_by_conn_id(scu_prim->u.connect.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.connect.conn_id); if (conn) { osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_A_CONN_CFM, scu_prim); conn->sccp.state = SUBSCR_SCCP_ST_CONNECTED; @@ -250,7 +338,7 @@ osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg))); /* Incoming data is a sign of a vital connection */ - conn = get_bsc_conn_by_conn_id(scu_prim->u.data.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.data.conn_id); if (conn) { a_reset_conn_success(conn->sccp.msc); handle_data_from_msc(conn, oph->msg); @@ -262,7 +350,7 @@ osmo_hexdump(msgb_l2(oph->msg), msgb_l2len(oph->msg)), scu_prim->u.disconnect.cause); /* indication of disconnect */ - conn = get_bsc_conn_by_conn_id(scu_prim->u.disconnect.conn_id); + conn = bsc_sccp_inst_get_gscon_by_conn_id(bsc_sccp, scu_prim->u.disconnect.conn_id); if (conn) { conn->sccp.state = SUBSCR_SCCP_ST_NONE; if (msgb_l2len(oph->msg) > 0) @@ -271,6 +359,10 @@ } break; + case OSMO_PRIM(OSMO_SCU_PRIM_N_PCSTATE, PRIM_OP_INDICATION): + handle_pcstate_ind(osmo_sccp_get_ss7(sccp), &scu_prim->u.pcstate); + break; + default: LOGP(DMSC, LOGL_ERROR, "Unhandled SIGTRAN operation %s on primitive %u\n", get_value_string(osmo_prim_op_names, oph->operation), oph->primitive); @@ -317,13 +409,14 @@ { struct osmo_ss7_instance *ss7; struct bsc_msc_data *msc; - int conn_id; + struct bsc_sccp_inst *bsc_sccp; + uint32_t conn_id; int rc; OSMO_ASSERT(conn); OSMO_ASSERT(msg); OSMO_ASSERT(conn->sccp.msc); - OSMO_ASSERT(conn->sccp.conn_id == -1); + OSMO_ASSERT(conn->sccp.conn.conn_id == SCCP_CONN_ID_UNSET); msc = conn->sccp.msc; @@ -332,15 +425,20 @@ return -EINVAL; } - conn->sccp.conn_id = conn_id = bsc_sccp_inst_next_conn_id(conn->sccp.msc->a.sccp); - if (conn->sccp.conn_id < 0) { + bsc_sccp = osmo_sccp_get_priv(msc->a.sccp); + conn->sccp.conn.conn_id = conn_id = bsc_sccp_inst_next_conn_id(bsc_sccp); + if (conn->sccp.conn.conn_id == SCCP_CONN_ID_UNSET) { LOGP(DMSC, LOGL_ERROR, "Unable to allocate SCCP Connection ID\n"); return -1; } - LOGP(DMSC, LOGL_DEBUG, "Allocated new connection id: %d\n", conn->sccp.conn_id); + if (bsc_sccp_inst_register_gscon(bsc_sccp, &conn->sccp.conn) < 0) { + LOGP(DMSC, LOGL_ERROR, "Unable to register SCCP connection (id=%u)\n", conn->sccp.conn.conn_id); + return -1; + } + LOGP(DMSC, LOGL_DEBUG, "Allocated new connection id: %u\n", conn->sccp.conn.conn_id); ss7 = osmo_ss7_instance_find(msc->a.cs7_instance); OSMO_ASSERT(ss7); - LOGP(DMSC, LOGL_INFO, "Opening new SCCP connection (id=%i) to MSC %d: %s\n", conn_id, + LOGP(DMSC, LOGL_INFO, "Opening new SCCP connection (id=%u) to MSC %d: %s\n", conn_id, msc->nr, osmo_sccp_addr_name(ss7, &msc->a.msc_addr)); rc = osmo_sccp_tx_conn_req_msg(msc->a.sccp_user, conn_id, &msc->a.bsc_addr, @@ -400,7 +498,7 @@ return -EINVAL; } - conn_id = conn->sccp.conn_id; + conn_id = conn->sccp.conn.conn_id; ss7 = osmo_ss7_instance_find(msc->a.cs7_instance); OSMO_ASSERT(ss7); @@ -514,6 +612,7 @@ int prev_msc_nr; struct osmo_sccp_instance *sccp; + struct bsc_sccp_inst *bsc_sccp; llist_for_each_entry(msc, msc_list, entry) { /* An MSC with invalid cs7 instance id defaults to cs7 instance 0 */ @@ -557,6 +656,10 @@ if (!sccp) return -EINVAL; + bsc_sccp = bsc_sccp_inst_alloc(tall_bsc_ctx); + bsc_sccp->sccp = sccp; + osmo_sccp_set_priv(sccp, bsc_sccp); + /* Now that the SCCP client is set up, configure all MSCs on this cs7 instance to use it */ llist_for_each_entry(msc, msc_list, entry) { char msc_name32; @@ -626,7 +729,7 @@ struct ipaccess_head *iph; struct ipaccess_head_ext *iph_ext; - if (asp->cfg.proto != OSMO_SS7_ASP_PROT_IPA) { + if (osmo_ss7_asp_get_proto(asp) != OSMO_SS7_ASP_PROT_IPA) { msgb_free(msg); return 0; }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/paging.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/paging.c
Changed
@@ -73,8 +73,8 @@ .tv_nsec = 500 * 1000 * 1000, }; -/* If no CCCH Lod Ind is received before this time period, the BTS is considered - * to have stopped sending CCCH Load Indication, probaby due to being under Load +/* If no CCCH Load Ind is received before this time period, the BTS is considered + * to have stopped sending CCCH Load Indication, probably due to being under Load * Threshold: */ #define bts_no_ccch_load_ind_timeout_sec(bts) ((bts)->ccch_load_ind_period * 2) @@ -361,7 +361,7 @@ * coming from abis_rsl.c * * We attempt to iterate once over the list of items but - * only upto available_slots. + * only up to available_slots. */ static void paging_handle_pending_requests(struct gsm_bts_paging_state *paging_bts) { @@ -562,7 +562,7 @@ } else if (bts_entry->initial_req_list_len == 1) { /* Worker timer is armed -> there was already one req before * bts_entry->initial_req_list_len == 1 -> There were no initial requests - * in the list, aka the timer is waiting for retransmition, + * in the list, aka the timer is waiting for retransmission, * which is a longer period. * Let's recaculate the time to adapt it to initial_period: */ struct timespec now, elapsed, tdiff; @@ -684,7 +684,7 @@ } /*! Update the BTS paging buffer slots on given BTS */ -void paging_update_buffer_space(struct gsm_bts *bts, uint16_t free_slots) +static void paging_update_buffer_space(struct gsm_bts *bts, uint16_t free_slots) { LOG_BTS(bts, DPAG, LOGL_DEBUG, "Rx CCCH Load Indication from BTS (available_slots %u -> %u)\n", bts->paging.available_slots, free_slots); @@ -841,8 +841,24 @@ return 0; } +/* Callback function to be called every time we receive a signal from CCCH */ +static int ccch_sig_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct ccch_signal_data *sd; + + if (signal != S_CCCH_PAGING_LOAD) + return 0; + + sd = signal_data; + + paging_update_buffer_space(sd->bts, sd->pg_buf_space); + return 0; +} + /* To be called once at startup of the process: */ void paging_global_init(void) { osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL); + osmo_signal_register_handler(SS_CCCH, ccch_sig_cb, NULL); }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/pcu_sock.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/pcu_sock.c
Changed
@@ -44,8 +44,9 @@ #include <osmocom/bsc/gsm_04_08_rr.h> #include <osmocom/bsc/bts.h> #include <osmocom/bsc/bts_sm.h> +#include <osmocom/bsc/timeslot_fsm.h> -static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg); +static int pcu_sock_send(struct gsm_network *net, struct msgb *msg); static const char *sapi_string = { PCU_IF_SAPI_RACH = "RACH", @@ -54,14 +55,14 @@ PCU_IF_SAPI_BCCH = "BCCH", PCU_IF_SAPI_PDTCH = "PDTCH", PCU_IF_SAPI_PRACH = "PRACH", - PCU_IF_SAPI_PTCCH = "PTCCH", - PCU_IF_SAPI_AGCH_DT = "AGCH_DT", + PCU_IF_SAPI_PTCCH = "PTCCH", + PCU_IF_SAPI_PCH_2 = "PCH_2", + PCU_IF_SAPI_AGCH_2 = "AGCH_2", }; -/* Check if BTS has a PCU connection */ -static bool pcu_connected(struct gsm_bts *bts) +bool pcu_connected(const struct gsm_network *net) { - struct pcu_sock_state *state = bts->pcu_state; + struct pcu_sock_state *state = net->pcu_state; if (!state) return false; @@ -106,6 +107,19 @@ } } +/* Check if it is possible to use the TS as PDCH (not now, but maybe later) */ +static bool ts_usable_as_pdch(const struct gsm_bts_trx_ts *ts) +{ + switch (ts->pchan_from_config) { + case GSM_PCHAN_TCH_F_PDCH: + case GSM_PCHAN_OSMO_DYN: + case GSM_PCHAN_PDCH: + return true; + default: + return false; + } +} + /* Fill the frequency hopping parameter */ static void info_ind_fill_fhp(struct gsm_pcu_if_info_trx_ts *ts_info, const struct gsm_bts_trx_ts *ts) @@ -174,7 +188,7 @@ bts_sm = bts->site_mgr; - LOGP(DPCU, LOGL_INFO, "Sending info for BTS %d\n", bts->nr); + LOG_BTS(bts, DPCU, LOGL_INFO, "Sending info for BTS\n"); rlcc = &bts->gprs.cell.rlc_cfg; @@ -288,14 +302,105 @@ info_ind_fill_trx(&info_ind->trxtrx->nr, trx); } - return pcu_sock_send(bts, msg); + return pcu_sock_send(bts->network, msg); +} + +static int pcu_tx_e1_ccu_ind(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { + struct gsm_pcu_if_e1_ccu_ind *e1_ccu_ind; + int i; + + if (trx->nr >= PCU_IF_NUM_TRX) { + LOG_TRX(trx, DPCU, LOGL_NOTICE, "PCU interface (version %u) " + "cannot handle more than %u transceivers => skipped\n", + PCU_IF_VERSION, PCU_IF_NUM_TRX); + continue; + } + + for (i = 0; i < ARRAY_SIZE(trx->ts); i++) { + struct gsm_pcu_if *pcu_prim; + struct gsm_bts_trx_ts *ts; + struct msgb *msg; + int rc; + + ts = &trx->tsi; + + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (!ts_usable_as_pdch(ts)) + continue; + + msg = pcu_msgb_alloc(PCU_IF_MSG_E1_CCU_IND, bts->nr); + if (!msg) + return -ENOMEM; + pcu_prim = (struct gsm_pcu_if *)msg->data; + e1_ccu_ind = &pcu_prim->u.e1_ccu_ind; + e1_ccu_ind->ts_nr = ts->nr; + e1_ccu_ind->trx_nr = trx->nr; + e1_ccu_ind->e1_nr = ts->e1_link.e1_nr; + e1_ccu_ind->e1_ts = ts->e1_link.e1_ts; + e1_ccu_ind->e1_ts_ss = ts->e1_link.e1_ts_ss; + + LOG_TRX(trx, DPCU, LOGL_INFO, "Sending E1 CCU info for TS %d\n", e1_ccu_ind->ts_nr); + rc = pcu_sock_send(bts->network, msg); + if (rc < 0) + return -EINVAL; + } + } + + return 0; } /* Allow test to overwrite it */ __attribute__((weak)) void pcu_info_update(struct gsm_bts *bts) { - if (pcu_connected(bts)) - pcu_tx_info_ind(bts); + if (pcu_connected(bts->network)) { + if (bsc_co_located_pcu(bts)) { + /* In cases where the CCU is connected via an E1 line, we transmit the connection parameters for the + * PDCH before we announce the other BTS related parameters. */ + if (is_e1_bts(bts)) + pcu_tx_e1_ccu_ind(bts); + pcu_tx_info_ind(bts); + } + } +} + +static int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn, + uint16_t arfcn, uint8_t block_nr, uint8_t *data, uint8_t len, + int8_t rssi, uint16_t ber10k, int16_t bto, int16_t lqual) +{ + struct msgb *msg; + struct gsm_pcu_if *pcu_prim; + struct gsm_pcu_if_data *data_ind; + struct gsm_bts *bts = ts->trx->bts; + + LOGP(DPCU, LOGL_DEBUG, "Sending data indication: sapi=%s arfcn=%d block=%d data=%s\n", + sapi_stringsapi, arfcn, block_nr, osmo_hexdump(data, len)); + + msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr); + if (!msg) + return -ENOMEM; + pcu_prim = (struct gsm_pcu_if *) msg->data; + data_ind = &pcu_prim->u.data_ind; + + data_ind->sapi = sapi; + data_ind->rssi = rssi; + data_ind->fn = fn; + data_ind->arfcn = arfcn; + data_ind->trx_nr = ts->trx->nr; + data_ind->ts_nr = ts->nr; + data_ind->block_nr = block_nr; + data_ind->ber10k = ber10k; + data_ind->ta_offs_qbits = bto; + data_ind->lqual_cb = lqual; + if (len) + memcpy(data_ind->data, data, len); + data_ind->len = len; + + return pcu_sock_send(bts->network, msg); } /* Forward rach indication to PCU */ @@ -307,13 +412,12 @@ struct gsm_pcu_if_rach_ind *rach_ind; /* Bail if no PCU is connected */ - if (!pcu_connected(bts)) { - LOGP(DRSL, LOGL_ERROR, "BTS %d CHAN RQD(GPRS) but PCU not " - "connected!\n", bts->nr); + if (!pcu_connected(bts->network)) { + LOG_BTS(bts, DRSL, LOGL_ERROR, "CHAN RQD(GPRS) but PCU not connected!\n"); return -ENODEV; } - LOGP(DPCU, LOGL_INFO, "Sending RACH indication: qta=%d, ra=%d, " + LOG_BTS(bts, DPCU, LOGL_INFO, "Sending RACH indication: qta=%d, ra=%d, " "fn=%d\n", qta, ra, fn); msg = pcu_msgb_alloc(PCU_IF_MSG_RACH_IND, bts->nr); @@ -329,37 +433,37 @@ rach_ind->is_11bit = is_11bit; rach_ind->burst_type = burst_type; - return pcu_sock_send(bts, msg); + return pcu_sock_send(bts->network, msg); } -/* Confirm the sending of an immediate assignment to the pcu */ -int pcu_tx_imm_ass_sent(struct gsm_bts *bts, uint32_t tlli) +int pcu_tx_data_cnf(struct gsm_bts *bts, uint32_t msg_id, uint8_t sapi) { struct msgb *msg; struct gsm_pcu_if *pcu_prim; - struct gsm_pcu_if_data_cnf_dt *data_cnf_dt; + struct gsm_pcu_if_data_cnf *data_cnf; - LOGP(DPCU, LOGL_INFO, "Sending PCH confirm with direct TLLI\n"); + LOGP(DPCU, LOGL_DEBUG, "Sending DATA.cnf: sapi=%s msg_id=%08x\n", + sapi_stringsapi, msg_id); - msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_CNF_DT, bts->nr); + msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_CNF_2, bts->nr); if (!msg) return -ENOMEM; pcu_prim = (struct gsm_pcu_if *) msg->data; - data_cnf_dt = &pcu_prim->u.data_cnf_dt; + data_cnf = &pcu_prim->u.data_cnf2; - data_cnf_dt->sapi = PCU_IF_SAPI_PCH; - data_cnf_dt->tlli = tlli; + data_cnf->sapi = sapi; + data_cnf->msg_id = msg_id; - return pcu_sock_send(bts, msg); + return pcu_sock_send(bts->network, msg); } /* we need to decode the raw RR paging message (see PCU code * Encoding::write_paging_request) and extract the mobile identity * (P-TMSI) from it */ -static int pcu_rx_rr_paging(struct gsm_bts *bts, uint8_t paging_group, - const uint8_t *raw_rr_msg) +static int pcu_rx_rr_paging_pch(struct gsm_bts *bts, uint8_t paging_group, + const struct gsm_pcu_if_pch *pch) { - struct gsm48_paging1 *p1 = (struct gsm48_paging1 *) raw_rr_msg; + struct gsm48_paging1 *p1 = (struct gsm48_paging1 *) pch->data; uint8_t chan_needed; struct osmo_mobile_identity mi; int rc; @@ -369,14 +473,14 @@ chan_needed = (p1->cneed2 << 2) | p1->cneed1; rc = osmo_mobile_identity_decode(&mi, p1->data+1, p1->data0, false); if (rc) { - LOGP(DPCU, LOGL_ERROR, "PCU Sends paging " - "request type %02x (chan_needed=%02x): Unable to decode Mobile Identity\n", + LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU Sends paging " + "request type %02x (chan_needed=%02x): Unable to decode Mobile Identity\n", p1->msg_type, chan_needed); rc = -EINVAL; break; } - LOGP(DPCU, LOGL_ERROR, "PCU Sends paging " - "request type %02x (chan_needed=%02x, mi=%s)\n", + LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU Sends paging " + "request type %02x (chan_needed=%02x, mi=%s)\n", p1->msg_type, chan_needed, osmo_mobile_identity_to_str_c(OTC_SELECT, &mi)); /* NOTE: We will have to add 2 to mi_len and subtract 2 from * the mi pointer because rsl_paging_cmd() will perform the @@ -388,12 +492,12 @@ break; case GSM48_MT_RR_PAG_REQ_2: case GSM48_MT_RR_PAG_REQ_3: - LOGP(DPCU, LOGL_ERROR, "PCU Sends unsupported paging " + LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU Sends unsupported paging " "request type %02x\n", p1->msg_type); rc = -EINVAL; break; default: - LOGP(DPCU, LOGL_ERROR, "PCU Sends unknown paging " + LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU Sends unknown paging " "request type %02x\n", p1->msg_type); rc = -EINVAL; break; @@ -402,77 +506,76 @@ return rc; } +static int pcu_rx_rr_imm_ass_pch(struct gsm_bts *bts, uint8_t paging_group, + const struct gsm_pcu_if_pch *pch, bool confirm) +{ + LOG_BTS(bts, DPCU, LOGL_DEBUG, "PCU Sends immediate assignment via PCH (msg_id=0x%08x, IMSI=%s, Paging group=0x%02x)\n", + pch->msg_id, pch->imsi, paging_group); + + /* NOTE: Sending an IMMEDIATE ASSIGNMENT via PCH became necessary with GPRS in order to be able to + * assign downlink TBFs directly through the paging channel. However, this method never became part + * of the RSL specs. This means that each BTS vendor has to come up with a proprietary method. At + * the moment we only support Ericsson RBS here. */ + if (is_ericsson_bts(bts)) + return rsl_ericsson_imm_assign_cmd(bts, pch->msg_id, sizeof(pch->data), pch->data, paging_group, + confirm); + + LOG_BTS(bts, DPCU, LOGL_ERROR, "BTS model does not support sending immediate assignment via PCH!\n"); + return -ENOTSUP; +} + static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, struct gsm_pcu_if_data *data_req) { - struct msgb *msg; - char imsi_digit_buf4; - uint32_t tlli = -1; uint8_t pag_grp; int rc = 0; + const struct gsm_pcu_if_pch *pch; + const struct gsm_pcu_if_agch *agch; + const struct gsm48_imm_ass *gsm48_imm_ass; - LOGP(DPCU, LOGL_DEBUG, "Data request received: sapi=%s arfcn=%d " + LOG_BTS(bts, DPCU, LOGL_DEBUG, "Data request received: sapi=%s arfcn=%d " "block=%d data=%s\n", sapi_stringdata_req->sapi, data_req->arfcn, data_req->block_nr, osmo_hexdump(data_req->data, data_req->len)); switch (data_req->sapi) { - case PCU_IF_SAPI_PCH: - /* the first three bytes are the last three digits of - * the IMSI, which we need to compute the paging group */ - imsi_digit_buf0 = data_req->data0; - imsi_digit_buf1 = data_req->data1; - imsi_digit_buf2 = data_req->data2; - imsi_digit_buf3 = '\0'; - LOGP(DPCU, LOGL_DEBUG, "SAPI PCH imsi %s\n", imsi_digit_buf); - pag_grp = gsm0502_calc_paging_group(&bts->si_common.chan_desc, - str_to_imsi(imsi_digit_buf)); - pcu_rx_rr_paging(bts, pag_grp, data_req->data+3); - break; - case PCU_IF_SAPI_AGCH: - msg = msgb_alloc(data_req->len, "pcu_agch"); - if (!msg) { - rc = -ENOMEM; + case PCU_IF_SAPI_AGCH_2: + if (data_req->len < sizeof(struct gsm_pcu_if_agch)) { + LOG_BTS(bts, DPCU, LOGL_ERROR, "Received PCU data request with invalid/small length %d\n", + data_req->len); break; } - msg->l3h = msgb_put(msg, data_req->len); - memcpy(msg->l3h, data_req->data, data_req->len); - if (rsl_imm_assign_cmd(bts, msg->len, msg->data)) { - msgb_free(msg); - rc = -EIO; - } + agch = (struct gsm_pcu_if_agch *)data_req->data; + if (rsl_imm_assign_cmd(bts, GSM_MACBLOCK_LEN, agch->data)) + return -EIO; + + /* Send the confirmation immediately. This is as accurate as we can get since from this point on the + * BTS hardware is responsible to schedule the sending of the IMMEDIATE ASSIGNMENT */ + if (agch->confirm) + return pcu_tx_data_cnf(bts, agch->msg_id, PCU_IF_SAPI_AGCH_2); break; - case PCU_IF_SAPI_AGCH_DT: - /* DT = direct tlli. A tlli is prefixed */ - - if (data_req->len < 5) { - LOGP(DPCU, LOGL_ERROR, "Received PCU data request with invalid/small length %d\n", - data_req->len); - break; - } - memcpy(&tlli, data_req->data, 4); - - msg = msgb_alloc(data_req->len - 4, "pcu_agch"); - if (!msg) { - rc = -ENOMEM; + case PCU_IF_SAPI_PCH_2: + if (data_req->len < sizeof(struct gsm_pcu_if_pch)) { + LOG_BTS(bts, DPCU, LOGL_ERROR, "Received PCU data request with invalid/small length %d\n", + data_req->len); break; } - msg->l3h = msgb_put(msg, data_req->len - 4); - memcpy(msg->l3h, data_req->data + 4, data_req->len - 4); - - if (bts->type == GSM_BTS_TYPE_RBS2000) - rc = rsl_ericsson_imm_assign_cmd(bts, tlli, msg->len, msg->data); - else - rc = rsl_imm_assign_cmd(bts, msg->len, msg->data); - if (rc) { - msgb_free(msg); - rc = -EIO; - } + pch = (struct gsm_pcu_if_pch *)data_req->data; + pag_grp = gsm0502_calc_paging_group(&bts->si_common.chan_desc, str_to_imsi(pch->imsi)); + gsm48_imm_ass = (struct gsm48_imm_ass *)pch->data; + + if (gsm48_imm_ass->msg_type == GSM48_MT_RR_IMM_ASS) + return pcu_rx_rr_imm_ass_pch(bts, pag_grp, pch, pch->confirm); + + if (pcu_rx_rr_paging_pch(bts, pag_grp, pch)) + return -EIO; + if (pch->confirm) + return pcu_tx_data_cnf(bts, pch->msg_id, PCU_IF_SAPI_PCH_2); break; default: - LOGP(DPCU, LOGL_ERROR, "Received PCU data request with " + LOG_BTS(bts, DPCU, LOGL_ERROR, "Received PCU data request with " "unsupported sapi %d\n", data_req->sapi); rc = -EINVAL; } @@ -480,6 +583,92 @@ return rc; } +static int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable) +{ + /* the SI is per-BTS so it doesn't matter which TRX we use */ + struct gsm_bts_trx *trx = bts->c0; + + uint8_t si_bufGSM_MACBLOCK_LEN; + uint8_t len; + int rc; + + if (enable) { + memcpy(si_buf, GSM_BTS_SI(bts, si_type), GSM_MACBLOCK_LEN); + len = GSM_MACBLOCK_LEN; + LOG_BTS(bts, DPCU, LOGL_DEBUG, "Updating SI%s to PCU: %s\n", + get_value_string(osmo_sitype_strs, si_type), + osmo_hexdump_nospc(si_buf, GSM_MACBLOCK_LEN)); + } else { + si_buf0 = si_type; + len = 1; + + /* Note: SI13 is the only system information type that is revked + * by just sending a completely empty message. This is due to + * historical reasons */ + if (si_type != SYSINFO_TYPE_13) + len = 0; + + LOG_BTS(bts, DPCU, LOGL_DEBUG, "Revoking SI%s from PCU\n", + get_value_string(osmo_sitype_strs, si_buf0)); + } + + /* The low-level data like FN, ARFCN etc will be ignored but we have to + * set lqual high enough to bypass the check at lower levels */ + rc = pcu_tx_data_ind(&trx->ts0, PCU_IF_SAPI_BCCH, 0, 0, 0, si_buf, len, + 0, 0, 0, INT16_MAX); + if (rc < 0) + LOG_BTS(bts, DPCU, LOGL_NOTICE, "Failed to send SI%s to PCU: rc=%d\n", + get_value_string(osmo_sitype_strs, si_type), rc); + + return rc; +} + +static int pcu_tx_si_all(struct gsm_bts *bts) +{ + const enum osmo_sysinfo_type si_types = { SYSINFO_TYPE_1, SYSINFO_TYPE_2, SYSINFO_TYPE_3, SYSINFO_TYPE_13 }; + unsigned int i; + int rc = 0; + + for (i = 0; i < ARRAY_SIZE(si_types); i++) { + if (GSM_BTS_HAS_SI(bts, si_typesi)) { + rc = pcu_tx_si(bts, si_typesi, true); + if (rc < 0) + return rc; + } else { + LOG_BTS(bts, DPCU, LOGL_INFO, + "SI%s is not available on PCU connection\n", + get_value_string(osmo_sitype_strs, si_typesi)); + } + } + + return 0; +} + +static int pcu_rx_txt_ind(struct gsm_bts *bts, + const struct gsm_pcu_if_txt_ind *txt) +{ + int rc; + + switch (txt->type) { + case PCU_VERSION: + LOG_BTS(bts, DPCU, LOGL_INFO, "OsmoPCU version %s connected\n", + txt->text); + rc = pcu_tx_si_all(bts); + if (rc < 0) + return -EINVAL; + break; + case PCU_OML_ALERT: + LOG_BTS(bts, DPCU, LOGL_ERROR, "PCU external alarm: %s\n", txt->text); + break; + default: + LOG_BTS(bts, DPCU, LOGL_ERROR, "Unknown TXT_IND type %u received\n", + txt->type); + return -EINVAL; + } + + return 0; +} + #define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \ do { \ size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \ @@ -495,8 +684,9 @@ int rc = 0; struct gsm_bts *bts; - /* FIXME: allow multiple BTS */ - bts = llist_entry(net->bts_list.next, struct gsm_bts, list); + bts = gsm_bts_num(net, pcu_prim->bts_nr); + if (!bts) + return -EINVAL; switch (msg_type) { case PCU_IF_MSG_DATA_REQ: @@ -504,6 +694,10 @@ CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.data_req); rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req); break; + case PCU_IF_MSG_TXT_IND: + CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.txt_ind); + rc = pcu_rx_txt_ind(bts, &pcu_prim->u.txt_ind); + break; default: LOGP(DPCU, LOGL_ERROR, "Received unknown PCU msg type %d\n", msg_type); @@ -517,9 +711,9 @@ * PCU socket interface */ -static int pcu_sock_send(struct gsm_bts *bts, struct msgb *msg) +static int pcu_sock_send(struct gsm_network *net, struct msgb *msg) { - struct pcu_sock_state *state = bts->pcu_state; + struct pcu_sock_state *state = net->pcu_state; struct osmo_fd *conn_bfd; struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msg->data; @@ -544,25 +738,10 @@ return 0; } -static void pcu_sock_close(struct pcu_sock_state *state) +static void pdch_deact_bts(struct gsm_bts *bts) { - struct osmo_fd *bfd = &state->conn_bfd; - struct gsm_bts *bts; struct gsm_bts_trx *trx; - struct gsm_bts_trx_ts *ts; - int i, j; - - /* FIXME: allow multiple BTS */ - bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); - - LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); - - close(bfd->fd); - bfd->fd = -1; - osmo_fd_unregister(bfd); - - /* re-enable the generation of ACCEPT for new connections */ - osmo_fd_read_enable(&state->listen_bfd); + int j; #if 0 /* remove si13, ... */ @@ -571,18 +750,38 @@ #endif /* release PDCH */ - for (i = 0; i < 8; i++) { - trx = gsm_bts_trx_num(bts, i); - if (!trx) - break; - for (j = 0; j < 8; j++) { - ts = &trx->tsj; + llist_for_each_entry(trx, &bts->trx_list, list) { + for (j = 0; j < ARRAY_SIZE(trx->ts); j++) { + struct gsm_bts_trx_ts *ts = &trx->tsj; + /* BSC co-located PCU applies only to Ericsson RBS, which supports only GSM_PCHAN_OSMO_DYN. + * So we need to deact only on this pchan kind. */ if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED - && ts->pchan_is == GSM_PCHAN_PDCH) { - printf("l1sap_chan_rel(trx,gsm_lchan2chan_nr(ts->lchan));\n"); + && ts->pchan_on_init == GSM_PCHAN_OSMO_DYN) { + ts_pdch_deact(ts); } } } +} + +static void pcu_sock_close(struct pcu_sock_state *state) +{ + struct osmo_fd *bfd = &state->conn_bfd; + struct gsm_bts *bts; + + LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); + + osmo_fd_unregister(bfd); + close(bfd->fd); + bfd->fd = -1; + + /* re-enable the generation of ACCEPT for new connections */ + osmo_fd_read_enable(&state->listen_bfd); + + /* Disable all PDCHs on all BTSs that are served by the PCU */ + llist_for_each_entry(bts, &state->net->bts_list, list) { + if (bsc_co_located_pcu(bts)) + pdch_deact_bts(bts); + } /* flush the queue */ while (!llist_empty(&state->upqueue)) { @@ -700,36 +899,53 @@ return rc; } +static void pdch_act_bts(struct gsm_bts *bts) +{ + struct gsm_bts_trx *trx; + int j; + + /* activate PDCH */ + llist_for_each_entry(trx, &bts->trx_list, list) { + for (j = 0; j < ARRAY_SIZE(trx->ts); j++) { + struct gsm_bts_trx_ts *ts = &trx->tsj; + /* (See comment in pdch_deact_bts above) */ + if (ts->mo.nm_state.operational == NM_OPSTATE_ENABLED + && ts->pchan_on_init == GSM_PCHAN_OSMO_DYN) { + ts_pdch_act(ts); + } + } + } +} + /* accept connection coming from PCU */ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags) { struct pcu_sock_state *state = (struct pcu_sock_state *)bfd->data; struct osmo_fd *conn_bfd = &state->conn_bfd; struct sockaddr_un un_addr; + struct gsm_bts *bts; socklen_t len; - int rc; + int fd; len = sizeof(un_addr); - rc = accept(bfd->fd, (struct sockaddr *) &un_addr, &len); - if (rc < 0) { + fd = accept(bfd->fd, (struct sockaddr *)&un_addr, &len); + if (fd < 0) { LOGP(DPCU, LOGL_ERROR, "Failed to accept a new connection\n"); return -1; } if (conn_bfd->fd >= 0) { - LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have " - "another active connection ?!?\n"); + LOGP(DPCU, LOGL_NOTICE, "PCU connects but we already have another active connection ?!?\n"); /* We already have one PCU connected, this is all we support */ osmo_fd_read_disable(&state->listen_bfd); - close(rc); + close(fd); return 0; } - osmo_fd_setup(conn_bfd, rc, OSMO_FD_READ, pcu_sock_cb, state, 0); + osmo_fd_setup(conn_bfd, fd, OSMO_FD_READ, pcu_sock_cb, state, 0); if (osmo_fd_register(conn_bfd) != 0) { - LOGP(DPCU, LOGL_ERROR, "Failed to register new connection " - "fd\n"); + LOGP(DPCU, LOGL_ERROR, "Failed to register new connection fd\n"); close(conn_bfd->fd); conn_bfd->fd = -1; return -1; @@ -737,11 +953,17 @@ LOGP(DPCU, LOGL_NOTICE, "PCU socket connected to external PCU\n"); + /* Activate all PDCHs on all BTSs that are served by the PCU */ + llist_for_each_entry(bts, &state->net->bts_list, list) { + if (bsc_co_located_pcu(bts)) + pdch_act_bts(bts); + } + return 0; } /* Open connection to PCU */ -int pcu_sock_init(const char *path, struct gsm_bts *bts) +int pcu_sock_init(struct gsm_network *net) { struct pcu_sock_state *state; struct osmo_fd *bfd; @@ -752,12 +974,12 @@ return -ENOMEM; INIT_LLIST_HEAD(&state->upqueue); - state->net = bts->network; + state->net = net; state->conn_bfd.fd = -1; bfd = &state->listen_bfd; - rc = osmo_sock_unix_init(SOCK_SEQPACKET, 0, path, OSMO_SOCK_F_BIND); + rc = osmo_sock_unix_init(SOCK_SEQPACKET, 0, net->pcu_sock_path, OSMO_SOCK_F_BIND); if (rc < 0) { LOGP(DPCU, LOGL_ERROR, "Could not create unix socket: %s\n", strerror(errno)); @@ -776,16 +998,17 @@ return rc; } - LOGP(DPCU, LOGL_INFO, "Started listening on PCU socket: %s\n", path); + LOGP(DPCU, LOGL_INFO, "Started listening on PCU socket (PCU IF v%u): %s\n", + PCU_IF_VERSION, net->pcu_sock_path); - bts->pcu_state = state; + net->pcu_state = state; return 0; } /* Close connection to PCU */ -void pcu_sock_exit(struct gsm_bts *bts) +void pcu_sock_exit(struct gsm_network *net) { - struct pcu_sock_state *state = bts->pcu_state; + struct pcu_sock_state *state = net->pcu_state; struct osmo_fd *bfd, *conn_bfd; if (!state) @@ -795,8 +1018,8 @@ if (conn_bfd->fd > 0) pcu_sock_close(state); bfd = &state->listen_bfd; - close(bfd->fd); osmo_fd_unregister(bfd); + close(bfd->fd); talloc_free(state); - bts->pcu_state = NULL; + net->pcu_state = NULL; }
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/power_control.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/power_control.c
Changed
@@ -1,7 +1,7 @@ /* MS Power Control Loop L1 */ /* (C) 2014 by Holger Hans Peter Freyther - * (C) 2020-2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2020-2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de> * * All Rights Reserved
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/system_information.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/system_information.c
Changed
@@ -220,7 +220,16 @@ uint8_t qrx, uint8_t meas_bw) { struct osmo_earfcn_si2q *e = &bts->si_common.si2quater_neigh_list; - int r = osmo_earfcn_add(e, earfcn, (meas_bw < EARFCN_MEAS_BW_INVALID) ? meas_bw : OSMO_EARFCN_MEAS_INVALID); + int r; + + /* EARFCN may already exist, so we delete it to avoid duplicates */ + if (osmo_earfcn_del(e, earfcn) == 0) + LOGP(DRR, LOGL_NOTICE, "EARFCN %u is already in the list, modifying\n", earfcn); + + if (meas_bw < EARFCN_MEAS_BW_INVALID) + r = osmo_earfcn_add(e, earfcn, meas_bw); + else + r = osmo_earfcn_add(e, earfcn, OSMO_EARFCN_MEAS_INVALID); if (r < 0) return r; @@ -298,16 +307,21 @@ size_t len = bts->si_common.uarfcn_length, i; uint8_t si2q; int pos = uarfcn_sc_pos(bts, arfcn, scramble); - uint16_t scr = diversity ? encode_fdd(scramble, true) : encode_fdd(scramble, false), + uint16_t scr = encode_fdd(scramble, diversity), *ual = bts->si_common.data.uarfcn_list, *scl = bts->si_common.data.scramble_list; + if (pos >= 0) { + LOGP(DRR, LOGL_NOTICE, + "EARFCN (%u, %u) is already in the list, modifying\n", + arfcn, scramble); + sclpos = scr; + return 0; + } + if (len == MAX_EARFCN_LIST) return -ENOMEM; - if (pos >= 0) - return -EADDRINUSE; - /* find the suitable position for arfcn if any */ pos = uarfcn_sc_pos(bts, arfcn, SC_BOUND); i = (pos < 0) ? len : pos; @@ -757,7 +771,19 @@ * SI1 Rest Octets (10.5.2.32), contains NCH position and band * indicator but that is not in the 04.08. */ - rc = osmo_gsm48_rest_octets_si1_encode(si1->rest_octets, NULL, is_dcs_net(bts)); + if (bts->nch.num_blocks) { + rc = osmo_gsm48_si1ro_nch_pos_encode(bts->nch.num_blocks, bts->nch.first_block); + if (rc < 0) { + LOGP(DRR, LOGL_ERROR, "Unable to encode NCH position (num_blocks=%u, first_block=%u)\n", + bts->nch.num_blocks, bts->nch.first_block); + rc = osmo_gsm48_rest_octets_si1_encode(si1->rest_octets, NULL, is_dcs_net(bts)); + } else { + uint8_t nch_pos = rc; + rc = osmo_gsm48_rest_octets_si1_encode(si1->rest_octets, &nch_pos, is_dcs_net(bts)); + } + } else { + rc = osmo_gsm48_rest_octets_si1_encode(si1->rest_octets, NULL, is_dcs_net(bts)); + } return sizeof(*si1) + rc; } @@ -1069,8 +1095,8 @@ memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); - /* ip.access nanoBTS needs l2_plen!! */ - if (is_ipaccess_bts(bts)) { + /* Abis/IP needs l2_plen!! */ + if (is_ipa_abisip_bts(bts)) { *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; } @@ -1100,8 +1126,8 @@ memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); - /* ip.access nanoBTS needs l2_plen!! */ - if (is_ipaccess_bts(bts)) { + /* Abis/IP needs l2_plen!! */ + if (is_ipa_abisip_bts(bts)) { *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; } @@ -1139,8 +1165,8 @@ memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); - /* ip.access nanoBTS needs l2_plen!! */ - if (is_ipaccess_bts(bts)) { + /* Abis/IP needs l2_plen!! */ + if (is_ipa_abisip_bts(bts)) { *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; } @@ -1174,8 +1200,8 @@ memset(output, GSM_MACBLOCK_PADDING, GSM_MACBLOCK_LEN); memset(&si6_ro_info, 0, sizeof(si6_ro_info)); - /* ip.access nanoBTS needs l2_plen!! */ - if (is_ipaccess_bts(bts)) { + /* Abis/IP needs l2_plen!! */ + if (is_ipa_abisip_bts(bts)) { *output++ = GSM48_LEN2PLEN(l2_plen); l2_plen++; } @@ -1218,7 +1244,9 @@ .nmo = GPRS_NMO_II, .t3168 = 2000, .t3192 = 1500, - .drx_timer_max = 3, + /* 3GPP TS 45.002 6.5.6: + * "On BCCH, the operator should limit DRX_TIMER_MAX ... to 4 seconds" */ + .drx_timer_max = 4, .bs_cv_max = 15, .ctrl_ack_type_use_block = bts->gprs.ctrl_ack_type_use_block, .ext_info_present = true,
View file
osmo-bsc_1.10.0.tar.xz/src/osmo-bsc/timeslot_fsm.c -> osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/timeslot_fsm.c
Changed
@@ -49,8 +49,8 @@ static void ts_fsm_update_id(struct gsm_bts_trx_ts *ts) { - osmo_fsm_inst_update_id_f(ts->fi, "%u-%u-%u-%s", ts->trx->bts->nr, ts->trx->nr, ts->nr, - gsm_pchan_id(ts->pchan_on_init)); + osmo_fsm_inst_update_id_f_sanitize(ts->fi, '_', "%u-%u-%u-%s", ts->trx->bts->nr, ts->trx->nr, ts->nr, + gsm_pchan_name(ts->pchan_on_init)); } static __attribute__((constructor)) void ts_fsm_init(void) @@ -323,11 +323,37 @@ chan_counts_ts_clear(ts); } -static void ts_fsm_unused_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +static void ts_fsm_unused_pdch_act(struct osmo_fsm_inst *fi) { struct gsm_bts_trx_ts *ts = ts_fi_ts(fi); struct gsm_bts *bts = ts->trx->bts; + if (bts->gprs.mode == BTS_GPRS_NONE) { + LOG_TS(ts, LOGL_DEBUG, "GPRS mode is 'none': not activating PDCH.\n"); + return; + } + + if (!ts->pdch_act_allowed) { + LOG_TS(ts, LOGL_DEBUG, "PDCH is disabled for this timeslot," + " either due to a PDCH ACT NACK, or from manual VTY command:" + " not activating PDCH. (last error: %s)\n", + ts->last_errmsg ? : "-"); + return; + } + + if (bsc_co_located_pcu(bts) && !pcu_connected(bts->network)) { + LOG_TS(ts, LOGL_DEBUG, "PCU not connected: not activating PDCH.\n"); + return; + } + + osmo_fsm_inst_state_chg(fi, TS_ST_WAIT_PDCH_ACT, CHAN_ACT_DEACT_TIMEOUT, + T_CHAN_ACT_DEACT); +} + +static void ts_fsm_unused_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_bts_trx_ts *ts = ts_fi_ts(fi); + chan_counts_ts_update(ts); /* We are entering the unused state. There must by definition not be any lchans waiting to be @@ -342,19 +368,7 @@ switch (ts->pchan_on_init) { case GSM_PCHAN_OSMO_DYN: case GSM_PCHAN_TCH_F_PDCH: - if (bts->gprs.mode == BTS_GPRS_NONE) { - LOG_TS(ts, LOGL_DEBUG, "GPRS mode is 'none': not activating PDCH.\n"); - return; - } - if (!ts->pdch_act_allowed) { - LOG_TS(ts, LOGL_DEBUG, "PDCH is disabled for this timeslot," - " either due to a PDCH ACT NACK, or from manual VTY command:" - " not activating PDCH. (last error: %s)\n", - ts->last_errmsg ? : "-"); - return; - } - osmo_fsm_inst_state_chg(fi, TS_ST_WAIT_PDCH_ACT, CHAN_ACT_DEACT_TIMEOUT, - T_CHAN_ACT_DEACT); + ts_fsm_unused_pdch_act(fi); break; case GSM_PCHAN_CCCH_SDCCH4_CBCH: @@ -399,6 +413,10 @@ /* ignored. */ return; + case TS_EV_PDCH_ACT: + ts_fsm_unused_pdch_act(fi); + return; + default: OSMO_ASSERT(false); } @@ -522,6 +540,10 @@ } } + case TS_EV_PDCH_DEACT: + ts_fsm_pdch_deact(fi); + return; + case TS_EV_LCHAN_UNUSED: /* ignored */ return; @@ -880,6 +902,7 @@ .in_event_mask = 0 | S(TS_EV_LCHAN_REQUESTED) | S(TS_EV_LCHAN_UNUSED) + | S(TS_EV_PDCH_ACT) , .out_state_mask = 0 | S(TS_ST_WAIT_PDCH_ACT) @@ -912,6 +935,7 @@ .in_event_mask = 0 | S(TS_EV_LCHAN_REQUESTED) | S(TS_EV_LCHAN_UNUSED) + | S(TS_EV_PDCH_DEACT) , .out_state_mask = 0 | S(TS_ST_WAIT_PDCH_DEACT) @@ -983,6 +1007,8 @@ OSMO_VALUE_STRING(TS_EV_PDCH_ACT_NACK), OSMO_VALUE_STRING(TS_EV_PDCH_DEACT_ACK), OSMO_VALUE_STRING(TS_EV_PDCH_DEACT_NACK), + OSMO_VALUE_STRING(TS_EV_PDCH_DEACT), + OSMO_VALUE_STRING(TS_EV_PDCH_ACT), {} }; @@ -1096,3 +1122,23 @@ return true; } + +void ts_pdch_act(struct gsm_bts_trx_ts *ts) +{ + /* We send the activation event only when the timeslot is UNUSED. In all other cases the timeslot FSM + * will automatically handle the activation at some later point. */ + if (ts->fi->state != TS_ST_UNUSED) + return; + + osmo_fsm_inst_dispatch(ts->fi, TS_EV_PDCH_ACT, NULL); +} + +void ts_pdch_deact(struct gsm_bts_trx_ts *ts) +{ + /* We send the deactivation event only when the timeslot is active as PDCH. The timeslot FSM will check + * if the PCU is available before activating the PDCH again. */ + if (ts->fi->state != TS_ST_PDCH) + return; + + osmo_fsm_inst_dispatch(ts->fi, TS_EV_PDCH_DEACT, NULL); +}
View file
osmo-bsc_1.11.0.tar.xz/src/osmo-bsc/vgcs_fsm.c
Added
@@ -0,0 +1,1272 @@ +/* Handle VGCS/VBCS calls. (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/>. + */ + +/* The process consists of two state machnes: + * + * The VGCS call state machine handles the voice group/broadcast call control. + * There is one instance for every call. It controls the uplink states of the + * call. They will be reported to the MSC or can be changed by the MSC. + * One SCCP connection for is associated with the state machine. This is used + * to talk to the MSC about state changes. + * + * The VGCS channel state machine handles the channel states in each cell. + * There is one instance for every cell and every call. The instances are + * linked to the call state process. It controls the uplink states of the + * channel. They will be reported to the call state machine or can be changed + * by the call state machine. + * One SCCP connection for every cell is associated with the state machine. + * It is used to perform VGCS channel assignment. + * + */ + +#include <osmocom/mgcp_client/mgcp_client_endpoint_fsm.h> +#include <osmocom/bsc/osmo_bsc.h> +#include <osmocom/bsc/gsm_data.h> +#include <osmocom/bsc/vgcs_fsm.h> +#include <osmocom/bsc/handover_fsm.h> +#include <osmocom/bsc/abis_rsl.h> +#include <osmocom/bsc/lchan_fsm.h> +#include <osmocom/bsc/lchan_select.h> +#include <osmocom/bsc/bsc_subscr_conn_fsm.h> +#include <osmocom/bsc/assignment_fsm.h> +#include <osmocom/bsc/gsm_08_08.h> +#include <osmocom/bsc/gsm_04_08_rr.h> +#include <osmocom/bsc/bts_trx.h> +#include <osmocom/bsc/bts.h> + +#define S(x) (1 << (x)) + +#define LOG_CALL(conn, level, fmt, args...) \ + LOGP(DASCI, level, \ + (conn->vgcs_call.sf == GSM0808_SF_VGCS) ? ("VGCS callref %s: " fmt) : ("VBS callref %s: " fmt), \ + gsm44068_group_id_string(conn->vgcs_call.call_ref), ##args) +#define LOG_CHAN(conn, level, fmt, args...) \ + LOGP(DASCI, level, \ + (conn->vgcs_chan.sf == GSM0808_SF_VGCS) ? ("VGCS callref %s, cell %s: " fmt) \ + : ("VBS callref %s, cell %s: " fmt), \ + gsm44068_group_id_string(conn->vgcs_chan.call_ref), conn->vgcs_chan.ci_str, ##args) + +const char *gsm44068_group_id_string(uint32_t callref) +{ + static char string9; + + snprintf(string, sizeof(string), "%08u", callref); + + return string; +} + +static struct osmo_fsm vgcs_call_fsm; +static struct osmo_fsm vgcs_chan_fsm; + +static __attribute__((constructor)) void vgcs_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&vgcs_call_fsm) == 0); + OSMO_ASSERT(osmo_fsm_register(&vgcs_chan_fsm) == 0); +} + +static const struct value_string vgcs_fsm_event_names = { + OSMO_VALUE_STRING(VGCS_EV_SETUP), + OSMO_VALUE_STRING(VGCS_EV_ASSIGN_REQ), + OSMO_VALUE_STRING(VGCS_EV_TALKER_DET), + OSMO_VALUE_STRING(VGCS_EV_LISTENER_DET), + OSMO_VALUE_STRING(VGCS_EV_MSC_ACK), + OSMO_VALUE_STRING(VGCS_EV_MSC_REJECT), + OSMO_VALUE_STRING(VGCS_EV_MSC_SEIZE), + OSMO_VALUE_STRING(VGCS_EV_MSC_RELEASE), + OSMO_VALUE_STRING(VGCS_EV_MSC_DTAP), + OSMO_VALUE_STRING(VGCS_EV_LCHAN_ACTIVE), + OSMO_VALUE_STRING(VGCS_EV_LCHAN_ERROR), + OSMO_VALUE_STRING(VGCS_EV_MGW_OK), + OSMO_VALUE_STRING(VGCS_EV_MGW_FAIL), + OSMO_VALUE_STRING(VGCS_EV_TALKER_EST), + OSMO_VALUE_STRING(VGCS_EV_TALKER_DATA), + OSMO_VALUE_STRING(VGCS_EV_TALKER_REL), + OSMO_VALUE_STRING(VGCS_EV_TALKER_FAIL), + OSMO_VALUE_STRING(VGCS_EV_BLOCK), + OSMO_VALUE_STRING(VGCS_EV_REJECT), + OSMO_VALUE_STRING(VGCS_EV_UNBLOCK), + OSMO_VALUE_STRING(VGCS_EV_CLEANUP), + OSMO_VALUE_STRING(VGCS_EV_CALLING_ASSIGNED), + { } +}; + +static struct gsm_subscriber_connection *find_calling_subscr_conn(struct gsm_subscriber_connection *conn) +{ + struct gsm_subscriber_connection *c; + + llist_for_each_entry(c, &conn->network->subscr_conns, entry) { + if (!c->assignment.fi) + continue; + if (c->assignment.req.target_lchan != conn->lchan) + continue; + return c; + } + + return NULL; +} + +/* + * VGCS call FSM + */ + +static void vgcs_call_detach_and_destroy(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct gsm_subscriber_connection *conn = fi->priv, *c; + struct msgb *msg; + + /* Flush message queue. */ + while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue))) + msgb_free(msg); + + /* Detach all cell instances. */ + while (!llist_empty(&conn->vgcs_call.chan_list)) { + c = llist_entry(conn->vgcs_call.chan_list.next, struct gsm_subscriber_connection, vgcs_chan.list); + c->vgcs_chan.call = NULL; + llist_del(&c->vgcs_chan.list); + } + + /* No Talker. */ + conn->vgcs_call.talker = NULL; + + /* Remove pointer of FSM. */ + conn->vgcs_call.fi = NULL; +} + +static void vgcs_call_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + + switch (event) { + case VGCS_EV_SETUP: + LOG_CALL(conn, LOGL_DEBUG, "VGCS/VBS SETUP from MSC.\n"); + /* MSC sends VGCS/VBS SETUP for a new call. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0); + /* Remove unsupported features. */ + conn->vgcs_call.ff.tp_ind = 0; + conn->vgcs_call.ff.as_ind_circuit = 0; + conn->vgcs_call.ff.as_ind_link = 0; + conn->vgcs_call.ff.bss_res = 0; + conn->vgcs_call.ff.tcp = 0; + /* Acknowlege the call. */ + bsc_tx_setup_ack(conn, &conn->vgcs_call.ff); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_call_fsm_idle(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv, *c; + struct handover_rr_detect_data *d = data; + struct msgb *msg; + + switch (event) { + case VGCS_EV_TALKER_DET: + LOG_CALL(conn, LOGL_DEBUG, "Talker detected.\n"); + /* Talker detected on a channel, call becomes busy. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BUSY, 0, 0); + conn->vgcs_call.talker = d->msg->lchan->conn; + /* Reset pending states. */ + while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue))) + msgb_free(msg); + conn->vgcs_call.msc_ack = false; + conn->vgcs_call.talker_rel = false; + /* Report busy uplink to the MSC. */ + bsc_tx_uplink_req(conn); + /* Block all other channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) { + if (c == conn->vgcs_call.talker) + continue; + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL); + } + break; + case VGCS_EV_LISTENER_DET: + LOG_CALL(conn, LOGL_DEBUG, "Listener detected.\n"); + // Listener detection not supported. + break; + case VGCS_EV_MSC_SEIZE: + LOG_CALL(conn, LOGL_DEBUG, "MSC seizes all channels.\n"); + /* MSC seizes call (talker on a different BSS), call becomes blocked. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BLOCKED, 0, 0); + /* Block all channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL); + break; + case VGCS_EV_MSC_RELEASE: + /* Ignore, because there is no blocked channel in this state. */ + break; + case VGCS_EV_MSC_REJECT: + LOG_CALL(conn, LOGL_DEBUG, "MSC rejects talker on uplink.\n"); + /* Race condition: Talker released before the MSC rejects the talker. Ignore! */ + break; + case VGCS_EV_CLEANUP: + LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +/* Get L3 info from message, if exists. Return the length or otherwise return 0. */ +int l3_data_from_msg(struct msgb *msg, uint8_t **l3_info) +{ + struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); + + /* No space for L3 info */ + if (msgb_l2len(msg) < sizeof(*rllh) + 3 || rllh->data0 != RSL_IE_L3_INFO) + return 0; + + *l3_info = msg->l3h = &rllh->data3; + return msgb_l3len(msg); +} + +static void vgcs_call_fsm_busy(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv, *c; + struct msgb *msg = data; + uint8_t cause = (data) ? *(uint8_t *)data : 0; + uint8_t *l3_info; + int l3_len; + int rc; + + switch (event) { + case VGCS_EV_TALKER_EST: + LOG_CALL(conn, LOGL_DEBUG, "Talker established uplink.\n"); + /* Talker established L2 connection. Sent L3 info to MSC, if MSC already acked, otherwise enqueue. */ + if (conn->vgcs_call.msc_ack) { + LOG_CALL(conn, LOGL_DEBUG, "Sending establishment messages to MSC.\n"); + l3_len = l3_data_from_msg(msg, &l3_info); + if (conn->vgcs_call.talker) + bsc_tx_uplink_req_conf(conn, &conn->vgcs_call.talker->vgcs_chan.ci, l3_info, l3_len); + else + LOG_CALL(conn, LOGL_ERROR, "Talker establishes, but talker not set, please fix!\n"); + } else { + LOG_CALL(conn, LOGL_DEBUG, "No uplink request ack from MSC yet, queue message.\n"); + msg = msgb_copy(msg, "Queued Talker establishment"); + if (msg) + msgb_enqueue(&conn->vgcs_call.l3_queue, msg); + } + break; + case VGCS_EV_TALKER_DATA: + LOG_CALL(conn, LOGL_DEBUG, "Talker sent data on uplink.\n"); + /* Talker sends data. Sent L3 info to MSC, if MSC already acked, otherwise enqueue. */ + if (conn->vgcs_call.msc_ack) { + LOG_CALL(conn, LOGL_DEBUG, "Sending data messages to MSC.\n"); + bsc_dtap(conn, 0, msg); + } else { + LOG_CALL(conn, LOGL_DEBUG, "No uplink request ack from MSC yet, queue message.\n"); + msg = msgb_copy(msg, "Queued DTAP"); + if (msg) + msgb_enqueue(&conn->vgcs_call.l3_queue, msg); + } + break; + case VGCS_EV_MSC_DTAP: + LOG_CALL(conn, LOGL_DEBUG, "MSC sends DTAP message to talker.\n"); + if (!conn->vgcs_call.talker) + msgb_free(data); + rc = osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_MSC_DTAP, data); + if (rc < 0) + msgb_free(data); + break; + case VGCS_EV_TALKER_REL: + LOG_CALL(conn, LOGL_DEBUG, "Talker released on uplink.\n"); + if (!conn->vgcs_call.msc_ack) { + LOG_CALL(conn, LOGL_DEBUG, "Talker released before MSC acknowleded or rejected.\n"); + conn->vgcs_call.talker_rel = true; + conn->vgcs_call.talker_cause = cause; + break; + } +talker_released: + /* Talker released channel, call becomes idle. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0); + conn->vgcs_call.talker = NULL; + /* Report free uplink to the MSC. */ + bsc_tx_uplink_release_ind(conn, cause); + /* Unblock all other channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) { + if (c == conn->vgcs_call.talker) + continue; + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL); + } + break; + case VGCS_EV_MSC_SEIZE: + LOG_CALL(conn, LOGL_DEBUG, "MSC seizes all channels. (channels are blocked)\n"); + /* Race condition: MSC seizes call (talker on a different BSS), call becomes blocked. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BLOCKED, 0, 0); + /* Reject talker. (Forward to chan FSM.) */ + if (conn->vgcs_call.talker) { + osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_REJECT, NULL); + conn->vgcs_call.talker = NULL; + } + /* Block all channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_BLOCK, NULL); + break; + case VGCS_EV_MSC_ACK: + LOG_CALL(conn, LOGL_DEBUG, "MSC acks talker on uplink.\n"); + /* MSC acknowledges uplink. Send L3 info to MSC, if talker already established. */ + conn->vgcs_call.msc_ack = true; + /* Send establish message via UPLINK REQUEST CONFIRM, if already received. */ + msg = msgb_dequeue(&conn->vgcs_call.l3_queue); + if (msg) { + LOG_CALL(conn, LOGL_DEBUG, "Sending queued establishment messages to MSC.\n"); + l3_len = l3_data_from_msg(msg, &l3_info); + if (conn->vgcs_call.talker) + bsc_tx_uplink_req_conf(conn, &conn->vgcs_call.talker->vgcs_chan.ci, l3_info, l3_len); + else + LOG_CALL(conn, LOGL_ERROR, "MSC acks taker, but talker not set, please fix!\n"); + msgb_free(msg); + } + /* Send data messages via UPLINK APPLICATION DATA, if already received. */ + while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue))) { + LOG_CALL(conn, LOGL_DEBUG, "Sending queued DTAP messages to MSC.\n"); + bsc_dtap(conn, 0, msg); + msgb_free(msg); + } + /* If there is a pending talker release. */ + if (conn->vgcs_call.talker_rel) { + LOG_CALL(conn, LOGL_DEBUG, "Sending queued talker release messages to MSC.\n"); + cause = conn->vgcs_call.talker_cause; + goto talker_released; + } + break; + case VGCS_EV_MSC_REJECT: + LOG_CALL(conn, LOGL_DEBUG, "MSC rejects talker on uplink.\n"); + /* MSC rejects talker, call becomes idle. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0); + /* Reject talker. (Forward to chan FSM.) */ + if (conn->vgcs_call.talker) + osmo_fsm_inst_dispatch(conn->vgcs_call.talker->vgcs_chan.fi, VGCS_EV_REJECT, NULL); + else + LOG_CALL(conn, LOGL_ERROR, "MSC rejects, but talker not set, please fix!\n"); + conn->vgcs_call.talker = NULL; + /* Unblock all other channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) { + if (c == conn->vgcs_call.talker) + continue; + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL); + } + break; + case VGCS_EV_CLEANUP: + LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_call_fsm_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv, *c; + struct msgb *msg; + + switch (event) { + case VGCS_EV_CALLING_ASSIGNED: + LOG_CALL(conn, LOGL_DEBUG, "Calling subscriber assigned and now on uplink.\n"); + /* Talker detected on a channel, call becomes busy. */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_BUSY, 0, 0); + conn->vgcs_call.talker = data; + /* Reset pending states, but imply that MSC acked this uplink session. */ + while ((msg = msgb_dequeue(&conn->vgcs_call.l3_queue))) + msgb_free(msg); + conn->vgcs_call.msc_ack = true; + break; + case VGCS_EV_TALKER_REL: + LOG_CALL(conn, LOGL_DEBUG, "Talker released on uplink.\n"); + /* Talker release was complete. Ignore. */ + break; + case VGCS_EV_MSC_RELEASE: + LOG_CALL(conn, LOGL_DEBUG, "MSC releases all channels. (channels are free)\n"); + /* MSC releases call (no mor talker on a different BSS), call becomes idle */ + osmo_fsm_inst_state_chg(fi, VGCS_CALL_ST_IDLE, 0, 0); + /* Unblock all channels. */ + llist_for_each_entry(c, &conn->vgcs_call.chan_list, vgcs_chan.list) + osmo_fsm_inst_dispatch(c->vgcs_chan.fi, VGCS_EV_UNBLOCK, NULL); + break; + case VGCS_EV_CLEANUP: + LOG_CALL(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + osmo_fsm_inst_term(conn->vgcs_call.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_call_fsm_states = { + VGCS_CALL_ST_NULL = { + .name = "NULL", + .in_event_mask = S(VGCS_EV_SETUP), + .out_state_mask = S(VGCS_CALL_ST_IDLE), + .action = vgcs_call_fsm_null, + }, + VGCS_CALL_ST_IDLE = { + .name = "IDLE", + .in_event_mask = S(VGCS_EV_TALKER_DET) | + S(VGCS_EV_MSC_SEIZE) | + S(VGCS_EV_MSC_RELEASE) | + S(VGCS_EV_MSC_REJECT) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CALL_ST_BUSY) | + S(VGCS_CALL_ST_BLOCKED) | + S(VGCS_CALL_ST_NULL), + .action = vgcs_call_fsm_idle, + }, + VGCS_CALL_ST_BUSY = { + .name = "BUSY", + .in_event_mask = S(VGCS_EV_TALKER_EST) | + S(VGCS_EV_TALKER_DATA) | + S(VGCS_EV_MSC_DTAP) | + S(VGCS_EV_TALKER_REL) | + S(VGCS_EV_MSC_SEIZE) | + S(VGCS_EV_MSC_ACK) | + S(VGCS_EV_MSC_REJECT) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CALL_ST_IDLE) | + S(VGCS_CALL_ST_BLOCKED) | + S(VGCS_CALL_ST_NULL), + .action = vgcs_call_fsm_busy, + }, + VGCS_CALL_ST_BLOCKED = { + .name = "BLOCKED", + .in_event_mask = S(VGCS_EV_CALLING_ASSIGNED) | + S(VGCS_EV_TALKER_REL) | + S(VGCS_EV_MSC_RELEASE) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CALL_ST_IDLE) | + S(VGCS_CALL_ST_BUSY) | + S(VGCS_CALL_ST_NULL), + .action = vgcs_call_fsm_blocked, + }, +}; + +static struct osmo_fsm vgcs_call_fsm = { + .name = "vgcs_call", + .states = vgcs_call_fsm_states, + .num_states = ARRAY_SIZE(vgcs_call_fsm_states), + .log_subsys = DASCI, + .event_names = vgcs_fsm_event_names, + .cleanup = vgcs_call_detach_and_destroy, +}; + +/* Handle VGCS/VBS SETUP message. + * + * See 3GPP TS 48.008 §3.2.1.50 + */ +int vgcs_vbs_call_start(struct gsm_subscriber_connection *conn, struct msgb *msg) +{ + int payload_length = msg->tail - msg->l4h; + struct tlv_parsed tp; + struct gsm_subscriber_connection *c; + struct gsm0808_group_callref *gc = &conn->vgcs_call.gc_ie; + int rc; + uint8_t cause; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, payload_length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS; + goto reject; + } + + /* Check for mandatory Group Call Reference. */ + if (!TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) { + LOGPFSML(conn->fi, LOGL_ERROR, "Mandatory group call reference not present.\n"); + cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + goto reject; + } + + /* Decode Group Call Reference. */ + rc = gsm0808_dec_group_callref(gc, TLVP_VAL(&tp, GSM0808_IE_GROUP_CALL_REFERENCE), + TLVP_LEN(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "Unable to decode group call reference.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + conn->vgcs_call.sf = gc->sf; + conn->vgcs_call.call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo; + + /* Check for duplicated callref. */ + llist_for_each_entry(c, &conn->network->subscr_conns, entry) { + if (!c->vgcs_call.fi) + continue; + if (c == conn) + continue; + if (conn->vgcs_call.sf == c->vgcs_call.sf + && conn->vgcs_call.call_ref == c->vgcs_call.call_ref) { + LOG_CALL(conn, LOGL_ERROR, "A %s call with callref %s already exists.\n", + (conn->vgcs_call.sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS", + gsm44068_group_id_string(conn->vgcs_call.call_ref)); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + } + + /* Decode VGCS Feature Flags */ + if (TLVP_PRESENT(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS)) { + rc = gsm0808_dec_vgcs_feature_flags(&conn->vgcs_call.ff, + TLVP_VAL(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS), + TLVP_LEN(&tp, GSM0808_IE_VGCS_FEATURE_FLAGS)); + if (rc < 0) { + LOG_CALL(conn, LOGL_ERROR, "Unable to decode feature flags.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + conn->vgcs_call.ff_present = true; + } + + /* Create VGCS FSM. */ + conn->vgcs_call.fi = osmo_fsm_inst_alloc(&vgcs_call_fsm, conn->network, conn, LOGL_DEBUG, NULL); + if (!conn->vgcs_call.fi) { + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + + /* Init list of cells that are used by the call. */ + INIT_LLIST_HEAD(&conn->vgcs_call.chan_list); + + /* Init L3 queue. */ + INIT_LLIST_HEAD(&conn->vgcs_call.l3_queue); + + osmo_fsm_inst_dispatch(conn->vgcs_call.fi, VGCS_EV_SETUP, NULL); + return 0; +reject: + bsc_tx_setup_refuse(conn, cause); + return -EINVAL; +} + +/* + * VGCS chan FSM + */ + +static void vgcs_chan_detach_and_destroy(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause) +{ + struct gsm_subscriber_connection *conn = fi->priv; + + if (conn->vgcs_chan.fi->state != VGCS_CHAN_ST_WAIT_EST) { + /* Remove call from notification channel. */ + if (conn->lchan) + rsl_notification_cmd(conn->lchan->ts->trx->bts, NULL, &conn->vgcs_chan.gc_ie, NULL); + else + LOG_CHAN(conn, LOGL_ERROR, "Unable to remove notification, lchan is already gone.\n"); + } + + /* Detach from call, if not already. */ + if (conn->vgcs_chan.call) { + llist_del(&conn->vgcs_chan.list); + conn->vgcs_chan.call = NULL; + } + + /* Remove pointer of FSM. */ + conn->vgcs_chan.fi = NULL; +} + +static void uplink_released(struct gsm_subscriber_connection *conn) +{ + LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n"); + /* Go into blocked or free state. */ + if (conn->vgcs_chan.call && conn->vgcs_chan.call->vgcs_call.fi + && conn->vgcs_chan.call->vgcs_call.fi->state == VGCS_CALL_ST_IDLE) + osmo_fsm_inst_state_chg(conn->vgcs_chan.fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + else + osmo_fsm_inst_state_chg(conn->vgcs_chan.fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0); +} + +static void vgcs_chan_fsm_null(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + struct lchan_activate_info info; + + switch (event) { + case VGCS_EV_ASSIGN_REQ: + LOG_CHAN(conn, LOGL_DEBUG, "MSC assigns channel.\n"); + /* MSC requests channel assignment. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_WAIT_EST, 0, 0); + /* Requesting channel from BTS. */ + info = (struct lchan_activate_info){ + .activ_for = ACTIVATE_FOR_VGCS_CHANNEL, + .for_conn = conn, + .chreq_reason = GSM_CHREQ_REASON_OTHER, + .ch_mode_rate = conn->vgcs_chan.ch_mode_rate, + .ch_indctr = conn->vgcs_chan.ct.ch_indctr, + /* TSC is used from TS config. */ + .encr = conn->vgcs_chan.new_lchan->encr, + /* Timing advance of 0 is used until channel is activated for uplink. */ + .ta_known = true, + .ta = 0, + }; + if (conn->vgcs_chan.call->vgcs_call.sf == GSM0808_SF_VGCS) + info.type_for = LCHAN_TYPE_FOR_VGCS; + else + info.type_for = LCHAN_TYPE_FOR_VBS; + /* Activate lchan. If an error occurs, this the function call may trigger VGCS_EV_LCHAN_ERROR event. + * This means that this must be the last action in this handler. */ + lchan_activate(conn->vgcs_chan.new_lchan, &info); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_wait_est(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + const struct mgcp_conn_peer *mgw_info; + + switch (event) { + case VGCS_EV_LCHAN_ACTIVE: + LOG_CHAN(conn, LOGL_DEBUG, "lchan is active.\n"); + /* If no MGW is used. */ + if (!gscon_is_aoip(conn)) { + LOG_CHAN(conn, LOGL_DEBUG, "Not connecting MGW endpoint, no AoIP connection.\n"); + goto no_aoip; + } + /* Send activation to MGW. */ + LOG_CHAN(conn, LOGL_DEBUG, "Connecting MGW endpoint to the MSC's RTP port: %s:%u\n", + conn->vgcs_chan.msc_rtp_addr, conn->vgcs_chan.msc_rtp_port); + /* Connect MGW. The function call may trigger VGCS_EV_MGW_OK event. + * This means that this must be the last action in this handler. + * If this function fails, VGCS_EV_MGW_FAIL will not trigger. */ + if (!gscon_connect_mgw_to_msc(conn, + conn->vgcs_chan.new_lchan, + conn->vgcs_chan.msc_rtp_addr, + conn->vgcs_chan.msc_rtp_port, + fi, + VGCS_EV_MGW_OK, + VGCS_EV_MGW_FAIL, + NULL, + NULL)) { + /* Report failure to MSC. */ + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + break; + } + break; + case VGCS_EV_LCHAN_ERROR: + LOG_CHAN(conn, LOGL_DEBUG, "lchan failed.\n"); + /* BTS reports failure on channel request. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_NULL, 0, 0); + /* Report failure to MSC. */ + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + break; + case VGCS_EV_MGW_OK: + LOG_CHAN(conn, LOGL_DEBUG, "MGW endpoint connected.\n"); + /* MGW reports success. */ + mgw_info = osmo_mgcpc_ep_ci_get_rtp_info(conn->user_plane.mgw_endpoint_ci_msc); + if (!mgw_info) { + LOG_CHAN(conn, LOGL_ERROR, "Unable to retrieve RTP port info allocated by MGW for" + " the MSC side."); + /* Report failure to MSC. */ + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + break; + } + LOG_CHAN(conn, LOGL_DEBUG, "MGW's MSC side CI: %s:%u\n", mgw_info->addr, mgw_info->port); +no_aoip: + /* Channel established from BTS. */ + gscon_change_primary_lchan(conn, conn->vgcs_chan.new_lchan); + /* Change state according to call state. */ + if (conn->vgcs_chan.call && conn->vgcs_chan.call->vgcs_call.fi + && conn->vgcs_chan.call->vgcs_call.fi->state == VGCS_CALL_ST_IDLE) + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + else + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0); + /* Add call to notification channel. */ + if (conn->vgcs_chan.call) + rsl_notification_cmd(conn->lchan->ts->trx->bts, conn->lchan, &conn->vgcs_chan.gc_ie, NULL); + /* Report result to MSC. */ + bsc_tx_vgcs_vbs_assignment_result(conn, &conn->vgcs_chan.ct, &conn->vgcs_chan.ci, + conn->vgcs_chan.call_id); + break; + case VGCS_EV_MGW_FAIL: + LOG_CHAN(conn, LOGL_DEBUG, "MGW endpoint failed.\n"); + /* MGW reports failure. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_NULL, 0, 0); + /* Report failure to MSC. */ + bsc_tx_vgcs_vbs_assignment_fail(conn, GSM0808_CAUSE_EQUIPMENT_FAILURE); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + case VGCS_EV_BLOCK: + case VGCS_EV_UNBLOCK: + /* Ignore, because channel is not yet ready. */ + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_active_blocked(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv, *cc; + + switch (event) { + case VGCS_EV_UNBLOCK: + LOG_CHAN(conn, LOGL_DEBUG, "Unblocking channel.\n"); + /* No uplink is used in other cell. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + break; + case VGCS_EV_TALKER_DET: + LOG_CHAN(conn, LOGL_DEBUG, "Talker detected on blocked channel.\n"); + if (conn->vgcs_chan.call->vgcs_call.sf == GSM0808_SF_VBS) + LOG_CHAN(conn, LOGL_ERROR, "Talker detection not allowed on VBS channel.\n"); + /* Race condition: BTS detected a talker. Waiting for talker to establish or fail. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0); + break; + case VGCS_EV_TALKER_EST: + cc = find_calling_subscr_conn(conn); + if (!cc) { + LOG_CHAN(conn, LOGL_ERROR, "No assignment requested from MSC!\n"); + /* Uplink is used while blocked. Waiting for channel to be release. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0); + /* Send UPLINK RELEASE to MS. */ + gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL); + /* Go into blocked or free state. */ + uplink_released(conn); + break; + } + /* Talker is assigning to this channel. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_EST, 0, 0); + /* Report talker detection to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_CALLING_ASSIGNED, conn); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_enter_active_free(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_subscriber_connection *conn = fi->priv; + + /* Send UPLINK FREE message to BTS. This hits on every state change (and or timer start). */ + LOG_CHAN(conn, LOGL_DEBUG, "Sending UPLINK FREE message to channel.\n"); + gsm48_send_uplink_free(conn->lchan, 0, NULL); +} + +static void vgcs_chan_fsm_active_free(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + + switch (event) { + case VGCS_EV_BLOCK: + LOG_CHAN(conn, LOGL_DEBUG, "Blocking channel.\n"); + /* Uplink is used in other cell. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_BLOCKED, 0, 0); + /* Send UPLINK BUSY to MS. */ + LOG_CHAN(conn, LOGL_DEBUG, "Sending UPLINK BUSY message to channel.\n"); + gsm48_send_uplink_busy(conn->lchan); + break; + case VGCS_EV_TALKER_DET: + LOG_CHAN(conn, LOGL_DEBUG, "Talker detected on free channel.\n"); + /* BTS detected a talker. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_INIT, 0, 0); + /* Report talker detection to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_DET, data); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_active_init(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + uint8_t cause = (data) ? *(uint8_t *)data : 0; + + switch (event) { + case VGCS_EV_BLOCK: + case VGCS_EV_REJECT: + LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n"); + /* Uplink is used in other cell. Waiting for channel to be established and then released. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0); + break; + case VGCS_EV_TALKER_EST: + LOG_CHAN(conn, LOGL_DEBUG, "Talker established uplink.\n"); + /* Uplink has been established */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_EST, 0, 0); + /* Report talker establishment to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_EST, data); + break; + case VGCS_EV_TALKER_FAIL: + LOG_CHAN(conn, LOGL_NOTICE, "Uplink failed, establishment timeout.\n"); + /* Release datalink */ + rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END); + /* fall thru */ + case VGCS_EV_TALKER_REL: + LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n"); + /* Uplink establishment failed. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + /* Report release indication to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL, &cause); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_active_est(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + uint8_t cause = (data) ? *(uint8_t *)data : 0; + struct msgb *msg = data; + + switch (event) { + case VGCS_EV_BLOCK: + case VGCS_EV_REJECT: + LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n"); + /* Uplink is used in other cell. Waiting for channel to be release. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_REL, 0, 0); + /* Send UPLINK RELEASE to MS. */ + gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL); + /* Go into blocked or free state. */ + uplink_released(conn); + break; + case VGCS_EV_TALKER_DATA: + LOG_CHAN(conn, LOGL_DEBUG, "Talker sends data on uplink.\n"); + if (msg) { + struct gsm48_hdr *gh; + uint8_t pdisc; + uint8_t msg_type; + if (msgb_l3len(msg) < sizeof(*gh)) { + LOG_LCHAN(msg->lchan, LOGL_ERROR, + "Message too short for a GSM48 header (%u)\n", msgb_l3len(msg)); + break; + } + gh = msgb_l3(msg); + pdisc = gsm48_hdr_pdisc(gh); + msg_type = gsm48_hdr_msg_type(gh); + if (pdisc == GSM48_PDISC_RR && msg_type == GSM48_MT_RR_UPLINK_RELEASE) { + LOG_CHAN(conn, LOGL_DEBUG, "Uplink is released by UPLINK RELEASE message.\n"); + /* Release datalink */ + rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END); + /* Talker released the uplink. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + /* Report talker release to call state machine. */ + if (conn->vgcs_chan.call) { + cause = GSM0808_CAUSE_CALL_CONTROL; + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL, + &cause); + } + break; + } + if (pdisc == GSM48_PDISC_RR && msg_type == GSM48_MT_RR_ASS_COMPL) { + LOG_CHAN(conn, LOGL_DEBUG, "Asssignment complete.\n"); + struct gsm_subscriber_connection *cc; + cc = find_calling_subscr_conn(conn); + if (!cc) { + LOG_CHAN(conn, LOGL_ERROR, "No assignment requested from MSC!\n"); + break; + } + LOG_CHAN(conn, LOGL_DEBUG, "Trigger State machine.\n"); + osmo_fsm_inst_dispatch(cc->assignment.fi, ASSIGNMENT_EV_RR_ASSIGNMENT_COMPLETE, msg); + break; + } + } + /* Report talker data to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_DATA, data); + break; + case VGCS_EV_MSC_DTAP: + LOG_CHAN(conn, LOGL_DEBUG, "MSC sends DTAP message to talker.\n"); + osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_MT_DTAP, data); + break; + case VGCS_EV_TALKER_FAIL: + LOG_CHAN(conn, LOGL_NOTICE, "Uplink failed after establishment.\n"); + /* Release datalink */ + rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END); + /* fall thru */ + case VGCS_EV_TALKER_REL: + LOG_CHAN(conn, LOGL_DEBUG, "Uplink is now released.\n"); + /* Talker released the uplink. */ + osmo_fsm_inst_state_chg(fi, VGCS_CHAN_ST_ACTIVE_FREE, 0, 0); + /* Report talker release to call state machine. */ + if (conn->vgcs_chan.call) + osmo_fsm_inst_dispatch(conn->vgcs_chan.call->vgcs_call.fi, VGCS_EV_TALKER_REL, &cause); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static void vgcs_chan_fsm_active_rel(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_subscriber_connection *conn = fi->priv; + + switch (event) { + case VGCS_EV_BLOCK: + case VGCS_EV_REJECT: + LOG_CHAN(conn, LOGL_DEBUG, "Blocking/rejecting channel.\n"); + /* Race condition: Uplink is used in other cell, we are already releasing. */ + break; + case VGCS_EV_TALKER_EST: + LOG_CHAN(conn, LOGL_DEBUG, "Talker established uplink, releasing.\n"); + /* Finally the talker established the connection. Send UPLINK RELEASE to MS. */ + gsm48_send_uplink_release(conn->lchan, GSM48_RR_CAUSE_NORMAL); + /* Release datalink */ + rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END); + /* fall thru */ + case VGCS_EV_TALKER_FAIL: + /* Release datalink */ + rsl_release_request(conn->lchan, 0, RSL_REL_LOCAL_END); + /* fall thru */ + case VGCS_EV_TALKER_REL: + /* Go into blocked or free state. */ + uplink_released(conn); + break; + case VGCS_EV_CLEANUP: + LOG_CHAN(conn, LOGL_DEBUG, "SCCP connection clearing.\n"); + /* MSC wants to terminate. */ + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + break; + default: + OSMO_ASSERT(false); + } +} + +static const struct osmo_fsm_state vgcs_chan_fsm_states = { + VGCS_CHAN_ST_NULL = { + .name = "NULL", + .in_event_mask = S(VGCS_EV_ASSIGN_REQ), + .out_state_mask = S(VGCS_CHAN_ST_WAIT_EST), + .action = vgcs_chan_fsm_null, + }, + VGCS_CHAN_ST_WAIT_EST = { + .name = "WAIT_EST", + .in_event_mask = S(VGCS_EV_LCHAN_ACTIVE) | + S(VGCS_EV_LCHAN_ERROR) | + S(VGCS_EV_MGW_OK) | + S(VGCS_EV_MGW_FAIL) | + S(VGCS_EV_CLEANUP) | + S(VGCS_EV_BLOCK) | + S(VGCS_EV_UNBLOCK), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_BLOCKED) | + S(VGCS_CHAN_ST_ACTIVE_FREE), + .action = vgcs_chan_fsm_wait_est, + }, + VGCS_CHAN_ST_ACTIVE_BLOCKED = { + .name = "ACTIVE/BLOCKED", + .in_event_mask = S(VGCS_EV_UNBLOCK) | + S(VGCS_EV_TALKER_DET) | + S(VGCS_EV_TALKER_EST) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_EST) | + S(VGCS_CHAN_ST_ACTIVE_FREE) | + S(VGCS_CHAN_ST_ACTIVE_REL), + .action = vgcs_chan_fsm_active_blocked, + }, + VGCS_CHAN_ST_ACTIVE_FREE = { + .name = "ACTIVE/FREE", + .in_event_mask = S(VGCS_EV_BLOCK) | + S(VGCS_EV_TALKER_DET) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_BLOCKED) | + S(VGCS_CHAN_ST_ACTIVE_INIT) | + S(VGCS_CHAN_ST_ACTIVE_FREE), + .action = vgcs_chan_fsm_active_free, + .onenter = vgcs_chan_fsm_enter_active_free, + }, + VGCS_CHAN_ST_ACTIVE_INIT = { + .name = "ACTIVE/INIT", + .in_event_mask = S(VGCS_EV_BLOCK) | + S(VGCS_EV_REJECT) | + S(VGCS_EV_TALKER_EST) | + S(VGCS_EV_TALKER_FAIL) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_EST) | + S(VGCS_CHAN_ST_ACTIVE_REL) | + S(VGCS_CHAN_ST_ACTIVE_FREE), + .action = vgcs_chan_fsm_active_init, + }, + VGCS_CHAN_ST_ACTIVE_EST = { + .name = "ACTIVE/ESTABLISHED", + .in_event_mask = S(VGCS_EV_BLOCK) | + S(VGCS_EV_REJECT) | + S(VGCS_EV_TALKER_DATA) | + S(VGCS_EV_MSC_DTAP) | + S(VGCS_EV_TALKER_REL) | + S(VGCS_EV_TALKER_FAIL) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_FREE) | + S(VGCS_CHAN_ST_ACTIVE_REL), + .action = vgcs_chan_fsm_active_est, + }, + VGCS_CHAN_ST_ACTIVE_REL = { + .name = "ACTIVE/RELEASE", + .in_event_mask = S(VGCS_EV_BLOCK) | + S(VGCS_EV_REJECT) | + S(VGCS_EV_TALKER_EST) | + S(VGCS_EV_TALKER_REL) | + S(VGCS_EV_TALKER_FAIL) | + S(VGCS_EV_CLEANUP), + .out_state_mask = S(VGCS_CHAN_ST_NULL) | + S(VGCS_CHAN_ST_ACTIVE_BLOCKED) | + S(VGCS_CHAN_ST_ACTIVE_FREE), + .action = vgcs_chan_fsm_active_rel, + }, +}; + +static struct osmo_fsm vgcs_chan_fsm = { + .name = "vgcs_chan", + .states = vgcs_chan_fsm_states, + .num_states = ARRAY_SIZE(vgcs_chan_fsm_states), + .log_subsys = DASCI, + .event_names = vgcs_fsm_event_names, + .cleanup = vgcs_chan_detach_and_destroy, +}; + +/* Handle VGCS/VBS ASSIGNMENT REQUEST message. + * + * See 3GPP TS 48.008 §3.2.1.53 + */ +int vgcs_vbs_chan_start(struct gsm_subscriber_connection *conn, struct msgb *msg) +{ + int payload_length = msg->tail - msg->l4h; + struct tlv_parsed tp; + struct gsm_subscriber_connection *c; + struct gsm0808_group_callref *gc = &conn->vgcs_chan.gc_ie; + struct assignment_request req = { + .aoip = gscon_is_aoip(conn), + }; + uint8_t cause; + struct gsm_bts *bts; + struct gsm_lchan *lchan = NULL; + int rc; + int i; + + if (osmo_bssap_tlv_parse(&tp, msg->l4h + 1, payload_length - 1) < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "%s(): tlv_parse() failed\n", __func__); + cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS; + goto reject; + } + + /* Check for mandatory IEs. */ + if (!TLVP_PRESENT(&tp, GSM0808_IE_CHANNEL_TYPE) + || !TLVP_PRESENT(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT) + || !TLVP_PRESENT(&tp, GSM0808_IE_CELL_IDENTIFIER) + || !TLVP_PRESENT(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)) { + LOGPFSML(conn->fi, LOGL_ERROR, "Mandatory IE not present.\n"); + cause = GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING; + goto reject; + } + + /* Decode Channel Type element. */ + rc = gsm0808_dec_channel_type(&conn->vgcs_chan.ct, TLVP_VAL(&tp, GSM0808_IE_CHANNEL_TYPE), + TLVP_LEN(&tp, GSM0808_IE_CHANNEL_TYPE)); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "Unable to decode Channel Type.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + + /* Only speech is supported. */ + if (conn->vgcs_chan.ct.ch_indctr != GSM0808_CHAN_SPEECH) { + cause = GSM0808_CAUSE_INVALID_MESSAGE_CONTENTS; + goto reject; + } + + /* Decode Assignment Requirement element. */ + rc = gsm0808_dec_assign_req(&conn->vgcs_chan.ar, TLVP_VAL(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT), + TLVP_LEN(&tp, GSM0808_IE_ASSIGNMENT_REQUIREMENT)); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "Unable to decode Assignment Requirement.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + + /* Decode Cell Identifier element. */ + rc = gsm0808_dec_cell_id(&conn->vgcs_chan.ci, TLVP_VAL(&tp, GSM0808_IE_CELL_IDENTIFIER), + TLVP_LEN(&tp, GSM0808_IE_CELL_IDENTIFIER)); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "Unable to decode Cell Identifier.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + gsm0808_cell_id_u_name(conn->vgcs_chan.ci_str, sizeof(conn->vgcs_chan.ci_str), conn->vgcs_chan.ci.id_discr, + &conn->vgcs_chan.ci.id); + + /* Decode Group Call Reference element. */ + rc = gsm0808_dec_group_callref(gc, TLVP_VAL(&tp, GSM0808_IE_GROUP_CALL_REFERENCE), + TLVP_LEN(&tp, GSM0808_IE_GROUP_CALL_REFERENCE)); + if (rc < 0) { + LOGPFSML(conn->fi, LOGL_ERROR, "Unable to decode Group Call Reference.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + conn->vgcs_chan.sf = gc->sf; + conn->vgcs_chan.call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo; + + /* Find BTS from Cell Identity. */ + bts = gsm_bts_by_cell_id(conn->network, &conn->vgcs_chan.ci, 0); + if (!bts) { + LOG_CHAN(conn, LOGL_ERROR, "No cell found that matches the given Cell Identifier.\n"); + cause = GSM0808_CAUSE_RQSTED_TERRESTRIAL_RESOURCE_UNAVAILABLE; + goto reject; + } + + /* If Cell Identity is ambiguous. */ + if (gsm_bts_by_cell_id(conn->network, &conn->vgcs_chan.ci, 1)) + LOG_CHAN(conn, LOGL_NOTICE, "More thant one cell found that match the given Cell Identifier.\n"); + + /* Decode channel related elements. + * This must be done after selecting the BTS, because codec selection requires relation to BTS. */ + rc = bssmap_handle_ass_req_ct_speech(conn, bts, &tp, &conn->vgcs_chan.ct, &req, &cause); + if (rc < 0) + goto reject; + + /* Store AoIP elements. */ + osmo_strlcpy(conn->vgcs_chan.msc_rtp_addr, req.msc_rtp_addr, sizeof(conn->vgcs_chan.msc_rtp_addr)); + conn->vgcs_chan.msc_rtp_port = req.msc_rtp_port; + if (TLVP_PRESENT(&tp, GSM0808_IE_CALL_ID)) { + /* Decode Call Identifier element. */ + rc = gsm0808_dec_call_id(&conn->vgcs_chan.call_id, TLVP_VAL(&tp, GSM0808_IE_CALL_ID), + TLVP_LEN(&tp, GSM0808_IE_CALL_ID)); + if (rc < 0) { + LOG_CHAN(conn, LOGL_ERROR, "Unable to decode Call Identifier.\n"); + cause = GSM0808_CAUSE_INCORRECT_VALUE; + goto reject; + } + } + + /* Try to allocate a new lchan in order of preference. */ + for (i = 0; i < req.n_ch_mode_rate; i++) { + lchan = lchan_select_by_chan_mode(bts, + req.ch_mode_rate_listi.chan_mode, + req.ch_mode_rate_listi.chan_rate, + SELECT_FOR_VGCS, NULL); + if (!lchan) + continue; + LOG_CHAN(conn, LOGL_DEBUG, "Selected new lchan %s for mode%d = %s channel_rate=%d\n", + gsm_lchan_name(lchan), i, gsm48_chan_mode_name(req.ch_mode_rate_listi.chan_mode), + req.ch_mode_rate_listi.chan_rate); + + conn->vgcs_chan.ch_mode_rate = req.ch_mode_rate_listi; + break; + } + if (!lchan) { + LOG_CHAN(conn, LOGL_ERROR, "Requested lchan not available.\n"); + cause = GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE; + goto reject; + } + conn->vgcs_chan.new_lchan = lchan; + + /* Create VGCS FSM. */ + conn->vgcs_chan.fi = osmo_fsm_inst_alloc(&vgcs_chan_fsm, conn->network, conn, LOGL_DEBUG, NULL); + if (!conn->vgcs_chan.fi) + goto reject; + + /* Attach to call control instance, if a call with same callref exists. */ + llist_for_each_entry(c, &conn->network->subscr_conns, entry) { + if (!c->vgcs_call.fi) + continue; + if (c->vgcs_call.sf == conn->vgcs_chan.sf + && c->vgcs_call.call_ref == conn->vgcs_chan.call_ref) { + llist_add_tail(&conn->vgcs_chan.list, &c->vgcs_call.chan_list); + conn->vgcs_chan.call = c; + break; + } + } + if (!conn->vgcs_chan.call) { + LOG_CHAN(conn, LOGL_ERROR, "A %s call with callref %s does not exist.\n", + (conn->vgcs_chan.sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS", + gsm44068_group_id_string(conn->vgcs_chan.call_ref)); + cause = GSM0808_CAUSE_VGCS_VBS_CALL_NON_EXISTENT; + osmo_fsm_inst_term(conn->vgcs_chan.fi, 0, NULL); + goto reject; + } + + osmo_fsm_inst_dispatch(conn->vgcs_chan.fi, VGCS_EV_ASSIGN_REQ, NULL); + return 0; +reject: + bsc_tx_vgcs_vbs_assignment_fail(conn, cause); + return -EINVAL; +} + +/* Return lchan of group call that exists in the same BTS. */ +struct gsm_lchan *vgcs_vbs_find_lchan(struct gsm_bts *bts, struct gsm0808_group_callref *gc) +{ + struct gsm_subscriber_connection *call = NULL, *c; + struct gsm_lchan *lchan = NULL; + uint32_t call_ref = (osmo_load32be_ext_2(gc->call_ref_hi, 3) << 3) | gc->call_ref_lo; + + /* Find group call. */ + llist_for_each_entry(c, &bts->network->subscr_conns, entry) { + if (!c->vgcs_call.fi) + continue; + if (c->vgcs_call.sf == gc->sf + && c->vgcs_call.call_ref == call_ref) { + call = c; + break; + } + } + if (!call) { + LOGP(DASCI, LOGL_ERROR, "Cannot assign to channel, %s channel with callref %s does not exist.\n", + (gc->sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS", gsm44068_group_id_string(call_ref)); + return NULL; + } + + /* Find channel in same BTS. */ + llist_for_each_entry(c, &call->vgcs_call.chan_list, vgcs_chan.list) { + if (c->lchan && c->lchan->ts->trx->bts == bts) + lchan = c->lchan; + } + if (!call) { + LOGP(DASCI, LOGL_ERROR, "Cannot assign to channel, caller's BTS has no %s channel with callref %s.\n", + (gc->sf == GSM0808_SF_VGCS) ? "VGCS" : "VBS", gsm44068_group_id_string(call_ref)); + return NULL; + } + + return lchan; +}
View file
osmo-bsc_1.10.0.tar.xz/src/utils/Makefile.am -> osmo-bsc_1.11.0.tar.xz/src/utils/Makefile.am
Changed
@@ -28,17 +28,17 @@ isdnsync \ meas_json \ $(NULL) -if HAVE_SQLITE3 +if BUILD_MEAS_UDP2DB bin_PROGRAMS += \ osmo-meas-udp2db \ $(NULL) -if HAVE_PCAP +endif +if BUILD_MEAS_PCAP2DB bin_PROGRAMS += \ osmo-meas-pcap2db \ $(NULL) endif -endif -if HAVE_LIBCDK +if BUILD_MEAS_VIS bin_PROGRAMS += \ meas_vis \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/src/utils/meas_db.c -> osmo-bsc_1.11.0.tar.xz/src/utils/meas_db.c
Changed
@@ -29,10 +29,11 @@ #include <osmocom/core/utils.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/bsc/meas_rep.h> +#include <osmocom/bsc/meas_feed.h> #include "meas_db.h" -#define INS_MR "INSERT INTO meas_rep (time, imsi, name, scenario, nr, bs_power, ms_timing_offset, fpc, ms_l1_pwr, ms_l1_ta) VALUES (?,?,?,?,?,?,?,?,?,?)" +#define INS_MR "INSERT INTO meas_rep (time, bts_nr, trx_nr, ts_nr, ss_nr, lchan_type, pchan_type, imsi, name, scenario, nr, bs_power, ms_timing_offset, fpc, ms_l1_pwr, ms_l1_ta) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" #define INS_UD "INSERT INTO meas_rep_unidir (meas_id, rx_lev_full, rx_lev_sub, rx_qual_full, rx_qual_sub, dtx, uplink) VALUES (?,?,?,?,?,?,?)" #define UPD_MR "UPDATE meas_rep SET ul_unidir=?, dl_unidir=? WHERE id=?" @@ -79,52 +80,57 @@ } /* insert a measurement report into the database */ -int meas_db_insert(struct meas_db_state *st, const char *imsi, - const char *name, unsigned long timestamp, - const char *scenario, - const struct gsm_meas_rep *mr) +int meas_db_insert(struct meas_db_state *st, unsigned long timestamp, + const struct meas_feed_meas *mfm) { sqlite3_int64 rowid, ul_rowid, dl_rowid; SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 1, timestamp)); - if (imsi) - SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 2, - imsi, -1, SQLITE_STATIC)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 2, mfm->bts_nr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 3, mfm->trx_nr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 4, mfm->ts_nr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 5, mfm->ss_nr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mfm->lchan_type)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mfm->pchan_type)); + + if (mfm->imsi0 != '\0') + SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 8, + mfm->imsi, -1, SQLITE_STATIC)); else - SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 2)); + SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 8)); - if (name) - SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 3, - name, -1, SQLITE_STATIC)); + if (mfm->name0 != '\0') + SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 9, + mfm->name, -1, SQLITE_STATIC)); else - SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 3)); + SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 9)); - if (scenario) - SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 4, - scenario, -1, SQLITE_STATIC)); + if (mfm->scenario0 != '\0') + SCK_OK(st->db, sqlite3_bind_text(st->stmt_ins_mr, 10, + mfm->scenario, -1, SQLITE_STATIC)); else - SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 4)); + SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 10)); - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 5, mr->nr)); - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 6, mr->bs_power_db / 2)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 11, mfm->mr.nr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 12, mfm->mr.bs_power_db / 2)); - if (mr->flags & MEAS_REP_F_MS_TO) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 7, mr->ms_timing_offset)); + if (mfm->mr.flags & MEAS_REP_F_MS_TO) + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 13, mfm->mr.ms_timing_offset)); else - SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 7)); + SCK_OK(st->db, sqlite3_bind_null(st->stmt_ins_mr, 13)); - if (mr->flags & MEAS_REP_F_FPC) - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 8, 1)); + if (mfm->mr.flags & MEAS_REP_F_FPC) + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 14, 1)); else - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 8, 0)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 14, 0)); - if (mr->flags & MEAS_REP_F_MS_L1) { - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 9, - mr->ms_l1.pwr)); - SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 10, - mr->ms_l1.ta)); + if (mfm->mr.flags & MEAS_REP_F_MS_L1) { + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 15, + mfm->mr.ms_l1.pwr)); + SCK_OK(st->db, sqlite3_bind_int(st->stmt_ins_mr, 16, + mfm->mr.ms_l1.ta)); } SCK_DONE(st->db, sqlite3_step(st->stmt_ins_mr)); @@ -133,14 +139,14 @@ rowid = sqlite3_last_insert_rowid(st->db); /* insert uplink measurement */ - ul_rowid = _insert_ud(st, rowid, mr->flags & MEAS_REP_F_UL_DTX, - 1, &mr->ul); + ul_rowid = _insert_ud(st, rowid, mfm->mr.flags & MEAS_REP_F_UL_DTX, + 1, &mfm->mr.ul); SCK_OK(st->db, sqlite3_bind_int(st->stmt_upd_mr, 1, ul_rowid)); /* insert downlink measurement, if present */ - if (mr->flags & MEAS_REP_F_DL_VALID) { - dl_rowid = _insert_ud(st, rowid, mr->flags & MEAS_REP_F_DL_DTX, - 0, &mr->dl); + if (mfm->mr.flags & MEAS_REP_F_DL_VALID) { + dl_rowid = _insert_ud(st, rowid, mfm->mr.flags & MEAS_REP_F_DL_DTX, + 0, &mfm->mr.dl); SCK_OK(st->db, sqlite3_bind_int(st->stmt_upd_mr, 2, dl_rowid)); } else SCK_OK(st->db, sqlite3_bind_null(st->stmt_upd_mr, 2)); @@ -181,6 +187,12 @@ "CREATE TABLE IF NOT EXISTS meas_rep (" "id INTEGER PRIMARY KEY AUTOINCREMENT," "time TIMESTAMP," + "bts_nr INTEGER," + "trx_nr INTEGER," + "ts_nr INTEGER," + "ss_nr INTEGER," + "lchan_type INTEGER," + "pchan_type INTEGER," "imsi TEXT," "name TEXT," "scenario TEXT," @@ -207,6 +219,12 @@ "SELECT " "meas_rep.id, " "datetime(time,'unixepoch') AS timestamp, " + "bts_nr," + "trx_nr," + "ts_nr," + "ss_nr," + "lchan_type," + "pchan_type," "imsi, " "name, " "scenario, " @@ -238,6 +256,12 @@ "SELECT " "id," "timestamp," + "bts_nr," + "trx_nr," + "ts_nr," + "ss_nr," + "lchan_type," + "pchan_type," "imsi," "name," "scenario,"
View file
osmo-bsc_1.10.0.tar.xz/src/utils/meas_db.h -> osmo-bsc_1.11.0.tar.xz/src/utils/meas_db.h
Changed
@@ -9,9 +9,7 @@ int meas_db_begin(struct meas_db_state *st); int meas_db_commit(struct meas_db_state *st); -int meas_db_insert(struct meas_db_state *st, const char *imsi, - const char *name, unsigned long timestamp, - const char *scenario, - const struct gsm_meas_rep *mr); +int meas_db_insert(struct meas_db_state *st, unsigned long timestamp, + const struct meas_feed_meas *mfm); #endif
View file
osmo-bsc_1.10.0.tar.xz/src/utils/meas_pcap2db.c -> osmo-bsc_1.11.0.tar.xz/src/utils/meas_pcap2db.c
Changed
@@ -47,15 +47,7 @@ static void handle_mfm(const struct pcap_pkthdr *h, const struct meas_feed_meas *mfm) { - const char *scenario; - - if (strlen(mfm->scenario)) - scenario = mfm->scenario; - else - scenario = NULL; - - meas_db_insert(db, mfm->imsi, mfm->name, h->ts.tv_sec, - scenario, &mfm->mr); + meas_db_insert(db, h->ts.tv_sec, mfm); } static void pcap_cb(u_char *user, const struct pcap_pkthdr *h,
View file
osmo-bsc_1.10.0.tar.xz/src/utils/meas_udp2db.c -> osmo-bsc_1.11.0.tar.xz/src/utils/meas_udp2db.c
Changed
@@ -1,4 +1,4 @@ -/* liesten to meas_feed on UDP and write it to sqlite3 database */ +/* listen to meas_feed on UDP and write it to sqlite3 database */ /* (C) 2012 by Harald Welte <laforge@gnumonks.org> * @@ -47,7 +47,6 @@ { struct meas_feed_hdr *mfh = (struct meas_feed_hdr *) msgb_data(msg); struct meas_feed_meas *mfm = (struct meas_feed_meas *) msgb_data(msg); - const char *scenario; time_t now = time(NULL); if (mfh->version != MEAS_FEED_VERSION) @@ -56,13 +55,7 @@ if (mfh->msg_type != MEAS_FEED_MEAS) return -EINVAL; - if (strlen(mfm->scenario)) - scenario = mfm->scenario; - else - scenario = NULL; - - meas_db_insert(db, mfm->imsi, mfm->name, now, - scenario, &mfm->mr); + meas_db_insert(db, now, mfm); return 0; }
View file
osmo-bsc_1.10.0.tar.xz/tests/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/Makefile.am
Changed
@@ -34,17 +34,7 @@ $(TESTSUITE) \ vty_test_runner.py \ ctrl_test_runner.py \ - cbc.vty \ - gprs_bvci_default.vty \ - handover_cfg.vty \ - neighbor_ident.vty \ - nri_cfg.vty \ - osmo-bsc.vty \ - timer.vty \ - power_ctrl.vty \ - interf_meas.vty \ - acch_overpower.vty \ - bts_features.vty \ + $(srcdir)/*.vty \ ctrl/osmo-bsc-neigh-test.cfg \ ctrl/osmo-bsc-apply-config-file.cfg \ ctrl/osmo-bsc-apply-config-file-invalid.cfg \ @@ -57,14 +47,14 @@ $(NULL) if ENABLE_EXT_TESTS -python-tests: $(BUILT_SOURCES) +python-tests: $(top_builddir)/src/osmo-bsc/osmo-bsc $(MAKE) vty-test osmotestvty.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v osmotestconfig.py -p $(abs_top_srcdir) -w $(abs_top_builddir) -v $(srcdir)/vty_test_runner.py -w $(abs_top_builddir) -v $(srcdir)/ctrl_test_runner.py -w $(abs_top_builddir) -v else -python-tests: $(BUILT_SOURCES) +python-tests: echo "Not running python-based tests (determined at configure-time)" endif @@ -74,7 +64,7 @@ # To update the VTY script from current application behavior, # pass -u to vty_script_runner.py by doing: # make vty-test U=-u -vty-test: +vty-test: $(top_builddir)/src/osmo-bsc/osmo-bsc osmo_verify_transcript_vty.py -v \ -n OsmoBSC -p 4242 \ -r "$(top_builddir)/src/osmo-bsc/osmo-bsc -c $(top_srcdir)/doc/examples/osmo-bsc/osmo-bsc-minimal.cfg" \
View file
osmo-bsc_1.10.0.tar.xz/tests/abis/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/abis/Makefile.am
Changed
@@ -14,6 +14,8 @@ $(COVERAGE_CFLAGS) \ $(NULL) +AM_LDFLAGS = -no-install + EXTRA_DIST = \ abis_test.ok \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/tests/abis/abis_test.c -> osmo-bsc_1.11.0.tar.xz/tests/abis/abis_test.c
Changed
@@ -136,7 +136,7 @@ }, }; -static void test_abis_nm_ipaccess_cgi() +static void test_abis_nm_ipaccess_cgi(void) { int i; bool pass = true;
View file
osmo-bsc_1.10.0.tar.xz/tests/acc/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/acc/Makefile.am
Changed
@@ -14,6 +14,8 @@ $(COVERAGE_CFLAGS) \ $(NULL) +AM_LDFLAGS = -no-install + EXTRA_DIST = \ acc_test.ok \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/tests/bsc/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/bsc/Makefile.am
Changed
@@ -18,6 +18,7 @@ AM_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) EXTRA_DIST = \ @@ -43,3 +44,7 @@ $(LIBRARY_GSM) \ -lrt \ $(NULL) + +.PHONY: update_exp +update_exp: + $(builddir)/bsc_test > $(srcdir)/bsc_test.ok
View file
osmo-bsc_1.10.0.tar.xz/tests/bsc/bsc_test.c -> osmo-bsc_1.11.0.tar.xz/tests/bsc/bsc_test.c
Changed
@@ -29,6 +29,12 @@ #include <osmocom/bsc/osmo_bsc.h> #include <osmocom/bsc/bsc_msc_data.h> +#include <osmocom/bsc/bss.h> +#include <osmocom/bsc/bts.h> +#include <osmocom/bsc/timeslot_fsm.h> +#include <osmocom/bsc/lchan_fsm.h> +#include <osmocom/bsc/assignment_fsm.h> +#include <osmocom/bsc/bsc_subscr_conn_fsm.h> #include <osmocom/gsm/gad.h> #include <osmocom/core/application.h> @@ -180,6 +186,61 @@ bsc_gsmnet = NULL; } +static void test_fsm_ids_with_pchan_names(void) +{ + struct gsm_network *net; + struct gsm_bts *bts; + struct gsm_bts_trx *trx; + struct gsm_bts_trx_ts *ts; + struct gsm_lchan *lchan; + enum gsm_phys_chan_config pchan; + struct gsm_subscriber_connection *conn; + + rate_ctr_init(ctx); + tall_bsc_ctx = ctx; + bsc_network_alloc(); + net = bsc_gsmnet; + + /* Have a BTS so that we have trx, timeslots, lchans that have FSMs to check the id of */ + bts = bsc_bts_alloc_register(net, GSM_BTS_TYPE_UNKNOWN, HARDCODED_BSIC); + trx = gsm_bts_trx_alloc(bts); + + printf("\nTesting FSM ids that contain pchan names\n"); + ts = &trx->ts0; + lchan = &ts->lchan0; + + conn = bsc_subscr_con_allocate(net); + conn->lchan = lchan; + conn->assignment.new_lchan = lchan; + conn->sccp.conn.conn_id = 123; + conn->bsub = bsc_subscr_find_or_create_by_tmsi(net->bsc_subscribers, 0x423, "test"); + gscon_update_id(conn); + + /* dirty dirty hack, to just point at some fi so we can update the id */ + conn->assignment.fi = trx->ts1.fi; + + for (pchan = 0; pchan < _GSM_PCHAN_MAX; pchan++) { + ts->pchan_from_config = pchan; + /* trigger ID update in ts and lchan */ + osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_READY, NULL); + + if (lchan->fi) + assignment_fsm_update_id(conn); + + printf("pchan=%s:\n ts->fi->id = %s\n lchan->fi->id = %s\n assignment.fi->id = %s\n", + gsm_pchan_name(pchan), + ts->fi->id, + lchan->fi ? lchan->fi->id : "null", + lchan->fi ? conn->assignment.fi->id : "null"); + + osmo_fsm_inst_dispatch(ts->fi, TS_EV_OML_DOWN, NULL); + } + + talloc_free(net); + bsc_gsmnet = NULL; + printf("\n"); +} + static const struct log_info_cat log_categories = { DNM = { .name = "DNM", @@ -216,6 +277,7 @@ osmo_init_logging2(ctx, &log_info); test_scan(); + test_fsm_ids_with_pchan_names(); printf("Testing execution completed.\n"); talloc_free(ctx);
View file
osmo-bsc_1.10.0.tar.xz/tests/bsc/bsc_test.ok -> osmo-bsc_1.11.0.tar.xz/tests/bsc/bsc_test.ok
Changed
@@ -1,4 +1,55 @@ Testing BTS<->MSC message scan. Going to test item: 0 Going to test item: 1 + +Testing FSM ids that contain pchan names +pchan=NONE: + ts->fi->id = 0-1-0-NONE + lchan->fi->id = null + assignment.fi->id = null +pchan=CCCH: + ts->fi->id = 0-1-0-CCCH + lchan->fi->id = null + assignment.fi->id = null +pchan=CCCH+SDCCH4: + ts->fi->id = 0-1-0-CCCH_SDCCH4 + lchan->fi->id = 0-1-0-CCCH_SDCCH4-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-CCCH_SDCCH4-0 +pchan=TCH/F: + ts->fi->id = 0-1-0-TCH_F + lchan->fi->id = 0-1-0-TCH_F-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-TCH_F-0 +pchan=TCH/H: + ts->fi->id = 0-1-0-TCH_H + lchan->fi->id = 0-1-0-TCH_H-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-TCH_H-0 +pchan=SDCCH8: + ts->fi->id = 0-1-0-SDCCH8 + lchan->fi->id = 0-1-0-SDCCH8-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-SDCCH8-0 +pchan=PDCH: + ts->fi->id = 0-1-0-PDCH + lchan->fi->id = null + assignment.fi->id = null +pchan=DYNAMIC/IPACCESS: + ts->fi->id = 0-1-0-DYNAMIC_IPACCESS + lchan->fi->id = 0-1-0-DYNAMIC_IPACCESS-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-DYNAMIC_IPACCESSasTCH_F-0 +pchan=UNKNOWN: + ts->fi->id = 0-1-0-UNKNOWN + lchan->fi->id = null + assignment.fi->id = null +pchan=CCCH+SDCCH4+CBCH: + ts->fi->id = 0-1-0-CCCH_SDCCH4_CBCH + lchan->fi->id = 0-1-0-CCCH_SDCCH4_CBCH-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-CCCH_SDCCH4_CBCH-0 +pchan=SDCCH8+CBCH: + ts->fi->id = 0-1-0-SDCCH8_CBCH + lchan->fi->id = 0-1-0-SDCCH8_CBCH-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-SDCCH8_CBCH-0 +pchan=DYNAMIC/OSMOCOM: + ts->fi->id = 0-1-0-DYNAMIC_OSMOCOM + lchan->fi->id = 0-1-0-DYNAMIC_OSMOCOM-0 + assignment.fi->id = msc4294967295-conn123_subscr-TMSI-0x00000423_0-1-0-DYNAMIC_OSMOCOMasNONE-0 + Testing execution completed.
View file
osmo-bsc_1.10.0.tar.xz/tests/codec_pref/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/codec_pref/Makefile.am
Changed
@@ -12,8 +12,7 @@ $(LIBOSMOSIGTRAN_CFLAGS) \ $(NULL) -AM_LDFLAGS = \ - $(NULL) +AM_LDFLAGS = -no-install EXTRA_DIST = \ codec_pref_test.ok \
View file
osmo-bsc_1.10.0.tar.xz/tests/codec_pref/codec_pref_test.c -> osmo-bsc_1.11.0.tar.xz/tests/codec_pref/codec_pref_test.c
Changed
@@ -30,27 +30,8 @@ void *ctx = NULL; -#define MSC_AUDIO_SUPPORT_MAX 5 #define N_CONFIG_VARIANTS 9 -/* Make sure that there is some memory to put our test configuration. */ -static void init_msc_config(struct bsc_msc_data *msc) -{ - unsigned int i; - - msc->audio_support = talloc_zero_array(ctx, struct gsm_audio_support *, MSC_AUDIO_SUPPORT_MAX); - msc->audio_length = MSC_AUDIO_SUPPORT_MAX; - for (i = 0; i < MSC_AUDIO_SUPPORT_MAX; i++) { - msc->audio_supporti = talloc_zero(msc->audio_support, struct gsm_audio_support); - } -} - -/* Free memory that we have used for the test configuration. */ -static void free_msc_config(struct bsc_msc_data *msc) -{ - talloc_free(msc->audio_support); -} - /* The speech codec list is sent by the MS and lists the voice codec settings * that the MS is able to support. The BSC must select one of this codecs * depending on what the MSC is able to support. The following function @@ -215,74 +196,74 @@ switch (config_no) { case 0: /* FR1 only */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 0; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 0; msc->audio_length = 1; break; case 1: /* HR1 only */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 1; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 1; msc->audio_length = 1; break; case 2: /* FR2 only */ - msc->audio_support0->ver = 2; - msc->audio_support0->hr = 0; + msc->audio_support0.ver = 2; + msc->audio_support0.hr = 0; msc->audio_length = 1; break; case 3: /* FR3 only */ - msc->audio_support0->ver = 3; - msc->audio_support0->hr = 0; + msc->audio_support0.ver = 3; + msc->audio_support0.hr = 0; msc->audio_length = 1; break; case 4: /* HR3 only */ - msc->audio_support0->ver = 3; - msc->audio_support0->hr = 1; + msc->audio_support0.ver = 3; + msc->audio_support0.hr = 1; msc->audio_length = 1; break; case 5: /* FR1 and HR1 */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 0; - msc->audio_support1->ver = 1; - msc->audio_support1->hr = 1; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 0; + msc->audio_support1.ver = 1; + msc->audio_support1.hr = 1; msc->audio_length = 2; break; case 6: /* FR1, FR2 and HR1 */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 0; - msc->audio_support1->ver = 2; - msc->audio_support1->hr = 0; - msc->audio_support2->ver = 1; - msc->audio_support2->hr = 1; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 0; + msc->audio_support1.ver = 2; + msc->audio_support1.hr = 0; + msc->audio_support2.ver = 1; + msc->audio_support2.hr = 1; msc->audio_length = 3; break; case 7: /* FR1, FR3 and HR3 */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 0; - msc->audio_support1->ver = 3; - msc->audio_support1->hr = 0; - msc->audio_support2->ver = 3; - msc->audio_support2->hr = 1; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 0; + msc->audio_support1.ver = 3; + msc->audio_support1.hr = 0; + msc->audio_support2.ver = 3; + msc->audio_support2.hr = 1; msc->audio_length = 3; break; case 8: /* FR1, FR2, FR3, HR1 and HR3 */ - msc->audio_support0->ver = 1; - msc->audio_support0->hr = 0; - msc->audio_support1->ver = 2; - msc->audio_support1->hr = 0; - msc->audio_support2->ver = 3; - msc->audio_support2->hr = 0; - msc->audio_support3->ver = 1; - msc->audio_support3->hr = 1; - msc->audio_support4->ver = 3; - msc->audio_support4->hr = 1; + msc->audio_support0.ver = 1; + msc->audio_support0.hr = 0; + msc->audio_support1.ver = 2; + msc->audio_support1.hr = 0; + msc->audio_support2.ver = 3; + msc->audio_support2.hr = 0; + msc->audio_support3.ver = 1; + msc->audio_support3.hr = 1; + msc->audio_support4.ver = 3; + msc->audio_support4.hr = 1; msc->audio_length = 5; break; } @@ -394,10 +375,10 @@ printf(" * BSS: audio support settings (%u items):\n", msc->audio_length); for (i = 0; i < msc->audio_length; i++) - if (msc->audio_supporti->hr) - printf(" audio_support%u=HR%u\n", i, msc->audio_supporti->ver); + if (msc->audio_supporti.hr) + printf(" audio_support%u=HR%u\n", i, msc->audio_supporti.ver); else - printf(" audio_support%u=FR%u\n", i, msc->audio_supporti->ver); + printf(" audio_support%u=FR%u\n", i, msc->audio_supporti.ver); printf(" * BTS: audio support settings:\n"); printf(" (GSM-FR implicitly supported)\n"); @@ -426,8 +407,6 @@ printf("============== test_one_to_one ==============\n\n"); - init_msc_config(&msc_local); - for (i = 0; i < N_CONFIG_VARIANTS; i++) { make_msc_config(&msc_local, i); make_scl_config(&scl_ms, i); @@ -436,8 +415,6 @@ rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == 0); } - - free_msc_config(&msc_local); } /* Network supports all combinations, MS varies */ @@ -452,8 +429,6 @@ printf("============== test_ms ==============\n\n"); - init_msc_config(&msc_local); - make_msc_config(&msc_local, 8); make_ct_config(&ct_msc, 8); make_bts_config(&bts_local, 8); @@ -462,8 +437,6 @@ rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == 0); } - - free_msc_config(&msc_local); } /* BSS and MS support all combinations, MSC varies */ @@ -478,8 +451,6 @@ printf("============== test_ct ==============\n\n"); - init_msc_config(&msc_local); - make_msc_config(&msc_local, 8); make_scl_config(&scl_ms, 8); make_bts_config(&bts_local, 8); @@ -488,8 +459,6 @@ rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == 0); } - - free_msc_config(&msc_local); } /* MSC and MS support all combinations, BSS varies */ @@ -504,8 +473,6 @@ printf("============== test_msc ==============\n\n"); - init_msc_config(&msc_local); - make_ct_config(&ct_msc, 8); make_scl_config(&scl_ms, 8); make_bts_config(&bts_local, 8); @@ -514,8 +481,6 @@ rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == 0); } - - free_msc_config(&msc_local); } /* Some mixed configurations that are supposed to work */ @@ -529,8 +494,6 @@ printf("============== test_selected_working ==============\n\n"); - init_msc_config(&msc_local); - make_scl_config(&scl_ms, 6); make_ct_config(&ct_msc, 5); make_msc_config(&msc_local, 7); @@ -572,8 +535,6 @@ make_bts_config(&bts_local, 1); rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == 0); - - free_msc_config(&msc_local); } /* Some mixed configurations that can not work */ @@ -587,8 +548,6 @@ printf("============== test_selected_non_working ==============\n\n"); - init_msc_config(&msc_local); - make_scl_config(&scl_ms, 1); make_ct_config(&ct_msc, 5); make_msc_config(&msc_local, 7); @@ -630,8 +589,6 @@ make_bts_config(&bts_local, 7); rc = test_match_codec_pref(&ct_msc, &scl_ms, &msc_local, &bts_local); OSMO_ASSERT(rc == -1); - - free_msc_config(&msc_local); } /* Try execute bss_supp_codec_list(), display input and output parameters */ @@ -644,10 +601,10 @@ printf(" * BSS: audio support settings (%u items):\n", msc->audio_length); for (i = 0; i < msc->audio_length; i++) - if (msc->audio_supporti->hr) - printf(" audio_support%u=HR%u\n", i, msc->audio_supporti->ver); + if (msc->audio_supporti.hr) + printf(" audio_support%u=HR%u\n", i, msc->audio_supporti.ver); else - printf(" audio_support%u=FR%u\n", i, msc->audio_supporti->ver); + printf(" audio_support%u=FR%u\n", i, msc->audio_supporti.ver); printf(" * BTS: audio support settings:\n"); printf(" (GSM-FR implicitly supported)\n"); @@ -660,7 +617,7 @@ printf(" * result: speech codec list (%u items):\n", scl.len); for (i = 0; i < scl.len; i++) { printf(" codec%u->type=%s", i, gsm0808_speech_codec_type_name(scl.codeci.type)); - if (msc->audio_supporti->ver == 3) + if (msc->audio_supporti.ver == 3) printf(" S15-S0=%04x", scl.codeci.cfg); printf("\n"); } @@ -676,8 +633,6 @@ uint8_t k; printf("============== test_gen_bss_supp_codec_list_cfgs ==============\n\n"); - init_msc_config(&msc_local); - for (i = 0; i < N_CONFIG_VARIANTS; i++) { for (k = 0; k < N_CONFIG_VARIANTS; k++) { make_msc_config(&msc_local, i); @@ -686,8 +641,6 @@ test_gen_bss_supported_codec_list(&msc_local, &bts_local); } } - - free_msc_config(&msc_local); } static const struct log_info_cat log_categories = {
View file
osmo-bsc_1.10.0.tar.xz/tests/ctrl_test_runner.py -> osmo-bsc_1.11.0.tar.xz/tests/ctrl_test_runner.py
Changed
@@ -63,7 +63,9 @@ def tearDown(self): self.disconnect() - osmoutil.end_proc(self.proc) + rc = osmoutil.end_proc(self.proc) + if rc is not None and rc != 0: + raise Exception("Process returned %d" % rc) def disconnect(self): if not (self.sock is None): @@ -233,8 +235,8 @@ self.assertEqual(r'mtype', 'GET_REPLY') self.assertEqual(r'value', 'CCCH+SDCCH4,0,0 TCH/F,0,0 TCH/H,0,0 SDCCH8,0,0' - + ' TCH/F_PDCH,0,0 CCCH+SDCCH4+CBCH,0,0' - + ' SDCCH8+CBCH,0,0 TCH/F_TCH/H_SDCCH8_PDCH,0,0') + + ' DYNAMIC/IPACCESS,0,0 CCCH+SDCCH4+CBCH,0,0' + + ' SDCCH8+CBCH,0,0 DYNAMIC/OSMOCOM,0,0') def testBtsOmlConnectionState(self): """Check OML state. It will not be connected"""
View file
osmo-bsc_1.11.0.tar.xz/tests/gprs_params.vty
Added
@@ -0,0 +1,116 @@ +OsmoBSC> enable +OsmoBSC# configure terminal +OsmoBSC(config)# network +OsmoBSC(config-net)# bts 0 + +OsmoBSC(config-net-bts)# ### GPRS is disabled by default +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... + gprs mode none +... + +OsmoBSC(config-net-bts)# ### Default EGPRS params +OsmoBSC(config-net-bts)# gprs mode gprs +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... + gprs mode gprs + gprs routing area 0 + gprs network-control-order nc0 + gprs power-control alpha 0 + gprs cell bvci 2 + gprs cell timer blocking-timer 3 + gprs cell timer blocking-retries 3 + gprs cell timer unblocking-retries 3 + gprs cell timer reset-timer 3 + gprs cell timer reset-retries 3 + gprs cell timer suspend-timer 10 + gprs cell timer suspend-retries 3 + gprs cell timer resume-timer 10 + gprs cell timer resume-retries 3 + gprs cell timer capability-update-timer 10 + gprs cell timer capability-update-retries 3 + gprs nsei 0 + gprs ns timer tns-block 3 + gprs ns timer tns-block-retries 3 + gprs ns timer tns-reset 3 + gprs ns timer tns-reset-retries 3 + gprs ns timer tns-test 30 + gprs ns timer tns-alive 3 + gprs ns timer tns-alive-retries 10 + gprs nsvc 0 nsvci 0 + gprs nsvc 0 local udp port 0 + gprs nsvc 1 nsvci 0 + gprs nsvc 1 local udp port 0 +... + + +OsmoBSC(config-net-bts)# ### NSVC sub-command syntax +OsmoBSC(config-net-bts)# gprs nsvc? + nsvc Network Service Virtual Connection (NS-VC) +OsmoBSC(config-net-bts)# gprs nsvc ? + <0-1> NSVC Logical Number +OsmoBSC(config-net-bts)# gprs nsvc 0 ? + nsvci NS Virtual Connection Identifier + local GPRS NS Local UDP Port + remote GPRS NS Remote UDP Port +OsmoBSC(config-net-bts)# gprs nsvc 0 nsvci ? + <0-65535> GPRS NS VC Identifier +OsmoBSC(config-net-bts)# gprs nsvc 0 local ? + udp GPRS NS Local UDP Port +OsmoBSC(config-net-bts)# gprs nsvc 0 local udp ? + port GPRS NS Local UDP Port +OsmoBSC(config-net-bts)# gprs nsvc 0 local udp port ? + <0-65535> GPRS NS Local UDP Port Number +OsmoBSC(config-net-bts)# gprs nsvc 0 remote ? + udp GPRS NS Remote UDP Port + ip GPRS NS Remote IP Address +OsmoBSC(config-net-bts)# gprs nsvc 0 remote udp ? + port GPRS NS Remote UDP Port +OsmoBSC(config-net-bts)# gprs nsvc 0 remote udp port ? + <0-65535> GPRS NS Remote UDP Port Number +OsmoBSC(config-net-bts)# gprs nsvc 0 remote ip ? + A.B.C.D GPRS NS Remote IPv4 Address + X:X::X:X GPRS NS Remote IPv6 Address + +OsmoBSC(config-net-bts)# ### NSVC sub-command params +OsmoBSC(config-net-bts)# gprs nsvc 0 nsvci 4242 +OsmoBSC(config-net-bts)# gprs nsvc 1 nsvci 2424 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... + gprs nsvc 0 nsvci 4242 + gprs nsvc 0 local udp port 0 + gprs nsvc 1 nsvci 2424 + gprs nsvc 1 local udp port 0 +... +OsmoBSC(config-net-bts)# gprs nsvc 1 local udp port 23023 +OsmoBSC(config-net-bts)# gprs nsvc 1 remote udp port 23032 +OsmoBSC(config-net-bts)# gprs nsvc 1 remote ip 1.2.3.4 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... + gprs nsvc 0 nsvci 4242 + gprs nsvc 0 local udp port 0 + gprs nsvc 1 nsvci 2424 + gprs nsvc 1 local udp port 23023 + gprs nsvc 1 remote ip 1.2.3.4 + gprs nsvc 1 remote udp port 23032 +... + +OsmoBSC(config-net-bts)# ### Disable secondary NSVC +OsmoBSC(config-net-bts)# gprs nsvc 1 remote udp port 0 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... + gprs nsvc 0 nsvci 4242 + gprs nsvc 0 local udp port 0 + gprs nsvc 1 nsvci 2424 + gprs nsvc 1 local udp port 23023 +...
View file
osmo-bsc_1.10.0.tar.xz/tests/gsm0408/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/gsm0408/Makefile.am
Changed
@@ -13,6 +13,8 @@ $(LIBOSMOSIGTRAN_CFLAGS) \ $(NULL) +AM_LDFLAGS = -no-install + check_PROGRAMS = \ gsm0408_test \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/tests/gsm0408/gsm0408_test.c -> osmo-bsc_1.11.0.tar.xz/tests/gsm0408/gsm0408_test.c
Changed
@@ -405,7 +405,7 @@ }, }; -static void test_gsm48_ra_id_by_bts() +static void test_gsm48_ra_id_by_bts(void) { int i; bool pass = true; @@ -440,7 +440,7 @@ OSMO_ASSERT(pass); } -static void test_gsm48_multirate_config() +static void test_gsm48_multirate_config(void) { struct gsm48_multi_rate_conf *gsm48_ie; struct amr_multirate_conf mr;
View file
osmo-bsc_1.10.0.tar.xz/tests/gsm0408/gsm0408_test.ok -> osmo-bsc_1.11.0.tar.xz/tests/gsm0408/gsm0408_test.ok
Changed
@@ -79,93 +79,91 @@ BTS deallocated OK in test_si2q_mu() BTS allocation OK in test_si2q_long() Testing SYSINFO_TYPE_2quater combined EARFCN & UARFCN generation: -generating SI2quater for 17 EARFCNs and 1 UARFCNs... -generated valid SI2quater 00/05: 23 59 06 07 40 a0 25 0f 70 0c 1a 10 9c 00 02 cc 1e 09 07 82 39 76 56 0b +generating SI2quater for 16 EARFCNs and 1 UARFCNs... +generated valid SI2quater 00/05: 23 59 06 07 40 a0 25 0f 70 0c 1a 10 9c 00 02 cc 1e 09 07 84 d7 2e ca c1 +generated valid SI2quater 01/05: 23 59 06 07 42 a0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b +generated valid SI2quater 02/05: 23 59 06 07 44 a0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b +generated valid SI2quater 03/05: 23 59 06 07 46 a0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b +generated valid SI2quater 04/05: 23 59 06 07 48 a0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b +generated valid SI2quater 05/05: 23 59 06 07 4a a0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 2 UARFCNs... +generated valid SI2quater 00/05: 23 59 06 07 40 a0 25 0f 70 14 4d e7 00 46 00 01 66 0f 04 72 ec ac 0b 2b generated valid SI2quater 01/05: 23 59 06 07 42 a0 04 87 00 00 b3 07 84 d8 3c 1e c1 e1 75 cb b2 b0 2b 2b generated valid SI2quater 02/05: 23 59 06 07 44 a0 04 87 00 00 b3 08 3f d8 42 06 42 10 6d cb b2 b0 2b 2b generated valid SI2quater 03/05: 23 59 06 07 46 a0 04 87 00 00 b3 08 42 a8 42 9e c2 15 31 cb b2 b0 2b 2b generated valid SI2quater 04/05: 23 59 06 07 48 a0 04 87 00 00 b3 08 55 b8 42 b5 42 12 75 cb b2 b0 2b 2b generated valid SI2quater 05/05: 23 59 06 07 4a a0 04 87 00 00 b3 08 4a c8 42 5d c2 13 29 cb b2 b0 2b 2b -generating SI2quater for 17 EARFCNs and 2 UARFCNs... -generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 14 4d e7 00 46 00 01 66 0f 04 72 ec ac 0b 2b +generating SI2quater for 16 EARFCNs and 3 UARFCNs... +generated valid SI2quater 00/05: 23 59 06 07 40 a0 25 0f 70 1c 4d e7 03 04 87 00 00 b3 07 82 39 76 56 0b +generated valid SI2quater 01/05: 23 59 06 07 42 a0 04 87 00 00 b3 07 84 d8 3c 1e c1 e1 75 cb b2 b0 2b 2b +generated valid SI2quater 02/05: 23 59 06 07 44 a0 04 87 00 00 b3 08 3f d8 42 06 42 10 6d cb b2 b0 2b 2b +generated valid SI2quater 03/05: 23 59 06 07 46 a0 04 87 00 00 b3 08 42 a8 42 9e c2 15 31 cb b2 b0 2b 2b +generated valid SI2quater 04/05: 23 59 06 07 48 a0 04 87 00 00 b3 08 55 b8 42 b5 42 12 75 cb b2 b0 2b 2b +generated valid SI2quater 05/05: 23 59 06 07 4a a0 04 87 00 00 b3 08 4a c8 42 5d c2 13 29 cb b2 b0 2b 2b +generating SI2quater for 16 EARFCNs and 4 UARFCNs... +generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 24 59 fa 26 73 84 87 00 00 b2 e5 d9 58 2b 2b generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 3 UARFCNs... -generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 1c 4d e7 03 04 87 00 00 b3 07 82 39 76 56 0b +generating SI2quater for 16 EARFCNs and 5 UARFCNs... +generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 2c 59 fa 30 73 f6 04 87 00 00 b2 e5 d9 58 2b generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 4 UARFCNs... -generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 24 59 fa 26 73 84 87 00 00 b2 e5 d9 58 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 5 UARFCNs... -generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 2c 59 fa 30 73 f6 04 87 00 00 b2 e5 d9 58 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 6 UARFCNs... +generating SI2quater for 16 EARFCNs and 6 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 34 f1 ae 15 f3 f4 83 03 2b 2b 2b 2b 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 7 UARFCNs... +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 7 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 3c f1 ae 15 f3 f4 83 01 83 2b 2b 2b 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 8 UARFCNs... +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 8 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 45 19 a0 0d 7d 7e a6 19 e7 0b 2b 2b 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 9 UARFCNs... +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 9 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 4d 19 a0 26 fd 66 a6 03 e7 fa 0b 2b 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 10 UARFCNs... +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 10 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 55 47 89 1e fd 7c b0 00 e7 9b b0 2b 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b -generating SI2quater for 17 EARFCNs and 11 UARFCNs... +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b +generating SI2quater for 16 EARFCNs and 11 UARFCNs... generated valid SI2quater 00/06: 23 59 06 07 40 c0 25 0f 70 5d 47 89 1e fd 7c b0 01 67 9b b3 f8 2b 2b 2b -generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e0 90 78 4d 72 ec ac 0b 2b 2b -generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 83 d8 3c 2e c2 0f f5 cb b2 b0 2b 2b -generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 40 c8 42 0d c2 10 a9 cb b2 b0 2b 2b -generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 53 d8 42 a6 42 15 6d cb b2 b0 2b 2b -generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 56 a8 42 4e c2 12 b1 cb b2 b0 2b 2b -generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4b b8 42 65 39 76 56 0b 2b 2b 2b 2b +generated valid SI2quater 01/06: 23 59 06 07 42 c0 04 87 00 00 b3 07 82 41 e1 36 0f 07 ae 5d 95 83 2b 2b +generated valid SI2quater 02/06: 23 59 06 07 44 c0 04 87 00 00 b3 07 85 d8 41 fe c2 10 31 cb b2 b0 2b 2b +generated valid SI2quater 03/06: 23 59 06 07 46 c0 04 87 00 00 b3 08 41 b8 42 15 42 14 f5 cb b2 b0 2b 2b +generated valid SI2quater 04/06: 23 59 06 07 48 c0 04 87 00 00 b3 08 54 c8 42 ad c2 15 a9 cb b2 b0 2b 2b +generated valid SI2quater 05/06: 23 59 06 07 4a c0 04 87 00 00 b3 08 49 d8 42 56 42 12 ed cb b2 b0 2b 2b +generated valid SI2quater 06/06: 23 59 06 07 4c c0 04 87 00 00 b3 08 4c a7 2e ca c1 2b 2b 2b 2b 2b 2b 2b BTS deallocated OK in test_si2q_long() BTS allocation OK in test_si_ba_ind() Testing if BA-IND is set as expected in SI2xxx and SI5xxx
View file
osmo-bsc_1.10.0.tar.xz/tests/handover/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/handover/Makefile.am
Changed
@@ -18,6 +18,7 @@ AM_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) EXTRA_DIST = \ @@ -36,6 +37,11 @@ handover_test_LDFLAGS = \ -Wl,--wrap=abis_rsl_sendmsg \ + -Wl,--wrap=bsc_cipher_mode_compl \ + -Wl,--wrap=bsc_cm_update \ + -Wl,--wrap=bsc_compl_l3 \ + -Wl,--wrap=bsc_dtap \ + -Wl,--wrap=bsc_sapi_n_reject \ -Wl,--wrap=osmo_mgcpc_ep_ci_request \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/tests/handover/handover_test.c -> osmo-bsc_1.11.0.tar.xz/tests/handover/handover_test.c
Changed
@@ -112,7 +112,7 @@ osmo_timers_update(); } -void fake_time_start() +void fake_time_start(void) { struct timespec *clock_override; @@ -1522,7 +1522,7 @@ return CMD_SUCCESS; } -static void ho_test_vty_init() +static void ho_test_vty_init(void) { install_element(CONFIG_NODE, &create_n_bts_cmd); install_element(CONFIG_NODE, &create_bts_cmd); @@ -1687,11 +1687,6 @@ bsc_vty_init(bsc_gsmnet); ho_test_vty_init(); - lchan_fsm_init(); - bsc_subscr_conn_fsm_init(); - handover_fsm_init(); - assignment_fsm_init(); - ho_set_algorithm(bsc_gsmnet->ho, 2); ho_set_ho_active(bsc_gsmnet->ho, true); ho_set_hodec2_as_active(bsc_gsmnet->ho, true); @@ -1745,15 +1740,27 @@ void trau_send_frame() {} /* Stub */ int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) { return 0; } -void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {} -void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n) {} -int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) + +void __real_bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause); +void __wrap_bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {} + +void __real_bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n); +void __wrap_bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n) {} + +int __real_bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel); +int __wrap_bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { return 0; } -void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {} -void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause) {} -void bsc_cm_update(struct gsm_subscriber_connection *conn, + +void __real_bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg); +void __wrap_bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {} + +void __real_bsc_cm_update(struct gsm_subscriber_connection *conn, + const uint8_t *cm2, uint8_t cm2_len, + const uint8_t *cm3, uint8_t cm3_len); +void __wrap_bsc_cm_update(struct gsm_subscriber_connection *conn, const uint8_t *cm2, uint8_t cm2_len, const uint8_t *cm3, uint8_t cm3_len) {} + const char *osmo_mgcpc_ep_name(const struct osmo_mgcpc_ep *ep) { return "fake-ep";
View file
osmo-bsc_1.11.0.tar.xz/tests/msc.vty
Added
@@ -0,0 +1,119 @@ +OsmoBSC> enable + +OsmoBSC# configure terminal +OsmoBSC(config)# msc 0 + +OsmoBSC(config-msc)# codec-list? + codec-list Set the allowed audio codecs and their order of preference +OsmoBSC(config-msc)# codec-list ? + LIST 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) + +OsmoBSC(config-msc)# # Default list -- should match the default in osmo_msc_data_alloc() +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list fr1 hr1 fr2 fr3 hr3 +... + +OsmoBSC(config-msc)# # Change order +OsmoBSC(config-msc)# codec-list fr3 hr3 fr2 fr1 hr1 +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list fr3 hr3 fr2 fr1 hr1 +... +OsmoBSC(config-msc)# codec-list hr1 hr3 fr1 fr2 fr3 +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list foo +"foo" is not a valid codec version + +OsmoBSC(config-msc)# codec-list fr10 +"fr10" is not a valid codec version + +OsmoBSC(config-msc)# codec-list hr10 +"hr10" is not a valid codec version + +OsmoBSC(config-msc)# codec-list FR1 +"FR1" is not a valid codec version + +OsmoBSC(config-msc)# # Ensure the codec-list with wrong args did not change the config +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list fr1 fr1 +duplicate entry in 'msc' / 'codec-list': fr1 +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list fr0 fr1 +"fr0" is not a valid codec version +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list hr0 hr1 +"hr0" is not a valid codec version +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list fr8 fr9 +"fr8" is not a valid codec version +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list hr8 hr9 +"hr8" is not a valid codec version +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list fr2 hr2 +"hr2" is not a valid codec version +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list hr1 hr3 fr1 fr2 fr3 +... + +OsmoBSC(config-msc)# codec-list fr1 fr2 fr3 fr4 +OsmoBSC(config-msc)# show running-config +... +msc 0 +... + codec-list fr1 fr2 fr3 fr4 +... +OsmoBSC(config-msc)# # TODO: should fr4 thru fr7 be rejected + +OsmoBSC(config-msc)# codec-list fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 fr1 +Too many items in 'msc' / 'codec-list': 17. There can be at most 16 entries.
View file
osmo-bsc_1.10.0.tar.xz/tests/nanobts_omlattr/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/nanobts_omlattr/Makefile.am
Changed
@@ -12,6 +12,8 @@ $(LIBOSMOSIGTRAN_CFLAGS) \ $(NULL) +AM_LDFLAGS = -no-install + check_PROGRAMS = \ nanobts_omlattr_test \ $(NULL)
View file
osmo-bsc_1.10.0.tar.xz/tests/osmo-bsc.vty -> osmo-bsc_1.11.0.tar.xz/tests/osmo-bsc.vty
Changed
@@ -177,6 +177,7 @@ chan-req Channel allocation for CHANNEL REQUEST (RACH) assignment Channel allocation for assignment handover Channel allocation for handover + vgcs-vbs Channel allocation for VGCS/VBS OsmoBSC(config-net-bts)# channel allocator mode set-all ? ascending Allocate Timeslots and Transceivers in ascending order @@ -191,6 +192,10 @@ descending Allocate Timeslots and Transceivers in descending order dynamic Dynamic lchan selection based on configured parameters +OsmoBSC(config-net-bts)# channel allocator mode vgcs-vbs ? + ascending Allocate Timeslots and Transceivers in ascending order + descending Allocate Timeslots and Transceivers in descending order + OsmoBSC(config-net-bts)# channel allocator dynamic-param ? sort-by-trx-power Whether to sort TRX instances by their respective power levels ul-rxlev Uplink RxLev
View file
osmo-bsc_1.10.0.tar.xz/tests/paging/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/paging/Makefile.am
Changed
@@ -28,6 +28,7 @@ paging_test_LDFLAGS = \ -Wl,--wrap=abis_rsl_sendmsg \ + -no-install \ $(NULL) paging_test_LDADD = \
View file
osmo-bsc_1.11.0.tar.xz/tests/si2quater_neighbor_list.vty
Added
@@ -0,0 +1,169 @@ +OsmoBSC> enable +OsmoBSC# configure terminal +OsmoBSC(config)# network + +OsmoBSC(config-net)# ## No neighbor EARFCNs by default +OsmoBSC(config-net)# show running-config +... !si2quater neighbor-list + + +OsmoBSC(config-net)# bts 0 +OsmoBSC(config-net-bts)# si2quater? + si2quater SI2quater Neighbor List +OsmoBSC(config-net-bts)# si2quater ? + neighbor-list SI2quater Neighbor List +OsmoBSC(config-net-bts)# si2quater neighbor-list ? + add Add to manual SI2quater neighbor list + del Delete from SI2quater manual neighbor list + +OsmoBSC(config-net-bts)# si2quater neighbor-list add ? + earfcn EARFCN of neighbor + uarfcn UARFCN of neighbor +OsmoBSC(config-net-bts)# si2quater neighbor-list del ? + earfcn EARFCN of neighbor + uarfcn UARFCN of neighbor + + +OsmoBSC(config-net-bts)# ### Delete command syntax +OsmoBSC(config-net-bts)# si2quater neighbor-list del earfcn ? + <0-65535> EARFCN +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn ? + <0-16383> UARFCN + + +OsmoBSC(config-net-bts)# ### EARFCN add command syntax +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn ? + <0-65535> EARFCN of neighbor +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi ? + <0-31> threshold high bits +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo ? + <0-32> threshold low bits (32 means NA) +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio ? + <0-8> priority (8 means NA) +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv ? + <0-32> QRXLEVMIN (32 means NA) +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas ? + <0-8> measurement bandwidth (8 means NA) +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 ? + <cr> + + +OsmoBSC(config-net-bts)# ### UARFCN add command syntax +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn ? + <0-16383> UARFCN of neighbor +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 0 ? + <0-511> scrambling code +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 0 0 ? + <0-1> diversity bit +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 0 0 0 ? + <cr> + + +OsmoBSC(config-net-bts)# ### EARFCN add/del command tests +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 65535 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 + si2quater neighbor-list add earfcn 65535 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 +... !si2quater neighbor-list + +OsmoBSC(config-net-bts)# si2quater neighbor-list del earfcn 33 +% Unable to delete arfcn 33: No such file or directory + +OsmoBSC(config-net-bts)# si2quater neighbor-list del earfcn 65535 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add earfcn 0 thresh-hi 0 thresh-lo 32 prio 8 qrxlv 32 meas 8 +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### EARFCN add command: different params +OsmoBSC(config-net-bts)# ### FIXME: osmo-bsc does not support different thresh/prio/qrxlv +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 300 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 5 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add earfcn 0 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 8 + si2quater neighbor-list add earfcn 300 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 5 +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### EARFCN add command: EARFCN already exists +OsmoBSC(config-net-bts)# si2quater neighbor-list add earfcn 300 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 2 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add earfcn 0 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 8 + si2quater neighbor-list add earfcn 300 thresh-hi 7 thresh-lo 5 prio 5 qrxlv 6 meas 2 +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### Remove remaining EARFCNs +OsmoBSC(config-net-bts)# si2quater neighbor-list del earfcn 0 +OsmoBSC(config-net-bts)# si2quater neighbor-list del earfcn 300 +OsmoBSC(config-net-bts)# show running-config +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### UARFCN add/del command tests +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 1 256 0 +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 111 211 1 +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 111 511 1 +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 16383 0 0 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add uarfcn 1 256 0 + si2quater neighbor-list add uarfcn 111 511 1 + si2quater neighbor-list add uarfcn 111 211 1 + si2quater neighbor-list add uarfcn 16383 0 0 +... !si2quater neighbor-list + +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 1 +% Command incomplete. +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 33 256 +% Unable to delete uarfcn: pair not found +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 1 255 +% Unable to delete uarfcn: pair not found + +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 1 256 +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 16383 0 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add uarfcn 111 511 1 + si2quater neighbor-list add uarfcn 111 211 1 +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### UARFCN add command: UARFCN already exists +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 111 511 1 +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 111 511 0 +OsmoBSC(config-net-bts)# show running-config +... + bts 0 +... !si2quater neighbor-list + si2quater neighbor-list add uarfcn 111 511 0 + si2quater neighbor-list add uarfcn 111 211 1 +... !si2quater neighbor-list + + +OsmoBSC(config-net-bts)# ### FIXME: UARFCN 0 cannot be added +OsmoBSC(config-net-bts)# si2quater neighbor-list add uarfcn 0 1 1 +% Warning: not enough space in SI2quater for a given UARFCN (0, 1) + + +OsmoBSC(config-net-bts)# ### Remove remaining UARFCNs +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 111 511 +OsmoBSC(config-net-bts)# si2quater neighbor-list del uarfcn 111 211 +OsmoBSC(config-net-bts)# show running-config +... !si2quater neighbor-list
View file
osmo-bsc_1.10.0.tar.xz/tests/subscr/Makefile.am -> osmo-bsc_1.11.0.tar.xz/tests/subscr/Makefile.am
Changed
@@ -17,6 +17,7 @@ AM_LDFLAGS = \ $(COVERAGE_LDFLAGS) \ + -no-install \ $(NULL) EXTRA_DIST = \
View file
osmo-bsc_1.10.0.tar.xz/tests/subscr/bsc_subscr_test.c -> osmo-bsc_1.11.0.tar.xz/tests/subscr/bsc_subscr_test.c
Changed
@@ -29,7 +29,7 @@ #include <stdlib.h> #include <inttypes.h> -struct llist_head *bsc_subscribers; +struct bsc_subscr_store *bsc_subscribers; #define VERBOSE_ASSERT(val, expect_op, fmt) \ do { \ @@ -61,26 +61,26 @@ printf("Test BSC subscriber allocation and deletion\n"); /* Check for emptiness */ - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 0, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 0, "%d"); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi1, BSUB_USE) == NULL); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi2, BSUB_USE) == NULL); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi3, BSUB_USE) == NULL); /* Allocate entry 1 */ s1 = bsc_subscr_find_or_create_by_imsi(bsc_subscribers, imsi1, BSUB_USE); - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 1, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 1, "%d"); assert_bsc_subscr(s1, imsi1); - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 1, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 1, "%d"); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi2, BSUB_USE) == NULL); /* Allocate entry 2 */ s2 = bsc_subscr_find_or_create_by_imsi(bsc_subscribers, imsi2, BSUB_USE); - s2->tmsi = 0x73517351; - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 2, "%d"); + bsc_subscr_set_tmsi(s2, 0x73517351); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 2, "%d"); /* Allocate entry 3 */ s3 = bsc_subscr_find_or_create_by_imsi(bsc_subscribers, imsi3, BSUB_USE); - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 3, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 3, "%d"); /* Check entries */ assert_bsc_subscr(s1, imsi1); @@ -90,7 +90,7 @@ /* Free entry 1 */ bsc_subscr_put(s1, BSUB_USE); s1 = NULL; - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 2, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 2, "%d"); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi1, BSUB_USE) == NULL); assert_bsc_subscr(s2, imsi2); @@ -99,7 +99,7 @@ /* Free entry 2 */ bsc_subscr_put(s2, BSUB_USE); s2 = NULL; - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 1, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 1, "%d"); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi1, BSUB_USE) == NULL); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi2, BSUB_USE) == NULL); assert_bsc_subscr(s3, imsi3); @@ -107,10 +107,10 @@ /* Free entry 3 */ bsc_subscr_put(s3, BSUB_USE); s3 = NULL; - VERBOSE_ASSERT(llist_count(bsc_subscribers), == 0, "%d"); + VERBOSE_ASSERT(llist_count(&bsc_subscribers->bsub_list), == 0, "%d"); OSMO_ASSERT(bsc_subscr_find_by_imsi(bsc_subscribers, imsi3, BSUB_USE) == NULL); - OSMO_ASSERT(llist_empty(bsc_subscribers)); + OSMO_ASSERT(llist_empty(&bsc_subscribers->bsub_list)); } static const struct log_info_cat log_categories = { @@ -126,7 +126,7 @@ .num_cat = ARRAY_SIZE(log_categories), }; -int main() +int main(int argc, char **argv) { void *ctx = talloc_named_const(NULL, 0, "bsc_subscr_test"); printf("Testing BSC subscriber core code.\n"); @@ -137,8 +137,7 @@ log_set_print_category_hex(osmo_stderr_target, 0); log_set_print_category(osmo_stderr_target, 1); - bsc_subscribers = talloc_zero(ctx, struct llist_head); - INIT_LLIST_HEAD(bsc_subscribers); + bsc_subscribers = bsc_subscr_store_alloc(ctx); test_bsc_subscr();
View file
osmo-bsc_1.10.0.tar.xz/tests/subscr/bsc_subscr_test.ok -> osmo-bsc_1.11.0.tar.xz/tests/subscr/bsc_subscr_test.ok
Changed
@@ -1,11 +1,11 @@ Testing BSC subscriber core code. Test BSC subscriber allocation and deletion -llist_count(bsc_subscribers) == 0 -llist_count(bsc_subscribers) == 1 -llist_count(bsc_subscribers) == 1 -llist_count(bsc_subscribers) == 2 -llist_count(bsc_subscribers) == 3 -llist_count(bsc_subscribers) == 2 -llist_count(bsc_subscribers) == 1 -llist_count(bsc_subscribers) == 0 +llist_count(&bsc_subscribers->bsub_list) == 0 +llist_count(&bsc_subscribers->bsub_list) == 1 +llist_count(&bsc_subscribers->bsub_list) == 1 +llist_count(&bsc_subscribers->bsub_list) == 2 +llist_count(&bsc_subscribers->bsub_list) == 3 +llist_count(&bsc_subscribers->bsub_list) == 2 +llist_count(&bsc_subscribers->bsub_list) == 1 +llist_count(&bsc_subscribers->bsub_list) == 0 Done
View file
osmo-bsc_1.10.0.tar.xz/tests/timer.vty -> osmo-bsc_1.11.0.tar.xz/tests/timer.vty
Changed
@@ -8,7 +8,7 @@ net: T101 = 10 s inter-BSC/MSC Handover incoming, BSSMAP HO Request to HO Accept (default: 10 s) net: T3101 = 3 s RR Immediate Assignment (default: 3 s) net: T3103 = 5 s Handover (default: 5 s) -net: T3105 = 100 ms Physical Information (default: 100 ms) +net: T3105 = 100 ms Physical Information (default: 100 ms, range: 1 .. inf) net: T3107 = 5 s (unused) (default: 5 s) net: T3109 = 5 s RSL SACCH deactivation (default: 5 s) net: T3111 = 2 s Wait time before RSL RF Channel Release (default: 2 s) @@ -64,7 +64,7 @@ net: T101 = 10 s inter-BSC/MSC Handover incoming, BSSMAP HO Request to HO Accept (default: 10 s) net: T3101 = 3 s RR Immediate Assignment (default: 3 s) net: T3103 = 5 s Handover (default: 5 s) -net: T3105 = 100 ms Physical Information (default: 100 ms) +net: T3105 = 100 ms Physical Information (default: 100 ms, range: 1 .. inf) net: T3107 = 5 s (unused) (default: 5 s) net: T3109 = 5 s RSL SACCH deactivation (default: 5 s) net: T3111 = 2 s Wait time before RSL RF Channel Release (default: 2 s)
View file
osmo-bsc_1.11.0.tar.xz/tests/timeslot.vty
Added
@@ -0,0 +1,73 @@ +OsmoBSC> enable +OsmoBSC# configure terminal +OsmoBSC(config)# network +OsmoBSC(config-net)# bts 0 +OsmoBSC(config-net-bts)# trx 0 +OsmoBSC(config-net-bts-trx)# timeslot 0 + +OsmoBSC(config-net-bts-trx-ts)# list +... + phys_chan_config (none|ccch|ccch+sdcch4|tch/f|tch/h|sdcch8|pdch|dynamic/ipaccess|unknown|ccch+sdcch4+cbch|sdcch8+cbch|dynamic/osmocom|tch/f_pdch|tch/f_tch/h_sdcch8_pdch) + training_sequence_code <0-7> + hopping enabled (0|1) + hopping sequence-number <0-63> + hopping maio <0-63> + hopping arfcn add <0-1023> + hopping arfcn del <0-1023> + hopping arfcn del-all + e1 line E1_LINE timeslot <1-31> sub-slot (0|1|2|3|full) + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config? + phys_chan_config Physical Channel Combination + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config ? + none Physical Channel not configured + ccch FCCH + SCH + BCCH + CCCH (Comb. IV) + ccch+sdcch4 FCCH + SCH + BCCH + CCCH + 4 SDCCH + 2 SACCH (Comb. V) + tch/f TCH/F + FACCH/F + SACCH (Comb. I) + tch/h 2 TCH/H + 2 FACCH/H + 2 SACCH (Comb. II) + sdcch8 8 SDCCH + 4 SACCH (Comb. VII) + pdch Packet Data Channel for GPRS/EDGE + dynamic/ipaccess Dynamic TCH/F or GPRS PDCH (dynamic/ipaccess is an alias for tch/f_pdch) + unknown Unknown / Unsupported channel combination + ccch+sdcch4+cbch FCCH + SCH + BCCH + CCCH + CBCH + 3 SDCCH + 2 SACCH (Comb. V) + sdcch8+cbch 7 SDCCH + 4 SACCH + CBCH (Comb. VII) + dynamic/osmocom Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH (dynamic/osmocom is an alias for tch/f_tch/h_sdcch8_pdch) + tch/f_pdch Dynamic TCH/F or GPRS PDCH (dynamic/ipaccess is an alias for tch/f_pdch) + tch/f_tch/h_sdcch8_pdch Dynamic TCH/F or TCH/H or SDCCH/8 or GPRS PDCH (dynamic/osmocom is an alias for tch/f_tch/h_sdcch8_pdch) + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config none +OsmoBSC(config-net-bts-trx-ts)# show running-config +... + trx 0 +... + timeslot 0 + hopping enabled 0 +... + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config tch/f +OsmoBSC(config-net-bts-trx-ts)# show running-config +... + trx 0 +... + timeslot 0 + phys_chan_config TCH/F +... + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config TCH/F +OsmoBSC(config-net-bts-trx-ts)# show running-config +... + trx 0 +... + timeslot 0 + phys_chan_config TCH/F +... + +OsmoBSC(config-net-bts-trx-ts)# phys_chan_config tch/f_tch/h_sdcch8_pdch +OsmoBSC(config-net-bts-trx-ts)# show running-config +... + trx 0 +... + timeslot 0 + phys_chan_config DYNAMIC/OSMOCOM +...
View file
osmo-bsc_1.10.0.tar.xz/tests/vty_test_runner.py -> osmo-bsc_1.11.0.tar.xz/tests/vty_test_runner.py
Changed
@@ -65,7 +65,9 @@ if self.vty: self.vty._close_socket() self.vty = None - osmoutil.end_proc(self.proc) + rc = osmoutil.end_proc(self.proc) + if rc is not None and rc != 0: + raise Exception("Process returned %d" % rc) class TestVTYGenericBSC(TestVTYBase):
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.