diff options
289 files changed, 25430 insertions, 6654 deletions
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..7592debf --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +open_collective: osmocom @@ -54,6 +54,8 @@ src/osmo-bts-oc2g/misc/.dirstamp tests/atconfig tests/package.m4 +tests/amr/amr_test +tests/csd/csd_test tests/agch/agch_test tests/paging/paging_test tests/cipher/cipher_test @@ -92,6 +94,7 @@ debian/tmp/ doc/manuals/*.html doc/manuals/*.svg doc/manuals/*.pdf +doc/manuals/vty/*.pdf doc/manuals/*__*.png doc/manuals/*.check doc/manuals/generated/ @@ -103,3 +106,7 @@ doc/manuals/common doc/manuals/build contrib/osmo-bts.spec +contrib/ber/rtp_ber +contrib/ber/rtp_gen_map + +arm-poky-linux-gnueabi-libtool @@ -27,16 +27,16 @@ Homepage -------- The official homepage of the project is -https://osmocom.org/projects/osmobts/wiki +<https://osmocom.org/projects/osmobts/wiki> GIT Repository -------------- You can clone from the official osmo-bts.git repository using - git clone git://git.osmocom.org/osmo-bts.git + git clone https://gitea.osmocom.org/cellular-infrastructure/osmo-bts -There is a cgit interface at https://git.osmocom.org/osmo-bts/ +There is a web interface at <https://gitea.osmocom.org/cellular-infrastructure/osmo-bts> Documentation ------------- @@ -57,6 +57,13 @@ There also is an [Abis reference Manual](https://ftp.osmocom.org/docs/latest/osmobts-abis.pdf) describing the OsmoBTS specific A-bis dialect. +Forum +----- + +We welcome any osmo-bts related discussions in the +[Cellular Network Infrastructure -> 2G RAN (GERAN)](https://discourse.osmocom.org/c/cni/geran) +section of the osmocom discourse (web based Forum). + Mailing List ------------ @@ -69,6 +76,13 @@ Please observe the [Osmocom Mailing List Rules](https://osmocom.org/projects/cellular-infrastructure/wiki/Mailing_List_Rules) when posting. +Issue Tracker +------------- + +We use the [issue tracker of the osmo-bts project on osmocom.org](https://osmocom.org/projects/osmobts/issues) for +tracking the state of bug reports and feature requests. Feel free to submit any issues you may find, or help +us out by resolving existing issues. + Contributing ------------ diff --git a/TODO-RELEASE b/TODO-RELEASE index aa0b2fd3..96426a51 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -1,6 +1,12 @@ -# When cleaning up this file: bump API version(s) in the following files: -# configure.ac, debian/control, and contrib/osmo-bts.spec.in. -update libosmo-abis dependency to > 1.1.1 for osmo_rtp_socket_set_priority() -update libosmo-abis dependency to > 1.1.1 for new e1_input vty commands for DSCP + priority -update libosmocore dependency to > 1.5.1-73-g524b4f80 for osmo_bts_features_desc() -update libosmocore dependency to > 1.5.1-133-g09f075fa for name in (struct rate_ctr_group) +# When cleaning up this file: bump API version in corresponding Makefile.am and rename corresponding debian/lib*.install +# according to https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info +# In short: +# LIBVERSION=c:r:a +# If the library source code has changed at all since the last update, then increment revision: c:r + 1:a. +# If any interfaces have been added, removed, or changed since the last update: c + 1:0:0. +# If any interfaces have been added since the last public release: c:r:a + 1. +# If any interfaces have been removed or changed since the last public release: c:r:0. +#library what description / commit summary line +libosmogsm >1.9.0 added new PRIM_INFO to include/osmocom/gsm/l1sap.h +libosmogsm >1.9.0 use of RLP code in libosmogsm +libosmoctrl >1.9.0 use ctrl_cmd_send2() diff --git a/configure.ac b/configure.ac index 2b5a3169..6d5d931f 100644 --- a/configure.ac +++ b/configure.ac @@ -69,14 +69,15 @@ then fi dnl checks for libraries -PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.5.0) -PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.1.0) -PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.1.0) +PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOCTRL, libosmoctrl >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOCODEC, libosmocodec >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOCODING, libosmocoding >= 1.9.0) +PKG_CHECK_MODULES(LIBOSMOABIS, libosmoabis >= 1.5.0) +PKG_CHECK_MODULES(LIBOSMOTRAU, libosmotrau >= 1.5.0) +PKG_CHECK_MODULES(LIBOSMONETIF, libosmo-netif >= 1.4.0) AC_MSG_CHECKING([whether to enable support for sysmobts calibration tool]) AC_ARG_ENABLE(sysmobts-calib, @@ -349,6 +350,56 @@ then AC_SUBST([OSMO_GSM_MANUALS_DIR]) fi +AC_ARG_ENABLE([external_tests], + AC_HELP_STRING([--enable-external-tests], + [Include the VTY/CTRL tests in make check [default=no]]), + [enable_ext_tests="$enableval"],[enable_ext_tests="no"]) +if test "x$enable_ext_tests" = "xyes" ; then + AC_CHECK_PROG(PYTHON3_AVAIL,python3,yes) + if test "x$PYTHON3_AVAIL" != "xyes" ; then + AC_MSG_ERROR([Please install python3 to run the VTY/CTRL tests.]) + fi + AC_CHECK_PROG(OSMOTESTEXT_CHECK,osmotestvty.py,yes) + if test "x$OSMOTESTEXT_CHECK" != "xyes" ; then + AC_MSG_ERROR([Please install https://gitea.osmocom.org/cellular-infrastructure/osmo-python-tests to run the VTY/CTRL tests.]) + fi +fi +AC_MSG_CHECKING([whether to enable VTY/CTRL tests]) +AC_MSG_RESULT([$enable_ext_tests]) +AM_CONDITIONAL(ENABLE_EXT_TESTS, test "x$enable_ext_tests" = "xyes") + +# +# SystemTap support +# +AC_MSG_CHECKING([whether to include systemtap tracing support]) +AC_ARG_ENABLE([systemtap], + [AS_HELP_STRING([--enable-systemtap], + [Enable inclusion of systemtap trace support])], + [ENABLE_SYSTEMTAP="${enableval}"], [ENABLE_SYSTEMTAP='no']) +AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$ENABLE_SYSTEMTAP = xyes]) +AC_MSG_RESULT(${ENABLE_SYSTEMTAP}) + +if test "x${ENABLE_SYSTEMTAP}" = xyes; then + # Additional configuration for --enable-systemtap is HERE + AC_CHECK_PROGS(DTRACE, dtrace) + if test -z "$DTRACE"; then + AC_MSG_ERROR([dtrace not found]) + fi + AC_CHECK_HEADER([sys/sdt.h], [SDT_H_FOUND='yes'], + [SDT_H_FOUND='no'; + AC_MSG_ERROR([systemtap support needs sys/sdt.h header])]) + AC_DEFINE([HAVE_SYSTEMTAP], [1], [Define to 1 if using SystemTap probes.]) + AC_ARG_WITH([tapset-install-dir], + [AS_HELP_STRING([--with-tapset-install-dir], + [The absolute path where the tapset dir will be installed])], + [if test "x${withval}" = x; then + ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset" + else + ABS_TAPSET_DIR="${withval}" + fi], [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"]) + AC_SUBST(ABS_TAPSET_DIR) +fi + # https://www.freedesktop.org/software/systemd/man/daemon.html AC_ARG_WITH([systemdsystemunitdir], [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files])],, @@ -393,10 +444,13 @@ AC_OUTPUT( tests/tx_power/Makefile tests/power/Makefile tests/meas/Makefile + tests/amr/Makefile + tests/csd/Makefile doc/Makefile doc/examples/Makefile doc/manuals/Makefile contrib/Makefile + contrib/ber/Makefile contrib/systemd/Makefile contrib/osmo-bts.spec Makefile) diff --git a/contrib/Makefile.am b/contrib/Makefile.am index 3439c97b..5594199b 100644 --- a/contrib/Makefile.am +++ b/contrib/Makefile.am @@ -1 +1 @@ -SUBDIRS = systemd +SUBDIRS = systemd ber diff --git a/contrib/ber/Makefile.am b/contrib/ber/Makefile.am new file mode 100644 index 00000000..9bd7f404 --- /dev/null +++ b/contrib/ber/Makefile.am @@ -0,0 +1,28 @@ +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + -I$(builddir) \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(NULL) + +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(NULL) + +noinst_PROGRAMS = rtp_ber rtp_gen_map + +rtp_ber_SOURCES = rtp_ber.c codec_bit_class.h + +rtp_gen_map_SOURCES = rtp_gen_map.c + +update_codec_bit_class_h: rtp_gen_map + $(AM_V_GEN)./$< > $(top_srcdir)/contrib/ber/codec_bit_class.h diff --git a/contrib/ber/README b/contrib/ber/README new file mode 100644 index 00000000..07c4a785 --- /dev/null +++ b/contrib/ber/README @@ -0,0 +1,26 @@ +BER testing tool +---------------- + +* Check all configs (MSC/BSC/BTS) for proper codec support + - FR enabled + - EFR enabled + - AMR 12.2 enabled (and all other modes disabled !) + - Use `amr-payload octet-aligned` in BSC config + +* Check BTS config + - Disable jitter buffer : `bts N / rtp jitter-buffer 0` + +* Check BSC config + - Disable radio timeout : `network / bts n / radio-link-timeout infinite` + +* Start BER testing tool + - `./rtp_ber 4000` + +* On the MSC CLI, start a silent-call, then request GSM to test loop + - `subscriber imsi <XXX> silent-call start tch/f speech-amr` + - `subscriber imsi <XXX> ms-test close-loop b` + + Don't forget to terminate the loop and terminate the silent call ! + + - `subscriber imsi <XXX> ms-test open-loop` + - `subscriber imsi <XXX> silent-call stop` diff --git a/contrib/ber/codec_bit_class.h b/contrib/ber/codec_bit_class.h new file mode 100644 index 00000000..2a712e76 --- /dev/null +++ b/contrib/ber/codec_bit_class.h @@ -0,0 +1,59 @@ +static const int gsm_fr_bitclass[] = { + -1, -1, -1, -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, 1, 2, 2, + 0, 0, 1, 2, 2, 0, 0, 1, 2, 2, 0, 1, 1, 2, 0, 1, + 2, 2, 0, 1, 2, 1, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, + 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, + 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, + 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, + 1, 2, 1, 1, 2, 1, 1, 2, 0, 0, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, + 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, + 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, + 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 2, + 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, + 2, 2, 1, 2, 2, 1, 2, 2, +}; + +static const int gsm_efr_bitclass[] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 2, 2, 1, 2, +}; + +static const int gsm_amr_12_2_bitclass[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, -1, -1, -1, -1, +}; + diff --git a/contrib/ber/rtp_ber.c b/contrib/ber/rtp_ber.c new file mode 100644 index 00000000..01c1441a --- /dev/null +++ b/contrib/ber/rtp_ber.c @@ -0,0 +1,483 @@ +/* RTP based GSM BER testing for osmo-bts, implementing ideas described in + * https://osmocom.org/projects/osmobts/wiki/BER_Testing + * + * In short: The command transmits a PRBS sequence encapsulated in RTP frames, which are sent + * to the BTS, which transmits that data in the (unimpaired) downlink. The mobile station + * receives the data and is instructed to loop it back in the (possibly impaired) uplink. + * The BTS receives that uplink, puts in in RTP frames which end up being received back by this + * very tool. By correlating the received RTP with the PRBS sequence, this tool can compute + * the BER (Bit Error Rate) of the (possibly impaired) uplink. Doing this with different + * RF channel model simulators in the uplink allows to establish BER at different levels and + * channel conditions. */ + +/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <osmocom/codec/codec.h> +#include <osmocom/core/logging.h> +#include <osmocom/core/prbs.h> +#include <osmocom/core/timer.h> +#include <osmocom/core/utils.h> +#include <osmocom/trau/osmo_ortp.h> + +#include <codec_bit_class.h> + + +struct app_state { + struct osmo_rtp_socket *rs; + + enum { + WAIT_CONN = 0, /* Wait for incoming connection */ + WAIT_LOOP, /* Wait for a somewhat valid packet to start measuring */ + RUNNING, /* Main state */ + } state; + + int pt; + + int ref_len; + uint8_t ref_bytes[GSM_FR_BYTES]; /* FR is the largest possible one */ + ubit_t ref_bits[8*GSM_FR_BYTES]; + + struct osmo_timer_list rtp_timer; + + uint16_t rx_last_seq; + uint32_t rx_last_ts; + uint32_t rx_idx; + uint32_t tx_idx; + + const int *err_tbl; /* Classification table */ + int err_frames; /* Number of accumulated frames */ + int err_cnt[3]; /* Bit error counter */ + int err_tot[3]; /* Total # bits in that class */ +}; + +#define FLOW_REG_TX_MAX_ADVANCE 200 +#define FLOW_REG_TX_MIN_ADVANCE 50 + + +const struct log_info log_info; + + +static const uint8_t amr_size_by_ft[] = { + [0] = 12, /* 4.75 */ + [1] = 13, /* 5.15 */ + [2] = 15, /* 5.9 */ + [3] = 17, /* 6.7 */ + [4] = 19, /* 7.4 */ + [5] = 20, /* 7.95 */ + [6] = 26, /* 10.2 */ + [7] = 31, /* 12.2 */ + [8] = 5, /* SID */ +}; + +static const char * const amr_rate_by_ft[] = { + [0] = "4.75", + [1] = "5.15", + [2] = "5.9", + [3] = "6.7", + [4] = "7.4", + [5] = "7.95", + [6] = "10.2", + [7] = "12.2", + [8] = "SID", +}; + + +static void +_gsm_fr_gen_ref(struct app_state *as) +{ + struct osmo_prbs_state pn9; + + /* Length */ + as->ref_len = GSM_FR_BYTES; + + /* Marker */ + as->ref_bits[0] = 1; + as->ref_bits[1] = 1; + as->ref_bits[2] = 0; + as->ref_bits[3] = 1; + + /* PN */ + osmo_prbs_state_init(&pn9, &osmo_prbs9); + pn9.state = 31; + osmo_prbs_get_ubits(&as->ref_bits[4], 260, &pn9); + + /* Convert to bytes */ + osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_FR_BYTES, 0); + + /* Init error classes */ + as->err_tot[0] = 50; + as->err_tot[1] = 132; + as->err_tot[2] = 78; + as->err_tbl = gsm_fr_bitclass; +} + +static void +_gsm_efr_gen_ref(struct app_state *as) +{ + struct osmo_prbs_state pn9; + + /* Length */ + as->ref_len = GSM_EFR_BYTES; + + /* Marker */ + as->ref_bits[0] = 1; + as->ref_bits[1] = 1; + as->ref_bits[2] = 0; + as->ref_bits[3] = 0; + + /* PN */ + osmo_prbs_state_init(&pn9, &osmo_prbs9); + pn9.state = 31; + osmo_prbs_get_ubits(&as->ref_bits[4], 244, &pn9); + + /* Convert to bytes */ + osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 8*GSM_EFR_BYTES, 0); + + /* Init error classes */ + as->err_tot[0] = 50; + as->err_tot[1] = 125; + as->err_tot[2] = 73; + as->err_tbl = gsm_efr_bitclass; +} + +static void +_gsm_amr_gen_ref(struct app_state *as) +{ + struct osmo_prbs_state pn9; + uint8_t hdr[2]; + + /* Length */ + as->ref_len = 33; + + /* Header */ + hdr[0] = 0x70; + hdr[1] = 0x3c; + osmo_pbit2ubit_ext(as->ref_bits, 0, hdr, 0, 16, 0); + + /* PN */ + osmo_prbs_state_init(&pn9, &osmo_prbs9); + pn9.state = 31; + osmo_prbs_get_ubits(&as->ref_bits[16], 244, &pn9); + + /* Unused bits */ + as->ref_bits[260] = 0; + as->ref_bits[261] = 0; + as->ref_bits[262] = 0; + as->ref_bits[263] = 0; + + /* Convert to bytes */ + osmo_ubit2pbit_ext(as->ref_bytes, 0, as->ref_bits, 0, 264, 0); + + /* Init error classes */ + as->err_tot[0] = 81; + as->err_tot[1] = 163; + as->err_tot[2] = -1; + as->err_tbl = gsm_amr_12_2_bitclass; +} + + +static void +_gsm_gen_ref(struct app_state *as) +{ + switch (as->pt) { + case RTP_PT_GSM_FULL: + _gsm_fr_gen_ref(as); + break; + case RTP_PT_GSM_EFR: + _gsm_efr_gen_ref(as); + break; + case RTP_PT_AMR: + _gsm_amr_gen_ref(as); + break; + default: + fprintf(stderr, "[!] Unsupported payload type for BER measurement\n"); + } +} + +static int +_gsm_ber(struct app_state *as, const uint8_t *payload, unsigned int payload_len) +{ + ubit_t rx_bits[8*33]; + int err[3]; /* Class 1a, 1b, 2 */ + int ones; + int i, j; + + if (payload) { + /* Process real-payload */ + osmo_pbit2ubit_ext(rx_bits, 0, payload, 0, 8*payload_len, 0); + + err[0] = err[1] = err[2] = 0; + ones = 0; + + for (i = 0; i < 8 * payload_len; i++) { + j = as->err_tbl[i]; + if (j >= 0) { + err[j] += rx_bits[i] ^ as->ref_bits[i]; + ones += rx_bits[i]; + } + } + + if (ones < 32) { // This frames is probably us underrunning Tx, don't use it + fprintf(stderr, "[w] Frame ignored as probably TX underrun %d %d\n", as->tx_idx, as->rx_idx); + return 1; + } + } else { + /* No payload -> Lost frame completely */ + err[0] = as->err_tot[0] / 2; + err[1] = as->err_tot[1] / 2; + err[2] = as->err_tot[2] / 2; + } + + if (as->state == RUNNING) { + /* Update records */ + if (err[0] != 0) { + /* Class 1a bits bad -> Frame error */ + as->err_cnt[0]++; + } + + as->err_cnt[1] += err[1]; /* Class 1b */ + as->err_cnt[2] += err[2]; /* class 2 */ + + as->err_frames++; + + /* Enough for a read-out ? */ + if (as->err_frames == 200) { + printf("FBER: %4.2f C1b RBER: %5.3f C2 RBER: %5.3f\n", + 100.0f * as->err_cnt[0] / as->err_frames, + 100.0f * as->err_cnt[1] / (as->err_tot[1] * as->err_frames), + 100.0f * as->err_cnt[2] / (as->err_tot[2] * as->err_frames) + ); + memset(as->err_cnt, 0, sizeof(as->err_cnt)); + as->err_frames = 0; + } + } + + return err[0] != 0; +} + +static int +_rtp_check_payload_type(const uint8_t *payload, unsigned int payload_len) +{ + uint8_t ft; + int pt = -1; + + switch (payload_len) { + case GSM_FR_BYTES: /* FR or AMR 12.2k */ + /* Check for AMR */ + ft = (payload[1] >> 3) & 0xf; + if (ft == 7) + pt = RTP_PT_AMR; + + /* Check for FR */ + else if ((payload[0] & 0xF0) == 0xD0) + pt = RTP_PT_GSM_FULL; + + /* None of the above */ + else + fprintf(stderr, "[!] FR without 0xD0 signature or AMR with unknwon Frame Type ?!?\n"); + + break; + case GSM_EFR_BYTES: /* EFR */ + if ((payload[0] & 0xF0) != 0xC0) + fprintf(stderr, "[!] EFR without 0xC0 signature ?!?\n"); + pt = RTP_PT_GSM_EFR; + break; + case GSM_HR_BYTES: /* HR */ + pt = RTP_PT_GSM_HALF; + break; + default: /* AMR */ + { + uint8_t cmr, cmi, sti; + cmr = payload[0] >> 4; + ft = (payload[1] >> 3) & 0xf; + + if (payload_len != amr_size_by_ft[ft]+2) + fprintf(stderr, "AMR FT %u(%s) but size %u\n", + ft, amr_rate_by_ft[ft], payload_len); + + switch (ft) { + case 0: case 1: case 2: case 3: + case 4: case 5: case 6: case 7: + cmi = ft; + printf("AMR SPEECH with FT/CMI %u(%s), " + "CMR %u\n", + cmi, amr_rate_by_ft[cmi], + cmr); + break; + case 8: /* SID */ + cmi = (payload[2+4] >> 1) & 0x7; + sti = payload[2+4] & 0x10; + printf("AMR SID %s with CMI %u(%s), CMR %u(%s)\n", + sti ? "UPDATE" : "FIRST", + cmi, amr_rate_by_ft[cmi], + cmr, amr_rate_by_ft[cmr]); + break; + } + } + break; + } + + return pt; +} + +static void +rtp_timer_cb(void *priv) +{ + struct app_state *as = (struct app_state *)priv; + + /* Send at least one frame if we're not too far ahead */ + if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MAX_ADVANCE)) { + osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION); + as->tx_idx++; + } else { + fprintf(stderr, "Skipped\n"); + } + + /* Then maybe a second one to try and catch up to RX */ + if (as->tx_idx < (as->rx_idx + FLOW_REG_TX_MIN_ADVANCE)) { + osmo_rtp_send_frame(as->rs, as->ref_bytes, as->ref_len, GSM_RTP_DURATION); + as->tx_idx++; + } + + /* Re-schedule */ + osmo_timer_schedule(&as->rtp_timer, 0, 20000); +} + +static int +rtp_seq_num_diff(uint16_t new, uint16_t old) +{ + int d = (int)new - (int)old; + while (d > 49152) + d -= 65536; + while (d < -49152) + d += 65536; + return d; +} + +static void +rtp_rx_cb(struct osmo_rtp_socket *rs, + const uint8_t *payload, unsigned int payload_len, + uint16_t seq_number, uint32_t timestamp, bool marker) +{ + struct app_state *as = (struct app_state *)rs->priv; + int pt, rc, d; + +// printf("Rx(%u, %d, %d, %d): %s\n", payload_len, seq_number, timestamp, marker, osmo_hexdump(payload, payload_len)); + + /* Identify payload */ + pt = _rtp_check_payload_type(payload, payload_len); + + /* First packet ? */ + if (as->state == WAIT_CONN) { + /* Setup for this payload type */ + as->pt = pt; + osmo_rtp_socket_set_pt(as->rs, pt); + _gsm_gen_ref(as); + + /* Timer every 20 ms */ + osmo_timer_setup(&as->rtp_timer, rtp_timer_cb, as); + osmo_timer_add(&as->rtp_timer); + osmo_timer_schedule(&as->rtp_timer, 0, 20000); + + /* Init our time tracking */ + as->rx_last_seq = seq_number; + as->rx_last_ts = timestamp; + + /* Now we wait for a loop */ + as->state = WAIT_LOOP; + } + + /* RX sequence & timstamp tracking */ + if (rtp_seq_num_diff(seq_number, as->rx_last_seq) > 1) + fprintf(stderr, "[!] RTP sequence number discontinuity (%d -> %d)\n", as->rx_last_seq, seq_number); + + d = (timestamp - as->rx_last_ts) / GSM_RTP_DURATION; + + as->rx_idx += d; + as->rx_last_seq = seq_number; + as->rx_last_ts = timestamp; + + /* Account for missing frames in BER tracking */ + if (d > 1) { + fprintf(stderr, "[!] RTP %d missing frames assumed lost @%d\n", d-1, seq_number); + while (--d) + _gsm_ber(as, NULL, 0); + } + + /* BER analysis */ + rc = _gsm_ber(as, payload, payload_len); + + if ((as->state == WAIT_LOOP) && (rc == 0)) + as->state = RUNNING; +} + + +int main(int argc, char **argv) +{ + struct app_state _as, *as = &_as; + int rc, port; + + /* Args */ + if (argc < 2) + return -1; + + port = atoi(argv[1]); + + /* App init */ + memset(as, 0x00, sizeof(struct app_state)); + + log_init(&log_info, NULL); + osmo_rtp_init(NULL); + + /* Start auto-connect RTP socket */ + as->rs = osmo_rtp_socket_create(NULL, 0); + + as->rs->priv = as; + as->rs->rx_cb = rtp_rx_cb; + + /* Jitter buffer gets in the way, we want the raw traffic */ + osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JIT_ADAP, 0); + osmo_rtp_socket_set_param(as->rs, OSMO_RTP_P_JITBUF, 0); + + /* Bind to requested port */ + fprintf(stderr, "[+] Binding RTP socket on port %u...\n", port); + rc = osmo_rtp_socket_bind(as->rs, "0.0.0.0", port); + if (rc < 0) { + fprintf(stderr, "[!] error binding RTP socket: %d\n", rc); + return rc; + } + + /* We 'connect' to the first source we hear from */ + osmo_rtp_socket_autoconnect(as->rs); + + /* Main loop */ + while (1) + osmo_select_main(0); + + return 0; +} diff --git a/contrib/ber/rtp_gen_map.c b/contrib/ber/rtp_gen_map.c new file mode 100644 index 00000000..40b70253 --- /dev/null +++ b/contrib/ber/rtp_gen_map.c @@ -0,0 +1,145 @@ +/* utility to generate codec_bit_class.h, a file with structures + * describing which [protection] class each bit of a given codec frame belongs to */ + +/* (C) 2019 sysmocom - s.f.m.c. GmbH; Author: Sylvain Munaut + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include <stdio.h> + +#include <osmocom/codec/codec.h> + + +static int +gen_table_fr(int *tbl) +{ + int i, j; + + tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1; + + for (i = 0; i < 260; i++) { + j = 4 + gsm610_bitorder[i]; + if (i < 50) + tbl[j] = 0; /* Class 1a */ + else if (i < 182) + tbl[j] = 1; /* Class 1b */ + else + tbl[j] = 2; /* Class 2 */ + } + + return GSM_FR_BYTES * 8; +} + +static int +gen_table_efr(int *tbl) +{ + int i, j, k; + + tbl[0] = tbl[1] = tbl[2] = tbl[3] = -1; + + for (i = 0; i < 260; i++) { + j = gsm660_bitorder[i]; + + if (j < 71) + k = j; + else if (j < 73) + k = 71; + else if (j < 123) + k = j - 2; + else if (j < 125) + k = 119; + else if (j < 178) + k = j - 4; + else if (j < 180) + k = 172; + else if (j < 230) + k = j - 6; + else if (j < 232) + k = 222; + else if (j < 252) + k = j - 8; + else + continue; + + if (i < 50) + tbl[k] = 0; /* Class 1a */ + else if (i < 182) + tbl[k] = 1; /* Class 1b */ + else + tbl[k] = 2; /* Class 2 */ + } + + return GSM_EFR_BYTES * 8; +} + +static int +gen_table_amr_12_2(int *tbl) +{ + int i; + + for (i = 0; i < 16; i++) + tbl[i] = -1; + + for (i = 0; i < 244; i++) + tbl[i+16] = i < 81 ? 0 : 1; + + for (i = 0; i < 4; i++) + tbl[i+16+244] = -1; + + return 8 * 33; +} + + +static void +print_table(const char *name, int *tbl, int len) +{ + int i; + + printf("static const int %s[] = {\n", name); + + for (i = 0; i < len; i++) { + if ((i & 15) == 0) + printf("\t"); + + printf("%2d", tbl[i]); + + if (((i & 15) == 15) || (i == len-1)) + printf(",\n"); + else + printf(", "); + } + + printf("};\n\n"); +} + + +int main(int argc, char *argv[]) +{ + int tbl[33*8]; + int rv; + + rv = gen_table_fr(tbl); + print_table("gsm_fr_bitclass", tbl, rv); + + rv = gen_table_efr(tbl); + print_table("gsm_efr_bitclass", tbl, rv); + + rv = gen_table_amr_12_2(tbl); + print_table("gsm_amr_12_2_bitclass", tbl, rv); + + return 0; +} diff --git a/contrib/jenkins_bts_trx.sh b/contrib/jenkins_bts_trx.sh index 54efa56f..9ac820d0 100755 --- a/contrib/jenkins_bts_trx.sh +++ b/contrib/jenkins_bts_trx.sh @@ -9,7 +9,8 @@ export LD_LIBRARY_PATH="$inst/lib" osmo-build-dep.sh libosmocore "" --disable-doxygen -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" @@ -17,6 +18,7 @@ configure_flags="\ --enable-sanitize \ --enable-werror \ --enable-trx \ + --enable-external-tests \ " build_bts "osmo-bts-trx" "$configure_flags" diff --git a/contrib/jenkins_lc15.sh b/contrib/jenkins_lc15.sh index c7d62c96..89dd54b6 100755 --- a/contrib/jenkins_lc15.sh +++ b/contrib/jenkins_lc15.sh @@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" osmo-layer1-headers.sh lc15 "$FIRMWARE_VERSION" diff --git a/contrib/jenkins_oc2g.sh b/contrib/jenkins_oc2g.sh index b8badce6..e4795cf5 100755 --- a/contrib/jenkins_oc2g.sh +++ b/contrib/jenkins_oc2g.sh @@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" osmo-layer1-headers.sh oc2g "$FIRMWARE_VERSION" diff --git a/contrib/jenkins_oct.sh b/contrib/jenkins_oct.sh index bd57dd18..d1b6aee2 100755 --- a/contrib/jenkins_oct.sh +++ b/contrib/jenkins_oct.sh @@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" osmo-layer1-headers.sh oct "$FIRMWARE_VERSION" diff --git a/contrib/jenkins_oct_and_bts_trx.sh b/contrib/jenkins_oct_and_bts_trx.sh index 67f67aa4..f188147d 100755 --- a/contrib/jenkins_oct_and_bts_trx.sh +++ b/contrib/jenkins_oct_and_bts_trx.sh @@ -9,7 +9,8 @@ export LD_LIBRARY_PATH="$inst/lib" osmo-build-dep.sh libosmocore "" --disable-doxygen -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" @@ -20,6 +21,7 @@ configure_flags="\ --with-octsdr-2g=$deps/layer1-headers/ \ --enable-octphy \ --enable-trx \ + --enable-external-tests \ " build_bts "osmo-bts-octphy+trx" "$configure_flags" diff --git a/contrib/jenkins_sysmobts.sh b/contrib/jenkins_sysmobts.sh index d0d05ae6..87a98f33 100755 --- a/contrib/jenkins_sysmobts.sh +++ b/contrib/jenkins_sysmobts.sh @@ -9,7 +9,8 @@ osmo-build-dep.sh libosmocore "" --disable-doxygen export PKG_CONFIG_PATH="$inst/lib/pkgconfig:$PKG_CONFIG_PATH" export LD_LIBRARY_PATH="$inst/lib" -osmo-build-dep.sh libosmo-abis +osmo-build-dep.sh libosmo-abis "" --disable-dahdi +osmo-build-dep.sh libosmo-netif "" --disable-doxygen cd "$deps" osmo-layer1-headers.sh sysmo "$FIRMWARE_VERSION" @@ -21,6 +22,7 @@ configure_flags="\ --enable-werror \ --enable-sysmocom-bts \ --with-sysmobts=$inst/include/ \ + --enable-external-tests \ " # This will not work for the femtobts diff --git a/contrib/osmo-bts.spec.in b/contrib/osmo-bts.spec.in index a6d5e861..73731cf6 100644 --- a/contrib/osmo-bts.spec.in +++ b/contrib/osmo-bts.spec.in @@ -27,16 +27,15 @@ BuildRequires: pkgconfig >= 0.20 %if 0%{?suse_version} BuildRequires: systemd-rpm-macros %endif -BuildRequires: pkgconfig(libosmoabis) >= 1.1.0 -BuildRequires: pkgconfig(libosmocodec) >= 1.5.0 -BuildRequires: pkgconfig(libosmocoding) >= 1.5.0 -BuildRequires: pkgconfig(libosmocore) >= 1.5.0 -BuildRequires: pkgconfig(libosmoctrl) >= 1.5.0 -BuildRequires: pkgconfig(libosmogsm) >= 1.5.0 -BuildRequires: pkgconfig(libosmotrau) >= 1.1.0 -BuildRequires: pkgconfig(libosmovty) >= 1.5.0 -### FIXME: DependencyHACK to include osmocom/gprs/protocol/gsm_04_60.h -BuildRequires: pkgconfig(libosmogb) +BuildRequires: pkgconfig(libosmocodec) >= 1.9.0 +BuildRequires: pkgconfig(libosmocoding) >= 1.9.0 +BuildRequires: pkgconfig(libosmocore) >= 1.9.0 +BuildRequires: pkgconfig(libosmoctrl) >= 1.9.0 +BuildRequires: pkgconfig(libosmogsm) >= 1.9.0 +BuildRequires: pkgconfig(libosmovty) >= 1.9.0 +BuildRequires: pkgconfig(libosmoabis) >= 1.5.0 +BuildRequires: pkgconfig(libosmotrau) >= 1.5.0 +BuildRequires: pkgconfig(libosmo-netif) >= 1.4.0 %{?systemd_requires} %description diff --git a/contrib/systemd/lc15bts-mgr.service b/contrib/systemd/lc15bts-mgr.service index bf788e61..350a1a24 100644 --- a/contrib/systemd/lc15bts-mgr.service +++ b/contrib/systemd/lc15bts-mgr.service @@ -2,11 +2,15 @@ Description=osmo-bts manager for LC15 / sysmoBTS 2100 After=lc15-sysdev-remap.service Wants=lc15-sysdev-remap.service +After=network-online.target +Wants=network-online.target [Service] Type=simple NotifyAccess=all WatchdogSec=21780s +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 diff --git a/contrib/systemd/oc2gbts-mgr.service b/contrib/systemd/oc2gbts-mgr.service index ed915b33..883e0ba0 100644 --- a/contrib/systemd/oc2gbts-mgr.service +++ b/contrib/systemd/oc2gbts-mgr.service @@ -2,11 +2,15 @@ Description=osmo-bts manager for OC-2G After=oc2g-sysdev-remap.service Wants=oc2g-sysdev-remap.service +After=network-online.target +Wants=network-online.target [Service] Type=simple NotifyAccess=all WatchdogSec=21780s +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 diff --git a/contrib/systemd/osmo-bts-lc15.service b/contrib/systemd/osmo-bts-lc15.service index 7c511100..03341bd3 100644 --- a/contrib/systemd/osmo-bts-lc15.service +++ b/contrib/systemd/osmo-bts-lc15.service @@ -1,17 +1,22 @@ [Unit] Description=osmo-bts for LC15 / sysmoBTS 2100 +After=network-online.target +Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/osmo-bts-lc15 -t 2 -s -c /etc/osmocom/osmo-bts-lc15.cfg -M +StateDirectory=osmocom +WorkingDirectory=%S/osmocom RuntimeDirectory=osmo-bts Restart=always RestartSec=2 -RestartPreventExitStatus=1 -# The msg queues must be read fast enough +# CPU scheduling policy: CPUSchedulingPolicy=rr -CPUSchedulingPriority=1 +# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority): +CPUSchedulingPriority=11 +# See sched(7) for further details on real-time policies and priorities [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-bts-oc2g.service b/contrib/systemd/osmo-bts-oc2g.service index 860aeb1f..bc64a54c 100644 --- a/contrib/systemd/osmo-bts-oc2g.service +++ b/contrib/systemd/osmo-bts-oc2g.service @@ -1,17 +1,22 @@ [Unit] Description=osmo-bts for OC-2G +After=network-online.target +Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/osmo-bts-oc2g -s -c /etc/osmocom/osmo-bts-oc2g.cfg -M +StateDirectory=osmocom +WorkingDirectory=%S/osmocom RuntimeDirectory=osmo-bts Restart=always RestartSec=2 -RestartPreventExitStatus=1 -# The msg queues must be read fast enough +# CPU scheduling policy: CPUSchedulingPolicy=rr -CPUSchedulingPriority=1 +# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority): +CPUSchedulingPriority=11 +# See sched(7) for further details on real-time policies and priorities [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-bts-sysmo.service b/contrib/systemd/osmo-bts-sysmo.service index 92558172..3d996554 100644 --- a/contrib/systemd/osmo-bts-sysmo.service +++ b/contrib/systemd/osmo-bts-sysmo.service @@ -1,5 +1,7 @@ [Unit] Description=osmo-bts for sysmocom sysmoBTS +After=network-online.target +Wants=network-online.target [Service] Type=simple @@ -7,13 +9,16 @@ ExecStartPre=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness' ExecStart=/usr/bin/osmo-bts-sysmo -s -c /etc/osmocom/osmo-bts-sysmo.cfg -M ExecStopPost=/bin/sh -c 'echo 0 > /sys/class/leds/activity_led/brightness' ExecStopPost=/bin/sh -c 'cat /lib/firmware/sysmobts-v?.bit > /dev/fpgadl_par0 ; sleep 3s; cat /lib/firmware/sysmobts-v?.out > /dev/dspdl_dm644x_0; sleep 1s' +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 -RestartPreventExitStatus=1 -# The msg queues must be read fast enough +# CPU scheduling policy: CPUSchedulingPolicy=rr -CPUSchedulingPriority=1 +# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority): +CPUSchedulingPriority=20 +# See sched(7) for further details on real-time policies and priorities [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-bts-trx.service b/contrib/systemd/osmo-bts-trx.service index 97c2b070..9763dff8 100644 --- a/contrib/systemd/osmo-bts-trx.service +++ b/contrib/systemd/osmo-bts-trx.service @@ -1,15 +1,21 @@ [Unit] Description=Osmocom osmo-bts for osmo-trx +After=network-online.target +Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/osmo-bts-trx -s -c /etc/osmocom/osmo-bts-trx.cfg +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 -# Let it process messages quickly enough +# CPU scheduling policy: CPUSchedulingPolicy=rr -CPUSchedulingPriority=1 +# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority): +CPUSchedulingPriority=11 +# See sched(7) for further details on real-time policies and priorities [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/osmo-bts-virtual.service b/contrib/systemd/osmo-bts-virtual.service index 16332669..dee3ab7f 100644 --- a/contrib/systemd/osmo-bts-virtual.service +++ b/contrib/systemd/osmo-bts-virtual.service @@ -1,15 +1,21 @@ [Unit] Description=Osmocom GSM BTS for virtual Um layer based on GSMTAP/UDP +After=network-online.target +Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/osmo-bts-virtual -s -c /etc/osmocom/osmo-bts-virtual.cfg +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 -# Let it process messages quickly enough +# CPU scheduling policy: CPUSchedulingPolicy=rr -CPUSchedulingPriority=1 +# For real-time scheduling policies an integer between 1 (lowest priority) and 99 (highest priority): +CPUSchedulingPriority=11 +# See sched(7) for further details on real-time policies and priorities [Install] WantedBy=multi-user.target diff --git a/contrib/systemd/sysmobts-mgr.service b/contrib/systemd/sysmobts-mgr.service index 4346991d..ef2751c7 100644 --- a/contrib/systemd/sysmobts-mgr.service +++ b/contrib/systemd/sysmobts-mgr.service @@ -1,9 +1,13 @@ [Unit] Description=osmo-bts manager for sysmoBTS +After=network-online.target +Wants=network-online.target [Service] Type=simple ExecStart=/usr/bin/sysmobts-mgr -ns -c /etc/osmocom/sysmobts-mgr.cfg +StateDirectory=osmocom +WorkingDirectory=%S/osmocom Restart=always RestartSec=2 diff --git a/debian/changelog b/debian/changelog index bc44837b..410c549a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,816 @@ +osmo-bts (1.7.0) unstable; urgency=medium + + [ arehbein ] + * common: Fix memleak in get_smscb_block() + * doc: Adapt to use of 'telnet_init_default' + * common: Remove redundant checks + * common: Remove unused function gsm_objclass2nmstate() + * gsm_objclass2mo(): Change signature/set NACK cause + * gsm_objclass2obj(): Change signature/set NACK cause + * PCU interface: Log version when starting listener + * common: Have PCU socket connection use osmo_wqueue + * common: Make socket queue max. length configurable + + [ Max ] + * bts-virtual: fix segfault + * osmo-bts-trx: log TRXC/TRXD connection address + * osmo-bts-trx: use bool for true/false flags + * GSMTAP: allow configuring local address + * license: fix typos + + [ Vadim Yanitskiy ] + * paging_add_imm_ass(): remove meaningless from_pcu argument + * osmo-bts-{trx,virtual}: clean up bts_model_l1sap_down() + * osmo-bts-{trx,virtual}: check lchan against NULL in bts_model_l1sap_down() + * osmo-bts-{trx,virtual}: set rc on error in bts_model_l1sap_down() + * GSMTAP: print 'gsmtap-local-host' if not NULL + * osmo-bts-virtual: indicate BTS_FEAT_[E]GPRS to the BSC + * rsl: remove redundant gsm_lchan_name() in rsl_tx_rf_rel_ack() + * rsl: reduce logging verbosity on some messages + * tests: use -no-install libtool flag to avoid ./lt-* scripts + * scheduler: log pchan value in trx_sched_set_pchan() + * osmo-bts-virtual: properly handle dynamic TS in vbts_set_ts() + * contrib/osmo-bts.spec.in: do not depend on libosmogb + * osmo-bts-trx: properly activate [CBCH/]BCCH/CCCH + * rsl: rsl_handle_chan_mod_ie(): add missing GSM48_CMODE_* values + * osmo-bts-{sysmo,lc15,oc2g}: fix segfault in ph_tch_req() + * tests: $(BUILT_SOURCES) is not defined, depend on osmo-bts-virtual + * osmo-bts-virtual: properly activate [CBCH/]BCCH/CCCH + * flags: add missing entries to bts_impl_flag_desc[] + * flags: group BTS_INTERNAL_FLAG_* into an enum + * flags: ensure completeness of bts_impl_flag_desc[] + * fixup: common: Remove unused function gsm_objclass2nmstate() + * oml: gsm_objclass2{mo,obj}(): cosmetic: return immediately + * oml: gsm_objclass2{mo,obj}(): set cause for unknown obj_class + * oml: reset BCCH carrier power reduction mode (if enabled) + * copyright: fix typo: sysmocom s/s.m.f.c./s.f.m.c./ GmbH + * osmo-bts-trx: alloc/free burst buffers in trx_sched_set_lchan() + * osmo-bts-trx: use direct pointer to chan_state->{ul,dl}_bursts + * osmo-bts-trx: tch_dl_dequeue(): do not drop CSD frames + * osmo-bts-trx: tx_pdtch_fn(): use msgb_l2len() + * osmo-bts-trx: fix recent regression in Tx lchan handlers + * osmo-bts-trx: remove redundant memset() on receipt of NOPE.ind + * l1sap: use gsm0502_fn2ccch_block() from libosmogsm + * scheduler: fix wrong union field in _sched_compose_tch_ind() + * scheduler: use msgb_hexdump_l2() in _sched_compose_tch_ind() + * scheduler: unify argument names/order for _sched_compose_*_ind() + * scheduler: constify *data pointer in _sched_compose_*_ind() + * scheduler: use size_t for data_len in _sched_compose_*_ind() + * fix bts_supports_cm(): properly check feature flags for VGCS/VBS + * measurement: suppress unsupported tch_mode warnings for CSD + * osmo-bts-trx: pull the AMR header in tch_dl_dequeue() + * osmo-bts-trx: implement CSD scheduling support + * osmo-bts-trx: implement FACCH/[FH] support for CSD + * osmo-bts-trx: implement TCH/F2.4 support for CSD + * osmo-bts-trx: visualize rx_tch[fh]_fn() functions + * osmo-bts-trx: unify and enrich 'Received bad data' logging + * osmo-bts-trx: rx_tchf_fn(): move compute_ber10k() above + * osmo-bts-trx: rx_tch[fh]_fn(): combine rc-checking ifs + * osmo-bts-trx: change 'Received bad data' back to LOGL_DEBUG + * osmo-bts-trx: tx_tch[fh]_fn(): fix NULL pointer dereference + * osmo-bts-trx: document/clarify the meaning of BUFMAX=24 + * l1sap: proper rate adaptation for CSD (RFC4040 'clearmode') + * csd_v110_rtp_encode(): properly set E1/E2/E3 bits + * osmo-bts-trx: bts_supports_cm_data(): allow non-transparent modes + * rsl: rsl_handle_chan_mod_ie(): set lchan->csd_mode + * rsl: rsl_handle_chan_mod_ie(): do not use legacy defines + * csd_v110: fix comments in csd_v110_rtp_{en,de}code() + * csd_v110: properly set E1/E2/E3 for non-transparent data + * csd_v110: handle empty/incomplete Uplink frames gracefully + + [ Philipp Maier ] + * pcu_sock: rename rc to fd + * pcu_sock: cosmetic: remove whitespace after type cast + * pcu_sock: cosmetic: remove unnecessary line breaks + * pcu_sock: do not mess with the osmo fd flags directly + * sched_lchan_tchx: use GSM_HR_BYTES_RTP_RFC5993 constant + * l1sap: fix wording in comment + * pcu_sock: don not continue when running out of TRX space + * paging: cosmetic: rename all IMM.ASS references to MAC block + * paging: parse PCUIF data indication outside of paging.c + * paging: do not confirm PAGING COMMAND messages + * pcu_sock: move variable declaration of imsi[4] into related scope + * l1sap: cosmetic: rename payload_len to rtp_pl_len + * pcu_sock: use PCUIF version 11 (direct TLLI) + * paging: also accept zero length IMSI strings 3 + * pcuif_proto: rename tlli to msg_id + * pcu_sock: get rid of fn parameter in pcu_tx_pch_data_cnf + * pcuif_proto: remove unnecessary members from gsm_pcu_if_data_cnf_dt + * pcuif_proto: get rid of _DT, _dt (Direct TLLI) + * bts: make bts_agch_dequeue static + * pcuif_proto: use confirm flag in struct gsm_pcu_if_pch + * pcu_sock: use PCU_IF_SAPI_AGCH_2 instead PCU_IF_SAPI_AGCH + * pcu_sock: print SAPI and msg_id when sending confirmation + + [ Pau Espin Pedrol ] + * bts-trx: Fix no NM Radio{Carrier,Channel} switching to Enabled if one TRX is rf_locked + * pcu_sock: Submit all DATA.ind regardless of link quality + * pcu_sock.c: Call osmo_fd_unregister() before closing and changing bfd->fd + * Rewrite pcu_sock_write() + * lchan: Improve error path logging in gsm_pchan2chan_nr() + * cosmetic: gsm_pchan2chan_nr(): Update spec documentation + * cosmetic: bts_trx.h: Fix whitespace + * Avoid tx RF Resource Ind for disabled TRX + * bts-trx: Avoid pushing interf_meas for disabled TRX + * contrib/ber: Avoid regenerating codec_bit_class.h every build + * bts-trx: Drop unused param to internal function + * Clarify configuration of TSC on each timeslot + * bts_model_apply_oml(): Drop unneded code + * oml.c: Remove dot character at the end of log lines + * nm: Apply BTS/TRX/TS OML Attributes through NM FSMs + * nm: Drop NM_EV_SETATTR_{ACK/NACK} + * oml: Get rid of unused tlv_parsed param in bts_model_apply_oml() + * bts_model_apply_oml(): Improve definition of parameter + * lc15,oc2g,sysmo: Update GPRS NM object state at the right time + * Simplify implementation of bts_model_opstart() in all bts types + * nm: Apply OPSTART through NM FSMs + * NM: NACK received OML OPSTART if no attributes were set beforehand + * Introduce NM FSM for GPRS NSE object + * Fix octet 2 of NM GPRS Cell + * Introduce NM FSM for GPRS Cell object + * Rearrange declaration of struct gsm_bts_gprs_nsvc + * Move NSVC structs to be part of NSE + * bts: Simplify lifecycle of BTS inside bts_list + * Introduce NM FSM for GPRS NSVC object + * nm: Dispatch NM_EV_SW_ACT in cascade to BTS SiteMgr children + * Merge gsm_network into gsm_bts_sm and place gsm_bts under it + * Move GPRS NSE under BTS SiteMgr + * Drop NM_EV_BBTRANSC_INSTALLED in favour of generic NM_EV_SW_ACT + * nm: Document current state of SW_ACT in TRX related objects + * Properly report all states through NM FSM upon OML link up + * Update g_bts_sm->num_bts when bts is added/removed from bts list + * Move pcu_sock_state to gprs section of bts_sm + * pcu_sock: Allocate pcu_sock_state using g_bts_sm talloc context + * pcu_sock: Drop bts_sm pointer + * oml: Fix potential null ptr access on trx object + * bts-sysmo: Fix pinst->version filled too early + * bts-sysmo: Delay marking phy_link as connected until L1 reset + got info + * vty.c: Use already available tpp pointer + * octphy: Fix clearly wrong noop assignment + * bbtransc/rcarrier: Fix statechg done twice upon NM_EV_RX_OPSTART + * Increase PCUIF wqueue size + * bts-trx: Fix CCCH not enabled if BS_AG_BLKS_RES!=1 is provided by BSC + * rsl: Improve logic reactivating CCCH upon SI3 BS_AG_BLKS_RES change + + [ Oliver Smith ] + * gitignore: add vty pdf + * doc: rsl: add RSL_IE_IPAC_RTP_CSD_FORMAT + * rsl_rx_ipac_XXcx: parse csd_fmt_d/ir + * debian: set compat level to 10 + * systemd: depend on networking-online.target + * gitignore: add arm-poky-linux-gnueabi-libtool + * osmo-bts-sysmo: trx_mute_on_init_cb: call bts_update_status + * osmo-bts-sysmo: activate_rf: no dispatch on fail + * osmo-bts-sysmo/l1_if: move mute_rf_compl_cb up + * osmo-bts-sysmo: mute PHY until OML is ready + + [ Harald Welte ] + * DTX: bts-{sysmo,oc2g,lc15}: Print DEBUG messages about ONSET + * cosmetic: Replace %i with %d + * Introduce LOGPLCFN() for logging lchan-name + frame number + * bts-{sysmo,oc2g,lc15}: Fix RTP of AMR SID_FIRST_P1 + * common/vty: Print AMR MultiRate Configuration in "show lchan" + * bts-{sysmo,oc2g,lc15}: Dump logical channel params during MPH-ACTIVATE.req + * cosmetic: use __func__ instead of __FUNCTION__ + * lc15: fix compiler warning about wrong indent + * lc15: Remove unused warning + * lc15/oc2g: remove unused variables + * oc2g: Fix 'unused variable' compiler warning + * cosmetic: Remove "FIXME?" from Odd AMR CMI phase + * lc15: fix compiler warning about unused variable cell_size + * Replace explicit gsm_lchan_name() calls with LOGPLCHAN + * logging: Introduce LOGPLCGT() + * cosmetic: Change LOGPLCFN argument order + * paging: Add support for generating NLN/NLN-Status in P1 Rest Octets + * Add ASCI (advanced speech call items) log sub-system + * ASCI: NCH / NOTIFICATION support + * validate RSL "channel rate and type" against VGCS/VBS flags + * Store "Channel rate and type" from RSL Channel Mode IE in BTS + * ASCI: VGCS/VBS RACH -> RSL TALKER/LISTENER DETECT + * sysmo: Enable VGSCS + VBS feature flags + * omldummy: Claim to support VBS + VGCS towards BSC + + [ Mychaela N. Falconia ] + * trx: detect UL SID in EFR just like in FR + * sysmo: fix handling of SID in EFR + * common: implement rtp continuous-streaming mode + * rtp continuous-streaming: fix BFI in the quality-suppressed case + * sysmo: emit empty RTP ticks during FACCH stealing on TCH/F + * bts-{lc15,oc2g,sysmo}: support EFR in repeat_last_sid() + * RTP input, FR & EFR: preen incoming payloads for SID errors + * lc15,oc2g: fix handling of SID in EFR + * all models, FR/EFR UL: change SID check to _is_any_sid() + * trx: remove model-specific BFI packet formats + * refactor: replace rtppayload_is_valid() with preening before enqueue + * all models, HR1 codec: accept both TS101318 and RFC5993 formats + * trx: fix HR1 codec breakage from format change + * trx, HR1 codec: change UL PHY output format to TS 101 318 + * all models, HR1 codec: select RTP output format via vty option + * FR/HR/EFR TCH DL: implement DTX rules + * HR1 codec: validate ToC header in RFC5993 RTP input + * HR1 codec: act on SID indication in RFC5993 RTP input + * trx TCH DL: transmit invalid speech blocks instead of dummy FACCH + * ECU in UL path: make it optional per vty config + * ECU in UL path: move state alloc/free to l1sap + * ECU in UL path: move it from trx model to l1sap + + [ Sylvain Munaut ] + * contrib: Add BER testing tool + + [ Andreas Eversberg ] + * Change return value of bts_supports_cm() from int to bool + * ASCI: Add function to reactivate channel + * ASCI: Retrieve NCH position from System Information 1 + * ASCI: Add Notification CHannel (NCH) support + * ASCI: Add support for rest octets in Paging request type 2 and 3 + * ASCI: Send only NLN on Paging request type 1 rest octets + * ASCI: Add Notification/FACCH support + * ASCI: Repeat UPLINK FREE message until uplink becomes busy + * Add test cases for rest octets of Paging Requests + * ASCI: Enable UPLINK ACCESS on various BTS models + + [ Keith ] + * Fix incorrect order of params passed to logging macro + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 12 Sep 2023 16:05:30 +0200 + +osmo-bts (1.6.0) unstable; urgency=medium + + [ Vadim Yanitskiy ] + * osmo-bts-trx: call osmo_timer_del() unconditionally + * osmo-bts-trx: amr_loop: trigger the loop unconditionally + * osmo-bts-trx: fix handling of ciphering params in PRIM_INFO_MODIFY + * osmo-bts-trx: rx_rach_fn(): properly detect handover RACH + * osmo-bts-trx: handle MTS 0b0110 indicating an Access Burst + * osmo-bts-trx: use lookup tables for checking AMR CMI/CMR on Downlink + * osmo-bts-trx: drop ul_amr_fn_is_cmi() / dl_amr_fn_is_cmi() + + [ Pau Espin Pedrol ] + * rsl: rx ipac crcx/mdcx: Log payload_type2 + * logging: Move category descriptions to be in order with enum + * Clean up osmo-bts-*/Makefile.am + * Split out lchan rtp socket creation from rsl handling code + * Avoid counting lchan->dl_tch_queue length every time a msg is enqueued + * Use libosmocore API msgb_queue_free() to free lists + * rsl: Reduce scope of variable + * Move lchan_dl_tch_queue_enqueue to lchan.c and make it public + * cosmetic: Fix formatting of if-else block brackets + * Depend on libosmo-netif + * Clarify RTP AMR header offset in TCH enc/dec + * tests/*/Makefile.am: Fix typo in LIBOSMONETIF_CFLAGS + * tests/*/Makefile.am: Add missing libosmo-netif cflags + * oc2g: Makefile.am Fix typo in LIBOSMONETIF_LIBS + * Introduce Osmux support + * abis: Avoid TCP/IPA RSL sockets continue conn establishment while shutting down + * osmux: Log sendto() error + * lchan: Reset Abis RTP/Osmux config during lchan release + * vty: Fix SPEECH_MODE printed with hex prefix but dec value + * vty: Print Osmux CID on lchans using Osmux + * Allocate struct osmux_in_handle through new libosmo-netif APIs + * osmux: Drop logging of osmux internal counters + * osmux: Match remote address in osmux_lchan_find() + * osmux: Log remote address upon rx of osmux pkt + * osmux: Lower log level when osmux batch received for unknown CID + * osmux: nullify osmux.rtpst after freeing it + * osmux: Skip lchans in lookup which still have no remote associated + * osmux: Close osmux socket when bts is freed + * osmux: Fix null ptr dereference sending UL data before the remote is configured + * osmux: Rotate over available Osmux CID when allocating a new one + * osmux: Use new osmux_xfrm_input API to set name on each link + * vty: Fix typo in write-config: osmux / local-port + * vty: Fix typo in symbol name + + [ Max ] + * Set working directory in systemd service file + * Don't manually create pid file + * Document realtime options in .service units + * Update realtime scheduling priority in service file + * ctrl: take both address and port from vty config + * Add SI10 support + + [ Philipp Maier ] + * pcu_sock: fix sourcecode formatting + * measurement: do not call msgb_l3len without checking + * l1sap: do not call msgb_l2hlen without checking + * rsl: use unsigned int + * pcuif_proto: cosmetic: add constant PCU_IF_NUM_NSVC and replace magic numbers + * sched_lchan_tchf: replace numeric constant with define constant + * l1sap: remove unused pointer variable + * pcuif_proto: use define constant to specify nax number of trx + * pcu_sock: use ARRAY_SIZE rather then magic number + + [ Keith ] + * osmo-bts-trx: respond to tx-attenuation config in real time. + + [ Harald Welte ] + * update outdated vty copyright statement + + [ Daniel Willmann ] + * shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C + * shutdown_fsm: Add power_ramp_force() to jump straight to the tgt power + + [ daniel ] + * Revert "shutdown_fsm: Only ramp down power when stopping bts through Ctrl-C" + + [ Alexander Couzens ] + * OML: NSVC[1] MO should have the same initial state as NVSC[0] + + [ Oliver Smith ] + * oc2gbts_mgr_calib: fix build against gpsd >= 3.20 + * contrib/jenkins: build libosmo-abis without dahdi + + [ arehbein ] + * osmo-bts: Transition to use of 'telnet_init_default' + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 07 Feb 2023 17:15:52 +0100 + +osmo-bts (1.5.0) unstable; urgency=medium + + [ Pau Espin Pedrol ] + * bts_shutdown_fsm.h: Remove wrong comment describing enum + * bts: Properly free bts->shutdown_fi when struct gsm_bts is freed + * bts-trx: amr: Fix return code of osmo_amr_rtp_dec() checked too late + * Change some log levels NOTICE->INFO + * rsl: Conditionally decrease log level if cause is normal event + * bts-trx: Log lchan if avaialble in Meas Avg + * doc: rsl: Fix description of 'IP Connection Statistics' IE + * bts-trx: sched_lchan_tchh.c: Workaround gcc false positive error + * bts-sysmo: Replace use of deprecated ipa_client_conn_create API + + [ Harald Welte ] + * cbch: Fix bts_smscb_state_reset() to avoid double-free + * cbch: Fix dangling cur_msg leading to double-free in bts_cbch_reset() + * [lc15,oc2g,octphy] Fix memory leak on write queue overflow + * update git URLs (git -> https; gitea) + + [ Oliver Smith ] + * debian/control: add osmo-bts meta-package + * treewide: remove FSF address + * model_init: order features alphabetically + * model_init: set BTS_FEAT_PAGINATION_COORDINATION + * model_init: order features alphabetically, part 2 + * src/common/bts.c: set BTS_FEAT_PAGING_COORDINATION + * src/common/bts.c: set BTS_FEAT_CCN + + [ Vadim Yanitskiy ] + * oml: use proper talloc context in oml_rx_set_radio_attr() + * oml: use ts->trx as talloc-context in oml_rx_set_chan_attr() + * oml: fix copy-pasted comments in oml_rx_set_*_attr() + * oml: assign unique names to 'struct tlv_parsed' chunks + * osmo-bts-trx: use l1ts as talloc context for burst buffers + * osmo-bts-trx: fix a memleak in trx_sched_set_lchan() + * cbch: cosmetic: use talloc_zero() in bts_process_smscb_cmd() + * phy_instance_destroy(): fix NULL pointer dereference + * logging: get rid of logging category DSUM + * osmo-bts-trx: make use of OSMO_UNLIKELY() when handling TRXD PDUs + * osmo-bts-trx: cosmetic: use rate_ctr_inc2() instead of rate_ctr_inc() + * osmo-bts-trx: new rate counter 'trx_sched:dl_fh_cache_miss' + * VTY: fix ambiguity in BTS specific command definitions + * osmo-bts-trx: do not run osmo_{fr,hr}_check_sid() on FACCH/U frames + * osmo-bts-trx: rx_tchh_fn(): do not calculate BER10k for FACCH twice + * rsl: fix wrong IE being checked in rsl_rx_chan_activ() + * osmo-bts-trx: rx_tchh_fn(): fix HR SID detection (wrong offset) + * osmo-bts-trx: rx_tchh_fn(): mark valid SID frames as such + * osmo-bts-trx: use consistent naming for 'enum sched_meas_avg_mode' + * osmo-bts-trx: use a lookup table in trx_sched_meas_avg() + * osmo-bts-trx: rx_tchh_fn(): use proper meas averaging mode + * trx_sched_ul_burst(): get rid of the 'switch' statement + * fix gsm_bts_get_cbch(): CBCH can be allocated on Cn + * osmo-bts-trx: rx_tchh_fn(): indicate BER10k=0 for FACCH BFIs + * osmo-bts-trx: rx_tchh_fn(): get rid of chan_state->meas_avg_facch + * osmo-bts-trx: rx_{tchf,tchh}_fn(): also use meas_avg for BFI + * osmo-bts-trx: rx_{tchf,tchh}_fn(): shift Rx burst buffer on bid=0 + * osmo-bts-trx: rx_{tchf,tchh}_fn(): ensure complete set of bursts + * osmo-bts-trx: rx_{tchf,tchh}_fn(): get TDMA FN from meas history + * osmo-bts-trx: rx_{tchh,tchf}_fn(): use AMR CMI lookup tables + * osmo-bts-trx: rx_{tchh,tchf}_fn(): use tch_mode directly + * osmo-bts-trx: rx_tchh_fn(): fix meas reporting in signalling mode + * osmo-bts-trx: move AMR CMI lookup tables to the respective files + * osmo-bts-trx: rx_tchh_fn(): fix indexes in the AMR CMI lookup table + * osmo-bts-trx: rx_tchf_fn(): clarify indexes in the AMR CMI lookup table + * power_ctrl_params_def_reset(): set .ctrl_interval for both UL/DL + * scheduler: remove redundant OSMO_ASSERT() statements + * scheduler: rts_tchh_fn(): use a lookup table for FACCH/H + * osmo-bts-trx: rx_tchh_fn(): use a lookup table for FACCH/H + * osmo-bts-{trx,virtual}: tx_tchh_fn(): remove FACCH/H alignment check + * osmo-bts-trx: rename 'loops.[ch]' to 'amr_loop.[ch]' + * osmo-bts-trx: use '#pragma once' in amr_loop.h + * osmo-bts-trx: amr_loop: remove unneeded #includes + * rsl: de-duplicate parsing of MultiRate configuration IE + * rsl: rsl_rx_chan_{activ,modif}: do not sent an Error Report + * rsl: parse_multirate_config(): check if AMR codec is used + * logging: use a different color tone for DLOOP + * rsl: always check return value of rsl_tlv_parse() + * rsl: misc / cosmetic fixes for tx_ipac_XXcx_nack() + * osmo-bts-virtual: remove unused 'codec_mode_request' argument + * l1sap: l1sap_chan_act(): alloc DTX FSM only for TCH + * l1sap: l1sap_chan_act(): remove unused *tp argument + * osmo-bts-trx: bts_report_interf_meas(): remove unused fn param + * rsl: use hard-coded defaults if the MultiRate conf IE is absent + * tests/amr/Makefile.am: use proper binary name prefix 'amr_test_' + * tests/amr: add a unit test for amr_parse_mr_conf() + * amr: fix parsing of threshold and hysteresis in amr_parse_mr_conf() + * tests: use 'check_PROGRAMS' instead of 'noinst_PROGRAMS' + * struct amr_multirate_conf: remove ms_mode[], raname bts_mode[] + * common: fix coding style: if is not a function + * osmo-bts-trx: amr_loop: simplify trx_loop_amr_set() + * osmo-bts-trx: use C/I in the AMR link adaptation loop + * osmo-bts-trx: amr_loop: improve logging in trx_loop_amr_input() + * osmo-bts-trx: amr_loop: allow upgrading codec mode > 0 + * osmo-bts-trx: amr_loop: log if AMR mode remains unchanged + * osmo-bts-trx: amr_loop: do not miss C/I samples + * osmo-bts-trx: prioritize FACCH in s/tx_tch_common()/tch_dl_dequeue()/s + * osmo-bts-trx: tx_tchh_fn(): make handling of FACCH/H cleaner + * osmo-bts-trx: fix scheduling of dummy FACCH/H and FACCH/F + * VTY: fix NULL-pointer dereference in 'show transceiver' + * osmo-bts-trx: check if scheduling of [dummy] FACCH/H is allowed + * osmo-bts-trx: rx_{tchh,tchf}_fn(): improve logging of AMR DTX frames + * pcu_sock: comment out {dl,ul}_tbf_ext related warnings + * osmo-bts-trx: drop Uplink loss detection from Downlink path + * scheduler: trx_sched_is_sacch_fn(): make ts pointer const + * struct bts_ul_meas: reflect C/I units in field name s/c_i/ci_cb/ + * tests/meas: improve logging in test_ts45008_83_is_sub_single() + * tests/meas: improve test_ts45008_83_is_sub_is_sub() + * measurement: log SUB/FULL as text in lchan_new_ul_meas() + * measurement: move SACCH detection to process_l1sap_meas_data() + * measurement: fix matching of SUB frames by TDMA FN + * osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame + * Revert "osmo-bts-trx: rx_tchf_fn(): do not treat AFS_SID_UPDATE as SUB frame" + + -- Pau Espin Pedrol <pespin@sysmocom.de> Wed, 29 Jun 2022 09:41:38 +0200 + +osmo-bts (1.4.0) unstable; urgency=medium + + [ Philipp Maier ] + * l1sap: Store status of SRR in an lchan struct memeber + * l1sap: add logging and VTY introspection for ACCH repetition + * sched_lchan_tchh: fix frame number and fill FACCH gap + * main,abis: change model name from sysmoBTS to osmo-bts + * paging: prioritize CS related paging over PS related pagings. + * allow to configure multiple oml remote-ip addresses + * sched_lchan_tch_x: do not use cmr as ft + * sched_lchan_tch_x: use functions to determine AMR tranmssion phase + * sched_lchan_tch_x: use ul_cmr and ul_ft when generating RTP bad frame + * rsl: simplfy parse_repeated_acch_capability + * rsl: parse temporary overpower value RSL CHAN ACT / MODIFY + + [ Vadim Yanitskiy ] + * doc/examples: remove obsolete power control parameters + * doc/examples: enable stderr logging for osmo-bts-virtual.cfg + * osmo-bts-trx: fix: do not call trx_if_close() two times + * osmo-bts-trx: fix segfault on trx_phy_inst_open() failure + * l1sap: use the passed 'trx' pointer in l1sap_chan_act() + * l1sap: use TLVP_PRES_LEN() macro in l1sap_chan_act() + * l1sap: check BTS_FEAT_MULTI_TSC in l1sap_chan_act() + * l1sap: fix wrong IEI and parsing in l1sap_chan_act() + * manuals: fix wrong VTY node for 'gsmtap-sapi' command + * manuals: document GSMTAP 'enable-all' / 'disable-all' + * osmo-bts-trx: correct definition of 'osmotrx rx-gain' command + * rsl: do not blindly ignore unhandled/unknown Channel Mode + * manuals: remove deprecated command line parameters + * manuals: document new 'gsmtap-remote-host' command + * l1sap: fix incorrect pointer cast in l1sap_chan_act() + * rsl: rename, fix and refactor lchan_tchmode_from_cmode() + * rsl: add missing Channel Mode values to rsl_handle_chan_mod_ie() + * lchan2lch_par(): fix missing default branch in switch + * osmo-bts-trx: cosmetic: TRXD 'header version' -> 'PDU version' + * osmo-bts-trx: remove outdated TRXD protocol documentation + * osmo-bts-trx: cosmetic: use '#pragma once' in trx_if.h + * osmo-bts-trx: define TRXC/TRXD message buffer size + * osmo-bts-trx: 'burst type' is actually modulation type + * osmo-bts-trx: move MTS parser into trx_data_parse_mts() + * osmo-bts-trx: discard TRXD PDUs with unexpected version + * osmo-bts-trx: move TDMA frame number check to trx_data_read_cb() + * osmo-bts-trx: cosmetic: get rid of TRX_CHDR_LEN macro + * osmo-bts-trx: generalize checking of TRXD header length + * osmo-bts-trx: pass 'struct phy_instance' to TRXD dissectors + * osmo-bts-trx: refactor handling of version specific TRXD parts + * osmo-bts-trx: enlarge and share TRXD message buffer + * osmo-bts-trx: assert PDU version in trx_if_send_burst() + * osmo-bts-trx: reduce code nasting in trx_if_send_burst() + * vty: fix the use of deprecated osmo_bts_feature_name() + * common/abis: fix the use of deprecated e1inp_line_get() API + * osmo-bts-trx: refactor parse_rsp(), fix compilation warnings + * rsl: fix wrong value printed in rsl_handle_chan_mod_ie() + * struct gsm_bts_trx: remove unused leftovers from openbsc + * common/sysinfo: make struct gsm_bts_trx const in num_agch() + * osmo-bts-{lc15,oc2g}: drop redundant checks in VTY commands + * [VAMOS] struct gsm_bts_trx: fix the PHY instance pointer + * [VAMOS] Merge bts_trx_init() into gsm_bts_trx_alloc() + * [VAMOS] osmo-bts-trx: move {chan,bid} to trx_{dl,ul}_burst_{req,ind} + * osmo-bts-trx: implement TRXDv2 protocol support + * scheduler.h: cosmetic: use #pragma once + * osmo-bts-trx: cosmetic: s/trx_sched_fn/bts_sched_fn/g + * osmo-bts-trx: remove redundant assert() in bts_sched_fn() + * osmo-bts-trx: fix hopping pointer bug in bts_sched_fn() + * [VAMOS] Re-organize osmo-bts-trx specific structures + * osmo-bts-trx: clarify logging messages in trx_if_{open,close}() + * osmo-bts-{trx,virtual}: fix: pinst->trx may be NULL + * common: make the arguments of phy_{link,instance}_name() const + * [VAMOS] common: make 'struct gsm_bts_trx_ts' pointers const + * [VAMOS] gsm_data.h: fix wrong bit-mask in BSIC2BCC macro + * [VAMOS] gsm_data.h: introduce and use BTS_TSC macro + * common: phy_links_open(): warn about dangling PHY instances + * [VAMOS] osmo-bts-trx: rework and split up bts_sched_fn() + * Fix regression in 'osmo-bts-trx: rework and split up bts_sched_fn()' + * [VAMOS] osmo-bts-trx: implement and enable PDU batching for TRXDv2 + * [VAMOS] osmo-bts-trx: indicate MTS in Downlink TRXDv2 PDUs + * [VAMOS] rsl_rx_mode_modif(): handle Channel Identification IE + * [VAMOS] rsl: call bts_supports_cm() from rsl_handle_chan_mod_ie() + * [VAMOS] bts_supports_cm(): handle RSL_CMOD_CRT_OSMO_TCH_VAMOS_{Bm,Lm} + * [VAMOS] common/scheduler: unify symbol names for training sequences + * [VAMOS] osmo-bts-trx: rework handling of Training Sequence + * [VAMOS] osmo-bts-trx: properly handle per-timeslot TSC values + * [VAMOS] scheduler: add new GMSK training sequences from 3GPP 45.002 + * [VAMOS] l1sap_chan_act(): handle Osmocom specific TSC IE + * [VAMOS] common/oml: generalize checking BTS_FEAT_MULTI_TSC + * [VAMOS] gsm_pchan2chan_nr(): use ABIS_RSL_CHAN_NR_CBITS_* macros + * [VAMOS] rsl_lchan_lookup(): use ABIS_RSL_CHAN_NR_CBITS_* macros + * [VAMOS] rsl_lchan_lookup(): make it more readable + * [VAMOS] gsm_data: rework and rename gsm_lchan_name_compute() + * [VAMOS] l1sap: get_lchan_by_chan_nr() may return NULL + * [VAMOS] oml_rx_set_chan_attr(): clarify NM_ATT_CHAN_COMB handling + * manuals/abis/rsl.adoc: s/TS 08.58/TS 48.058/ + * manuals/abis/rsl.adoc: rework Channel Number description + * manuals/abis/rsl.adoc: add missing CBCH Channel Number values + * manuals/abis/rsl.adoc: add VAMOS specific Channel Number values + * osmo-bts-trx: fix NULL pointer dereference in trx_if_send_burst() + * trx_sched_is_sacch_fn(): fix handling of dynamic timeslots + * [VAMOS] scheduler: drop meaningless channel number checks + * [VAMOS] conf_lchans_as_pchan(): improve readability + * [VAMOS] Implement the concept of 'shadow' timeslots + * [VAMOS] osmo-bts-trx: schedule bursts on 'shadow' timeslots + * l1sap: fix TDMA frame number wrap in l1sap_info_time_ind() + * conf_lchans_as_pchan(): fix GSM_LCHAN_{CCCH->CBCH} regression + * conf_lchans_as_pchan(): initialize all lchans with GSM_LCHAN_NONE + * measurement: remove over-defensive checks in is_meas_complete() + * [VAMOS] trx_sched_init_ts(): assign names to per-timeslot counters + * common/vty: facilitate finding duplicate PHY/TRX associations + * vty: ensure all warning messages are prefixed with '%%' + * osmo-bts-octphy: drop talloc_replace(), use osmo_talloc_replace_string() + * l1sap: fix TDMA frame number arithmetic in fn_ms_adj() + * osmo-bts-trx: fix typo: s/bisc/bsic/ in 'show transceiver' + * osmo-bts-trx: fix copy-pasted comment: s/sysmoBTS/osmo-bts-trx/ + * oml: fix handling of NM_ATT_INTERF_BOUND attribute + * Report interference levels in RSL RF RESource INDication + * scheduler: reorder enum trx_chan_type, add TRX_CHAN_IS_DEDIC() + * osmo-bts-trx: report interference levels to the upper layers + * osmo-bts-{trx,virtual}: get rid of dummy tx_idle_fn() + * scheduler: unset TRX_CHAN_FLAG_AUTO_ACTIVE for TRXC_IDLE + * osmo-bts-trx: print timeslot brief info in 'show transceiver' + * osmo-bts-trx: measure interference levels on TRXC_IDLE + * osmo-bts-trx: report PDCH interference levels to the PCU + * scheduler: fix wrong union field in trx_sched_tch_req() + * scheduler: fix: use ts_pchan() in trx_sched_set_cipher() + * Revert "power_control: BS power shall not be reduced on C0" + * osmo-bts-omldummy: indicate BTS_FEAT_BCCH_POWER_RED as supported + * osmo-bts-trx: implement BCCH carrier power reduction mode + * power_control: constrain BS power reduction on BCCH carrier + * manuals/abis/rsl.adoc: clarify RF Resource Indication conformance + * rsl: use tlvp_val16be() in rsl_rx_ipac_XXcx() + * gsm_lchan_interf_meas_calc_band(): also print number of AVG samples + * osmo-bts-trx: send dummy FACCH in the absense of RTP frames + * osmo-bts-trx: return -ENODEV if 'bursts_p' is NULL + * l1sap: unify channel (de)activation/modification messages + * gsm_lchan2chan_nr(): separate RSL specific variant of this API + * osmo-bts-trx: bts_model_l1sap_down(): remove chan_nr patching + * trx_sched_set_lchan(): use LOGL_INFO for logging messages + * osmo-bts-trx: remove an 'else' branch in _sched_dl_burst() + * osmo-bts-trx: implement Temporary Overpower for SACCH/FACCH + * scheduler: fix comments explaining the interleaving of TCH/H + * fix handle_ms_meas_report(): properly count measurement reports + * abis: fix memory leak in abis_oml_sendmsg() + * rsl: remove redundant logging in rsl_rx_chan_activ() + * .gitignore: add tests/amr/amr_test + * rsl: prevent race condition during timeslot re-configuration + * rsl_tx_rf_res(): separate interference AVG / band calculation + * rsl_tx_rf_res(): also report noise levels for PDTCH + * osmo-bts-trx: report PDCH interference levels to L1SAP + * l1sap: check if BTS model supports interference reporting + * vty: show interference level / band in 'show lchan' + * trx_sched_clean_ts(): also free() the associated 'struct l1sched_ts' + * trx_sched_clean(): also free() the shadow timeslot + * osmo-bts-trx: refactor 'maxdly' / 'maxdlynb' commands + * rsl: rsl_tx_meas_res() does not change l3, make it const + * rsl: send NACK if BTS_FEAT_ACCH_REP is not supported + * measurement: handle_ms_meas_report() accepts const gh + * measurement: move repeated_dl_facch_active_decision() here + * measurement: make sure that DL measurements are valid + * cosmetic: s/repeated_acch_capability/rep_acch_cap/g + * struct gsm_lchan: group ACCH repetition state fields + * struct gsm_lchan: move tch.rep_facch to rep_acch.dl_facch + * measurement: fix wrong operator used in handle_ms_meas_report() + * osmo-bts-trx: fix potential NULL pointer dereference + * lchan_set_state(): also free pending messages if any + * lchan: introduce and use lchan_is_tch() helper + * [overpower] rsl: store full content of RSL_IE_OSMO_TEMP_OVP_ACCH_CAP + * [overpower] lchan_dump_full_vty(): print overpower state + * [overpower] scheduler: handle {sacch,facch}_enabled flags + * l1sap: fix handling of lchan->pending_rel_ind_msg + * l1sap: move false PTCCH/U detection into PDCH branch + * l1sap: use designated initializers in process_l1sap_meas_data() + * l1sap: process_l1sap_meas_data() accepts pointer to lchan + * l1sap: make 'l1sap' argument of process_l1sap_meas_data() const + * rsl: fix a memory leak in handle_gprs_susp_req() + * l1sap: rework handling of DATA.ind on SACCH + * lchan_meas_handle_sacch(): check if Measurement Result is valid + * measurement: get rid of *le in lchan_meas_handle_sacch() + * measurement: pass *mr to repeated_dl_facch_active_decision() + * measurement: pass *mr to lchan_bs_pwr_ctrl() + * [overpower] Turn it on and off depending on DL RxQual + * measurement: make use of gsm48_meas_res_is_valid() + * common/Makefile.am: reformat {AM_CPPFLAGS,AM_CFLAGS,LDADD} + * rsl: exclude disabled timeslots from interference reports + * oml: use ARRAY_SIZE() in oml_rx_set_bts_attr() + * gsm_lchan_interf_meas_calc_avg(): fix band calculation + + [ Pau Espin Pedrol ] + * l1sap: Transmit pdtch invalid MAC blocks to PCU + * bts-trx: Always submit rx PDTCH DATA.ind to l1sap + * bts-trx: Avoid submitting first data_ind with FN=0 to upper layers + * bts-trx: Drop duplicate set of last_clk_ind + * bts-trx: reorder first timerfd schedule to decrease first timeout skew + * sysmo,oc2g,lc15: Make RadioChannel MO depend on RadioCarrier MO + * bts: Clean up TS selection in sign_link_up + * Fix regression in 'bts: Clean up TS selection in sign_link_up' + * Add missing value_string for NM_EV_* introduced recently + * pcuif: Set missing bsic field during Tx of info_ind + * Use new stat item/ctr getter APIs + * rsl: Use switch statement in rsl_rx_bcch_info() + * pcu_sock: Transmit SI2 + * doc: rsl.adoc: Fix trailing whitespace + * gsm_data: Drop unused function gsm_pchan_parse() + * pcuif_proto.h: Add new container messages + * Support forwarding proto IPAC_PROTO_EXT_PCU BSC<->PCU + * Rename osmo dyn ts enums to contain SDCCH8 + * Support SDCCH8 in osmo dyn ts + * Make gcc 11.1.0 false positivies happy + * rsl: Fix rx of multiple RSL_IPAC_EIE_MEAS_AVG_CFG IEs + * rsl: Support parsing up to 3 RSL_IPAC_EIE_MEAS_AVG_CFG IEs + * MS Power Control Loop: Take C/I into account + * MS Power Control Loop: Support EWMA algorithm for C/I measurements + * MS Power Control Loop: Improve logging + * BS Power Control Loop: refactor lchan_bs_pwr_ctrl() to look similar to lchan_ms_pwr_ctrl() + * BS Power Control Loop: Support EWMA average algo for RxQual meas + * BS Power Control Loop: Increase attenuation if RxQual is better than upper threshold + * MS/BS Power Control Loop: Do RxLEV meas avg & delta calculations directly on RxLevels + * MS/BS Power Control Loop: Fix downscaling averaging bug + * Power Control Loop: Move skip loop logic to function helper + * comsetic: measurement.c: fix typo in comment + * l1sap: Take L1SACCH MS_PWR from bitfield instead of manual parsing + * TA loop: Take into account UL SACCH 'Actual Timing advance' field + * ta_control: Allow switching TA quicker + * lchan: Move TA CTRL param to its own substruct + * MS Power Control Loop: Feed UL RSSI from correct measurement period + * MS Power Control Loop: Feed UL C/I from correct measurement period + * TA Control Loop: Change toa256 switch threshold to 75% of a symbol + * Power Control Loop: Set P_CON_INTERVAL to 1 by default + * Support configuring TA loop SACCH block rate + * MS Power Control Loop: Fix sub vs full being passed to algo + * abis: Clear code and drop code not executed + * abis.h: Drop unused state + * cosmetic: fix typo in comment + * abis.c: Rearrange code to follow logic state order + * abis.c: Convert early return to assert() + * power_control: Drop unused param in function + * tests: MS Power Control Loop: Show oscillation among good power levels + * cosmetic: Fix formatting of conditional operator + * abis: Move FSM registration to constructor function + * abis: Shorten string names of events + * abis.c: Transition to CONNECTED state only when OML link is up + * abis.c: Fix mess with priv->bsc_oml_host + * abis.c: Loop over list of BSCs until connection succeeds + * trx_provision_fsm: Add missing state transition OPEN_WAIT_POWEROFF_CNF => OPEN_POWEROFF + * nm_*_fsm: Add missing item in event mask list for state ENABLED + * Allow setting administrative state through oml_mo_state_chg() + * nm_*_fsm: Set adminsitrative state 'shutting down' when shutdown procedure starts + * MS Power Control Loop: Fix oscillations within good MS Power Levels + * nm_*_fsm: Move to state Disabled NotInstalled Locked when shtudown proc ends + * abis: Drop internal OML msg queue + * nm_*fsm: Make FSMs aware of object being properly configured or not + * bts_shutdown_fsm: Fix event name + * trx_if: Set pointer to null after freeing it + * trx_if: Allow calling trx_if_flush/close from within TRXC callback + * trx_if: delete retrans timer when flushing the Tx queue + * trx_provision_fsm: Properly reset FSM state upon starting listening for events + * bts-trx: Submit TRX_PROV_EV_CFG_ARFCN for C0 during SetBtsAttr + * bts-trx: Get rid of check_transceiver_availability_trx() + * MS Power Control Loop: Disable threshold comparison on {LOWER,UPPER}_CMP_N=0 + * l1sap: Support rx of empty rlcmac blocks from PCU + * bts-trx: Avoid race condition configuring TS-specific TSC values + * bts-trx: Submit TRX SW_ACT when PHY becomes connected + * trx_sched_clean_ts: Clean VAMOS shadow TS too + * phy_link: Introduce bts_model_phy_link_close() and use it in bts-trx + * nm_bts_fsm: Make sure PHYs are opened when SW_ACTivating it + * bts_shutdown_fsm: Allow configuring FSM to shutdown without exiting process + * abis: Call bts_model_abis_close() when Abis link goes down + * bts_trx: Drop non-executed path in trx_link_estab() + * Avoid sending Load Indications when BTS is not RSL-connected + * abis: Fix memory leak of bts->osmo_link upon link going down + * abis: Fix line leaked & recreated upon every reconnect + * bts-trx: Keep the process ongoing trying to reconnect on Abis link down + * Revert "bts-trx: Keep the process ongoing trying to reconnect on Abis link down" + * Revert "abis: Fix line leaked & recreated upon every reconnect" + * osmo-bts-omldummy: Fix crash accessing null phy + * bts-trx: Fix rxgain & maxdly VTY values being reset + * Decouple handling of Measurement Report from lapdm + * Move TA & Power Loops further up the stack, take DTXu flag into account + * scheduler: Fix lqual_cb not populated for TCH.ind + * abis: Fix line leaked & recreated upon every reconnect + * trx_provision_fsm: Fix TRX!=0 never going back to CLOSED state + * trx_provision_fsm: Support OPEN_POWEROFF->CLOSED transition + * bts-trx: Delay power ramp up until RCARRIER is ENABLED + * Delay abis reconnect while bts is shutting down + * bts-trx: Keep the process ongoing trying to reconnect on Abis link down + * trx_provision_fsm: Drop unneeded reset of fields + * trx_provision_fsm: Drop impossible paths + * trx_provision_fsm: poweronoff_sent flag: track POWERON and POWEROFF separately + * trx_provision_fsm: Fix shutdown while POWERON in transit + * rsl: NACK Chan Activation for lchans on disabled TS + * Introduce gsm_lchan_init() function helper + * MS Power Control Loop: Use P_CON_INTERVAL=2 by default + * load_indication.c: Avoid sending if CCCH is still not operational + * Move lchan,power_ctrl specific code from gsm_data.h to their own files + * Move lchan,power_control related code from gsm_data.c to their own files + * lchan.h: Add related ticket info to FIXME comment + * Introduce gsm_lchan_release function helper + * nm_channel_fsm: Release lchans after BTS shutdown + * nm_bts_fsm: Reset si_valid bitmask when BTS is shut down + * nm_*_fsm: Move reset state code to st_op_disabled_notinstalled_on_enter + * nm_*_fsm: reset mo.nm_attr from previous runs when entering state NOT_INSTALLED + * Add new gsm_bts_trx_free_shadow_ts() function + * Make sure lchan allocated memory from shadow_ts is properly freed + * rsl: Fix all shadow TS being Chan Act NACKed + * bts-trx: Guard call to trx_sched_clean with NULL trx ptr + * lchan: Setup early_rr_ia timer only once during init + * Move lchan related code to lchan.{c,h} + * lchan: Update log line level to use macro and level INFO + * lchan: Avoid applying transition changes if state new==old + * Move lchan_deactivate() to lchan.c + * Move lchan_init_lapdm inside lchan_set_state(LCHAN_S_ACTIVE) + * lchan: Call lapdm_channel_exit() when state changes to NONE + * bts_shutdown_fsm: Make sure pending power ramping are aborted before closing TRX + * gsm_pchan2chan_nr(): Properly assert if unexpected pchan is passed + * Reset CBCH state after BTS shutdown + * bts-trx: sched_lchan_pdtch: Refactor tx_pdtch_fn to get rid of goto tag + * bts-trx: sched: tx_pdtch_fn: Handle PCU idle blocks properly + * Revert "bts-trx: sched: tx_pdtch_fn: Handle PCU idle blocks properly" + * scheduler: Fix check against empty PDCH blocks + * bts-trx: sched: tx_pdtch_fn: Drop log line clogging logs + * l1sap: Avoid re-(de)activating already (de)active lchans + * scheduler: Avoid crash upon call to trx_sched_set_lchan if l1ts is uninitialized + * bts-trx: sched_lchan_tchf: Drop impossible code path + * scheduler: Fix FACCH msg with l2len==0 going to lower layers and logging errors + * bts-trx: sched_lchan_tchf: Change log level to debug for line informing about missing dl prim + * abis: Drop unneded if condition in else clause + * abis: Try one reconnect to previously connected BSC before trying next one + * gsm_ts_release(): Make sure pchan{,is_want} is reset to NONE + + [ Neels Hofmeyr ] + * osmobts-abis.adoc: add missing bibliography + * Abis manual: s/TS 12.21/TS 52.021 + * Abis manual: add Get Attributes, add BTS features + * Abis manual: add VAMOS to BTS features + * Abis manual: add RSL_IE_OSMO_TRAINING_SEQUENCE + * omldummy: introduce using getopt_long + * omldummy: add cmdline arg --features + * [VAMOS] osmo-bts-omldummy: allocate shadow timeslots + * remove unused LCHAN_S_INACTIVE + * enable Early Immediate Assignment + * add VTY transcript testing + * jenkins: enable new flag --enable-external-tests + * add osmo_tdef groups, exposing T timers on VTY config + * early IMM ASS: add configurable delay for RR IMM ASS + * early IA: change default X15 timer to 0 ms + * gsm_lchan_interf_meas_calc_avg(): adapt to the order of boundaries + + [ Harald Welte ] + * Introduce ability to set socket priority of RTP sockets + * manual: Include QoS chapter and add osmo-bts specific example + * manual: Remove manual revision history; we don't use it anywawy + * manuals: Update copyright years + * l1sap/gsmtap: Don't log UI fill frames [zero information field] + * rsl: fix handling of REL IND in lapdm_rll_tx_cb() + * initial support for static userspace probes via systemtap + + [ Keith ] + * sysmobts-mgr: Fix path to hwmon in /sys + + [ Eric Wild ] + * osmo-bts-trx: indicate A5/4 support, handle Kc128 + + [ Oliver Smith ] + * debian/control: remove dh-systemd build-depend + + [ Eric ] + * lc15, oc2g, sysmo: fix show dsp-trace-flags + * osmo-trx: fix maxdly + + [ Martin Hauke ] + * osmo-bts-trx-calypso.cfg: Adjust settings to work with current osmo-bts versions + + -- Pau Espin Pedrol <pespin@sysmocom.de> Tue, 16 Nov 2021 16:40:05 +0100 + osmo-bts (1.3.0) unstable; urgency=medium [ Michael McTernan ] diff --git a/debian/compat b/debian/compat index ec635144..f599e28b 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -9 +10 diff --git a/debian/control b/debian/control index 5a42d194..6a77d56c 100644 --- a/debian/control +++ b/debian/control @@ -2,25 +2,41 @@ Source: osmo-bts Maintainer: Osmocom team <openbsc@lists.osmocom.org> Section: net Priority: optional -Build-Depends: debhelper (>= 9), +Build-Depends: debhelper (>= 10), pkg-config, dh-autoreconf, - dh-systemd (>= 1.5), autotools-dev, pkg-config, - libosmocore-dev (>= 1.5.0), - libosmo-abis-dev (>= 1.1.0), + libosmocore-dev (>= 1.9.0), + libosmo-abis-dev (>= 1.5.0), + libosmo-netif-dev (>= 1.4.0), libgps-dev, txt2man, - osmo-gsm-manuals-dev (>= 1.1.0) + osmo-gsm-manuals-dev (>= 1.5.0) Standards-Version: 3.9.8 -Vcs-Browser: http://git.osmocom.org/osmo-bts/ -Vcs-Git: git://git.osmocom.org/osmo-bts +Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts +Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts Homepage: https://projects.osmocom.org/projects/osmobts +Package: osmo-bts +Architecture: any +Depends: osmo-bts-trx, osmo-bts-virtual, ${misc:Depends} +Description: Base Transceiver Station for GSM + OsmoBTS is a software implementation of Layer2/3 of a BTS. It implements the + following protocols/interfaces: + LAPDm (GSM 04.06) + RTP + A-bis/IP in IPA multiplex + OML (GSM TS 12.21) + RSL (GSM TS 08.58) + . + OsmoBTS is modular and has support for multiple back-ends. A back-end talks to + a specific L1/PHY implementation of the respective BTS hardware. Based on this + architecture, it should be relatively easy to add a new back-end to support + so-far unsupported GSM PHY/L1 and associated hardware. + Package: osmo-bts-trx Architecture: any -Conflicts: osmo-bts Depends: ${shlibs:Depends}, ${misc:Depends} Description: osmo-bts-trx GSM BTS with osmo-trx osmo-bts-trx to be used with the osmo-trx application @@ -35,7 +51,6 @@ Description: Debug symbols for the osmo-bts-trx Package: osmo-bts-virtual Architecture: any -Conflicts: osmo-bts Depends: ${shlibs:Depends}, ${misc:Depends} Description: Virtual Osmocom GSM BTS (no RF hardware; GSMTAP/UDP) This version of OsmoBTS doesn't use actual GSM PHY/Hardware/RF, but diff --git a/doc/examples/Makefile.am b/doc/examples/Makefile.am index 25a2151b..6a1ae959 100644 --- a/doc/examples/Makefile.am +++ b/doc/examples/Makefile.am @@ -1,16 +1,29 @@ -OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg +# all config examples must be listed here unconditionally, so that +# all of them end up in the release tarball (see OS#6349) +EXTRA_DIST = \ + trx/osmo-bts-trx.cfg \ + trx/osmo-bts-trx-calypso.cfg \ + octphy/osmo-bts-trx2dsp1.cfg \ + octphy/osmo-bts-octphy.cfg \ + oc2g/osmo-bts-oc2g.cfg \ + oc2g/oc2gbts-mgr.cfg \ + sysmo/sysmobts-mgr.cfg \ + sysmo/osmo-bts-sysmo.cfg \ + litecell15/osmo-bts-lc15.cfg \ + litecell15/lc15bts-mgr.cfg \ + virtual/osmo-bts-virtual.cfg \ + $(NULL) doc_virtualdir = $(docdir)/examples/osmo-bts-virtual doc_virtual_DATA = \ virtual/osmo-bts-virtual.cfg -EXTRA_DIST = $(doc_virtual_DATA) +OSMOCONF_FILES = virtual/osmo-bts-virtual.cfg if ENABLE_SYSMOBTS doc_sysmodir = $(docdir)/examples/osmo-bts-sysmo doc_sysmo_DATA = \ sysmo/osmo-bts-sysmo.cfg \ sysmo/sysmobts-mgr.cfg -EXTRA_DIST += $(doc_sysmo_DATA) OSMOCONF_FILES += sysmo/osmo-bts-sysmo.cfg sysmo/sysmobts-mgr.cfg endif @@ -19,7 +32,6 @@ doc_trxdir = $(docdir)/examples/osmo-bts-trx doc_trx_DATA = \ trx/osmo-bts-trx.cfg \ trx/osmo-bts-trx-calypso.cfg -EXTRA_DIST += $(doc_trx_DATA) OSMOCONF_FILES += trx/osmo-bts-trx.cfg endif @@ -28,7 +40,6 @@ doc_octphydir = $(docdir)/examples/osmo-bts-octphy doc_octphy_DATA = \ octphy/osmo-bts-trx2dsp1.cfg \ octphy/osmo-bts-octphy.cfg -EXTRA_DIST += $(doc_octphy_DATA) OSMOCONF_FILES += octphy/osmo-bts-octphy.cfg endif @@ -37,7 +48,6 @@ doc_lc15dir = $(docdir)/examples/osmo-bts-lc15 doc_lc15_DATA = \ litecell15/osmo-bts-lc15.cfg \ litecell15/lc15bts-mgr.cfg -EXTRA_DIST += $(doc_lc15_DATA) OSMOCONF_FILES += litecell15/osmo-bts-lc15.cfg litecell15/lc15bts-mgr.cfg endif @@ -46,7 +56,6 @@ doc_oc2gdir = $(docdir)/examples/osmo-bts-oc2g doc_oc2g_DATA = \ oc2g/osmo-bts-oc2g.cfg \ oc2g/oc2gbts-mgr.cfg -EXTRA_DIST += $(doc_oc2g_DATA) OSMOCONF_FILES += oc2g/osmo-bts-oc2g.cfg oc2g/oc2gbts-mgr.cfg endif diff --git a/doc/examples/litecell15/lc15bts-mgr.cfg b/doc/examples/litecell15/lc15bts-mgr.cfg index a92a3fd6..850fb15f 100644 --- a/doc/examples/litecell15/lc15bts-mgr.cfg +++ b/doc/examples/litecell15/lc15bts-mgr.cfg @@ -3,10 +3,12 @@ !! ! log stderr - logging filter all 1 logging color 1 - logging print category 0 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level temp info logging level fw info logging level find info diff --git a/doc/examples/litecell15/osmo-bts-lc15.cfg b/doc/examples/litecell15/osmo-bts-lc15.cfg index 907d83a2..16651eb7 100644 --- a/doc/examples/litecell15/osmo-bts-lc15.cfg +++ b/doc/examples/litecell15/osmo-bts-lc15.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/examples/oc2g/oc2gbts-mgr.cfg b/doc/examples/oc2g/oc2gbts-mgr.cfg index 8248f60d..ce72e5d3 100644 --- a/doc/examples/oc2g/oc2gbts-mgr.cfg +++ b/doc/examples/oc2g/oc2gbts-mgr.cfg @@ -3,10 +3,12 @@ !! ! log stderr - logging filter all 1 logging color 1 - logging print category 0 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level temp info logging level fw info logging level find info diff --git a/doc/examples/oc2g/osmo-bts-oc2g.cfg b/doc/examples/oc2g/osmo-bts-oc2g.cfg index f985f3bc..ddf69f42 100644 --- a/doc/examples/oc2g/osmo-bts-oc2g.cfg +++ b/doc/examples/oc2g/osmo-bts-oc2g.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/examples/octphy/osmo-bts-octphy.cfg b/doc/examples/octphy/osmo-bts-octphy.cfg index d6d03b5d..a3a00930 100644 --- a/doc/examples/octphy/osmo-bts-octphy.cfg +++ b/doc/examples/octphy/osmo-bts-octphy.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/examples/octphy/osmo-bts-trx2dsp1.cfg b/doc/examples/octphy/osmo-bts-trx2dsp1.cfg index bf590f7d..477bff8a 100644 --- a/doc/examples/octphy/osmo-bts-trx2dsp1.cfg +++ b/doc/examples/octphy/osmo-bts-trx2dsp1.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/examples/sysmo/osmo-bts-sysmo.cfg b/doc/examples/sysmo/osmo-bts-sysmo.cfg index 6ff043d8..f44c7189 100644 --- a/doc/examples/sysmo/osmo-bts-sysmo.cfg +++ b/doc/examples/sysmo/osmo-bts-sysmo.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/examples/sysmo/sysmobts-mgr.cfg b/doc/examples/sysmo/sysmobts-mgr.cfg index f891ada7..00be2fd0 100644 --- a/doc/examples/sysmo/sysmobts-mgr.cfg +++ b/doc/examples/sysmo/sysmobts-mgr.cfg @@ -3,9 +3,12 @@ !! ! log stderr - logging filter all 1 logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level temp info logging level fw info logging level find info diff --git a/doc/examples/trx/osmo-bts-trx-calypso.cfg b/doc/examples/trx/osmo-bts-trx-calypso.cfg index 3f2e7781..018744f8 100644 --- a/doc/examples/trx/osmo-bts-trx-calypso.cfg +++ b/doc/examples/trx/osmo-bts-trx-calypso.cfg @@ -1,11 +1,15 @@ ! ! OsmoBTS configuration example for CalypsoBTS -! http://osmocom.org/projects/baseband/wiki/CalypsoBTS +! https://osmocom.org/projects/baseband/wiki/CalypsoBTS !! ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl notice logging level oml notice logging level rll notice @@ -24,14 +28,15 @@ phy 0 instance 0 osmotrx ip local 127.0.0.1 osmotrx ip remote 127.0.0.1 - osmotrx timing-advance-loop - osmotrx ms-power-loop -65 osmotrx legacy-setbsic + osmotrx fn-advance 20 + osmotrx rts-advance 5 bts 0 oml remote-ip 127.0.0.1 - ipa unit-id 1801 0 + ipa unit-id 6969 0 gsmtap-sapi pdtch gsmtap-sapi ccch band 900 trx 0 phy 0 instance 0 + nominal-tx-power 23 diff --git a/doc/examples/trx/osmo-bts-trx.cfg b/doc/examples/trx/osmo-bts-trx.cfg index 81313e5c..6b239527 100644 --- a/doc/examples/trx/osmo-bts-trx.cfg +++ b/doc/examples/trx/osmo-bts-trx.cfg @@ -4,7 +4,11 @@ ! log stderr logging color 1 + logging print category-hex 0 + logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl notice logging level oml notice logging level rll notice diff --git a/doc/examples/virtual/osmo-bts-virtual.cfg b/doc/examples/virtual/osmo-bts-virtual.cfg index 13bc0e5a..4663f17f 100644 --- a/doc/examples/virtual/osmo-bts-virtual.cfg +++ b/doc/examples/virtual/osmo-bts-virtual.cfg @@ -3,10 +3,12 @@ !! ! log stderr - logging filter all 1 - logging color 0 + logging color 1 + logging print category-hex 0 logging print category 1 logging timestamp 0 + logging print file basename last + logging print level 1 logging level rsl info logging level oml info logging level rll notice diff --git a/doc/manuals/abis/rsl.adoc b/doc/manuals/abis/rsl.adoc index 8e2ead9d..e627f5c2 100644 --- a/doc/manuals/abis/rsl.adoc +++ b/doc/manuals/abis/rsl.adoc @@ -192,6 +192,7 @@ Conforms to 3GPP TS 48.058 § 8.4.20, with these exceptions: | 0x06 | RSL_SYSTEM_INFO_6 | 0x0d | RSL_SYSTEM_INFO_5bis | 0x0e | RSL_SYSTEM_INFO_5ter +| 0x0f | RSL_SYSTEM_INFO_10 | 0x47 | RSL_EXT_MEAS_ORDER | 0x48 | RSL_MEAS_INFO |=== @@ -516,6 +517,7 @@ number*. | Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3 | IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2 | RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2 +| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2 |=== [[rsl_crcx_msg_ack]] @@ -576,6 +578,7 @@ properties of a user-plane RTP connection. | Destination IP Port | <<RSL_IE_IPAC_REMOTE_PORT>> | O | TV | 3 | IP Speech Mode | <<RSL_IE_IPAC_SPEECH_MODE>> | O | TV | 2 | RTP Payload Type 2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> | O | TV | 2 +| RTP CSD Format | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | O | TV | 2 |=== [[rsl_mdcx_msg_ack]] @@ -871,6 +874,7 @@ addition to those indicated in 3GPP TS 48.058 Section 9.3: | 0xf5 | RSL_IE_IPAC_LOCAL_IP | <<RSL_IE_IPAC_LOCAL_IP>> | 0xf6 | RSL_IE_IPAC_CONN_STAT | <<RSL_IE_IPAC_CONN_STAT>> | 0xf8 | RSL_IE_IPAC_CONN_ID | <<RSL_IE_IPAC_CONN_ID>> +| 0xf9 | RSL_IE_IPAC_RTP_CSD_FORMAT | <<RSL_IE_IPAC_RTP_CSD_FORMAT>> | 0xfc | RSL_IE_IPAC_RTP_PAYLOAD2 | <<RSL_IE_IPAC_RTP_PAYLOAD2>> |=== @@ -953,8 +957,8 @@ IEI followed by four bytes IPv4 address. This information element contains statistics about the RTP connection. -It is encoded as 29 bytes, with the first byte as IEI and 28 bytes -fixed-length payload encoded as follows: +It is encoded as 30 bytes, with the first byte as IEI, the second byte as length +(=28), and 28 bytes fixed-length payload encoded as follows: .A-bis/IP Connection Statistics [options="header",width="60%",cols="15%,15%,70%"] @@ -1085,6 +1089,39 @@ for future use. | 8..255 | reserved values |=== +[[RSL_IE_IPAC_RTP_CSD_FORMAT]] +==== RSL_IE_IPAC_RTP_CSD_FORMAT + +This information element contains the RTP Circuit Switched Data format. + +.A-bis/IP RTP CSD Format +[options="header",width="60%",cols="15%,15%,70%"] +|=== +| Offset | Size | Description +| 0 | 4 | RTP CSD Format D +| 4 | 4 | RTP CSD Format IR +|=== + +.A-bis/IP RTP CSD Format D Values +[options="header",width="40%",cols="20%,80%"] +|=== +| Value | Description +| 0 | External TRAU format +| 1 | Non-TRAU Packed format +| 2 | TRAU within the BTS +| 3 | IWF-Free BTS-BTS Data +|=== + +.A-bis/IP RTP CSD Format IR Values +[options="header",width="40%",cols="20%,80%"] +|=== +| Value | Description +| 0 | 8 kb/s +| 1 | 16 kb/s +| 2 | 32 kb/s +| 3 | 48 kb/s +|=== + === A-bis RSL Initialization / BTS bring-up Upon receiving the 'IPA RSL CONNECT' OML message by the respective diff --git a/doc/manuals/chapters/architecture.adoc b/doc/manuals/chapters/architecture.adoc index a0e66cd0..ca3a1e33 100644 --- a/doc/manuals/chapters/architecture.adoc +++ b/doc/manuals/chapters/architecture.adoc @@ -82,13 +82,13 @@ order to specify which PHY instance is allocated to this specific TRX. | bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created | common | bts_controlif_setup() | Initialization of Control Interface | bts-specific | bts_model_ctrl_cmds_install() | Install model-specific control interface commands -| common | telnet_init() | Initialization of telnet interface +| common | telnet_init_default() | Initialization of telnet interface | common | pcu_sock_init() | Initialization of PCU socket | common | main() | Installation of signal handlers | common | abis_open() | Start of the A-bis connection to BSC | common | phy_links_open() | Iterate over list of configured PHY links | bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links -| common | write_pid_file() | Generate the pid file +| bts-specific | bts_model_phy_link_close() | Close each of the configured PHY links | common | osmo_daemonize() | Fork as daemon in background (if configured) | common | bts_main() | Run main loop until global variable quit >= 2 |=== diff --git a/doc/manuals/chapters/osmux_bts.adoc b/doc/manuals/chapters/osmux_bts.adoc new file mode 100644 index 00000000..8afc3c37 --- /dev/null +++ b/doc/manuals/chapters/osmux_bts.adoc @@ -0,0 +1,39 @@ +include::{commondir}/chapters/osmux/osmux.adoc[] + +=== Osmux Support in {program-name} + +Osmux usage in {program-name} in managed through the VTY commands in node +`osmux`. Command `use (on|off|only)` is used to configure use policy of Osmux +within {program-name}. Once enabled (`on` or `only`), {program-name} will +announce the _OSMUX_ BTS feature towards the BSC over OML. This way, the BSC +becomes aware that this BTS supports using Osmux to transfer voice call user +data when the AMR codec is selected. + +It is then up to the BSC to decide whether to use Osmux or not when establishing +a new call. If the BSC decides to use Osmux for a given call, then the _IPACC +CRCX/MDCX_ messages sent by the BSC will contain an extra _Osmux CID_ IE +appended, which contains the Osmux CID to be used by the BTS to send Osmux +frames to the co-located BSC MGW (aka the BSC MGW' local CID, or {program-name}' +remote CID). The IP address and port provided in the same messages refer to the +address and port where Osmux frames with the provided CID are expected to be +received. Similarly, {program-name} appends an _Osmux CID_ IE to the _IPACC +CRCX/MDCX ACK_ message it generates, this time with its own local Osmux CID. +Same goes for the BTS' local IP address and port where Osmux frames are expected +to be received. + +{program-name} will behave differently during call set up based on the VTY +command `use (on|off|only)` presented above: + +* `off`: If _IPACC CRCX_ from BSC contains _Osmux CID_ IE, meaning + BSC wants to use Osmux for this call, then {program-name} will reject the + request and the call set up will fail. +* `on`: {program-name} will support and accept both Osmux and non-Osmux (RTP) + upon call set up. If _IPACC CRCX_ from BSC contains the _Osmux CID_ IE on a + AMR call (`Channel Mode GSM3`), it will set up an Osmux stream on its end and + provide the BSC with the BTS-local CID. If the BSC provides no _Osmux CID_ IE, + then {program-name} will set up a regular RTP based call. +* `only`: Same as per `on`, except that {program-name} will accept only Osmux + calls on the CN-side, this is, if _IPACC CRCX_ from BSC doesn't + contain an _Osmux CID_ IE, it will reject the assignment and the call set up + will fail. This means also that only AMR calls (`Channel Mode GSM3`) are + allowed. diff --git a/doc/manuals/osmobts-usermanual.adoc b/doc/manuals/osmobts-usermanual.adoc index 9ef49604..fc7a5bd1 100644 --- a/doc/manuals/osmobts-usermanual.adoc +++ b/doc/manuals/osmobts-usermanual.adoc @@ -1,4 +1,5 @@ :gfdl-enabled: +:program-name: OsmoBTS OsmoBTS User Manual =================== @@ -30,6 +31,8 @@ include::{srcdir}/chapters/bts-models.adoc[] include::{srcdir}/chapters/architecture.adoc[] +include::{srcdir}/chapters/osmux_bts.adoc[] + include::./common/chapters/qos-dscp-pcp.adoc[] include::./common/chapters/vty_cpu_sched.adoc[] diff --git a/doc/manuals/vty/bts_vty_additions.xml b/doc/manuals/vty/bts_vty_additions.xml index 519c4b48..2d22b41d 100644 --- a/doc/manuals/vty/bts_vty_additions.xml +++ b/doc/manuals/vty/bts_vty_additions.xml @@ -1 +1,26 @@ -<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'/> +<!-- ex:ts=2:sw=2:et --> +<vtydoc xmlns='urn:osmocom:xml:libosmocore:vty:doc:1.0'> + <node id='phy-inst'> + <!-- FIXME: This command appears twice for some reason. --> + <command id='osmotrx maxdly <0-63>'> + <description> + Access Burst is the first burst a mobile transmits in order to establish a connection and it + is used to estimate Timing Advance (TA) which is then applied to Normal Bursts to compensate + for signal delay due to distance. So changing this setting effectively changes maximum range + of the cell, because Access Bursts with a delay higher than this value will be ignored. + </description> + </command> + <!-- FIXME: This command appears unconditionally, despite being hidden. --> + <command id='osmotrx maxdlynb <0-63>'> + <description> + USE FOR TESTING ONLY, DO NOT CHANGE IN PRODUCTION USE! + During the normal operation, delay of Normal Bursts is controlled by the Timing Advance loop + and thus Normal Bursts arrive to a BTS with no more than a couple GSM symbols, which is + already taken into account in osmo-trx. Changing this setting will have no effect in + production installations except increasing osmo-trx CPU load. This setting is only useful + when testing with a transmitter which cannot precisely synchronize to the BTS downlink + signal, like R&S CMD57. + </description> + </command> + </node> +</vtydoc> diff --git a/doc/startup.txt b/doc/startup.txt index c60cc0a7..46c526a7 100644 --- a/doc/startup.txt +++ b/doc/startup.txt @@ -21,13 +21,12 @@ The start-up procedure of OsmoBTS can be described as follows: | bts-specific | bts_model_phy_instance_set_defaults() | Called for every PHY Instance created | common | bts_controlif_setup() | Initialization of Control Interface | bts-specific | bts_model_ctrl_cmds_install() -| common | telnet_init() | Initialization of telnet interface +| common | telnet_init_default() | Initialization of telnet interface | common | pcu_sock_init() | Initialization of PCU socket | common | main() | Installation of signal handlers | common | abis_open() | Start of the A-bis connection to BSC | common | phy_links_open() | Iterate over list of configured PHY links | bts-specific | bts_model_phy_link_open() | Open each of the configured PHY links -| common | write_pid_file() | Generate the pid file | common | osmo_daemonize() | Fork as daemon in background (if configured) | common | bts_main() | Run main loop until global variable quit >= 2 | bts-specific | bts_model_oml_estab() | Called by core once OML link is established diff --git a/doc/trx_sched_tch.txt b/doc/trx_sched_tch.txt new file mode 100644 index 00000000..f8c79ffa --- /dev/null +++ b/doc/trx_sched_tch.txt @@ -0,0 +1,98 @@ +== rx_tchf_fn(): TCH/FS, TCH/EFS, TCH/AFS, TCH/F2.4, and FACCH/F + + 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 4 + | + |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A + | |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B + @ decoding from here + + +== rx_tchf_fn(): TCH/F14.4, TCH/F9.6, TCH/F4.8 + + 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | | | | | | | | | | | | | a | b | c | d | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | Rx bid={0,1,2,3}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 4 +| +|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A +| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B +@ decoding from here + + +== rx_tchh_fn(): TCH/HS, TCH/AHS + + 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 + | + |<~~~~~~~~~~~~~>| frame A + | |<~~~~~~~~~~~~~>| frame B + @ decoding from here + + +== rx_tchh_fn(): FACCH/H + + 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1} ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode ++---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---|---+---+---+---+---+---+---+---+ << 2 + | + |<~~~~~~~~~~~~~~~~~~~~~>| frame A + | |<~~~~~~~~~~~~~~~~~~~~~>| frame B + @ decoding from here + + +== rx_tchh_fn(): TCH/H4.8, TCH/H2.4 + + 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | | | a | b | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | | | a | b | c | d | | | Rx bid={0,1} +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | | | a | b | c | d | e | f | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | | | a | b | c | d | e | f | g | h | | | Rx bid={0,1} +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | | | Rx bid={0,1} +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | | | Rx bid={0,1} +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| | | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | | | Rx bid={0,1} +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | | | Rx bid={0,1}, decode +|---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ << 2 +| +|<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame A +| |<~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>| frame B +@ decoding from here diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am index d52c9aa4..cbd0fc37 100644 --- a/include/osmo-bts/Makefile.am +++ b/include/osmo-bts/Makefile.am @@ -1,9 +1,11 @@ noinst_HEADERS = \ abis.h \ abis_osmo.h \ + asci.h \ bts.h \ bts_model.h \ bts_shutdown_fsm.h \ + bts_sm.h \ bts_trx.h \ gsm_data.h \ logging.h \ @@ -11,6 +13,7 @@ noinst_HEADERS = \ oml.h \ paging.h \ rsl.h \ + rtp_input_preen.h \ signal.h \ vty.h \ amr.h \ @@ -21,7 +24,9 @@ noinst_HEADERS = \ tx_power.h \ control_if.h \ cbch.h \ + csd_v110.h \ l1sap.h \ + lchan.h \ power_control.h \ scheduler.h \ scheduler_backend.h \ @@ -29,4 +34,6 @@ noinst_HEADERS = \ dtx_dl_amr_fsm.h \ ta_control.h \ nm_common_fsm.h \ + notification.h \ + osmux.h \ $(NULL) diff --git a/include/osmo-bts/abis.h b/include/osmo-bts/abis.h index 62407ece..40707cd1 100644 --- a/include/osmo-bts/abis.h +++ b/include/osmo-bts/abis.h @@ -6,19 +6,15 @@ #include <osmo-bts/gsm_data.h> -#define OML_RETRY_TIMER 5 -#define OML_PING_TIMER 20 - -enum { - LINK_STATE_IDLE = 0, - LINK_STATE_RETRYING, - LINK_STATE_CONNECTING, - LINK_STATE_CONNECT, +enum abis_link_fsm_event { + ABIS_LINK_EV_SIGN_LINK_OML_UP, + ABIS_LINK_EV_SIGN_LINK_DOWN, + ABIS_LINK_EV_VTY_RM_ADDR, /* data: struct bsc_oml_host* being removed */ }; void abis_init(struct gsm_bts *bts); -struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host, - char *model_name); +int abis_open(struct gsm_bts *bts, char *model_name); + int abis_oml_sendmsg(struct msgb *msg); diff --git a/include/osmo-bts/amr.h b/include/osmo-bts/amr.h index f3132874..3fa4b8f2 100644 --- a/include/osmo-bts/amr.h +++ b/include/osmo-bts/amr.h @@ -14,5 +14,6 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, void amr_set_mode_pref(uint8_t *data, const struct amr_multirate_conf *amr_mrc, uint8_t cmi, uint8_t cmr); unsigned int amr_get_initial_mode(struct gsm_lchan *lchan); +void amr_init_mr_conf_def(struct gsm_lchan *lchan); #endif /* _OSMO_BTS_AMR_H */ diff --git a/include/osmo-bts/asci.h b/include/osmo-bts/asci.h new file mode 100644 index 00000000..99802962 --- /dev/null +++ b/include/osmo-bts/asci.h @@ -0,0 +1,43 @@ +#pragma once +#include <stdint.h> + +#include <osmo-bts/lchan.h> + +enum { + VGCS_TALKER_NONE = 0, + VGCS_TALKER_WAIT_FRAME, + VGCS_TALKER_ACTIVE, +}; + +void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn); + +void vgcs_lchan_activate(struct gsm_lchan *lchan); + +void vgcs_lchan_react(struct gsm_lchan *lchan); + +void vgcs_talker_frame(struct gsm_lchan *lchan); + +void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access); + +void vgcs_listener_reset(struct gsm_lchan *lchan); + +static inline bool vgcs_is_uplink_free(struct gsm_lchan *lchan) +{ + return lchan->asci.uplink_free; +} + +static inline void vgcs_uplink_free_get(struct gsm_lchan *lchan, uint8_t *msg) +{ + memcpy(msg, lchan->asci.uplink_free_msg, GSM_MACBLOCK_LEN); +} + +static inline void vgcs_uplink_free_set(struct gsm_lchan *lchan, uint8_t *msg) +{ + memcpy(lchan->asci.uplink_free_msg, msg, GSM_MACBLOCK_LEN); + lchan->asci.uplink_free = true; +} + +static inline void vgcs_uplink_free_reset(struct gsm_lchan *lchan) +{ + lchan->asci.uplink_free = false; +} diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 6a61d015..8a5fb820 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -5,6 +5,7 @@ #include <osmocom/core/socket.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts_trx.h> +#include <osmo-bts/osmux.h> struct gsm_bts_trx; @@ -24,11 +25,21 @@ enum { BTS_CTR_RACH_RCVD, BTS_CTR_RACH_DROP, BTS_CTR_RACH_HO, + BTS_CTR_RACH_VGCS, BTS_CTR_RACH_CS, BTS_CTR_RACH_PS, BTS_CTR_AGCH_RCVD, BTS_CTR_AGCH_SENT, BTS_CTR_AGCH_DELETED, + + BTS_CTR_RTP_RX_TOTAL, + BTS_CTR_RTP_RX_MARKER, + BTS_CTR_RTP_RX_DROP_PREEN, + BTS_CTR_RTP_RX_DROP_LOOPBACK, + BTS_CTR_RTP_RX_DROP_OVERFLOW, + BTS_CTR_RTP_RX_DROP_V110_DEC, + BTS_CTR_RTP_TX_TOTAL, + BTS_CTR_RTP_TX_MARKER, }; /* Used by OML layer for BTS Attribute reporting */ @@ -52,34 +63,28 @@ enum gsm_bts_type_variant { }; const char *btsvariant2str(enum gsm_bts_type_variant v); -/* TODO: add a brief description of this flag */ -#define BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP (1 << 0) -/* When this flag is set then the measurement data is included in - * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the - * measurement data is passed using a separate MPH INFO MEAS IND. - * (See also ticket: OS#2977) */ -#define BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB (1 << 1) -/* Whether the BTS model requires RadioCarrier MO to be in Enabled state - * (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */ -#define BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER (1 << 2) +enum bts_impl_flag { + /* TODO: add a brief description of this flag */ + BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP, + /* When this flag is set then the measurement data is included in + * (PRIM_PH_DATA) and struct ph_tch_param (PRIM_TCH). Otherwise the + * measurement data is passed using a separate MPH INFO MEAS IND. + * (See also ticket: OS#2977) */ + BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, + /* Whether the BTS model requires RadioCarrier MO to be in Enabled state + * (OPSTARTed) before OPSTARTing the RadioChannel MOs. See OS#5157 */ + BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, + /* Whether the BTS model reports interference measurements to L1SAP. */ + BTS_INTERNAL_FLAG_INTERF_MEAS, + + _BTS_INTERNAL_FLAG_NUM, /* must be at the end */ +}; /* BTS implementation flags (internal use, not exposed via OML) */ #define bts_internal_flag_get(bts, flag) \ - ((bts->flags & (typeof(bts->flags)) flag) != 0) + ((bts->flags & (typeof(bts->flags))(1 << flag)) != 0) #define bts_internal_flag_set(bts, flag) \ - bts->flags |= (typeof(bts->flags)) flag - -struct gsm_bts_gprs_nsvc { - struct gsm_bts *bts; - /* data read via VTY config file, to configure the BTS - * via OML from BSC */ - int id; - uint16_t nsvci; - struct osmo_sockaddr local; /* on the BTS */ - struct osmo_sockaddr remote; /* on the SGSN */ - - struct gsm_abis_mo mo; -}; + bts->flags |= (typeof(bts->flags))(1 << flag) struct gprs_rlc_cfg { uint16_t parameter[_NUM_RLC_PAR]; @@ -128,14 +133,28 @@ struct bts_power_ctrl_params { } pf; }; -/* BTS Site Manager */ -struct gsm_bts_sm { +/* GPRS CELL; ip.access specific NM Object */ +struct gsm_gprs_cell { struct gsm_abis_mo mo; + uint16_t bvci; + uint8_t timer[11]; + struct gprs_rlc_cfg rlc_cfg; + struct { + uint32_t gprs_codings; /* see NM_IPAC_F_GPRS_CODING_* flags */ + } support; +}; + +/* Struct that holds one OML-Address (Address of the BSC) */ +struct bsc_oml_host { + struct llist_head list; + char *addr; }; +#define BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT 100 + /* One BTS */ struct gsm_bts { - /* list header in net->bts_list */ + /* list header in g_bts_sm->bts_list */ struct llist_head list; /* number of the BTS in network */ @@ -149,6 +168,7 @@ struct gsm_bts { /* Base Station Identification Code (BSIC), lower 3 bits is BCC, * which is used as TSC for the CCCH */ uint8_t bsic; + bool bsic_configured; /* type of BTS */ enum gsm_bts_type_variant variant; enum gsm_band band; @@ -184,7 +204,7 @@ struct gsm_bts { /* CCCH is on C0 */ struct gsm_bts_trx *c0; - struct gsm_bts_sm site_mgr; + struct gsm_bts_sm *site_mgr; /* bitmask of all SI that are present/valid in si_buf */ uint32_t si_valid; @@ -214,18 +234,7 @@ struct gsm_bts { /* Not entirely sure how ip.access specific this is */ struct { - struct { - struct gsm_abis_mo mo; - uint16_t nsei; - uint8_t timer[7]; - } nse; - struct { - struct gsm_abis_mo mo; - uint16_t bvci; - uint8_t timer[11]; - struct gprs_rlc_cfg rlc_cfg; - } cell; - struct gsm_bts_gprs_nsvc nsvc[2]; + struct gsm_gprs_cell cell; uint8_t rac; } gprs; @@ -241,8 +250,9 @@ struct gsm_bts { int16_t boundary[6]; uint8_t intave; } interference; - unsigned int t200_ms[7]; + uint32_t t200_fn[7]; unsigned int t3105_ms; + unsigned int t3115_ms; /* VGCS UPLINK GRANT repeat timer */ struct { uint8_t overload_period; struct { @@ -265,6 +275,7 @@ struct gsm_bts { } rach; } load; uint8_t ny1; + uint8_t ny2; /* maximum number of repetitions for the VGCS UPLINK GRANT */ uint8_t max_ta; /* AGCH queuing */ @@ -294,9 +305,17 @@ struct gsm_bts { bool pni; /* Primary Notification Identifier */ } etws; + /* Advanced Speech Call Items (VBS/VGCS) + NCH related bits */ + struct { + int pos_nch; /* position of the NCH or < 0, if not available */ + uint8_t nln, nln_status; /* current notification list number and status */ + struct llist_head notifications; + int notification_entries; /* current number of entries in the list */ + int notification_count; /* counter to count all entries */ + } asci; + struct paging_state *paging_state; - char *bsc_oml_host; - struct llist_head oml_queue; + struct llist_head bsc_oml_hosts; unsigned int rtp_jitter_buf_ms; bool rtp_jitter_adaptive; @@ -306,8 +325,13 @@ struct gsm_bts { int rtp_ip_dscp; int rtp_priority; + bool rtp_nogaps_mode; /* emit RTP stream without any gaps */ + bool use_ul_ecu; /* "rtp internal-uplink-ecu" option */ + bool emit_hr_rfc5993; + struct { uint8_t ciphers; /* flags A5/1==0x1, A5/2==0x2, A5/3==0x4 */ + uint8_t max_ta; /* maximum timing advance */ } support; struct { uint8_t tc4_ctr; @@ -352,17 +376,26 @@ struct gsm_bts { struct { char *sock_path; + unsigned int sock_wqueue_len_max; } pcu; /* GSMTAP Um logging (disabled by default) */ struct { struct gsmtap_inst *inst; char *remote_host; + char *local_host; uint32_t sapi_mask; uint8_t sapi_acch; + bool rlp; + bool rlp_skip_null; } gsmtap; + struct osmux_state osmux; + struct osmo_fsm_inst *shutdown_fi; /* FSM instance to manage shutdown procedure during process exit */ + bool shutdown_fi_exit_proc; /* exit process when shutdown_fsm is finished? */ + bool shutdown_fi_skip_power_ramp; /* Skip power ramping and change power in one step? */ + struct osmo_fsm_inst *abis_link_fi; /* FSM instance to manage abis connection during process startup and link failure */ struct osmo_tdef *T_defs; /* Timer defines */ void *model_priv; /* Allocated by bts_model, contains model specific data pointer */ @@ -375,40 +408,47 @@ extern void *tall_bts_ctx; #define GSM_BTS_HAS_SI(bts, i) ((bts)->si_valid & (1 << i)) #define GSM_BTS_SI(bts, i) (void *)((bts)->si_buf[i][0]) -static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) { - return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr); +static inline struct gsm_bts *gsm_gprs_cell_get_bts(struct gsm_gprs_cell *cell) +{ + return (struct gsm_bts *)container_of(cell, struct gsm_bts, gprs.cell); } -struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num); -struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num); +struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num); +struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num); int bts_init(struct gsm_bts *bts); void bts_shutdown(struct gsm_bts *bts, const char *reason); +void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp); int bts_link_estab(struct gsm_bts *bts); int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg); -struct msgb *bts_agch_dequeue(struct gsm_bts *bts); int bts_agch_max_queue_length(int T, int bcch_conf); -int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, - int is_ag_res); + +enum ccch_msgt { + CCCH_MSGT_AGCH, + CCCH_MSGT_PCH, + CCCH_MSGT_NCH, +}; + +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch); int bts_supports_cipher(struct gsm_bts *bts, int rsl_cipher); uint8_t *bts_sysinfo_get(struct gsm_bts *bts, const struct gsm_time *g_time); void regenerate_si3_restoctets(struct gsm_bts *bts); void regenerate_si4_restoctets(struct gsm_bts *bts); int get_si4_ro_offset(const uint8_t *si4_buf); -uint8_t *lchan_sacch_get(struct gsm_lchan *lchan); -int lchan_init_lapdm(struct gsm_lchan *lchan); void load_timer_start(struct gsm_bts *bts); +void load_timer_stop(struct gsm_bts *bts); +bool load_timer_is_running(const struct gsm_bts *bts); void bts_update_status(enum bts_global_status which, int on); struct gsm_time *get_time(struct gsm_bts *bts); int bts_main(int argc, char **argv); -int bts_supports_cm(const struct gsm_bts *bts, - const struct rsl_ie_chan_mode *cm); +bool bts_supports_cm(const struct gsm_bts *bts, + const struct rsl_ie_chan_mode *cm); int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts); @@ -417,4 +457,11 @@ struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts); int bts_set_c0_pwr_red(struct gsm_bts *bts, const uint8_t red); +/* Context information to be put in the control buffer (db) of the AGCH msg + * buffer */ +struct bts_agch_msg_cb { + uint32_t msg_id; + bool confirm; +} __attribute__ ((packed)); + #endif /* _BTS_H */ diff --git a/include/osmo-bts/bts_model.h b/include/osmo-bts/bts_model.h index ef93fdad..673eb5b1 100644 --- a/include/osmo-bts/bts_model.h +++ b/include/osmo-bts/bts_model.h @@ -5,6 +5,7 @@ #include <osmocom/gsm/tlv.h> #include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmo-bts/gsm_data.h> @@ -20,8 +21,8 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, struct tlv_parsed *old_attr, struct tlv_parsed *new_attr, void *obj); -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int obj_kind, void *obj); +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj); int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj); diff --git a/include/osmo-bts/bts_shutdown_fsm.h b/include/osmo-bts/bts_shutdown_fsm.h index 1e74ac6b..553267dc 100644 --- a/include/osmo-bts/bts_shutdown_fsm.h +++ b/include/osmo-bts/bts_shutdown_fsm.h @@ -1,6 +1,6 @@ /* BTS shutdown FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -24,7 +24,6 @@ #include <osmocom/core/fsm.h> -/* 3GPP TS 24.008 § 4.1.3.3 GMM mobility management states on the network side */ enum bts_shutdown_fsm_states { BTS_SHUTDOWN_ST_NONE, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL, @@ -39,3 +38,6 @@ enum bts_shutdown_fsm_events { }; extern struct osmo_fsm bts_shutdown_fsm; + +struct gsm_bts; +bool bts_shutdown_in_progress(const struct gsm_bts *bts); diff --git a/include/osmo-bts/bts_sm.h b/include/osmo-bts/bts_sm.h new file mode 100644 index 00000000..e6610a5e --- /dev/null +++ b/include/osmo-bts/bts_sm.h @@ -0,0 +1,48 @@ +#pragma once + +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/socket.h> +#include <osmocom/gsm/gsm23003.h> + +#include <osmo-bts/oml.h> + +struct pcu_sock_state; + +/* GPRS NSVC; ip.access specific NM Object */ +struct gsm_gprs_nse; +struct gsm_gprs_nsvc { + struct gsm_abis_mo mo; + struct gsm_gprs_nse *nse; + /* data read via VTY config file, to configure the BTS + * via OML from BSC */ + int id; + uint16_t nsvci; + struct osmo_sockaddr local; /* on the BTS */ + struct osmo_sockaddr remote; /* on the SGSN */ +}; + +/* GPRS NSE; ip.access specific NM Object */ +struct gsm_gprs_nse { + struct gsm_abis_mo mo; + uint16_t nsei; + uint8_t timer[7]; + struct gsm_gprs_nsvc nsvc[2]; +}; + +struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse); + +/* BTS Site Manager */ +struct gsm_bts_sm { + struct gsm_abis_mo mo; + struct llist_head bts_list; + unsigned int num_bts; + struct osmo_plmn_id plmn; + struct { + struct pcu_sock_state *pcu_state; + struct gsm_gprs_nse nse; + } gprs; +}; + +extern struct gsm_bts_sm *g_bts_sm; + +struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx); diff --git a/include/osmo-bts/bts_trx.h b/include/osmo-bts/bts_trx.h index f033573f..9d3a748e 100644 --- a/include/osmo-bts/bts_trx.h +++ b/include/osmo-bts/bts_trx.h @@ -1,9 +1,16 @@ #pragma once +#include <osmocom/core/sockaddr_str.h> #include <osmo-bts/gsm_data.h> struct gsm_bts_bb_trx { struct gsm_abis_mo mo; + /* how do we talk RSL with this TRX? */ + struct { + struct osmo_sockaddr_str rem_addrstr; + uint8_t tei; + struct e1inp_sign_link *link; + } rsl; }; /* One TRX in a BTS */ @@ -16,9 +23,6 @@ struct gsm_bts_trx { uint8_t nr; /* human readable name / description */ char *description; - /* how do we talk RSL with this TRX? */ - uint8_t rsl_tei; - struct e1inp_sign_link *rsl_link; /* NM Radio Carrier and Baseband Transciever */ struct gsm_abis_mo mo; @@ -27,9 +31,10 @@ struct gsm_bts_trx { uint16_t arfcn; int nominal_power; /* in dBm */ unsigned int max_power_red; /* in actual dB */ - uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */ - uint8_t c0_idle_power_red; /* in actual dB OC-2G only */ + uint8_t max_power_backoff_8psk; /* in actual dB OC-2G only */ + uint8_t c0_idle_power_red; /* in actual dB OC-2G only */ + uint8_t ta_ctrl_interval; /* 1 step is 2 SACCH periods */ struct trx_power_params power_params; struct gsm_power_ctrl_params *bs_dpc_params; /* BS Dynamic Power Control */ @@ -39,6 +44,12 @@ struct gsm_bts_trx { /* The associated PHY instance */ struct phy_instance *pinst; + struct { + uint32_t freq_bands; /* see NM_IPAC_F_FREQ_BAND_* flags */ + uint32_t chan_types; /* see NM_IPAC_F_CHANT_* flags */ + uint32_t chan_modes; /* see NM_IPAC_F_CHANM_* flags */ + } support; + struct gsm_bts_trx_ts ts[TRX_NR_TS]; }; @@ -49,6 +60,7 @@ static inline struct gsm_bts_trx *gsm_bts_bb_trx_get_trx(struct gsm_bts_bb_trx * struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts); struct gsm_bts_trx *gsm_bts_trx_num(const struct gsm_bts *bts, int num); void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx); +void gsm_bts_trx_free_shadow_ts(struct gsm_bts_trx *trx); char *gsm_trx_name(const struct gsm_bts_trx *trx); const char *gsm_trx_unit_id(struct gsm_bts_trx *trx); @@ -56,6 +68,7 @@ int trx_link_estab(struct gsm_bts_trx *trx); void trx_operability_update(struct gsm_bts_trx *trx); uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg); +int pos_nch(const struct gsm_bts_trx *trx, const char *arg); bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx); #define LOGPTRX(trx, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_trx_name(trx), ## args) diff --git a/include/osmo-bts/cbch.h b/include/osmo-bts/cbch.h index 6bba5fa2..d5521f06 100644 --- a/include/osmo-bts/cbch.h +++ b/include/osmo-bts/cbch.h @@ -21,3 +21,5 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ /* call-back from bts model specific code when it wants to obtain a CBCH * block for a given gsm_time. outbuf must have 23 bytes of space. */ int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time); + +void bts_cbch_reset(struct gsm_bts *bts); diff --git a/include/osmo-bts/control_if.h b/include/osmo-bts/control_if.h index 490c87af..f6d877bc 100644 --- a/include/osmo-bts/control_if.h +++ b/include/osmo-bts/control_if.h @@ -1,5 +1,4 @@ #pragma once int bts_ctrl_cmds_install(struct gsm_bts *bts); -struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, - const char *bind_addr, uint16_t port); +struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port); diff --git a/include/osmo-bts/csd_v110.h b/include/osmo-bts/csd_v110.h new file mode 100644 index 00000000..f6be0ae2 --- /dev/null +++ b/include/osmo-bts/csd_v110.h @@ -0,0 +1,23 @@ +#pragma once + +/* RFC4040 "clearmode" RTP payload length */ +#define RFC4040_RTP_PLEN 160 + +struct gsm_lchan; + +struct csd_v110_frame_desc { + uint16_t num_blocks; + uint16_t num_bits; +}; + +struct csd_v110_lchan_desc { + struct csd_v110_frame_desc fr; + struct csd_v110_frame_desc hr; +}; + +extern const struct csd_v110_lchan_desc csd_v110_lchan_desc[256]; + +int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, + const uint8_t *data, size_t data_len); +int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, + const uint8_t *rtp, size_t rtp_len); diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h index 0ed63612..164c89fd 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -9,15 +9,13 @@ #include <osmocom/core/statistics.h> #include <osmocom/core/utils.h> #include <osmocom/core/linuxlist.h> -#include <osmocom/codec/ecu.h> -#include <osmocom/gsm/lapdm.h> +#include <osmocom/core/tdef.h> #include <osmocom/gsm/gsm23003.h> #include <osmocom/gsm/gsm0502.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/tlv.h> #include <osmocom/gsm/rxlev_stat.h> #include <osmocom/gsm/sysinfo.h> -#include <osmocom/gsm/meas_rep.h> #include <osmocom/gsm/bts_features.h> #include <osmocom/gsm/gsm48_rest_octets.h> #include <osmocom/gsm/protocol/gsm_04_08.h> @@ -29,6 +27,7 @@ #include <osmo-bts/paging.h> #include <osmo-bts/tx_power.h> #include <osmo-bts/oml.h> +#include <osmo-bts/lchan.h> #define GSM_FR_BITS 260 #define GSM_EFR_BITS 244 @@ -42,23 +41,6 @@ #define GSM_BTS_AGCH_QUEUE_LOW_LEVEL_DEFAULT 41 #define GSM_BTS_AGCH_QUEUE_HIGH_LEVEL_DEFAULT 91 -#define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args) - -struct gsm_network { - struct llist_head bts_list; - unsigned int num_bts; - struct osmo_plmn_id plmn; - struct pcu_sock_state *pcu_state; -}; - -enum lchan_ciph_state { - LCHAN_CIPH_NONE, - LCHAN_CIPH_RX_REQ, - LCHAN_CIPH_RX_CONF, - LCHAN_CIPH_RXTX_REQ, - LCHAN_CIPH_RX_CONF_TX_REQ, - LCHAN_CIPH_RXTX_CONF, -}; /* 16 is the max. number of SI2quater messages according to 3GPP TS 44.018 Table 10.5.2.33b.1: 4-bit index is used (2#1111 = 10#15) */ @@ -70,355 +52,58 @@ enum lchan_ciph_state { /* lchans 0..3 are SDCCH in combined channel configuration, use 4 as magic number for BCCH hack - see osmo-bts-../oml.c:opstart_compl() */ #define CCCH_LCHAN 4 +#define CBCH_LCHAN 2 #define TRX_NR_TS 8 #define TS_MAX_LCHAN 8 #define MAX_VERSION_LENGTH 64 -struct gsm_lchan; -struct osmo_rtp_socket; -struct pcu_sock_state; -struct smscb_msg; - -#define MAX_A5_KEY_LEN (128/8) -#define RSL_ENC_ALG_A5(x) (x+1) - -/* state of a logical channel */ -enum gsm_lchan_state { - LCHAN_S_NONE, /* channel is not active */ - LCHAN_S_ACT_REQ, /* channel activation requested */ - LCHAN_S_ACTIVE, /* channel is active and operational */ - LCHAN_S_REL_REQ, /* channel release has been requested */ - LCHAN_S_REL_ERR, /* channel is in an error state */ - LCHAN_S_BROKEN, /* channel is somehow unusable */ - LCHAN_S_INACTIVE, /* channel is set inactive */ -}; - -#define MAX_NUM_UL_MEAS 104 -#define LC_UL_M_F_L1_VALID (1 << 0) -#define LC_UL_M_F_RES_VALID (1 << 1) -#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2) - -struct bts_ul_meas { - /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */ - uint16_t ber10k; - /* timing advance offset (in 1/256 bits) */ - int16_t ta_offs_256bits; - /* C/I ratio in dB */ - float c_i; - /* flags */ - uint8_t is_sub:1; - /* RSSI in dBm * -1 */ - uint8_t inv_rssi; -}; - -struct amr_mode { - uint8_t mode; - uint8_t threshold; - uint8_t hysteresis; -}; - -struct amr_multirate_conf { - uint8_t gsm48_ie[2]; - struct amr_mode ms_mode[4]; - struct amr_mode bts_mode[4]; - uint8_t num_modes; -}; - -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, -}; - -/* State of the SAPIs in the lchan */ -enum lchan_sapi_state { - LCHAN_SAPI_S_NONE, - LCHAN_SAPI_S_REQ, - LCHAN_SAPI_S_ASSIGNED, - LCHAN_SAPI_S_REL, - LCHAN_SAPI_S_ERROR, -}; - -/* What kind of release/activation is done? A silent one for - * the PDCH or one triggered through RSL? */ -enum lchan_rel_act_kind { - LCHAN_REL_ACT_RSL, - LCHAN_REL_ACT_PCU, - LCHAN_REL_ACT_OML, - LCHAN_REL_ACT_REACT, /* remove once auto-activation hack is removed from opstart_compl() */ -}; - -struct gsm_rep_facch { - struct msgb *msg; - uint32_t fn; -}; - -/* MS/BS Power related measurement averaging algo */ -enum gsm_power_ctrl_meas_avg_algo { - GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE = 0x00, - GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED = 0x01, - GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED = 0x02, - GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN = 0x03, - /* EWMA is an Osmocom specific algo */ - GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA = 0x04, -}; - -/* MS/BS Power related measurement parameters */ -struct gsm_power_ctrl_meas_params { - /* Thresholds (see 3GPP TS 45.008, section A.3.2.1) */ - uint8_t lower_thresh; /* lower (decreasing) direction */ - uint8_t upper_thresh; /* upper (increasing) direction */ - - /* Threshold Comparators for lower (decreasing) direction */ - uint8_t lower_cmp_p; /* P1 for RxLev, P3 for RxQual */ - uint8_t lower_cmp_n; /* N1 for RxLev, N3 for RxQual */ - /* Threshold Comparators for upper (increasing) direction */ - uint8_t upper_cmp_p; /* P2 for RxLev, P4 for RxQual */ - uint8_t upper_cmp_n; /* N2 for RxLev, N4 for RxQual */ - - /* Hreqave and Hreqt (see 3GPP TS 45.008, Annex A) */ - uint8_t h_reqave; - uint8_t h_reqt; - - /* AVG algorithm and its specific parameters */ - enum gsm_power_ctrl_meas_avg_algo algo; - union { - /* Exponentially Weighted Moving Average */ - struct { - /* Smoothing factor: higher the value - less smoothing */ - uint8_t alpha; /* 1 .. 99 (in %) */ - } ewma; - }; -}; - -/* MS/BS Power Control parameters */ -struct gsm_power_ctrl_params { - /* Minimum interval between power level changes */ - uint8_t ctrl_interval; /* 1 step is 2 SACCH periods */ - - /* Power change step size (maximum) */ - uint8_t inc_step_size_db; /* increasing direction */ - uint8_t red_step_size_db; /* reducing direction */ - - /* Measurement averaging parameters for RxLev & RxQual */ - struct gsm_power_ctrl_meas_params rxqual_meas; - struct gsm_power_ctrl_meas_params rxlev_meas; -}; - -/* Default MS/BS Power Control parameters */ -extern const struct gsm_power_ctrl_params power_ctrl_params_def; - -/* Measurement pre-processing state */ -struct gsm_power_ctrl_meas_proc_state { - /* Number of measurements processed */ - unsigned int meas_num; - /* Algorithm specific data */ - union { - struct { - /* Scaled up 100 times average value */ - int Avg100; - } ewma; - }; -}; - -struct lchan_power_ctrl_state { - /* Dynamic Power Control parameters (NULL in static mode) */ - const struct gsm_power_ctrl_params *dpc_params; - /* Measurement pre-processing state (for dynamic mode) */ - struct gsm_power_ctrl_meas_proc_state rxlev_meas_proc; - /* Number of SACCH blocks to skip (for dynamic mode) */ - int skip_block_num; - - /* Depending on the context (MS or BS power control), fields 'current' and 'max' - * reflect either the MS power level (magic numbers), or BS Power reduction level - * (attenuation, in dB). */ - uint8_t current; - uint8_t max; -}; - -struct gsm_lchan { - /* The TS that we're part of */ - struct gsm_bts_trx_ts *ts; - /* The logical subslot number in the TS */ - uint8_t nr; - /* The logical channel type */ - enum gsm_chan_t type; - /* RSL channel mode */ - enum rsl_cmod_spd rsl_cmode; - /* If TCH, traffic channel mode */ - enum gsm48_chan_mode tch_mode; - enum lchan_csd_mode csd_mode; - /* State */ - enum gsm_lchan_state state; - const char *broken_reason; - /* Encryption information */ - struct { - uint8_t alg_id; - uint8_t key_len; - uint8_t key[MAX_A5_KEY_LEN]; - } encr; - - struct { - uint32_t bound_ip; - uint32_t connect_ip; - uint16_t bound_port; - uint16_t connect_port; - uint16_t conn_id; - uint8_t rtp_payload; - uint8_t rtp_payload2; - uint8_t speech_mode; - struct osmo_rtp_socket *rtp_socket; - } abis_ip; - - uint8_t rqd_ta; - - char *name; - - /* For handover, activation is described in 3GPP TS 48.058 4.1.3 and 4.1.4: - * - * | | Access || transmit | activate - * | MS Power | Delay || on main channel | dl SACCH - * ---------------------------------------------------------------------- - * async ho no * --> yes no - * async ho yes * --> yes may be started - * sync ho no no --> yes no - * sync ho yes no --> yes may be started - * sync ho yes yes --> yes shall be started - * - * Always start the main channel immediately. - * want_dl_sacch_active indicates whether dl SACCH should be activated on CHAN ACT. - */ - bool want_dl_sacch_active; - - /* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23. - * Currently we don't share these headers so this is a magic number. */ - struct llist_head sapi_cmds; - uint8_t sapis_dl[23]; - uint8_t sapis_ul[23]; - struct lapdm_channel lapdm_ch; - struct llist_head dl_tch_queue; - struct { - /* bitmask of all SI that are present/valid in si_buf */ - uint32_t valid; - /* bitmask of all SI that do not mirror the BTS-global SI values */ - uint32_t overridden; - uint32_t last; - /* buffers where we put the pre-computed SI: - SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */ - sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM]; - } si; - struct { - uint8_t flags; - /* RSL measurement result number, 0 at lchan_act */ - uint8_t res_nr; - /* number of measurements stored in array below */ - uint8_t num_ul_meas; - struct bts_ul_meas uplink[MAX_NUM_UL_MEAS]; - /* last L1 header from the MS */ - struct rsl_l1_info l1_info; - struct gsm_meas_rep_unidir ul_res; - int16_t ms_toa256; - /* Frame number of the last measurement indication receceived */ - uint32_t last_fn; - /* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */ - struct { - /* minimum value of toa256 during measurement period */ - int16_t toa256_min; - /* maximum value of toa256 during measurement period */ - int16_t toa256_max; - /* standard deviation of toa256 value during measurement period */ - uint16_t toa256_std_dev; - } ext; - /* Interference levels reported by PHY (in dBm) */ - int16_t interf_meas_dbm[31]; /* Intave max is 31 */ - uint8_t interf_meas_num; - } meas; - struct { - struct amr_multirate_conf amr_mr; - struct { - struct osmo_fsm_inst *dl_amr_fsm; - /* TCH cache */ - uint8_t cache[20]; - /* FACCH cache */ - uint8_t facch[GSM_MACBLOCK_LEN]; - uint8_t len; - uint32_t fn; - bool is_update; - /* set for each SID frame to detect talkspurt for codecs - without explicit ONSET event */ - bool ul_sid; - /* indicates if DTXd was active during DL measurement - period */ - bool dl_active; - /* last UL SPEECH resume flag */ - bool is_speech_resume; - } dtx; - uint8_t last_cmr; - uint32_t last_fn; - - /* SLOT #0 and #1 to store FACCH for repetition */ - struct gsm_rep_facch rep_facch[2]; - - } tch; - - /* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/ - int16_t ms_t_offs; - /* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */ - int16_t p_offs; - - /* BTS-side ciphering state (rx only, bi-directional, ...) */ - uint8_t ciph_state; - uint8_t ciph_ns; - uint8_t loopback; - struct { - uint8_t active; - uint8_t ref; - /* T3105: PHYS INF retransmission */ - struct osmo_timer_list t3105; - /* counts up to Ny1 */ - unsigned int phys_info_count; - } ho; - /* S counter for link loss */ - int s; - /* Kind of the release/activation. E.g. RSL or PCU */ - enum lchan_rel_act_kind rel_act_kind; - /* RTP header Marker bit to indicate beginning of speech after pause */ - bool rtp_tx_marker; - - /* MS/BS power control state */ - struct lchan_power_ctrl_state ms_power_ctrl; - struct lchan_power_ctrl_state bs_power_ctrl; - - /* MS/BS Dynamic Power Control parameters */ - struct gsm_power_ctrl_params ms_dpc_params; - struct gsm_power_ctrl_params bs_dpc_params; - - struct msgb *pending_rel_ind_msg; - - /* ECU (Error Concealment Unit) state */ - struct osmo_ecu_state *ecu_state; - - struct abis_rsl_osmo_rep_acch_cap repeated_acch_capability; - bool repeated_dl_facch_active; - bool repeated_ul_sacch_active; - bool repeated_dl_sacch_active; - - /* Message buffer to store DL-SACCH repeation candidate */ - struct msgb *rep_sacch; -}; - -extern const struct value_string lchan_ciph_state_names[]; -static inline const char *lchan_ciph_state_name(uint8_t state) { - return get_value_string(lchan_ciph_state_names, state); -} +/* NM_IPAC_F_CHANT_* mask for NM_IPAC_EIE_CHAN_TYPES (common) */ +#define NM_IPAC_MASK_CHANT_COMMON \ + (NM_IPAC_F_CHANT_TCHF | \ + NM_IPAC_F_CHANT_TCHH | \ + NM_IPAC_F_CHANT_SDCCH8 | \ + NM_IPAC_F_CHANT_BCCH | \ + NM_IPAC_F_CHANT_BCCH_SDCCH4) +/* NM_IPAC_F_CHANM_SPEECH_* mask for NM_IPAC_EIE_CHAN_MODES */ +#define NM_IPAC_MASK_CHANM_SPEECH \ + (NM_IPAC_F_CHANM_SPEECH_FS | \ + NM_IPAC_F_CHANM_SPEECH_EFS | \ + NM_IPAC_F_CHANM_SPEECH_AFS | \ + NM_IPAC_F_CHANM_SPEECH_HS | \ + NM_IPAC_F_CHANM_SPEECH_AHS) +/* NM_IPAC_F_CHANM_CSD_NT_* mask for NM_IPAC_EIE_CHAN_MODES */ +#define NM_IPAC_MASK_CHANM_CSD_NT \ + (NM_IPAC_F_CHANM_CSD_NT_4k8 | \ + NM_IPAC_F_CHANM_CSD_NT_9k6 | \ + NM_IPAC_F_CHANM_CSD_NT_14k4) +/* NM_IPAC_F_CHANM_CSD_T_* mask for NM_IPAC_EIE_CHAN_MODES */ +#define NM_IPAC_MASK_CHANM_CSD_T \ + (NM_IPAC_F_CHANM_CSD_T_1200_75 | \ + NM_IPAC_F_CHANM_CSD_T_600 | \ + NM_IPAC_F_CHANM_CSD_T_1k2 | \ + NM_IPAC_F_CHANM_CSD_T_2k4 | \ + NM_IPAC_F_CHANM_CSD_T_4k8 | \ + NM_IPAC_F_CHANM_CSD_T_9k6 | \ + NM_IPAC_F_CHANM_CSD_T_14k4) +/* NM_IPAC_F_GPRS_CODING_CS[1-4] mask for NM_IPAC_EIE_GPRS_CODING */ +#define NM_IPAC_MASK_GPRS_CODING_CS \ + (NM_IPAC_F_GPRS_CODING_CS1 | \ + NM_IPAC_F_GPRS_CODING_CS2 | \ + NM_IPAC_F_GPRS_CODING_CS3 | \ + NM_IPAC_F_GPRS_CODING_CS4) +/* NM_IPAC_F_GPRS_CODING_MCS[1-9] mask for NM_IPAC_EIE_GPRS_CODING */ +#define NM_IPAC_MASK_GPRS_CODING_MCS \ + (NM_IPAC_F_GPRS_CODING_MCS1 | \ + NM_IPAC_F_GPRS_CODING_MCS2 | \ + NM_IPAC_F_GPRS_CODING_MCS3 | \ + NM_IPAC_F_GPRS_CODING_MCS4 | \ + NM_IPAC_F_GPRS_CODING_MCS5 | \ + NM_IPAC_F_GPRS_CODING_MCS6 | \ + NM_IPAC_F_GPRS_CODING_MCS7 | \ + NM_IPAC_F_GPRS_CODING_MCS8 | \ + NM_IPAC_F_GPRS_CODING_MCS9) enum gsm_bts_trx_ts_flags { TS_F_PDCH_ACTIVE = 0x1000, @@ -439,7 +124,6 @@ struct gsm_bts_trx_ts { struct { enum gsm_phys_chan_config pchan_is; enum gsm_phys_chan_config pchan_want; - struct msgb *pending_chan_activ; } dyn; unsigned int flags; @@ -447,7 +131,10 @@ struct gsm_bts_trx_ts { /* Training Sequence Code (range 0..7) */ uint8_t tsc_oml; /* configured via OML */ - uint8_t tsc; /* currently in use */ + bool tsc_oml_configured; + uint8_t tsc_rsl; /* configured via RSL (Osmo extension) */ + bool tsc_rsl_configured; + uint8_t tsc; /* TSC currently in use. Preference: RSL, OML, BTS-BSIC-OML */ /* Training Sequence Set (range 0..3) */ uint8_t tsc_set; @@ -479,8 +166,6 @@ struct gsm_bts_trx_ts { struct gsm_lchan lchan[TS_MAX_LCHAN]; }; -#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0]) - enum gprs_rlc_par { RLC_T3142, RLC_T3169, @@ -517,6 +202,9 @@ enum gprs_cs { * OML connection will cause a special warning to be logged. */ #define OSMO_BTS_OML_CONN_EARLY_DISCONNECT 10 /* in seconds */ +extern struct osmo_tdef_group bts_tdef_groups[]; +extern struct osmo_tdef bts_T_defs[]; +extern struct osmo_tdef abis_T_defs[]; extern const struct value_string gsm_pchant_names[13]; extern const struct value_string gsm_pchant_descs[13]; @@ -524,8 +212,6 @@ const char *gsm_pchan_name(enum gsm_phys_chan_config c); const char *gsm_lchant_name(enum gsm_chan_t c); char *gsm_ts_name(const struct gsm_bts_trx_ts *ts); char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts); -void gsm_lchan_name_update(struct gsm_lchan *lchan); -const char *gsm_lchans_name(enum gsm_lchan_state s); #define GSM_TS_NAME_FMT \ "bts=%u,trx=%u,ts=%u" "%s" @@ -533,18 +219,6 @@ const char *gsm_lchans_name(enum gsm_lchan_state s); (ts)->trx->bts->nr, (ts)->trx->nr, (ts)->nr, \ (ts)->vamos.is_shadow ? ",shadow" : "" -static inline char *gsm_lchan_name(const struct gsm_lchan *lchan) -{ - return lchan->name; -} - -uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan); -uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan, - enum gsm_phys_chan_config as_pchan); - -void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm); -int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan); - #define BSIC2BCC(bsic) ((bsic) & 0x07) #define BTS_TSC(bts) BSIC2BCC((bts)->bsic) @@ -555,9 +229,6 @@ enum gsm_phys_chan_config ts_pchan(const struct gsm_bts_trx_ts *ts); uint8_t ts_subslots(const struct gsm_bts_trx_ts *ts); bool ts_is_tch(const struct gsm_bts_trx_ts *ts); -int lchan2ecu_codec(const struct gsm_lchan *lchan); - -void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state); int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pchan); @@ -566,16 +237,8 @@ int conf_lchans_as_pchan(struct gsm_bts_trx_ts *ts, bool ts_is_pdch(const struct gsm_bts_trx_ts *ts); -static inline bool lchan_is_dcch(const struct gsm_lchan *lchan) -{ - switch (lchan->type) { - case GSM_LCHAN_SDCCH: - case GSM_LCHAN_TCH_F: - case GSM_LCHAN_TCH_H: - return true; - default: - return false; - } -} +void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts); + +void gsm_ts_release(struct gsm_bts_trx_ts *ts); #endif /* _GSM_DATA_H */ diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h index f78d1143..34259bd3 100644 --- a/include/osmo-bts/l1sap.h +++ b/include/osmo-bts/l1sap.h @@ -4,6 +4,8 @@ #include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/protocol/gsm_08_58.h> +#define L1SAP_MSGB_HEADROOM 128 + /* lchan link ID */ #define LID_SACCH 0x40 #define LID_DEDIC 0x00 @@ -96,10 +98,11 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, uint32_t timestamp, bool marker); /* channel control */ -int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp); +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr); int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr); +int l1sap_uplink_access(struct gsm_lchan *lchan, bool active); enum l1sap_common_sapi { L1SAP_COMMON_SAPI_UNKNOWN, @@ -139,12 +142,11 @@ int add_l1sap_header(struct gsm_bts_trx *trx, struct msgb *rmsg, #define msgb_l1sap_prim(msg) ((struct osmo_phsap_prim *)(msg)->l1h) +void radio_link_timeout_reset(struct gsm_lchan *lchan); + int bts_check_for_first_ciphrd(struct gsm_lchan *lchan, uint8_t *data, int len); -int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn); - -void repeated_dl_facch_active_decision(struct gsm_lchan *lchan, - const uint8_t *l3, size_t l3_len); +enum ccch_msgt get_ccch_msgt(struct gsm_bts_trx *trx, uint32_t fn); #endif /* L1SAP_H */ diff --git a/include/osmo-bts/lchan.h b/include/osmo-bts/lchan.h new file mode 100644 index 00000000..585483bd --- /dev/null +++ b/include/osmo-bts/lchan.h @@ -0,0 +1,428 @@ +#pragma once + +#include <stdbool.h> +#include <stdint.h> +#include <netinet/in.h> + +#include <osmocom/core/timer.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/logging.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/codec/codec.h> +#include <osmocom/codec/ecu.h> +#include <osmocom/gsm/lapdm.h> +#include <osmocom/gsm/sysinfo.h> +#include <osmocom/gsm/protocol/gsm_08_58.h> +#include <osmocom/gsm/gsm48_rest_octets.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/meas_rep.h> +#include <osmocom/netif/osmux.h> + +#include <osmo-bts/power_control.h> + +#define LOGPLCHAN(lchan, ss, lvl, fmt, args...) LOGP(ss, lvl, "%s " fmt, gsm_lchan_name(lchan), ## args) + +enum lchan_ciph_state { + LCHAN_CIPH_NONE, + LCHAN_CIPH_RX_REQ, + LCHAN_CIPH_RX_CONF, + LCHAN_CIPH_RXTX_REQ, + LCHAN_CIPH_RX_CONF_TX_REQ, + LCHAN_CIPH_RXTX_CONF, +}; + +/* state of a logical channel */ +enum gsm_lchan_state { + LCHAN_S_NONE, /* channel is not active */ + LCHAN_S_ACT_REQ, /* channel activation requested */ + LCHAN_S_ACTIVE, /* channel is active and operational */ + LCHAN_S_REL_REQ, /* channel release has been requested */ + LCHAN_S_REL_ERR, /* channel is in an error state */ + LCHAN_S_BROKEN, /* channel is somehow unusable */ +}; + +#define MAX_NUM_UL_MEAS 104 +#define LC_UL_M_F_L1_VALID (1 << 0) +#define LC_UL_M_F_RES_VALID (1 << 1) +#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2) + +#define MAX_A5_KEY_LEN (128/8) +#define RSL_ENC_ALG_A5(x) (x+1) + +struct bts_ul_meas { + /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */ + uint16_t ber10k; + /* timing advance offset (in 1/256 bits) */ + int16_t ta_offs_256bits; + /* C/I ratio in cB */ + int16_t ci_cb; + /* flags */ + uint8_t is_sub:1; + /* RSSI in dBm * -1 */ + uint8_t inv_rssi; +}; + +struct amr_mode { + uint8_t mode; + uint8_t threshold; + uint8_t hysteresis; +}; + +struct amr_multirate_conf { + uint8_t gsm48_ie[2]; + struct amr_mode mode[4]; + uint8_t num_modes; +}; + +enum lchan_csd_mode { + LCHAN_CSD_M_NT = 0, + LCHAN_CSD_M_T_1200_75, + LCHAN_CSD_M_T_600, + LCHAN_CSD_M_T_1200, + LCHAN_CSD_M_T_2400, + LCHAN_CSD_M_T_4800, + LCHAN_CSD_M_T_9600, + LCHAN_CSD_M_T_14400, + LCHAN_CSD_M_T_29000, + LCHAN_CSD_M_T_32000, + _LCHAN_CSD_M_NUM, +}; + +/* State of the SAPIs in the lchan */ +enum lchan_sapi_state { + LCHAN_SAPI_S_NONE, + LCHAN_SAPI_S_REQ, + LCHAN_SAPI_S_ASSIGNED, + LCHAN_SAPI_S_REL, + LCHAN_SAPI_S_ERROR, +}; + +/* What kind of release/activation is done? A silent one for + * the PDCH or one triggered through RSL? */ +enum lchan_rel_act_kind { + LCHAN_REL_ACT_RSL, + LCHAN_REL_ACT_PCU, + LCHAN_REL_ACT_OML, + LCHAN_REL_ACT_REACT, /* FIXME: remove once auto-activation hack is removed from opstart_compl() (OS#1575) */ +}; + +struct gsm_rep_facch { + struct msgb *msg; + uint32_t fn; +}; + + +struct lchan_power_ctrl_state { + /* Dynamic Power Control parameters (NULL in static mode) */ + const struct gsm_power_ctrl_params *dpc_params; + /* Measurement pre-processing state (for dynamic mode) */ + struct gsm_power_ctrl_meas_proc_state rxlev_meas_proc; + struct gsm_power_ctrl_meas_proc_state rxqual_meas_proc; + struct gsm_power_ctrl_meas_proc_state ci_meas_proc; + /* Number of SACCH blocks to skip (for dynamic mode) */ + int skip_block_num; + + /* Depending on the context (MS or BS power control), fields 'current' and 'max' + * reflect either the MS power level (magic numbers), or BS Power reduction level + * (attenuation, in dB). */ + uint8_t current; + uint8_t max; +}; + +struct lchan_ta_ctrl_state { + /* Number of SACCH blocks to skip */ + int skip_block_num; + /* Currently requested TA */ + uint8_t current; +}; + +struct gsm_lchan { + /* The TS that we're part of */ + struct gsm_bts_trx_ts *ts; + /* The logical subslot number in the TS */ + uint8_t nr; + /* The logical channel type */ + enum gsm_chan_t type; + /* RSL channel rate and type */ + enum rsl_cmod_crt rsl_chan_rt; + /* RSL channel mode */ + enum rsl_cmod_spd rsl_cmode; + /* If TCH, traffic channel mode */ + enum gsm48_chan_mode tch_mode; + enum lchan_csd_mode csd_mode; + /* State */ + enum gsm_lchan_state state; + const char *broken_reason; + /* Encryption information */ + struct { + uint8_t alg_id; + uint8_t key_len; + uint8_t key[MAX_A5_KEY_LEN]; + } encr; + + struct { + uint32_t bound_ip; + uint32_t connect_ip; + uint16_t bound_port; + uint16_t connect_port; + uint16_t conn_id; + uint8_t rtp_payload; + uint8_t rtp_payload2; + uint8_t speech_mode; + struct { + bool use; + uint8_t local_cid; + uint8_t remote_cid; + /* Rx Osmux -> RTP, one allocated & owned per lchan */ + struct osmux_out_handle *out; + /* Tx RTP -> Osmux, shared by all lchans sharing a + * remote endp (addr+port), see "struct osmux_handle" */ + struct osmux_in_handle *in; + /* Used to build rtp messages we send to osmux */ + struct osmo_rtp_handle *rtpst; + } osmux; + struct osmo_rtp_socket *rtp_socket; + } abis_ip; + + char *name; + + /* For handover, activation is described in 3GPP TS 48.058 4.1.3 and 4.1.4: + * + * | | Access || transmit | activate + * | MS Power | Delay || on main channel | dl SACCH + * ---------------------------------------------------------------------- + * async ho no * --> yes no + * async ho yes * --> yes may be started + * sync ho no no --> yes no + * sync ho yes no --> yes may be started + * sync ho yes yes --> yes shall be started + * + * Always start the main channel immediately. + * want_dl_sacch_active indicates whether dl SACCH should be activated on CHAN ACT. + */ + bool want_dl_sacch_active; + + /* Number of different GsmL1_Sapi_t used in osmo_bts_sysmo is 23. + * Currently we don't share these headers so this is a magic number. */ + struct llist_head sapi_cmds; + uint8_t sapis_dl[23]; + uint8_t sapis_ul[23]; + struct lapdm_channel lapdm_ch; + /* It is required to have L3 info with DL establishment. */ + bool l3_info_estab; + struct llist_head dl_tch_queue; + unsigned int dl_tch_queue_len; + struct { + /* bitmask of all SI that are present/valid in si_buf */ + uint32_t valid; + /* bitmask of all SI that do not mirror the BTS-global SI values */ + uint32_t overridden; + uint32_t last; + /* buffers where we put the pre-computed SI: + SI2Q_MAX_NUM is the max number of SI2quater messages (see 3GPP TS 44.018) */ + sysinfo_buf_t buf[_MAX_SYSINFO_TYPE][SI2Q_MAX_NUM]; + } si; + struct { + uint8_t flags; + /* RSL measurement result number, 0 at lchan_act */ + uint8_t res_nr; + /* number of measurements stored in array below */ + uint8_t num_ul_meas; + struct bts_ul_meas uplink[MAX_NUM_UL_MEAS]; + /* last L1 header from the MS */ + struct rsl_l1_info l1_info; + struct gsm_meas_rep_unidir ul_res; + int16_t ms_toa256; + int16_t ul_ci_cb_full; + int16_t ul_ci_cb_sub; + /* Frame number of the last measurement indication receceived */ + uint32_t last_fn; + /* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */ + struct { + /* minimum value of toa256 during measurement period */ + int16_t toa256_min; + /* maximum value of toa256 during measurement period */ + int16_t toa256_max; + /* standard deviation of toa256 value during measurement period */ + uint16_t toa256_std_dev; + } ext; + /* Interference levels reported by PHY (in dBm) */ + int16_t interf_meas_avg_dbm; /* Average value */ + int16_t interf_meas_dbm[31]; /* Intave max is 31 */ + uint8_t interf_meas_num; + uint8_t interf_band; + } meas; + struct { + struct amr_multirate_conf amr_mr; + struct { + struct osmo_fsm_inst *dl_amr_fsm; + /* TCH cache */ + uint8_t cache[20]; + /* FACCH cache */ + uint8_t facch[GSM_MACBLOCK_LEN]; + uint8_t len; + uint32_t fn; + bool is_update; + /* set for each SID frame to detect talkspurt for codecs + without explicit ONSET event */ + bool ul_sid; + /* indicates if DTXd was active during DL measurement + period */ + bool dl_active; + /* last UL SPEECH resume flag */ + bool is_speech_resume; + } dtx; + struct { + bool last_rtp_input_was_sid; + uint8_t last_sid[GSM_FR_BYTES]; + uint8_t last_sid_len; + uint8_t last_sid_age; + /* A SID was transmitted on the DL in the period + * beginning with the last transmitted speech frame + * or the last mandatory-Tx position, whichever was + * more recent. */ + bool dl_sid_transmitted; + /* The current frame in the DL is taken up by FACCH */ + bool dl_facch_stealing; + } dtx_fr_hr_efr; + uint8_t last_cmr; + uint32_t last_fn; + struct { + /* buffers to re-combine RLP frame from multiple Um blocks */ + uint8_t rlp_buf_ul[576/8]; /* maximum size of RLP frame */ + uint8_t rlp_buf_dl[576/8]; /* maximum size of RLP frame */ + } csd; + } tch; + + /* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/ + int16_t ms_t_offs; + /* 3GPP TS 45.010 § 1.2 round trip propagation delay (in symbols) or -1 */ + int16_t p_offs; + + /* BTS-side ciphering state (rx only, bi-directional, ...) */ + uint8_t ciph_state; + uint8_t ciph_ns; + uint8_t loopback; + struct { + uint8_t active; + uint8_t ref; + /* T3105: PHYS INF retransmission */ + struct osmo_timer_list t3105; + /* counts up to Ny1 */ + unsigned int phys_info_count; + } ho; + struct { + bool listener_detected; + uint8_t talker_active; + uint8_t ref; + uint32_t fn; + /* T3115: VGCS UPLINK GRANT retransmission */ + struct osmo_timer_list t3115; + /* counts up to Ny2 */ + unsigned int vgcs_ul_grant_count; + /* uplink free message */ + bool uplink_free; + uint8_t uplink_free_msg[GSM_MACBLOCK_LEN]; + } asci; + /* S counter for link loss */ + int s; + /* Kind of the release/activation. E.g. RSL or PCU */ + enum lchan_rel_act_kind rel_act_kind; + /* Pending RSL CHANnel ACTIVation message */ + struct msgb *pending_chan_activ; + /* RTP header Marker bit to indicate beginning of speech after pause */ + bool rtp_tx_marker; + + /* TA Control Loop */ + struct lchan_ta_ctrl_state ta_ctrl; + + /* MS/BS power control state */ + struct lchan_power_ctrl_state ms_power_ctrl; + struct lchan_power_ctrl_state bs_power_ctrl; + + /* MS/BS Dynamic Power Control parameters */ + struct gsm_power_ctrl_params ms_dpc_params; + struct gsm_power_ctrl_params bs_dpc_params; + + /* Temporary ACCH overpower capabilities and state */ + struct abis_rsl_osmo_temp_ovp_acch_cap top_acch_cap; + bool top_acch_active; + + struct msgb *pending_rel_ind_msg; + + /* ECU (Error Concealment Unit) state */ + struct osmo_ecu_state *ecu_state; + + /* Repeated ACCH capabilities and current state */ + struct abis_rsl_osmo_rep_acch_cap rep_acch_cap; + struct { + bool dl_facch_active; + bool ul_sacch_active; + bool dl_sacch_active; + + /* Message buffers to store repeation candidates */ + struct gsm_rep_facch dl_facch[2]; + struct msgb *dl_sacch_msg; + } rep_acch; + + /* Cached early Immediate Assignment message: if the Immediate Assignment arrives before the channel is + * confirmed active, then cache it here and send it once the channel is confirmed to be active. This is related + * to the Early IA feature, see OsmoBSC config option 'immediate-assignment pre-chan-ack'. */ + struct msgb *early_rr_ia; + struct osmo_timer_list early_rr_ia_delay; +}; + +extern const struct value_string lchan_ciph_state_names[]; +static inline const char *lchan_ciph_state_name(uint8_t state) +{ + return get_value_string(lchan_ciph_state_names, state); +} + +#define GSM_LCHAN_SI(lchan, i) (void *)((lchan)->si.buf[i][0]) + +void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr); +void gsm_lchan_name_update(struct gsm_lchan *lchan); +int lchan_init_lapdm(struct gsm_lchan *lchan); +void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind); +int lchan_deactivate(struct gsm_lchan *lchan); +const char *gsm_lchans_name(enum gsm_lchan_state s); + +static inline char *gsm_lchan_name(const struct gsm_lchan *lchan) +{ + return lchan->name; +} + +uint8_t *lchan_sacch_get(struct gsm_lchan *lchan); + +uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan); +uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan); +uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan, + enum gsm_phys_chan_config as_pchan); + +void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm); +void gsm_lchan_interf_meas_calc_avg(struct gsm_lchan *lchan); + +int lchan2ecu_codec(const struct gsm_lchan *lchan); + +void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state); + +int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip); +int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port); +void lchan_rtp_socket_free(struct gsm_lchan *lchan); + +void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit); + +static inline bool lchan_is_dcch(const struct gsm_lchan *lchan) +{ + switch (lchan->type) { + case GSM_LCHAN_SDCCH: + case GSM_LCHAN_TCH_F: + case GSM_LCHAN_TCH_H: + return true; + default: + return false; + } +} + +#define lchan_is_tch(lchan) \ + ((lchan)->type == GSM_LCHAN_TCH_F || (lchan)->type == GSM_LCHAN_TCH_H) diff --git a/include/osmo-bts/logging.h b/include/osmo-bts/logging.h index 852c3836..ce08e47c 100644 --- a/include/osmo-bts/logging.h +++ b/include/osmo-bts/logging.h @@ -20,7 +20,8 @@ enum { DLOOP, DABIS, DRTP, - DSUM, + DOSMUX, + DASCI, }; extern const struct log_info bts_log_info; @@ -37,4 +38,12 @@ extern const struct log_info bts_log_info; #define DEBUGPFN(ss, fn, fmt, args...) \ LOGP(ss, LOGL_DEBUG, "%s " fmt, gsm_fn_as_gsmtime_str(fn), ## args) +/* LOGP with lchan + frame number prefix */ +#define LOGPLCFN(lchan, fn, ss, lvl, fmt, args...) \ + LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), gsm_fn_as_gsmtime_str(fn), ## args) + +/* LOGP with lchan + gsm_time prefix */ +#define LOGPLCGT(lchan, gt, ss, lvl, fmt, args...) \ + LOGP(ss, lvl, "%s %s " fmt, gsm_lchan_name(lchan), osmo_dump_gsmtime(gt), ## args) + #endif /* _LOGGING_H */ diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h index 45f275f1..ad86d8de 100644 --- a/include/osmo-bts/measurement.h +++ b/include/osmo-bts/measurement.h @@ -20,4 +20,6 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn); int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn); +void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg); + #endif diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h index 7ddbe88f..fb8e11a5 100644 --- a/include/osmo-bts/msg_utils.h +++ b/include/osmo-bts/msg_utils.h @@ -22,6 +22,9 @@ struct msgb; /* Access 3rd part of msgb control buffer */ #define rtpmsg_ts(x) ((x)->cb[2]) +/* Access 4th part of msgb control buffer */ +#define rtpmsg_is_rfc5993_sid(x) ((x)->cb[3]) + /** * Classification of OML message. ETSI for plain GSM 12.21 * messages and IPA/Osmo for manufacturer messages. diff --git a/include/osmo-bts/nm_common_fsm.h b/include/osmo-bts/nm_common_fsm.h index 4679b235..dadf806e 100644 --- a/include/osmo-bts/nm_common_fsm.h +++ b/include/osmo-bts/nm_common_fsm.h @@ -1,7 +1,7 @@ /* Header for all NM FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21: GSM 12.21 Objects' Operational state and availability status behaviour during initialization */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -25,18 +25,23 @@ #include <osmocom/core/fsm.h> #include <osmocom/core/utils.h> +#include <osmocom/core/msgb.h> /* Common */ enum nm_fsm_events { NM_EV_SW_ACT, + NM_EV_RX_SETATTR, /* data: struct nm_fsm_ev_setattr_data */ + NM_EV_RX_OPSTART, NM_EV_OPSTART_ACK, NM_EV_OPSTART_NACK, + NM_EV_SHUTDOWN_START, + NM_EV_SHUTDOWN_FINISH, + NM_EV_OML_UP, NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */ NM_EV_RSL_DOWN, /* RadioCarrier and BaseBand Transceiver only */ NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */ NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */ NM_EV_DISABLE, /* RadioCarrier and BaseBand Transceiver only */ - NM_EV_BBTRANSC_INSTALLED, /* Radio Channel only */ NM_EV_BBTRANSC_ENABLED, /* Radio Channel only */ NM_EV_BBTRANSC_DISABLED, /* Radio Channel only */ NM_EV_RCARRIER_ENABLED, /* Radio Channel only */ @@ -44,6 +49,10 @@ enum nm_fsm_events { }; extern const struct value_string nm_fsm_event_names[]; +struct nm_fsm_ev_setattr_data { + const struct msgb *msg; +}; + /* BTS SiteManager */ enum nm_bts_sm_op_fsm_states { @@ -85,3 +94,30 @@ enum nm_chan_op_fsm_states { NM_CHAN_ST_OP_ENABLED, }; extern struct osmo_fsm nm_chan_fsm; + +/* GPRS NSE */ +enum nm_gprs_nse_op_fsm_states { + NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED, + NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY, + NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE, + NM_GPRS_NSE_ST_OP_ENABLED, +}; +extern struct osmo_fsm nm_gprs_nse_fsm; + +/* GPRS NSVC */ +enum nm_gprs_nsvc_op_fsm_states { + NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED, + NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY, + NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE, + NM_GPRS_NSVC_ST_OP_ENABLED, +}; +extern struct osmo_fsm nm_gprs_nsvc_fsm; + +/* GPRS CELL */ +enum nm_gprs_cell_op_fsm_states { + NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED, + NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY, + NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE, + NM_GPRS_CELL_ST_OP_ENABLED, +}; +extern struct osmo_fsm nm_gprs_cell_fsm; diff --git a/include/osmo-bts/notification.h b/include/osmo-bts/notification.h new file mode 100644 index 00000000..e53d718b --- /dev/null +++ b/include/osmo-bts/notification.h @@ -0,0 +1,61 @@ +/* Maintain and generate ASCI notifications */ + +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +/* one [concurrent] ASCI (VBS/VGCS) notification */ +struct asci_notification { + struct llist_head list; /* linked to bts->asci.notifications */ + + /* Group call reference (TS 24.008 10.5.1.9 "Descriptive group or broadcast call reference") */ + uint8_t group_call_ref[5]; + + /* Group Channel Description (TS 44.018 10.5.2.14b) */ + struct { + bool present; + uint8_t value[255]; + uint8_t len; + } chan_desc; + + /* NCH DRX Information (TS 48.058 9.3.47) */ + struct { + bool present; + struct rsl_ie_nch_drx_info value; + } nch_drx_info; +}; + +int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc, + uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info); + +int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref); + +int bts_asci_notification_reset(struct gsm_bts *bts); + +const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts); + +void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len); + +int bts_asci_notify_nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf); +int bts_asci_notify_facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref, + const uint8_t *chan_desc, uint8_t chan_desc_len); diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h index 27afc538..41cdaf50 100644 --- a/include/osmo-bts/oml.h +++ b/include/osmo-bts/oml.h @@ -32,6 +32,7 @@ struct gsm_abis_mo { struct gsm_bts *bts; /* NM BTS Site Manager FSM */ struct osmo_fsm_inst *fi; + bool setattr_success; bool opstart_success; }; @@ -47,7 +48,7 @@ int oml_mo_statechg_ack(const struct gsm_abis_mo *mo); int oml_mo_statechg_nack(const struct gsm_abis_mo *mo, uint8_t nack_cause); /* Change the state and send STATE CHG REP */ -int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state); +int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state, int adm_state); /* First initialization of MO, does _not_ generate state changes */ void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state); @@ -62,11 +63,12 @@ int oml_tx_state_changed(const struct gsm_abis_mo *mo); int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo); int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause); +int oml_fom_ack_nack_copy_msg(const struct msgb *old_msg, uint8_t cause); int oml_mo_fom_ack_nack(const struct gsm_abis_mo *mo, uint8_t orig_msg_type, uint8_t cause); -extern const unsigned int oml_default_t200_ms[7]; +extern const uint32_t oml_default_t200_fn[7]; /* Transmit failure event report */ int oml_tx_failure_event_rep(const struct gsm_abis_mo *mo, enum abis_nm_severity severity, @@ -76,11 +78,11 @@ void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts, uint8_t obj_class, uint8_t p1, uint8_t p2, uint8_t p3); struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst); + const struct abis_om_obj_inst *obj_inst, + enum abis_nm_nack_cause *c); -struct gsm_nm_state *gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst); void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst); + const struct abis_om_obj_inst *obj_inst, + enum abis_nm_nack_cause *c); #endif // _OML_H */ diff --git a/include/osmo-bts/osmux.h b/include/osmo-bts/osmux.h new file mode 100644 index 00000000..9cdbea19 --- /dev/null +++ b/include/osmo-bts/osmux.h @@ -0,0 +1,48 @@ +#pragma once + +#include <stdint.h> +#include <stdbool.h> +#include <osmocom/core/select.h> +#include <osmocom/netif/osmux.h> + +struct gsm_bts; +struct gsm_lchan; + +enum osmux_usage { + OSMUX_USAGE_OFF = 0, + OSMUX_USAGE_ON = 1, + OSMUX_USAGE_ONLY = 2, +}; + +struct osmux_state { + enum osmux_usage use; + char *local_addr; + uint16_t local_port; + struct osmo_fd fd; + uint8_t batch_factor; + unsigned int batch_size; + bool dummy_padding; + struct llist_head osmux_handle_list; +}; + +/* Contains a "struct osmux_in_handle" towards a specific peer (remote IPaddr+port) */ +struct osmux_handle { + struct llist_head head; + struct gsm_bts *bts; + struct osmux_in_handle *in; + struct osmo_sockaddr rem_addr; + int refcnt; +}; + +int bts_osmux_init(struct gsm_bts *bts); +void bts_osmux_release(struct gsm_bts *bts); +int bts_osmux_open(struct gsm_bts *bts); + +int lchan_osmux_init(struct gsm_lchan *lchan, uint8_t rtp_payload); +void lchan_osmux_release(struct gsm_lchan *lchan); +int lchan_osmux_connect(struct gsm_lchan *lchan); +bool lchan_osmux_connected(const struct gsm_lchan *lchan); +int lchan_osmux_send_frame(struct gsm_lchan *lchan, const uint8_t *payload, + unsigned int payload_len, unsigned int duration, bool marker); + +int lchan_osmux_skipped_frame(struct gsm_lchan *lchan, unsigned int duration); diff --git a/include/osmo-bts/paging.h b/include/osmo-bts/paging.h index ef1fc93d..e74ba3c9 100644 --- a/include/osmo-bts/paging.h +++ b/include/osmo-bts/paging.h @@ -7,6 +7,55 @@ struct paging_state; struct gsm_bts; +struct asci_notification; + +/* abstract representation of P1 rest octets; we only implement those parts we need for now */ +struct p1_rest_octets { + struct { + bool present; + uint8_t nln; + uint8_t nln_status; + } nln_pch; + bool packet_page_ind[2]; + bool r8_present; + struct { + bool prio_ul_access; + bool etws_present; + struct { + bool is_first; + uint8_t page_nr; + const uint8_t *page; + size_t page_bytes; + } etws; + } r8; +}; + +/* abstract representation of P2 rest octets; we only implement those parts we need for now */ +struct p2_rest_octets { + struct { + bool present; + uint8_t cn3; + } cneed; + struct { + bool present; + uint8_t nln; + uint8_t nln_status; + } nln_pch; +}; + +/* abstract representation of P3 rest octets; we only implement those parts we need for now */ +struct p3_rest_octets { + struct { + bool present; + uint8_t cn3; + uint8_t cn4; + } cneed; + struct { + bool present; + uint8_t nln; + uint8_t nln_status; + } nln_pch; +}; /* initialize paging code */ struct paging_state *paging_init(struct gsm_bts *bts, @@ -35,9 +84,15 @@ int paging_si_update(struct paging_state *ps, struct gsm48_control_channel_descr int paging_add_identity(struct paging_state *ps, uint8_t paging_group, const uint8_t *identity_lv, uint8_t chan_needed); -/* Add an IMM.ASS message to the paging queue */ -int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, - uint8_t len, bool from_pcu); +/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a + * PAGING COMMAND (from the PCU) */ +int paging_add_macblock(struct paging_state *ps, uint32_t msg_id, const char *imsi, bool confirm, const uint8_t *macblock); + +/* Paging rest octests */ +void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro, + const struct asci_notification *notif); +void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro); +void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro); /* generate paging message for given gsm time */ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *gt, diff --git a/include/osmo-bts/pcu_if.h b/include/osmo-bts/pcu_if.h index 12a8abc9..3563c5ba 100644 --- a/include/osmo-bts/pcu_if.h +++ b/include/osmo-bts/pcu_if.h @@ -3,9 +3,11 @@ #include <osmo-bts/pcuif_proto.h> +struct gsm_bts_sm; + extern int pcu_direct; -#define PCUIF_HDR_SIZE ( sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u) ) +#define PCUIF_HDR_SIZE (sizeof(struct gsm_pcu_if) - sizeof(((struct gsm_pcu_if *)0)->u)) int pcu_tx_info_ind(void); int pcu_tx_si(const struct gsm_bts *bts, enum osmo_sysinfo_type si_type, bool enable); @@ -19,14 +21,13 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, int16_t qta, uint16_t ra, uint32_t fn, uint8_t is_11bit, enum ph_burst_type burst_type, uint8_t sapi); int pcu_tx_time_ind(uint32_t fn); -int pcu_tx_interf_ind(uint8_t bts_nr, uint8_t trx_nr, uint32_t fn, - const uint8_t *pdch_interf); +int pcu_tx_interf_ind(const struct gsm_bts_trx *trx, uint32_t fn); int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed); -int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len); +int pcu_tx_data_cnf(uint32_t msg_id, uint8_t sapi); int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id, uint8_t cause); -int pcu_sock_send(struct gsm_network *net, struct msgb *msg); +int pcu_sock_send(struct msgb *msg); -int pcu_sock_init(const char *path); +int pcu_sock_init(const char *path, int qlength_max); void pcu_sock_exit(void); bool pcu_connected(void); diff --git a/include/osmo-bts/pcuif_proto.h b/include/osmo-bts/pcuif_proto.h index 3e6f6510..04936af0 100644 --- a/include/osmo-bts/pcuif_proto.h +++ b/include/osmo-bts/pcuif_proto.h @@ -3,20 +3,20 @@ #include <osmocom/gsm/l1sap.h> #include <arpa/inet.h> +#include <osmocom/gsm/protocol/gsm_23_003.h> #define PCU_SOCK_DEFAULT "/tmp/pcu_bts" -#define PCU_IF_VERSION 0x0a +#define PCU_IF_VERSION 0x0c #define TXT_MAX_LEN 128 /* msg_type */ #define PCU_IF_MSG_DATA_REQ 0x00 /* send data to given channel */ -#define PCU_IF_MSG_DATA_CNF 0x01 /* confirm (e.g. transmission on PCH) */ #define PCU_IF_MSG_DATA_IND 0x02 /* receive data from given channel */ #define PCU_IF_MSG_SUSP_REQ 0x03 /* BTS forwards GPRS SUSP REQ to PCU */ #define PCU_IF_MSG_APP_INFO_REQ 0x04 /* BTS asks PCU to transmit APP INFO via PACCH */ #define PCU_IF_MSG_RTS_REQ 0x10 /* ready to send request */ -#define PCU_IF_MSG_DATA_CNF_DT 0x11 /* confirm (with direct tlli) */ +#define PCU_IF_MSG_DATA_CNF_2 0x11 /* confirm (using message id) */ #define PCU_IF_MSG_RACH_IND 0x22 /* receive RACH */ #define PCU_IF_MSG_INFO_IND 0x32 /* retrieve BTS info */ #define PCU_IF_MSG_ACT_REQ 0x40 /* activate/deactivate PDCH */ @@ -28,17 +28,16 @@ /* sapi */ #define PCU_IF_SAPI_RACH 0x01 /* channel request on CCCH */ -#define PCU_IF_SAPI_AGCH 0x02 /* assignment on AGCH */ -#define PCU_IF_SAPI_PCH 0x03 /* paging/assignment on PCH */ #define PCU_IF_SAPI_BCCH 0x04 /* SI on BCCH */ #define PCU_IF_SAPI_PDTCH 0x05 /* packet data/control/ccch block */ #define PCU_IF_SAPI_PRACH 0x06 /* packet random access channel */ #define PCU_IF_SAPI_PTCCH 0x07 /* packet TA control channel */ -#define PCU_IF_SAPI_AGCH_DT 0x08 /* assignment on AGCH but with additional TLLI */ +#define PCU_IF_SAPI_PCH_2 0x08 /* assignment on PCH (confirmed using message id) */ +#define PCU_IF_SAPI_AGCH_2 0x09 /* assignment on AGCH (confirmed using message id) */ /* flags */ #define PCU_IF_FLAG_ACTIVE (1 << 0)/* BTS is active */ -#define PCU_IF_FLAG_SYSMO (1 << 1)/* access PDCH of sysmoBTS directly */ +#define PCU_IF_FLAG_DIRECT_PHY (1 << 1)/* access PHY directly via dedicated hardware support */ #define PCU_IF_FLAG_CS1 (1 << 16) #define PCU_IF_FLAG_CS2 (1 << 17) #define PCU_IF_FLAG_CS3 (1 << 18) @@ -58,6 +57,20 @@ #define PCU_IF_ADDR_TYPE_IPV4 0x04 /* IPv4 address */ #define PCU_IF_ADDR_TYPE_IPV6 0x29 /* IPv6 address */ +/* BTS model */ +enum gsm_pcuif_bts_model { + PCU_IF_BTS_MODEL_UNSPEC, + PCU_IF_BTS_MODEL_LC15, + PCU_IF_BTS_MODEL_OC2G, + PCU_IF_BTS_MODEL_OCTPHY, + PCU_IF_BTS_MODEL_SYSMO, + PCU_IF_BTS_MODEL_TRX, + PCU_IF_BTS_MODEL_RBS, +}; + +#define PCU_IF_NUM_NSVC 2 +#define PCU_IF_NUM_TRX 8 + enum gsm_pcu_if_text_type { PCU_VERSION, PCU_OML_ALERT, @@ -83,19 +96,10 @@ struct gsm_pcu_if_data { int16_t lqual_cb; /* !< \brief Link quality in centiBel */ } __attribute__ ((packed)); -/* data confirmation with direct tlli (instead of raw mac block with tlli) */ -struct gsm_pcu_if_data_cnf_dt { +/* data confirmation with message id (instead of raw mac block) */ +struct gsm_pcu_if_data_cnf { uint8_t sapi; - uint32_t tlli; - uint32_t fn; - uint16_t arfcn; - uint8_t trx_nr; - uint8_t ts_nr; - uint8_t block_nr; - int8_t rssi; - uint16_t ber10k; /* !< \brief BER in units of 0.01% */ - int16_t ta_offs_qbits; /* !< \brief Burst TA Offset in quarter bits */ - int16_t lqual_cb; /* !< \brief Link quality in centiBel */ + uint32_t msg_id; } __attribute__ ((packed)); struct gsm_pcu_if_rts_req { @@ -140,7 +144,7 @@ struct gsm_pcu_if_info_trx { struct gsm_pcu_if_info_ind { uint32_t version; uint32_t flags; - struct gsm_pcu_if_info_trx trx[8]; /* TRX infos per BTS */ + struct gsm_pcu_if_info_trx trx[PCU_IF_NUM_TRX]; /* TRX infos per BTS */ uint8_t bsic; /* RAI */ uint16_t mcc, mnc; @@ -169,14 +173,15 @@ struct gsm_pcu_if_info_ind { uint8_t initial_cs; uint8_t initial_mcs; /* NSVC */ - uint16_t nsvci[2]; - uint16_t local_port[2]; - uint16_t remote_port[2]; - uint8_t address_type[2]; + uint16_t nsvci[PCU_IF_NUM_NSVC]; + uint16_t local_port[PCU_IF_NUM_NSVC]; + uint16_t remote_port[PCU_IF_NUM_NSVC]; + uint8_t address_type[PCU_IF_NUM_NSVC]; union { struct in_addr v4; struct in6_addr v6; - } remote_ip[2]; + } remote_ip[PCU_IF_NUM_NSVC]; + uint8_t bts_model; /* enum gsm_pcuif_bts_model */ } __attribute__ ((packed)); struct gsm_pcu_if_act_req { @@ -226,6 +231,32 @@ struct gsm_pcu_if_container { uint8_t data[0]; } __attribute__ ((packed)); +/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via PCH. The struct is sent as a data request + * (data_req) under SAPI PCU_IF_SAPI_PCH_2. */ +struct gsm_pcu_if_pch { + /* message id as reference for confirmation */ + uint32_t msg_id; + /* IMSI (to derive paging group) */ + char imsi[OSMO_IMSI_BUF_SIZE]; + /* GSM mac-block (with immediate assignment message) */ + uint8_t data[GSM_MACBLOCK_LEN]; + /* Set to true in case the receiving end must send a confirmation + * when the MAC block (data) has been sent. */ + bool confirm; +} __attribute__((packed)); + +/* Struct to send a (confirmed) IMMEDIATE ASSIGNMENT message via AGCH. The struct is sent as a data request + * (data_req) under SAPI PCU_IF_SAPI_AGCH_2. */ +struct gsm_pcu_if_agch { + /* message id as reference for confirmation */ + uint32_t msg_id; + /* GSM mac-block (with immediate assignment message) */ + uint8_t data[GSM_MACBLOCK_LEN]; + /* Set to true in case the receiving end must send a confirmation + * when the MAC block (data) has been sent. */ + bool confirm; +} __attribute__((packed)); + struct gsm_pcu_if { /* context based information */ uint8_t msg_type; /* message type */ @@ -234,8 +265,7 @@ struct gsm_pcu_if { union { struct gsm_pcu_if_data data_req; - struct gsm_pcu_if_data data_cnf; - struct gsm_pcu_if_data_cnf_dt data_cnf_dt; + struct gsm_pcu_if_data_cnf data_cnf2; struct gsm_pcu_if_data data_ind; struct gsm_pcu_if_susp_req susp_req; struct gsm_pcu_if_rts_req rts_req; diff --git a/include/osmo-bts/phy_link.h b/include/osmo-bts/phy_link.h index 4b8a8633..862ed48f 100644 --- a/include/osmo-bts/phy_link.h +++ b/include/osmo-bts/phy_link.h @@ -50,7 +50,8 @@ struct phy_link { bool use_legacy_setbsic; uint8_t trxd_pdu_ver_max; /* Maximum TRXD PDU version to negotiate */ bool powered; /* last POWERON (true) or POWEROFF (false) confirmed */ - bool poweronoff_sent; /* is there a POWERON/POWEROFF in transit? (one or the other based on ->powered) */ + bool poweron_sent; /* is there a POWERON in transit? */ + bool poweroff_sent; /* is there a POWEROFF in transit? */ } osmotrx; struct { char *mcast_dev; /* Network device for multicast */ @@ -112,7 +113,6 @@ struct phy_instance { } sysmobts; struct { struct trx_l1h *hdl; - bool sw_act_reported; struct trx_dl_burst_req br[TRX_NR_TS]; } osmotrx; struct { @@ -175,6 +175,7 @@ static inline struct phy_instance *trx_phy_instance(const struct gsm_bts_trx *tr } int bts_model_phy_link_open(struct phy_link *plink); +int bts_model_phy_link_close(struct phy_link *plink); #define LOGPPHL(plink, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_link_name(plink), ##args) #define LOGPPHI(pinst, section, lvl, fmt, args...) LOGP(section, lvl, "%s: " fmt, phy_instance_name(pinst), ##args) diff --git a/include/osmo-bts/power_control.h b/include/osmo-bts/power_control.h index f2e14cfe..0764ba76 100644 --- a/include/osmo-bts/power_control.h +++ b/include/osmo-bts/power_control.h @@ -1,11 +1,90 @@ #pragma once #include <stdint.h> -#include <osmo-bts/gsm_data.h> +#include <stdbool.h> +/* MS/BS Power related measurement averaging algo */ +enum gsm_power_ctrl_meas_avg_algo { + GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE = 0x00, + GSM_PWR_CTRL_MEAS_AVG_ALGO_UNWEIGHTED = 0x01, + GSM_PWR_CTRL_MEAS_AVG_ALGO_WEIGHTED = 0x02, + GSM_PWR_CTRL_MEAS_AVG_ALGO_MOD_MEDIAN = 0x03, + /* EWMA is an Osmocom specific algo */ + GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA = 0x04, +}; + +/* MS/BS Power related measurement parameters */ +struct gsm_power_ctrl_meas_params { + /* Thresholds (see 3GPP TS 45.008, section A.3.2.1) */ + uint8_t lower_thresh; /* lower (decreasing) direction */ + uint8_t upper_thresh; /* upper (increasing) direction */ + + /* Threshold Comparators for lower (decreasing) direction */ + uint8_t lower_cmp_p; /* P1 for RxLev, P3 for RxQual */ + uint8_t lower_cmp_n; /* N1 for RxLev, N3 for RxQual */ + /* Threshold Comparators for upper (increasing) direction */ + uint8_t upper_cmp_p; /* P2 for RxLev, P4 for RxQual */ + uint8_t upper_cmp_n; /* N2 for RxLev, N4 for RxQual */ + + /* Hreqave and Hreqt (see 3GPP TS 45.008, Annex A) */ + uint8_t h_reqave; + uint8_t h_reqt; + + /* AVG algorithm and its specific parameters */ + enum gsm_power_ctrl_meas_avg_algo algo; + union { + /* Exponentially Weighted Moving Average */ + struct { + /* Smoothing factor: higher the value - less smoothing */ + uint8_t alpha; /* 1 .. 99 (in %) */ + } ewma; + }; +}; + +/* MS/BS Power Control parameters */ +struct gsm_power_ctrl_params { + /* Minimum interval between power level changes */ + uint8_t ctrl_interval; /* 1 step is 2 SACCH periods */ + + /* Power change step size (maximum) */ + uint8_t inc_step_size_db; /* increasing direction */ + uint8_t red_step_size_db; /* reducing direction */ + + /* Measurement averaging parameters for RxLev & RxQual */ + struct gsm_power_ctrl_meas_params rxqual_meas; + struct gsm_power_ctrl_meas_params rxlev_meas; + + /* Measurement averaging parameters for C/I, per chan type */ + struct gsm_power_ctrl_meas_params ci_fr_meas; + struct gsm_power_ctrl_meas_params ci_hr_meas; + struct gsm_power_ctrl_meas_params ci_amr_fr_meas; + struct gsm_power_ctrl_meas_params ci_amr_hr_meas; + struct gsm_power_ctrl_meas_params ci_sdcch_meas; + struct gsm_power_ctrl_meas_params ci_gprs_meas; +}; + +/* Measurement pre-processing state */ +struct gsm_power_ctrl_meas_proc_state { + /* Number of measurements processed */ + unsigned int meas_num; + /* Algorithm specific data */ + union { + struct { + /* Scaled up 100 times average value */ + int Avg100; + } ewma; + }; +}; + +/* Default MS/BS Power Control parameters */ +extern const struct gsm_power_ctrl_params power_ctrl_params_def; +void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr); + +struct gsm_lchan; int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, const uint8_t ms_power_lvl, - const int8_t ul_rssi_dbm); + const int8_t ul_rssi_dbm, + const int16_t ul_lqual_cb); int lchan_bs_pwr_ctrl(struct gsm_lchan *lchan, - const struct gsm48_hdr *gh); + const struct gsm48_meas_res *mr); diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h index 4e79de5e..e3950e42 100644 --- a/include/osmo-bts/rsl.h +++ b/include/osmo-bts/rsl.h @@ -4,7 +4,8 @@ #define LCHAN_FN_DUMMY 0xFFFFFFFF #define LCHAN_FN_WAIT 0xFFFFFFFE -int msgb_queue_flush(struct llist_head *list); +bool rsl_chan_rt_is_asci(enum rsl_cmod_crt chan_rt); +bool rsl_chan_rt_is_vgcs(enum rsl_cmod_crt chan_rt); int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg); int rsl_tx_rf_res(struct gsm_bts_trx *trx); @@ -16,8 +17,8 @@ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_conn_fail(const struct gsm_lchan *lchan, uint8_t cause); int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan); int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay); - -int lchan_deactivate(struct gsm_lchan *lchan); +int rsl_tx_listener_det(struct gsm_lchan *lchan, uint8_t *acc_delay); +int rsl_tx_talker_det(struct gsm_lchan *lchan, uint8_t *acc_delay); /* call-back for LAPDm code, called when it wants to send msgs UP */ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx); @@ -34,6 +35,6 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc); int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflow, uint8_t amount); -int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le); +int rsl_tx_meas_res(struct gsm_lchan *lchan, const uint8_t *l3, unsigned int l3_len, int timing_offset); #endif // _RSL_H */ diff --git a/include/osmo-bts/rtp_input_preen.h b/include/osmo-bts/rtp_input_preen.h new file mode 100644 index 00000000..744ae2a9 --- /dev/null +++ b/include/osmo-bts/rtp_input_preen.h @@ -0,0 +1,20 @@ +/* + * RTP input validation function: makes the accept-or-drop decision, + * and for some codecs signals additional required actions such as + * dropping one header octet. + */ + +#pragma once + +#include <stdint.h> +#include <osmo-bts/lchan.h> + +enum pl_input_decision { + PL_DECISION_DROP, + PL_DECISION_ACCEPT, + PL_DECISION_STRIP_HDR_OCTET, +}; + +enum pl_input_decision +rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + unsigned rtp_pl_len, bool *rfc5993_sid_flag); diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h index 80a260fe..aea55959 100644 --- a/include/osmo-bts/scheduler.h +++ b/include/osmo-bts/scheduler.h @@ -5,13 +5,6 @@ #include <osmo-bts/gsm_data.h> -/* Whether a logical channel must be activated automatically */ -#define TRX_CHAN_FLAG_AUTO_ACTIVE (1 << 0) - -/* FIXME: we should actually activate 'auto-active' channels */ -#define TRX_CHAN_IS_ACTIVE(state, chan) \ - (trx_chan_desc[chan].flags & TRX_CHAN_FLAG_AUTO_ACTIVE || (state)->active) - #define TRX_GMSK_NB_TSC(br) \ _sched_train_seq_gmsk_nb[(br)->tsc_set][(br)->tsc] @@ -80,6 +73,7 @@ enum trx_mod_type { /* A set of measurements belonging to one Uplink burst */ struct l1sched_meas_set { + uint32_t fn; /* TDMA frame number */ int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */ int16_t ci_cb; /* Carrier-to-Interference (cB) */ float rssi; /* RSSI (dBm) */ @@ -96,13 +90,12 @@ struct l1sched_chan_state { bool active; /* Channel is active */ ubit_t *dl_bursts; /* burst buffer for TX */ enum trx_mod_type dl_mod_type; /* Downlink modulation type */ + uint8_t dl_mask; /* mask of transmitted bursts */ sbit_t *ul_bursts; /* burst buffer for RX */ - sbit_t *ul_bursts_prev;/* previous burst buffer for RX (repeated SACCH) */ uint32_t ul_first_fn; /* fn of first burst */ - uint8_t ul_mask; /* mask of received bursts */ + uint32_t ul_mask; /* mask of received bursts */ /* loss detection */ - uint8_t lost_frames; /* how many L2 frames were lost */ uint32_t last_tdma_fn; /* last processed TDMA frame number */ uint32_t proc_tdma_fs; /* how many TDMA frames were processed */ uint32_t lost_tdma_fs; /* how many TDMA frames were lost */ @@ -113,20 +106,19 @@ struct l1sched_chan_state { /* AMR */ uint8_t codec[4]; /* 4 possible codecs for amr */ int codecs; /* number of possible codecs */ - float ber_sum; /* sum of bit error rates */ - int ber_num; /* number of bit error rates */ + int lqual_cb_sum; /* sum of link quality samples (in cB) */ + int lqual_cb_num; /* number of link quality samples */ uint8_t ul_ft; /* current uplink FT index */ uint8_t dl_ft; /* current downlink FT index */ uint8_t ul_cmr; /* current uplink CMR index */ uint8_t dl_cmr; /* current downlink CMR index */ - uint8_t amr_loop; /* if AMR loop is enabled */ uint8_t amr_last_dtx; /* last received dtx frame type */ /* TCH/H */ uint8_t dl_ongoing_facch; /* FACCH/H on downlink */ uint8_t ul_ongoing_facch; /* FACCH/H on uplink */ - struct l1sched_meas_set meas_avg_facch; /* measurement results for last FACCH */ - uint16_t ber10k_facch; /* bit error rate for last FACCH */ + + uint8_t dl_facch_bursts; /* number of remaining DL FACCH bursts */ /* encryption */ int ul_encr_algo; /* A5/x encry algo downlink */ @@ -139,7 +131,7 @@ struct l1sched_chan_state { /* Uplink measurements */ struct { /* Active channel measurements (simple ring buffer) */ - struct l1sched_meas_set buf[8]; /* up to 8 entries */ + struct l1sched_meas_set buf[24]; /* up to 24 (BUFMAX) entries */ unsigned int current; /* current position */ /* Interference measurements */ @@ -193,6 +185,12 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch /*! \brief set all matching logical channels active/inactive */ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active); +/*! \brief set uplink access on given logical channels active/inactive */ +int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active); + +/*! \brief set all logical channels of BCCH/CCCH active/inactive */ +int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active); + /*! \brief set mode of all matching logical channels to given mode(s) */ int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_cmode, uint8_t tch_mode, int codecs, uint8_t codec0, uint8_t codec1, @@ -231,7 +229,7 @@ struct trx_sched_multiframe { int find_sched_mframe_idx(enum gsm_phys_chan_config pchan, uint8_t tn); /*! Determine if given frame number contains SACCH (true) or other (false) burst */ -bool trx_sched_is_sacch_fn(struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink); +bool trx_sched_is_sacch_fn(const struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink); extern const struct trx_sched_multiframe trx_sched_multiframes[]; #define TRX_BI_F_NOPE_IND (1 << 0) @@ -241,6 +239,7 @@ extern const struct trx_sched_multiframe trx_sched_multiframes[]; #define TRX_BI_F_TRX_NUM (1 << 4) #define TRX_BI_F_BATCH_IND (1 << 5) #define TRX_BI_F_SHADOW_IND (1 << 6) +#define TRX_BI_F_ACCESS_BURST (1 << 7) /*! UL burst indication with the corresponding meta info */ struct trx_ul_burst_ind { @@ -272,6 +271,8 @@ struct trx_ul_burst_ind { size_t burst_len; }; +#define TRX_BR_F_FACCH (1 << 0) + /*! DL burst request with the corresponding meta info */ struct trx_dl_burst_req { uint8_t flags; /*!< see TRX_BR_F_* */ @@ -302,18 +303,24 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi); /* Averaging mode for trx_sched_meas_avg() */ enum sched_meas_avg_mode { - /* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */ - SCHED_MEAS_AVG_M_QUAD, + /* first 22 of last 24 bursts (for TCH/F14.4, TCH/F9.6, TCH/F4.8) */ + SCHED_MEAS_AVG_M_S24N22, + /* last 22 bursts (for TCH/H4.8, TCH/H2.4) */ + SCHED_MEAS_AVG_M_S22N22, + /* last 4 bursts (default for xCCH, PTCCH and PDTCH) */ + SCHED_MEAS_AVG_M_S4N4, /* last 8 bursts (default for TCH/F and FACCH/F) */ - SCHED_MEAS_AVG_M_OCTO, + SCHED_MEAS_AVG_M_S8N8, + /* first 4 of last 6 bursts (default for TCH/H) */ + SCHED_MEAS_AVG_M_S6N4, /* last 6 bursts (default for FACCH/H) */ - SCHED_MEAS_AVG_M_SIX, + SCHED_MEAS_AVG_M_S6N6, /* first 4 of last 8 bursts */ - SCHED_MEAS_AVG_M8_FIRST_QUAD, + SCHED_MEAS_AVG_M_S8N4, /* first 2 of last 6 bursts */ - SCHED_MEAS_AVG_M6_FIRST_TWO, + SCHED_MEAS_AVG_M_S6N2, /* middle 2 of last 6 bursts */ - SCHED_MEAS_AVG_M6_MIDDLE_TWO, + SCHED_MEAS_AVG_M_S4N2, }; void trx_sched_meas_push(struct l1sched_chan_state *chan_state, @@ -321,3 +328,5 @@ void trx_sched_meas_push(struct l1sched_chan_state *chan_state, void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, struct l1sched_meas_set *avg, enum sched_meas_avg_mode mode); +uint32_t trx_sched_lookup_fn(const struct l1sched_chan_state *chan_state, + const unsigned int shift); diff --git a/include/osmo-bts/scheduler_backend.h b/include/osmo-bts/scheduler_backend.h index 50ba8228..820cca78 100644 --- a/include/osmo-bts/scheduler_backend.h +++ b/include/osmo-bts/scheduler_backend.h @@ -42,15 +42,17 @@ extern const ubit_t _sched_train_seq_gmsk_sb[64]; struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br); int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn, - enum trx_chan_type chan, uint8_t *l2, - uint8_t l2_len, float rssi, + enum trx_chan_type chan, + const uint8_t *data, size_t data_len, + uint16_t ber10k, float rssi, int16_t ta_offs_256bits, int16_t link_qual_cb, - uint16_t ber10k, enum osmo_ph_pres_info_type presence_info); int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn, - enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len, - int16_t ta_offs_256bits, uint16_t ber10k, float rssi, + enum trx_chan_type chan, + const uint8_t *data, size_t data_len, + uint16_t ber10k, float rssi, + int16_t ta_offs_256bits, int16_t link_qual_cb, uint8_t is_sub); int tx_fcch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br); diff --git a/include/osmo-bts/signal.h b/include/osmo-bts/signal.h index c8168a26..8359f021 100644 --- a/include/osmo-bts/signal.h +++ b/include/osmo-bts/signal.h @@ -15,4 +15,10 @@ enum signals_global { S_NEW_NSVC_ATTR, }; +struct nm_statechg_signal_data { + struct gsm_abis_mo *mo; + uint8_t old_state; + uint8_t new_state; +}; + #endif diff --git a/include/osmo-bts/ta_control.h b/include/osmo-bts/ta_control.h index 168f14a7..bf993319 100644 --- a/include/osmo-bts/ta_control.h +++ b/include/osmo-bts/ta_control.h @@ -2,4 +2,4 @@ #include <osmo-bts/gsm_data.h> -void lchan_ms_ta_ctrl(struct gsm_lchan *lchan); +void lchan_ms_ta_ctrl(struct gsm_lchan *lchan, uint8_t ms_tx_ta, int16_t toa256); diff --git a/include/osmo-bts/tx_power.h b/include/osmo-bts/tx_power.h index 8f68d8a5..73134c8b 100644 --- a/include/osmo-bts/tx_power.h +++ b/include/osmo-bts/tx_power.h @@ -77,7 +77,13 @@ int get_p_trxout_target_mdBm_lchan(const struct gsm_lchan *lchan); int get_p_trxout_actual_mdBm(const struct gsm_bts_trx *trx, uint8_t bs_power_red); int get_p_trxout_actual_mdBm_lchan(const struct gsm_lchan *lchan); -int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, ramp_compl_cb_t ramp_compl_cb); +int _power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass_max_power, ramp_compl_cb_t ramp_compl_cb, bool skip_ramping); +#define power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \ + _power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, false) +#define power_ramp_force(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb) \ + _power_ramp_start(trx, p_total_tgt_mdBm, bypass_max_power, ramp_compl_cb, true) + +void power_ramp_abort(struct gsm_bts_trx *trx); void power_trx_change_compl(struct gsm_bts_trx *trx, int p_trxout_cur_mdBm); diff --git a/include/osmo-bts/vty.h b/include/osmo-bts/vty.h index c815c85a..d326c5cd 100644 --- a/include/osmo-bts/vty.h +++ b/include/osmo-bts/vty.h @@ -12,6 +12,7 @@ enum bts_vty_node { PHY_INST_NODE, BTS_NODE, TRX_NODE, + OSMUX_NODE, }; extern struct cmd_element cfg_bts_auto_band_cmd; @@ -20,12 +21,9 @@ extern struct cmd_element cfg_bts_no_auto_band_cmd; struct phy_instance *vty_get_phy_instance(struct vty *vty, int phy_nr, int inst_nr); int bts_vty_go_parent(struct vty *vty); -int bts_vty_is_config_node(struct vty *vty, int node); int bts_vty_init(void *ctx); -struct gsm_network *gsmnet_from_vty(struct vty *v); - extern struct vty_app_info bts_vty_info; extern struct gsm_bts *g_bts; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 72438c67..d13415d1 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,6 +1,23 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOCODEC_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ + $(NULL) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) + +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) if ENABLE_LC15BTS AM_CFLAGS += -DENABLE_LC15BTS @@ -14,13 +31,17 @@ libbts_a_SOURCES = \ abis.c \ abis_osmo.c \ oml.c \ + osmux.c \ bts.c \ + bts_sm.c \ bts_trx.c \ rsl.c \ + rtp_input_preen.c \ vty.c \ paging.c \ measurement.c \ amr.c \ + asci.c \ lchan.c \ load_indication.c \ pcu_sock.c \ @@ -30,6 +51,7 @@ libbts_a_SOURCES = \ bts_ctrl_commands.c \ bts_ctrl_lookup.c \ bts_shutdown_fsm.c \ + csd_v110.c \ l1sap.c \ cbch.c \ power_control.c \ @@ -43,7 +65,23 @@ libbts_a_SOURCES = \ nm_bts_fsm.c \ nm_bb_transc_fsm.c \ nm_channel_fsm.c \ + nm_gprs_cell_fsm.c \ + nm_gprs_nse_fsm.c \ + nm_gprs_nsvc_fsm.c \ nm_radio_carrier_fsm.c \ + notification.c \ + probes.d \ $(NULL) libl1sched_a_SOURCES = scheduler.c + +if ENABLE_SYSTEMTAP +probes.h: probes.d + $(DTRACE) -C -h -s $< -o $@ + +probes.lo: probes.d + $(LIBTOOL) --mode=compile $(AM_V_lt) --tag=CC env CFLAGS="$(CFLAGS)" $(DTRACE) -C -G -s $< -o $@ + +BUILT_SOURCES = probes.h probes.lo +libbts_la_LDADD = probes.lo +endif diff --git a/src/common/abis.c b/src/common/abis.c index abef8264..5629cf23 100644 --- a/src/common/abis.c +++ b/src/common/abis.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -38,11 +38,13 @@ #include <osmocom/core/msgb.h> #include <osmocom/core/signal.h> #include <osmocom/core/macaddr.h> +#include <osmocom/core/fsm.h> #include <osmocom/abis/abis.h> #include <osmocom/abis/e1_input.h> #include <osmocom/abis/ipaccess.h> #include <osmocom/gsm/ipa.h> +#include <osmo-bts/abis.h> #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts.h> @@ -51,37 +53,306 @@ #include <osmo-bts/abis_osmo.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/bts_trx.h> +#include <osmo-bts/bts_shutdown_fsm.h> static struct gsm_bts *g_bts; -int abis_oml_sendmsg(struct msgb *msg) +static struct e1inp_line_ops line_ops; + +static struct ipaccess_unit bts_dev_info; + +#define S(x) (1 << (x)) +#define OML_RETRY_TIMER 5 + +enum abis_link_fsm_state { + ABIS_LINK_ST_WAIT_RECONNECT, /* OML link has not yet been established */ + ABIS_LINK_ST_CONNECTING, /* OML link in process of been established */ + ABIS_LINK_ST_CONNECTED, /* OML link is established, RSL links may be established or not */ + ABIS_LINK_ST_FAILED, /* There used to be an active OML connection but it became broken */ +}; + +static const struct value_string abis_link_fsm_event_names[] = { + { ABIS_LINK_EV_SIGN_LINK_OML_UP, "SIGN_LINK_OML_UP", }, + { ABIS_LINK_EV_SIGN_LINK_DOWN, "SIGN_LINK_DOWN" }, + { ABIS_LINK_EV_VTY_RM_ADDR, "VTY_RM_ADDR" }, + {} +}; + +struct abis_link_fsm_priv { + struct bsc_oml_host *current_bsc; + struct gsm_bts *bts; + char *model_name; + bool reconnect_to_current_bsc; +}; + +static void reset_oml_link(struct gsm_bts *bts) { - struct gsm_bts *bts = msg->trx->bts; + if (bts->oml_link) { + struct timespec now; - if (!bts->oml_link) { - llist_add_tail(&msg->list, &bts->oml_queue); + e1inp_sign_link_destroy(bts->oml_link); + + /* Log a special notice if the OML connection was dropped relatively quickly. */ + if (bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 && + bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) { + LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. " + "If this situation persists, please check your BTS and BSC configuration files for errors. " + "A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n", + (uint64_t) (now.tv_sec - bts->oml_conn_established_timestamp.tv_sec)); + } + bts->oml_link = NULL; + } + memset(&bts->oml_conn_established_timestamp, 0, sizeof(bts->oml_conn_established_timestamp)); + + /* Same for IPAC_PROTO_OSMO on the same ipa connection: */ + if (bts->osmo_link) { + e1inp_sign_link_destroy(bts->osmo_link); + bts->osmo_link = NULL; + } + +} + +static int pick_next_bsc(struct osmo_fsm_inst *fi) +{ + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + struct bsc_oml_host *last; + + if (llist_empty(&bts->bsc_oml_hosts)) { + LOGPFSML(fi, LOGL_ERROR, "List of BSCs to connect to is empty!\n"); + return -1; + } + + /* Keep current pointer to priv->current_bsc: */ + if (priv->reconnect_to_current_bsc) { + OSMO_ASSERT(priv->current_bsc); + priv->reconnect_to_current_bsc = false; return 0; - } else { - /* osmo-bts uses msg->trx internally, but libosmo-abis uses - * the signalling link at msg->dst */ - msg->dst = bts->oml_link; - return abis_sendmsg(msg); } + + last = (struct bsc_oml_host *)llist_last_entry(&bts->bsc_oml_hosts, struct bsc_oml_host, list); + + if (!priv->current_bsc || priv->current_bsc == last) /* Pick first one (wrap around): */ + priv->current_bsc = (struct bsc_oml_host *)llist_first_entry(&bts->bsc_oml_hosts, struct bsc_oml_host, list); + else + priv->current_bsc = (struct bsc_oml_host *)llist_entry(priv->current_bsc->list.next, struct bsc_oml_host, list); + + return 0; +} + +static void abis_link_connecting_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct e1inp_line *line; + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + + if (bts_shutdown_in_progress(bts)) { + LOGPFSML(fi, LOGL_NOTICE, "BTS is shutting down, delaying A-bis connection establishment to BSC\n"); + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0); + return; + } + + if (pick_next_bsc(fi) < 0) { + LOGPFSML(fi, LOGL_FATAL, "No BSC available, A-bis connection establishment failed\n"); + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0); + return; + } + + LOGP(DABIS, LOGL_NOTICE, "A-bis connection establishment to BSC (%s) in progress...\n", priv->current_bsc->addr); + + /* patch in various data from VTY and other sources */ + line_ops.cfg.ipa.addr = priv->current_bsc->addr; + osmo_get_macaddr(bts_dev_info.mac_addr, "eth0"); + bts_dev_info.site_id = bts->ip_access.site_id; + bts_dev_info.bts_id = bts->ip_access.bts_id; + bts_dev_info.unit_name = priv->model_name; + if (bts->description) + bts_dev_info.unit_name = bts->description; + bts_dev_info.location2 = priv->model_name; + + line = e1inp_line_find(0); + if (!line) + line = e1inp_line_create(0, "ipa"); + if (!line) { + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0); + return; + } + /* Line always comes already with a "ctor" reference, enough to keep it alive forever. */ + + e1inp_line_bind_ops(line, &line_ops); + /* This will open the OML connection now */ + if (e1inp_line_update(line) < 0) { + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_FAILED, 0, 0); + return; + } + + /* The TCP connection to the BSC is now in progress. + * Wait for OML Link UP to transition to CONNECTED. */ +} + +static void abis_link_connecting(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + + switch (event) { + case ABIS_LINK_EV_SIGN_LINK_OML_UP: + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTED, 0, 0); + break; + case ABIS_LINK_EV_SIGN_LINK_DOWN: + reset_oml_link(bts); + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0); + break; + default: + OSMO_ASSERT(0); + } +} + +static void abis_link_connected_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + bts_link_estab(g_bts); +} + +static void abis_link_connected(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + struct gsm_bts_trx *trx; + OSMO_ASSERT(event == ABIS_LINK_EV_SIGN_LINK_DOWN); + + /* First remove the OML signalling link */ + reset_oml_link(bts); + + /* Then iterate over the RSL signalling links */ + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->bb_transc.rsl.link) { + e1inp_sign_link_destroy(trx->bb_transc.rsl.link); + trx->bb_transc.rsl.link = NULL; + if (trx == trx->bts->c0) + load_timer_stop(trx->bts); + } else { + /* If we have no rsl_link yet it may mean that lower + * layers are still establishing the socket (TCP, IPA). + * Let's tell it to stop connection establishment since + * we are shutting down. */ + struct e1inp_line *line = e1inp_line_find(0); + if (line) + e1inp_ipa_bts_rsl_close_n(line, trx->nr); + } + /* Note: Here we could send NM_EV_RSL_DOWN to each + * trx->(bb_transc.)mo.fi, but we are starting shutdown of the + * entire BTS anyway through bts_model_abis_close(), so simply + * let bts_shutdown FSM take care of slowly powering down all + * the TRX. It would make sense to send NM_EV_RSL_DOWN only if a + * RSL link TRX!=C0 was going down, in order to selectively stop + * that TRX only. But libosmo-abis expects us to drop the entire + * line when something goes wrong... */ + } + bts_model_abis_close(bts); + + /* We want to try reconnecting to the current BSC at least once before switching to a new one: */ + priv->reconnect_to_current_bsc = true; + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_WAIT_RECONNECT, OML_RETRY_TIMER, 0); +} + +static void abis_link_failed_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + + /* None of the configured BSCs was reachable or there was an existing + * OML/RSL connection that broke. Initiate BTS process shut down now. */ + bts_model_abis_close(bts); } -static void drain_oml_queue(struct gsm_bts *bts) +static void abis_link_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) { - struct msgb *msg, *msg2; - - llist_for_each_entry_safe(msg, msg2, &bts->oml_queue, list) { - /* osmo-bts uses msg->trx internally, but libosmo-abis uses - * the signalling link at msg->dst */ - llist_del(&msg->list); - msg->dst = bts->oml_link; - abis_sendmsg(msg); + struct abis_link_fsm_priv *priv = fi->priv; + struct gsm_bts *bts = priv->bts; + + OSMO_ASSERT(event == ABIS_LINK_EV_VTY_RM_ADDR); + + if (priv->current_bsc == data) { + if (llist_count(&bts->bsc_oml_hosts) <= 1) + priv->current_bsc = NULL; + else + pick_next_bsc(fi); } } +int abis_link_fsm_timer_cb(struct osmo_fsm_inst *fi) +{ + switch (fi->state) { + case ABIS_LINK_ST_WAIT_RECONNECT: + osmo_fsm_inst_state_chg(fi, ABIS_LINK_ST_CONNECTING, 0, 0); + break; + default: + OSMO_ASSERT(0); + } + return 0; +} + + +static struct osmo_fsm_state abis_link_fsm_states[] = { + [ABIS_LINK_ST_WAIT_RECONNECT] = { + .name = "WAIT_RECONNECT", + .out_state_mask = + S(ABIS_LINK_ST_CONNECTING), + }, + [ABIS_LINK_ST_CONNECTING] = { + .name = "CONNECTING", + .in_event_mask = + S(ABIS_LINK_EV_SIGN_LINK_OML_UP) | + S(ABIS_LINK_EV_SIGN_LINK_DOWN), + .out_state_mask = + S(ABIS_LINK_ST_WAIT_RECONNECT) | + S(ABIS_LINK_ST_CONNECTED) | + S(ABIS_LINK_ST_FAILED), + .onenter = abis_link_connecting_onenter, + .action = abis_link_connecting, + }, + [ABIS_LINK_ST_CONNECTED] = { + .name = "CONNECTED", + .in_event_mask = + S(ABIS_LINK_EV_SIGN_LINK_DOWN), + .out_state_mask = + S(ABIS_LINK_ST_WAIT_RECONNECT), + .onenter = abis_link_connected_onenter, + .action = abis_link_connected, + }, + [ABIS_LINK_ST_FAILED] = { + .name = "FAILED", + .onenter = abis_link_failed_onenter, + }, +}; + +static struct osmo_fsm abis_link_fsm = { + .name = "abis_link", + .states = abis_link_fsm_states, + .num_states = ARRAY_SIZE(abis_link_fsm_states), + .log_subsys = DABIS, + .event_names = abis_link_fsm_event_names, + .allstate_action = abis_link_allstate, + .allstate_event_mask = S(ABIS_LINK_EV_VTY_RM_ADDR), + .timer_cb = abis_link_fsm_timer_cb, +}; + +int abis_oml_sendmsg(struct msgb *msg) +{ + struct gsm_bts *bts = msg->trx->bts; + + if (!bts->oml_link) { + LOGP(DABIS, LOGL_INFO, "Drop Tx OML msg, OML link is down\n"); + msgb_free(msg); + return 0; + } + + /* osmo-bts uses msg->trx internally, but libosmo-abis uses + * the signalling link at msg->dst */ + msg->dst = bts->oml_link; + return abis_sendmsg(msg); +} + int abis_bts_rsl_sendmsg(struct msgb *msg) { OSMO_ASSERT(msg->trx); @@ -93,7 +364,7 @@ int abis_bts_rsl_sendmsg(struct msgb *msg) /* osmo-bts uses msg->trx internally, but libosmo-abis uses * the signalling link at msg->dst */ - msg->dst = msg->trx->rsl_link; + msg->dst = msg->trx->bb_transc.rsl.link; return abis_sendmsg(msg); } @@ -116,8 +387,7 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, sizeof(g_bts->oml_conn_established_timestamp)); g_bts->osmo_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_OSMO, g_bts->c0, IPAC_PROTO_OSMO, 0); - drain_oml_queue(g_bts); - bts_link_estab(g_bts); + osmo_fsm_inst_dispatch(g_bts->abis_link_fi, ABIS_LINK_EV_SIGN_LINK_OML_UP, NULL); return g_bts->oml_link; case E1INP_SIGN_RSL: @@ -134,51 +404,18 @@ static struct e1inp_sign_link *sign_link_up(void *unit, struct e1inp_line *line, break; } e1inp_ts_config_sign(sign_ts, line); - trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL, - trx, trx->rsl_tei, 0); + trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL, + trx, trx->bb_transc.rsl.tei, 0); trx_link_estab(trx); - return trx->rsl_link; + return trx->bb_transc.rsl.link; } return NULL; } static void sign_link_down(struct e1inp_line *line) { - struct gsm_bts_trx *trx; LOGPIL(line, DABIS, LOGL_ERROR, "Signalling link down\n"); - - /* First remove the OML signalling link */ - if (g_bts->oml_link) { - struct timespec now; - - e1inp_sign_link_destroy(g_bts->oml_link); - - /* Log a special notice if the OML connection was dropped relatively quickly. */ - if (g_bts->oml_conn_established_timestamp.tv_sec != 0 && clock_gettime(CLOCK_MONOTONIC, &now) == 0 && - g_bts->oml_conn_established_timestamp.tv_sec + OSMO_BTS_OML_CONN_EARLY_DISCONNECT >= now.tv_sec) { - LOGP(DABIS, LOGL_FATAL, "OML link was closed early within %" PRIu64 " seconds. " - "If this situation persists, please check your BTS and BSC configuration files for errors. " - "A common error is a mismatch between unit_id configuration parameters of BTS and BSC.\n", - (uint64_t)(now.tv_sec - g_bts->oml_conn_established_timestamp.tv_sec)); - } - g_bts->oml_link = NULL; - } - memset(&g_bts->oml_conn_established_timestamp, 0, sizeof(g_bts->oml_conn_established_timestamp)); - - if (g_bts->osmo_link) { - e1inp_sign_link_destroy(g_bts->osmo_link); - g_bts->osmo_link = NULL; - } - - /* Then iterate over the RSL signalling links */ - llist_for_each_entry(trx, &g_bts->trx_list, list) { - if (trx->rsl_link) { - e1inp_sign_link_destroy(trx->rsl_link); - trx->rsl_link = NULL; - } - } - - bts_model_abis_close(g_bts); + osmo_fsm_inst_dispatch(g_bts->abis_link_fi, ABIS_LINK_EV_SIGN_LINK_DOWN, NULL); } @@ -277,33 +514,30 @@ void abis_init(struct gsm_bts *bts) osmo_signal_register_handler(SS_L_INPUT, &inp_s_cbfn, bts); } -struct e1inp_line *abis_open(struct gsm_bts *bts, char *dst_host, - char *model_name) +int abis_open(struct gsm_bts *bts, char *model_name) { - struct e1inp_line *line; + struct abis_link_fsm_priv *abis_link_fsm_priv; - /* patch in various data from VTY and other sources */ - line_ops.cfg.ipa.addr = dst_host; - osmo_get_macaddr(bts_dev_info.mac_addr, "eth0"); - bts_dev_info.site_id = bts->ip_access.site_id; - bts_dev_info.bts_id = bts->ip_access.bts_id; - bts_dev_info.unit_name = model_name; - if (bts->description) - bts_dev_info.unit_name = bts->description; - bts_dev_info.location2 = model_name; + if (llist_empty(&bts->bsc_oml_hosts)) { + LOGP(DABIS, LOGL_FATAL, "No BSC configured, cannot start BTS without knowing BSC OML IP\n"); + return -EINVAL; + } - line = e1inp_line_find(0); - if (line) { - e1inp_line_get2(line, __FILE__); /* We want a new reference for returned line */ - } else - line = e1inp_line_create(0, "ipa"); /* already comes with a reference */ - if (!line) - return NULL; - e1inp_line_bind_ops(line, &line_ops); + bts->abis_link_fi = osmo_fsm_inst_alloc(&abis_link_fsm, bts, NULL, LOGL_DEBUG, "abis_link"); + OSMO_ASSERT(bts->abis_link_fi); - /* This will open the OML connection now */ - if (e1inp_line_update(line) < 0) - return NULL; + abis_link_fsm_priv = talloc_zero(bts->abis_link_fi, struct abis_link_fsm_priv); + OSMO_ASSERT(abis_link_fsm_priv); + abis_link_fsm_priv->bts = bts; + abis_link_fsm_priv->model_name = model_name; + bts->abis_link_fi->priv = abis_link_fsm_priv; + + osmo_fsm_inst_state_chg(bts->abis_link_fi, ABIS_LINK_ST_CONNECTING, 0, 0); - return line; + return 0; +} + +static __attribute__((constructor)) void abis_link_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&abis_link_fsm) == 0); } diff --git a/src/common/abis_osmo.c b/src/common/abis_osmo.c index 46dc5fa9..beb9992d 100644 --- a/src/common/abis_osmo.c +++ b/src/common/abis_osmo.c @@ -1,6 +1,6 @@ /* OSMO extenion link associated to same line as oml_link: */ -/* (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -30,8 +30,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/pcu_if.h> #include <osmo-bts/pcuif_proto.h> - -extern struct gsm_network bts_gsmnet; +#include <osmo-bts/bts_sm.h> #define OM_HEADROOM_SIZE 128 @@ -106,7 +105,7 @@ static int rx_down_osmo_pcu(struct gsm_bts *bts, struct msgb *msg) /* Trim Abis lower layers: */ msgb_pull_to_l2(msg); /* we simply forward it to PCUIF: */ - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } /* incoming IPA/OSMO extension Abis message from BSC */ diff --git a/src/common/amr.c b/src/common/amr.c index 837757fe..47c9dcb5 100644 --- a/src/common/amr.c +++ b/src/common/amr.c @@ -6,6 +6,85 @@ #include <osmo-bts/logging.h> #include <osmo-bts/amr.h> +/* Reasonable defaults for AMR-FR and AMR-HR rate configuration. + * The values are taken from 3GPP TS 51.010-1 (version 13.11.0). + * See 14.2.19.4.1 and 14.2.20.4.1 for AMR-FR and AMR-HR, respectively. + * + * ^ C/I (dB) | FR / HR | + * | | + * | | + * MODE4 | | + * = | ----+---- THR_MX_Up(3) | 20.5 / 18.0 | + * | | | + * | = ----+---- THR_MX_Dn(4) | 18.5 / 16.0 | + * MODE3 | | + * | = ----+---- THR_MX_Up(2) | 14.5 / 14.0 | + * | | | + * = | ----+---- THR_MX_Dn(3) | 12.5 / 12.0 | + * MODE2 | | + * = | ----+---- THR_MX_Up(1) | 8.5 / 10.0 | + * | | | + * | = ----+---- THR_MX_Dn(2) | 6.5 / 8.0 | + * MODE1 | | + * | | + * | | + */ +static const struct gsm48_multi_rate_conf amr_fr_mr_cfg_def = { + .m4_75 = 1, + .m5_90 = 1, + .m7_95 = 1, + .m12_2 = 1, +}; +static const struct amr_mode amr_fr_bts_mode_def[] = { + { + .mode = 0, /* 4.75k */ + .threshold = 13, /* THR_MX_Dn(2): 6.5 dB */ + .hysteresis = 4, /* THR_MX_Up(1): 8.5 dB */ + }, + { + .mode = 2, /* 5.90k */ + .threshold = 25, /* THR_MX_Dn(3): 12.5 dB */ + .hysteresis = 4, /* THR_MX_Up(2): 14.5 dB */ + }, + { + .mode = 5, /* 7.95k */ + .threshold = 37, /* THR_MX_Dn(4): 18.5 dB */ + .hysteresis = 4, /* THR_MX_Up(3): 20.5 dB */ + }, + { + .mode = 7, /* 12.2k */ + /* this is the last mode, so no threshold */ + }, +}; + +static const struct gsm48_multi_rate_conf amr_hr_mr_cfg_def = { + .m4_75 = 1, + .m5_90 = 1, + .m6_70 = 1, + .m7_95 = 1, +}; +static const struct amr_mode amr_hr_bts_mode_def[] = { + { + .mode = 0, /* 4.75k */ + .threshold = 16, /* THR_MX_Dn(2): 8.0 dB */ + .hysteresis = 4, /* THR_MX_Up(1): 10.0 dB */ + }, + { + .mode = 2, /* 5.90k */ + .threshold = 24, /* THR_MX_Dn(3): 12.0 dB */ + .hysteresis = 4, /* THR_MX_Up(2): 14.0 dB */ + }, + { + .mode = 3, /* 6.70k */ + .threshold = 32, /* THR_MX_Dn(4): 16.0 dB */ + .hysteresis = 4, /* THR_MX_Up(3): 18.0 dB */ + }, + { + .mode = 5, /* 7.95k */ + /* this is the last mode, so no threshold */ + }, +}; + void amr_log_mr_conf(int ss, int logl, const char *pfx, struct amr_multirate_conf *amr_mrc) { @@ -16,9 +95,9 @@ void amr_log_mr_conf(int ss, int logl, const char *pfx, for (i = 0; i < amr_mrc->num_modes; i++) LOGPC(ss, logl, ", mode[%u] = %u/%u/%u", - i, amr_mrc->bts_mode[i].mode, - amr_mrc->bts_mode[i].threshold, - amr_mrc->bts_mode[i].hysteresis); + i, amr_mrc->mode[i].mode, + amr_mrc->mode[i].threshold, + amr_mrc->mode[i].hysteresis); LOGPC(ss, logl, "\n"); } @@ -27,7 +106,7 @@ static inline int get_amr_mode_idx(const struct amr_multirate_conf *amr_mrc, { unsigned int i; for (i = 0; i < amr_mrc->num_modes; i++) { - if (amr_mrc->bts_mode[i].mode == cmi) + if (amr_mrc->mode[i].mode == cmi) return i; } return -EINVAL; @@ -117,23 +196,26 @@ int amr_parse_mr_conf(struct amr_multirate_conf *amr_mrc, for (i = 0; i < 8; i++) { if (mr_conf[1] & (1 << i)) { - amr_mrc->bts_mode[j++].mode = i; + amr_mrc->mode[j++].mode = i; } } + /* skip the first two octets of the IE */ + mr_conf += 2; + if (num_codecs >= 2) { - amr_mrc->bts_mode[0].threshold = mr_conf[1] & 0x3F; - amr_mrc->bts_mode[0].hysteresis = mr_conf[2] >> 4; + amr_mrc->mode[0].threshold = mr_conf[0] & 0x3F; + amr_mrc->mode[0].hysteresis = mr_conf[1] >> 4; } if (num_codecs >= 3) { - amr_mrc->bts_mode[1].threshold = - ((mr_conf[2] & 0xF) << 2) | (mr_conf[3] >> 6); - amr_mrc->bts_mode[1].hysteresis = (mr_conf[3] >> 2) & 0xF; + amr_mrc->mode[1].threshold = + ((mr_conf[1] & 0xF) << 2) | (mr_conf[2] >> 6); + amr_mrc->mode[1].hysteresis = (mr_conf[2] >> 2) & 0xF; } if (num_codecs >= 4) { - amr_mrc->bts_mode[2].threshold = - ((mr_conf[3] & 0x3) << 4) | (mr_conf[4] >> 4); - amr_mrc->bts_mode[2].hysteresis = mr_conf[4] & 0xF; + amr_mrc->mode[2].threshold = + ((mr_conf[2] & 0x3) << 4) | (mr_conf[3] >> 4); + amr_mrc->mode[2].hysteresis = mr_conf[3] & 0xF; } return num_codecs; @@ -171,3 +253,26 @@ unsigned int amr_get_initial_mode(struct gsm_lchan *lchan) } } } + +void amr_init_mr_conf_def(struct gsm_lchan *lchan) +{ + const struct gsm48_multi_rate_conf *mr_cfg; + const struct amr_mode *bts_mode; + unsigned int num_modes; + + if (lchan->type == GSM_LCHAN_TCH_F) { + num_modes = ARRAY_SIZE(amr_fr_bts_mode_def); + bts_mode = &amr_fr_bts_mode_def[0]; + mr_cfg = &amr_fr_mr_cfg_def; + } else { + num_modes = ARRAY_SIZE(amr_hr_bts_mode_def); + bts_mode = &amr_hr_bts_mode_def[0]; + mr_cfg = &amr_hr_mr_cfg_def; + } + + memcpy(lchan->tch.amr_mr.gsm48_ie, mr_cfg, + sizeof(lchan->tch.amr_mr.gsm48_ie)); + memcpy(&lchan->tch.amr_mr.mode[0], &bts_mode[0], + sizeof(lchan->tch.amr_mr.mode)); + lchan->tch.amr_mr.num_modes = num_modes; +} diff --git a/src/common/asci.c b/src/common/asci.c new file mode 100644 index 00000000..4342f17c --- /dev/null +++ b/src/common/asci.c @@ -0,0 +1,211 @@ +/* ASCI (VGCS/VBS) related common code */ + +/* (C) 2023 by Harald Welte <laforge@osmocom.org> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <stdint.h> +#include <errno.h> + +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/gsm/rsl.h> + +#include <osmo-bts/bts.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/logging.h> +#include <osmo-bts/l1sap.h> +#include <osmo-bts/asci.h> + +static int tx_vgcs_ul_grant(struct gsm_lchan *lchan) +{ + struct gsm0408_vgcs_ul_grant ul_grant; + struct gsm_time gt; + struct msgb *msg; + + gsm_fn2gsmtime(>, lchan->asci.fn); + + /* build the RR VGCS UPLINK GRANT message as per TS 44.018 Section 9.1.49 */ + ul_grant = (struct gsm0408_vgcs_ul_grant) { + .hdr = { + .proto_discr = GSM48_PDISC_RR, + .msg_type = GSM48_MT_RR_VGCS_UPL_GRANT, + }, + .req_ref = { + .ra = lchan->asci.ref, + .t1 = gt.t1, + .t2 = gt.t2, + .t3_low = gt.t3 & 7, + .t3_high = gt.t3 >> 3, + }, + .ta = lchan->ta_ctrl.current, + }; + + /* Wrap it in a RSL UNITDATA REQUEST */ + msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0); + msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */ + msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(ul_grant), (uint8_t *) &ul_grant); + + /* send it towards MS, just like a RSL message from the BSC */ + return lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch); +} + +/* timer call-back for T3115 (VGCS UPLINK GRANT re-transmit) */ +static void vgcs_t3115_cb(void *data) +{ + struct gsm_lchan *lchan = data; + struct gsm_bts *bts = lchan->ts->trx->bts; + + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "T3115 timeout (%d resends left)\n", + bts->ny2 - lchan->asci.vgcs_ul_grant_count); + + if (lchan->state != LCHAN_S_ACTIVE) { + LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "is not active. It is in state %s. Ignoring\n", + gsm_lchans_name(lchan->state)); + return; + } + + if (lchan->asci.vgcs_ul_grant_count >= bts->ny2) { + lchan->asci.vgcs_ul_grant_count = 0; + LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "NY2 reached, sending CONNection FAILure to BSC.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_TALKER_ACC_FAIL); + lchan->asci.talker_active = VGCS_TALKER_NONE; + return; + } + + tx_vgcs_ul_grant(lchan); + lchan->asci.vgcs_ul_grant_count++; + osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000); +} + +/* Received random access on dedicated channel. */ +void vgcs_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay, uint32_t fn) +{ + LOGPLCHAN(lchan, DASCI, LOGL_NOTICE, "VGCS RACH on dedicated channel type %s received with " + "TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra); + + if (ra == 0x25) { /* See TS 44.018 Table 9.1.45.1 */ + /* Listener Detection (TS 48.058 Section 4.14) */ + if (!lchan->asci.listener_detected) { + rsl_tx_listener_det(lchan, &acc_delay); + lchan->asci.listener_detected = true; + } + } else { + /* Talker Detection (TS 48.058 Section 4.13) */ + struct gsm_bts *bts = lchan->ts->trx->bts; + + /* Talker detection on group channels only */ + if (!rsl_chan_rt_is_vgcs(lchan->rsl_chan_rt)) + return; + + if (lchan->asci.talker_active != VGCS_TALKER_NONE) { + LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Ignoring RACH, there is an active talker already.\n"); + return; + } + + /* Set timing advance, power level and activate SACCH */ + lchan->ta_ctrl.current = acc_delay; + lchan->ms_power_ctrl.current = lchan->ms_power_ctrl.max; + lchan->want_dl_sacch_active = true; + + /* Stop RACH detection, wait for valid frame */ + lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME; + if (l1sap_uplink_access(lchan, false) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access after TALKER DET.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + lchan->asci.talker_active = VGCS_TALKER_NONE; + return; + } + + lchan->asci.ref = ra; + lchan->asci.fn = fn; + + /* Send TALKER DETECT via RSL to BSC */ + rsl_tx_talker_det(lchan, &acc_delay); + + /* Send VGCS UPLINK GRANT */ + lchan->asci.vgcs_ul_grant_count = 1; + tx_vgcs_ul_grant(lchan); + + /* Start T3115 */ + LOGPLCHAN(lchan, DASCI, LOGL_DEBUG, "Starting T3115 with %u ms\n", bts->t3115_ms); + lchan->asci.t3115.cb = vgcs_t3115_cb; + lchan->asci.t3115.data = lchan; + osmo_timer_schedule(&lchan->asci.t3115, 0, bts->t3115_ms * 1000); + } +} + +/* Received channel activation. */ +void vgcs_lchan_activate(struct gsm_lchan *lchan) +{ + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated.\n"); + if (l1sap_uplink_access(lchan, true) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to activate uplink access after channel activation.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } +} + +/* Received channel reactivation. (for assignment) */ +void vgcs_lchan_react(struct gsm_lchan *lchan) +{ + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Channel is activated for assignment.\n"); + lchan->asci.talker_active = VGCS_TALKER_WAIT_FRAME; + if (l1sap_uplink_access(lchan, false) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, "Failed to deactivate uplink access for assignment.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } + radio_link_timeout_reset(lchan); +} + +/* Received first valid data frame on dedicated channel. */ +void vgcs_talker_frame(struct gsm_lchan *lchan) +{ + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "First valid frame detected, talker now active.\n"); + osmo_timer_del(&lchan->asci.t3115); + lchan->asci.talker_active = VGCS_TALKER_ACTIVE; + radio_link_timeout_reset(lchan); +} + +/* Release VGCS Talker state. */ +void vgcs_talker_reset(struct gsm_lchan *lchan, bool ul_access) +{ + if (lchan->asci.talker_active == VGCS_TALKER_NONE) + return; + + LOGPLCHAN(lchan, DASCI, LOGL_INFO, "Uplink released, no talker.\n"); + + /* Stop T3115 */ + osmo_timer_del(&lchan->asci.t3115); + + /* Talker released. */ + lchan->asci.talker_active = VGCS_TALKER_NONE; + if (ul_access) { + if (l1sap_uplink_access(lchan, true) != 0) { + LOGPLCHAN(lchan, DASCI, LOGL_ERROR, + "Failed to activate uplink access after uplink became free.\n"); + rsl_tx_conn_fail(lchan, RSL_ERR_EQUIPMENT_FAIL); + } + } +} + +/* Release VGCS Listener state. */ +void vgcs_listener_reset(struct gsm_lchan *lchan) +{ + lchan->asci.listener_detected = false; +} diff --git a/src/common/bts.c b/src/common/bts.c index 27c7f74c..56765eca 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -44,8 +44,10 @@ #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> #include <osmo-bts/bts_model.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/dtx_dl_amr_fsm.h> #include <osmo-bts/pcuif_proto.h> +#include <osmo-bts/pcu_if.h> #include <osmo-bts/rsl.h> #include <osmo-bts/oml.h> #include <osmo-bts/signal.h> @@ -54,17 +56,15 @@ #include <osmo-bts/bts_shutdown_fsm.h> #include <osmo-bts/nm_common_fsm.h> #include <osmo-bts/power_control.h> +#include <osmo-bts/osmux.h> +#include <osmo-bts/notification.h> +#define MAX_TA_DEF 63 /* default max Timing Advance value */ #define MIN_QUAL_RACH 50 /* minimum link quality (in centiBels) for Access Bursts */ #define MIN_QUAL_NORM -5 /* minimum link quality (in centiBels) for Normal Bursts */ static void bts_update_agch_max_queue_length(struct gsm_bts *bts); -struct gsm_network bts_gsmnet = { - .bts_list = { &bts_gsmnet.bts_list, &bts_gsmnet.bts_list }, - .num_bts = 0, -}; - void *tall_bts_ctx; /* Table 3.1 TS 04.08: Values of parameter S */ @@ -97,12 +97,22 @@ static const struct rate_ctr_desc bts_ctr_desc[] = { [BTS_CTR_RACH_RCVD] = {"rach:rcvd", "Received RACH requests (Um)"}, [BTS_CTR_RACH_DROP] = {"rach:drop", "Dropped RACH requests (Um)"}, [BTS_CTR_RACH_HO] = {"rach:handover", "Received RACH requests (Handover)"}, + [BTS_CTR_RACH_VGCS] = {"rach:vgcs", "Received RACH requests (VGCS)"}, [BTS_CTR_RACH_CS] = {"rach:cs", "Received RACH requests (CS/Abis)"}, [BTS_CTR_RACH_PS] = {"rach:ps", "Received RACH requests (PS/PCU)"}, [BTS_CTR_AGCH_RCVD] = {"agch:rcvd", "Received AGCH requests (Abis)"}, [BTS_CTR_AGCH_SENT] = {"agch:sent", "Sent AGCH requests (Abis)"}, [BTS_CTR_AGCH_DELETED] = {"agch:delete", "Sent AGCH DELETE IND (Abis)"}, + + [BTS_CTR_RTP_RX_TOTAL] = {"rtp:rx:total", "Total number of received RTP packets"}, + [BTS_CTR_RTP_RX_MARKER] = {"rtp:rx:marker", "Number of received RTP packets with marker bit set"}, + [BTS_CTR_RTP_RX_DROP_PREEN] = {"rtp:rx:drop:preen", "Total number of received RTP packets dropped during preening"}, + [BTS_CTR_RTP_RX_DROP_LOOPBACK] = {"rtp:rx:drop:loopback", "Total number of received RTP packets dropped during loopback"}, + [BTS_CTR_RTP_RX_DROP_OVERFLOW] = {"rtp:rx:drop:overflow", "Total number of received RTP packets dropped during DL queue overflow"}, + [BTS_CTR_RTP_RX_DROP_V110_DEC] = {"rtp:rx:drop:v110_dec", "Total number of received RTP packets dropped during V.110 decode"}, + [BTS_CTR_RTP_TX_TOTAL] = {"rtp:tx:total", "Total number of transmitted RTP packets"}, + [BTS_CTR_RTP_TX_MARKER] = {"rtp:tx:marker", "Number of transmitted RTP packets with marker bit set"}, }; static const struct rate_ctr_group_desc bts_ctrg_desc = { "bts", @@ -128,7 +138,7 @@ static const struct rate_ctr_group_desc cbch_ctrg_desc = { cbch_ctr_desc }; -static struct osmo_tdef bts_T_defs[] = { +struct osmo_tdef bts_T_defs[] = { /* T-1: FIXME: Ideally should be dynamically calculated per trx at * shutdown start based on params below, and highest trx value taken: * + VTY's power-ramp step-interval. @@ -143,7 +153,11 @@ static struct osmo_tdef bts_T_defs[] = { {} }; -static const uint8_t bts_nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 }; +struct osmo_tdef abis_T_defs[] = { + { .T=-15, .default_val=0, .unit=OSMO_TDEF_MS, .desc="Time to wait between Channel Activation and dispatching a cached early Immediate Assignment" }, + {} +}; + static const uint8_t bts_cell_timer_default[] = { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 }; static const struct gprs_rlc_cfg rlc_cfg_default = { @@ -201,32 +215,46 @@ const char *btsatttr2str(enum bts_attribute v) const struct value_string bts_impl_flag_desc[] = { { BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP, "DSP/HW based MS Power Control Loop" }, { BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB, "Measurement and Payload data combined" }, + { BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER, "OML RadioChannel MO depends on RadioCarrier MO" }, + { BTS_INTERNAL_FLAG_INTERF_MEAS, "Uplink interference measurements" }, { 0, NULL } }; +/* Ensure that all BTS_INTERNAL_FLAG_* entries are present in bts_impl_flag_desc[] */ +osmo_static_assert(ARRAY_SIZE(bts_impl_flag_desc) == _BTS_INTERNAL_FLAG_NUM + 1, _bts_impl_flag_desc); + static int gsm_bts_talloc_destructor(struct gsm_bts *bts) { - if (bts->site_mgr.mo.fi) { - osmo_fsm_inst_free(bts->site_mgr.mo.fi); - bts->site_mgr.mo.fi = NULL; - } if (bts->mo.fi) { osmo_fsm_inst_free(bts->mo.fi); bts->mo.fi = NULL; } + if (bts->shutdown_fi) { + osmo_fsm_inst_free(bts->shutdown_fi); + bts->shutdown_fi = NULL; + } + + bts_osmux_release(bts); + + llist_del(&bts->list); + g_bts_sm->num_bts--; return 0; } -struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num) +struct gsm_bts *gsm_bts_alloc(struct gsm_bts_sm *bts_sm, uint8_t bts_num) { - struct gsm_bts *bts = talloc_zero(ctx, struct gsm_bts); - int i; + struct gsm_bts *bts = talloc_zero(bts_sm, struct gsm_bts); if (!bts) return NULL; talloc_set_destructor(bts, gsm_bts_talloc_destructor); + /* add to list of BTSs */ + llist_add_tail(&bts->list, &bts_sm->bts_list); + g_bts_sm->num_bts++; + + bts->site_mgr = bts_sm; bts->nr = bts_num; bts->num_trx = 0; INIT_LLIST_HEAD(&bts->trx_list); @@ -234,36 +262,24 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num) bts->T_defs = bts_T_defs; osmo_tdefs_reset(bts->T_defs); + osmo_tdefs_reset(abis_T_defs); bts->shutdown_fi = osmo_fsm_inst_alloc(&bts_shutdown_fsm, bts, bts, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr); - bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr, - LOGL_INFO, "bts_sm"); - gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER, - 0xff, 0xff, 0xff); - + /* NM BTS */ bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr); gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff); - for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { - bts->gprs.nsvc[i].bts = bts; - bts->gprs.nsvc[i].id = i; - gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC, - bts->nr, i, 0xff); - } - memcpy(&bts->gprs.nse.timer, bts_nse_timer_default, - sizeof(bts->gprs.nse.timer)); - gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE, - bts->nr, 0xff, 0xff); - memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, - sizeof(bts->gprs.cell.timer)); - gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, - bts->nr, 0xff, 0xff); - memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, - sizeof(bts->gprs.cell.rlc_cfg)); + /* NM GPRS CELL */ + bts->gprs.cell.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_cell_fsm, bts, &bts->gprs.cell, + LOGL_INFO, NULL); + osmo_fsm_inst_update_id_f(bts->gprs.cell.mo.fi, "gprs_cell%d-0", bts->nr); + gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, bts->nr, 0, 0xff); + memcpy(&bts->gprs.cell.rlc_cfg, &rlc_cfg_default, sizeof(bts->gprs.cell.rlc_cfg)); + memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer)); /* create our primary TRX. It will be initialized during bts_init() */ bts->c0 = gsm_bts_trx_alloc(bts); @@ -279,14 +295,14 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num) return bts; } -struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num) +struct gsm_bts *gsm_bts_num(const struct gsm_bts_sm *bts_sm, int num) { struct gsm_bts *bts; - if (num >= net->num_bts) + if (num >= bts_sm->num_bts) return NULL; - llist_for_each_entry(bts, &net->bts_list, list) { + llist_for_each_entry(bts, &bts_sm->bts_list, list) { if (bts->nr == num) return bts; } @@ -302,19 +318,14 @@ int bts_init(struct gsm_bts *bts) static int initialized = 0; void *tall_rtp_ctx; - /* add to list of BTSs */ - llist_add_tail(&bts->list, &bts_gsmnet.bts_list); - bts->band = GSM_BAND_1800; INIT_LLIST_HEAD(&bts->agch_queue.queue); bts->agch_queue.length = 0; bts->ctrs = rate_ctr_group_alloc(bts, &bts_ctrg_desc, bts->nr); - if (!bts->ctrs) { - llist_del(&bts->list); + if (!bts->ctrs) return -1; - } /* enable management with default levels, * raise threshold to GSM_BTS_AGCH_QUEUE_THRESH_LEVEL_DISABLE to @@ -332,59 +343,66 @@ int bts_init(struct gsm_bts *bts) bts->rtp_port_range_next = bts->rtp_port_range_start; bts->rtp_ip_dscp = -1; bts->rtp_priority = -1; + bts->emit_hr_rfc5993 = true; /* Default (fall-back) MS/BS Power control parameters */ - bts->bs_dpc_params = power_ctrl_params_def; - bts->ms_dpc_params = power_ctrl_params_def; + power_ctrl_params_def_reset(&bts->bs_dpc_params, true); + power_ctrl_params_def_reset(&bts->ms_dpc_params, false); /* configurable via OML */ + bts->bsic = 0xff; /* invalid value, guarded by bsc_configured=false */ + bts->bsic_configured = false; bts->load.ccch.load_ind_period = 112; - load_timer_start(bts); bts->rtp_jitter_buf_ms = 100; - bts->max_ta = 63; + bts->max_ta = MAX_TA_DEF; bts->ny1 = 4; + bts->ny2 = 4; bts->t3105_ms = 300; + bts->t3115_ms = 300; bts->min_qual_rach = MIN_QUAL_RACH; bts->min_qual_norm = MIN_QUAL_NORM; bts->max_ber10k_rach = 1707; /* 7 of 41 bits is Eb/N0 of 0 dB = 0.1707 */ bts->pcu.sock_path = talloc_strdup(bts, PCU_SOCK_DEFAULT); - for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++) - bts->t200_ms[i] = oml_default_t200_ms[i]; + bts->pcu.sock_wqueue_len_max = BTS_PCU_SOCK_WQUEUE_LEN_DEFAULT; + for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++) + bts->t200_fn[i] = oml_default_t200_fn[i]; /* default RADIO_LINK_TIMEOUT */ bts->radio_link_timeout.oml = 32; bts->radio_link_timeout.current = bts->radio_link_timeout.oml; - /* Start with the site manager */ - oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + /* Start with the BTS */ oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); - - /* set BTS attr to dependency */ - oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); - oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); - oml_mo_state_init(&bts->gprs.nsvc[0].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); - oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); /* allocate a talloc pool for ORTP to ensure it doesn't have to go back * to the libc malloc all the time */ tall_rtp_ctx = talloc_pool(tall_bts_ctx, 262144); osmo_rtp_init(tall_rtp_ctx); - /* features implemented in 'common', available for all models */ - osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN); - osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC); + /* Osmux */ + rc = bts_osmux_init(bts); + if (rc < 0) + return rc; + + /* features implemented in 'common', available for all models, + * order alphabetically */ osmo_bts_set_feature(bts->features, BTS_FEAT_ABIS_OSMO_PCU); + osmo_bts_set_feature(bts->features, BTS_FEAT_CCN); osmo_bts_set_feature(bts->features, BTS_FEAT_DYN_TS_SDCCH8); + osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN); + osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC); + osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION); + + /* Maximum TA supported by the PHY (can be overridden by PHY specific code) */ + bts->support.max_ta = MAX_TA_DEF; rc = bts_model_init(bts); - if (rc < 0) { - llist_del(&bts->list); + if (rc < 0) return rc; - } /* TRX0 was allocated early during gsm_bts_alloc, not later through VTY */ bts_model_trx_init(bts->c0); - bts_gsmnet.num_bts++; if (!initialized) { osmo_signal_register_handler(SS_GLOBAL, bts_signal_cbfn, NULL); @@ -401,7 +419,10 @@ int bts_init(struct gsm_bts *bts) bts->smscb_queue_tgt_len = 2; bts->smscb_queue_hyst = 2; - INIT_LLIST_HEAD(&bts->oml_queue); + bts->asci.pos_nch = -ENOTSUP; + INIT_LLIST_HEAD(&bts->asci.notifications); + + INIT_LLIST_HEAD(&bts->bsc_oml_hosts); /* register DTX DL FSM */ rc = osmo_fsm_register(&dtx_dl_amr_fsm); @@ -418,97 +439,17 @@ int bts_init(struct gsm_bts *bts) /* main link is established, send status report */ int bts_link_estab(struct gsm_bts *bts) { - int i, j; - - LOGP(DSUM, LOGL_INFO, "Main link established, sending NM Status.\n"); + LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status\n"); - /* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */ - osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL); - osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL); - - /* those should all be in DEPENDENCY */ - oml_tx_state_changed(&bts->gprs.nse.mo); - oml_tx_state_changed(&bts->gprs.cell.mo); - oml_tx_state_changed(&bts->gprs.nsvc[0].mo); - oml_tx_state_changed(&bts->gprs.nsvc[1].mo); - - /* All other objects start off-line until the BTS Model code says otherwise */ - for (i = 0; i < bts->num_trx; i++) { - struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i); - - oml_tx_state_changed(&trx->mo); - oml_tx_state_changed(&trx->bb_transc.mo); - - for (j = 0; j < ARRAY_SIZE(trx->ts); j++) { - struct gsm_bts_trx_ts *ts = &trx->ts[j]; - - oml_tx_state_changed(&ts->mo); - } - } + /* Signal OML UP to BTS SITE MGR. It will automatically SW_ACT repoort + * and become Disabled-Offline, then dispatch same event to its children + * objects. + */ + osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_OML_UP, NULL); return bts_model_oml_estab(bts); } -/* prepare the per-SAPI T200 arrays for a given lchan */ -static int t200_by_lchan(int *t200_ms_dcch, int *t200_ms_acch, struct gsm_lchan *lchan) -{ - struct gsm_bts *bts = lchan->ts->trx->bts; - - /* we have to compensate for the "RTS advance" due to the asynchronous interface between - * the BTS (LAPDm) and the PHY/L1 (OsmoTRX or DSP in case of osmo-bts-{sysmo,lc15,oc2g,octphy} */ - int32_t fn_advance = bts_get_avg_fn_advance(bts); - int32_t fn_advance_us = fn_advance * 4615; - int fn_advance_ms = fn_advance_us / 1000; - - t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms; - t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms; - - if (lchan->repeated_acch_capability.dl_facch_all && (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)) { - t200_ms_acch[DL_SAPI0] *= 2; - t200_ms_acch[DL_SAPI3] *= 2; - } - - switch (lchan->type) { - case GSM_LCHAN_SDCCH: - t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms; - t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_SDCCH_SAPI3] + fn_advance_ms; - break; - case GSM_LCHAN_TCH_F: - t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms; - t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_F] + fn_advance_ms; - break; - case GSM_LCHAN_TCH_H: - t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms; - t200_ms_dcch[DL_SAPI3] = bts->t200_ms[T200_FACCH_H] + fn_advance_ms; - break; - default: - /* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */ - return -1; - } - return 0; -} - -int lchan_init_lapdm(struct gsm_lchan *lchan) -{ - struct lapdm_channel *lc = &lchan->lapdm_ch; - int t200_ms_dcch[_NR_DL_SAPI], t200_ms_acch[_NR_DL_SAPI]; - - if (t200_by_lchan(t200_ms_dcch, t200_ms_acch, lchan) == 0) { - LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG, - "Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in ms)\n", - t200_ms_dcch[DL_SAPI0], t200_ms_dcch[DL_SAPI3], - t200_ms_acch[DL_SAPI0], t200_ms_acch[DL_SAPI3]); - lapdm_channel_init3(lc, LAPDM_MODE_BTS, t200_ms_dcch, t200_ms_acch, lchan->type, - gsm_lchan_name(lchan)); - lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY); - lapdm_channel_set_l1(lc, NULL, lchan); - } - /* We still need to set Rx callback to receive RACH requests: */ - lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan); - - return 0; -} - #define CCCH_RACH_RATIO_COMBINED256 (256*1/9) #define CCCH_RACH_RATIO_SEPARATE256 (256*10/55) @@ -703,7 +644,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) struct gsm48_imm_ass_rej *imm_ass_cmd = msgb_l3(msg); if (bts->agch_queue.length > hard_limit) { - LOGP(DSUM, LOGL_ERROR, + LOGP(DRR, LOGL_ERROR, "AGCH: too many messages in queue, " "refusing message type %s, length = %d/%d\n", gsm48_rr_msg_name(((struct gsm48_imm_ass *)msgb_l3(msg))->msg_type), @@ -731,7 +672,7 @@ int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg) return 0; } -struct msgb *bts_agch_dequeue(struct gsm_bts *bts) +static struct msgb *bts_agch_dequeue(struct gsm_bts *bts) { struct msgb *msg = msgb_dequeue(&bts->agch_queue.queue); if (!msg) @@ -797,12 +738,12 @@ static void compact_agch_queue(struct gsm_bts *bts) return; } -int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, - int is_ag_res) +int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt, enum ccch_msgt ccch) { struct msgb *msg = NULL; int rc = 0; int is_empty = 1; + const struct bts_agch_msg_cb *msg_cb; /* Do queue house keeping. * This needs to be done every time a CCCH message is requested, since @@ -811,26 +752,39 @@ int bts_ccch_copy_msg(struct gsm_bts *bts, uint8_t *out_buf, struct gsm_time *gt */ compact_agch_queue(bts); - /* Check for paging messages first if this is PCH */ - if (!is_ag_res) - rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty); - - /* Check whether the block may be overwritten */ - if (!is_empty) - return rc; - - msg = bts_agch_dequeue(bts); - if (!msg) + switch (ccch) { + case CCCH_MSGT_NCH: + /* Send NCH message, it has priority over AGCH and does not overlap with PCH. */ + rc = bts_asci_notify_nch_gen_msg(bts, out_buf); return rc; + case CCCH_MSGT_PCH: + /* Check whether the block may be overwritten by AGCH. */ + rc = paging_gen_msg(bts->paging_state, out_buf, gt, &is_empty); + if (!is_empty) + return rc; + /* fall-through */ + case CCCH_MSGT_AGCH: + /* If fallen here and the AGCH queue is empty, return empty PCH message. */ + msg = bts_agch_dequeue(bts); + if (!msg) + return rc; + /* Continue to return AGCH message. */ + break; + } rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_SENT); + /* Confirm sending of the AGCH message towards the PCU */ + msg_cb = (struct bts_agch_msg_cb *) msg->cb; + if (msg_cb->confirm) + pcu_tx_data_cnf(msg_cb->msg_id, PCU_IF_SAPI_AGCH_2); + /* Copy AGCH message */ memcpy(out_buf, msgb_l3(msg), msgb_l3len(msg)); rc = msgb_l3len(msg); msgb_free(msg); - if (is_ag_res) + if (ccch == CCCH_MSGT_AGCH) bts->agch_queue.agch_msgs++; else bts->agch_queue.pch_msgs++; @@ -858,30 +812,35 @@ struct gsm_time *get_time(struct gsm_bts *bts) return &bts->gsm_time; } -int bts_supports_cm(const struct gsm_bts *bts, - const struct rsl_ie_chan_mode *cm) +bool bts_supports_cm_speech(const struct gsm_bts *bts, + const struct rsl_ie_chan_mode *cm) { enum osmo_bts_features feature = _NUM_BTS_FEAT; - switch (cm->spd_ind) { - case RSL_CMOD_SPD_SIGN: - /* We assume that signalling support is mandatory, - * there is no BTS_FEAT_* definition to check that. */ - return 1; - case RSL_CMOD_SPD_SPEECH: + /* Stage 1: check support for the requested channel type */ + switch (cm->chan_rt) { + case RSL_CMOD_CRT_TCH_GROUP_Bm: + case RSL_CMOD_CRT_TCH_GROUP_Lm: + if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VGCS)) + return false; + break; + case RSL_CMOD_CRT_TCH_BCAST_Bm: + case RSL_CMOD_CRT_TCH_BCAST_Lm: + if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VBS)) + return false; + break; + case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm: + case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm: + if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS)) + return false; break; - case RSL_CMOD_SPD_DATA: - default: - return 0; } - /* Before the requested pchan/cm combination can be checked, we need to - * convert it to a feature identifier we can check */ + /* Stage 2: check support for the requested codec */ switch (cm->chan_rt) { case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm: - if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS)) - return 0; - /* fall-through */ + case RSL_CMOD_CRT_TCH_GROUP_Bm: + case RSL_CMOD_CRT_TCH_BCAST_Bm: case RSL_CMOD_CRT_TCH_Bm: switch (cm->chan_rate) { case RSL_CMOD_SP_GSM1: @@ -895,14 +854,13 @@ int bts_supports_cm(const struct gsm_bts *bts, break; default: /* Invalid speech codec type => Not supported! */ - return 0; + return false; } break; case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm: - if (!osmo_bts_has_feature(bts->features, BTS_FEAT_VAMOS)) - return 0; - /* fall-through */ + case RSL_CMOD_CRT_TCH_GROUP_Lm: + case RSL_CMOD_CRT_TCH_BCAST_Lm: case RSL_CMOD_CRT_TCH_Lm: switch (cm->chan_rate) { case RSL_CMOD_SP_GSM1: @@ -913,7 +871,7 @@ int bts_supports_cm(const struct gsm_bts *bts, break; default: /* Invalid speech codec type => Not supported! */ - return 0; + return false; } break; @@ -921,35 +879,81 @@ int bts_supports_cm(const struct gsm_bts *bts, LOGP(DRSL, LOGL_ERROR, "Unhandled RSL channel type=0x%02x/rate=0x%02x\n", cm->chan_rt, cm->chan_rate); - return 0; + return false; } /* Check if the feature is supported by this BTS */ if (osmo_bts_has_feature(bts->features, feature)) - return 1; + return true; - return 0; + return false; +} + +static bool bts_supports_cm_data(const struct gsm_bts *bts, + const struct rsl_ie_chan_mode *cm) +{ + switch (bts->variant) { + case BTS_OSMO_TRX: + switch (cm->chan_rate) { + /* TODO: RSL_CMOD_CSD_NT_14k5 */ + /* TODO: RSL_CMOD_CSD_T_14k4 */ + case RSL_CMOD_CSD_NT_12k0: + case RSL_CMOD_CSD_T_9k6: + if (cm->chan_rt != RSL_CMOD_CRT_TCH_Bm) + return false; /* invalid */ + /* fall-through */ + case RSL_CMOD_CSD_NT_6k0: + case RSL_CMOD_CSD_T_4k8: + case RSL_CMOD_CSD_T_2k4: + case RSL_CMOD_CSD_T_1k2: + case RSL_CMOD_CSD_T_600: + case RSL_CMOD_CSD_T_1200_75: + return true; + default: + return false; + } + default: + return 0; + } +} + +bool bts_supports_cm(const struct gsm_bts *bts, + const struct rsl_ie_chan_mode *cm) +{ + switch (cm->spd_ind) { + case RSL_CMOD_SPD_SIGN: + /* We assume that signalling support is mandatory, + * there is no BTS_FEAT_* definition to check that. */ + return true; + case RSL_CMOD_SPD_SPEECH: + return bts_supports_cm_speech(bts, cm); + case RSL_CMOD_SPD_DATA: + return bts_supports_cm_data(bts, cm); + default: + return false; + } } /* return the gsm_lchan for the CBCH (if it exists at all) */ struct gsm_lchan *gsm_bts_get_cbch(struct gsm_bts *bts) { - struct gsm_lchan *lchan = NULL; struct gsm_bts_trx *trx = bts->c0; + /* According to 3GPP TS 45.002, table 3, CBCH can be allocated + * either on C0/TS0 (CCCH+SDCCH4) or on C0..n/TS0..3 (SDCCH/8). */ if (trx->ts[0].pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) - lchan = &trx->ts[0].lchan[2]; - else { - int i; - for (i = 0; i < 8; i++) { - if (trx->ts[i].pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) { - lchan = &trx->ts[i].lchan[2]; - break; - } + return &trx->ts[0].lchan[2]; /* C0/TS0 */ + + llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */ + unsigned int tn; + for (tn = 0; tn <= 3; tn++) { /* TS0..3 */ + struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + if (ts->pchan == GSM_PCHAN_SDCCH8_SACCH8C_CBCH) + return &ts->lchan[2]; } } - return lchan; + return NULL; } /* BCCH carrier power reduction (see 3GPP TS 45.008, section 7.1) */ diff --git a/src/common/bts_ctrl_commands.c b/src/common/bts_ctrl_commands.c index faaba6a1..5f6857cf 100644 --- a/src/common/bts_ctrl_commands.c +++ b/src/common/bts_ctrl_commands.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -84,12 +84,45 @@ static int set_oml_alert(struct ctrl_cmd *cmd, void *data) return CTRL_CMD_REPLY; } +static int verify_max_ber10k_rach(struct ctrl_cmd *cmd, const char *value, void *_data) +{ + int max_ber10k_rach = atoi(cmd->value); + + if (max_ber10k_rach < 0 || max_ber10k_rach > 10000) { + cmd->reply = "Value is out of range"; + return 1; + } + + return 0; +} + +static int get_max_ber10k_rach(struct ctrl_cmd *cmd, void *data) +{ + cmd->reply = talloc_asprintf(cmd, "%u", g_bts->max_ber10k_rach); + if (!cmd->reply) { + cmd->reply = "OOM"; + return CTRL_CMD_ERROR; + } + + return CTRL_CMD_REPLY; +} + +static int set_max_ber10k_rach(struct ctrl_cmd *cmd, void *data) +{ + g_bts->max_ber10k_rach = atoi(cmd->value); + cmd->reply = "OK"; + return CTRL_CMD_REPLY; +} + +CTRL_CMD_DEFINE(max_ber10k_rach, "max-ber10k-rach"); + int bts_ctrl_cmds_install(struct gsm_bts *bts) { int rc = 0; rc |= ctrl_cmd_install(CTRL_NODE_TRX, &cmd_therm_att); rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_oml_alert); + rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_max_ber10k_rach); g_bts = bts; return rc; diff --git a/src/common/bts_ctrl_lookup.c b/src/common/bts_ctrl_lookup.c index a3e3c8bc..2a5ff522 100644 --- a/src/common/bts_ctrl_lookup.c +++ b/src/common/bts_ctrl_lookup.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -88,14 +88,12 @@ err_index: return -ERANGE; } -struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, - const char *bind_addr, uint16_t port) +struct ctrl_handle *bts_controlif_setup(struct gsm_bts *bts, uint16_t port) { struct ctrl_handle *hdl; int rc = 0; - hdl = ctrl_interface_setup_dynip(bts, bind_addr, port, - bts_ctrl_node_lookup); + hdl = ctrl_interface_setup(bts, port, bts_ctrl_node_lookup); if (!hdl) return NULL; diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c index 0ac30789..13a0e1d0 100644 --- a/src/common/bts_shutdown_fsm.c +++ b/src/common/bts_shutdown_fsm.c @@ -1,6 +1,6 @@ /* BTS shutdown FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -29,6 +29,8 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/nm_common_fsm.h> #define X(s) (1 << (s)) @@ -58,6 +60,9 @@ static void st_none(struct osmo_fsm_inst *fi, uint32_t event, void *data) unsigned int count; switch(event) { case BTS_SHUTDOWN_EV_START: + /* Firt announce to NM objects that we are starting a shutdown procedure: */ + osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_START, NULL); + count = count_trx_operational(bts); if (count) { bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_RAMP_DOWN_COMPL); @@ -85,7 +90,10 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t llist_for_each_entry(trx, &bts->trx_list, list) { if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED) continue; - power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); + if (bts->shutdown_fi_skip_power_ramp) + power_ramp_force(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); + else + power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb); } } @@ -108,8 +116,15 @@ static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, vo LOGPFSML(fi, LOGL_INFO, "%s Ramping down complete, %u TRX remaining\n", gsm_trx_name(src_trx), remaining); - if (remaining == 0) + if (remaining == 0) { + /* Make sure we end up any remaining ongoing power ramp + * down under target shutdown tx power level, then + * finally transit to next state: + */ + llist_for_each_entry(trx, &bts->trx_list, list) + power_ramp_abort(trx); bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED); + } break; } } @@ -148,8 +163,15 @@ static void st_wait_trx_closed(struct osmo_fsm_inst *fi, uint32_t event, void *d static void st_exit_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { - LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfuly, exiting process\n"); - exit(0); + struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + + osmo_fsm_inst_dispatch(bts->site_mgr->mo.fi, NM_EV_SHUTDOWN_FINISH, NULL); + + if (bts->shutdown_fi_exit_proc) { + LOGPFSML(fi, LOGL_NOTICE, "Shutdown process completed successfully, exiting process\n"); + exit(0); + } + bts_shutdown_fsm_state_chg(fi, BTS_SHUTDOWN_ST_NONE); } static struct osmo_fsm_state bts_shutdown_fsm_states[] = { @@ -182,6 +204,8 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { }, [BTS_SHUTDOWN_ST_EXIT] = { .name = "EXIT", + .out_state_mask = + X(BTS_SHUTDOWN_ST_NONE), .onenter = st_exit_on_enter, } }; @@ -189,7 +213,7 @@ static struct osmo_fsm_state bts_shutdown_fsm_states[] = { const struct value_string bts_shutdown_fsm_event_names[] = { OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_START), OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_RAMP_COMPL), - OSMO_VALUE_STRING(BTS_SHUTDOWN_ST_WAIT_TRX_CLOSED), + OSMO_VALUE_STRING(BTS_SHUTDOWN_EV_TRX_CLOSED), { 0, NULL } }; @@ -224,18 +248,33 @@ static __attribute__((constructor)) void bts_shutdown_fsm_init(void) OSMO_ASSERT(osmo_fsm_register(&bts_shutdown_fsm) == 0); } -void bts_shutdown(struct gsm_bts *bts, const char *reason) +bool bts_shutdown_in_progress(const struct gsm_bts *bts) +{ + const struct osmo_fsm_inst *fi = bts->shutdown_fi; + return fi->state != BTS_SHUTDOWN_ST_NONE; +} + +void bts_shutdown_ext(struct gsm_bts *bts, const char *reason, bool exit_proc, bool skip_power_ramp) { struct osmo_fsm_inst *fi = bts->shutdown_fi; - if (fi->state != BTS_SHUTDOWN_ST_NONE) { + if (bts_shutdown_in_progress(bts)) { LOGPFSML(fi, LOGL_NOTICE, "BTS is already being shutdown.\n"); + if (exit_proc) + bts->shutdown_fi_exit_proc = true; return; } - - LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, reason: %s\n", reason); + bts->shutdown_fi_exit_proc = exit_proc; + bts->shutdown_fi_skip_power_ramp = skip_power_ramp; + LOGPFSML(fi, LOGL_NOTICE, "Shutting down BTS, exit %u, reason: %s\n", + exit_proc, reason); osmo_fsm_inst_dispatch(fi, BTS_SHUTDOWN_EV_START, NULL); } +void bts_shutdown(struct gsm_bts *bts, const char *reason) +{ + bts_shutdown_ext(bts, reason, true, true); +} + void bts_model_trx_close_cb(struct gsm_bts_trx *trx, int rc) { struct osmo_fsm_inst *fi = trx->bts->shutdown_fi; diff --git a/src/common/bts_sm.c b/src/common/bts_sm.c new file mode 100644 index 00000000..6e889b71 --- /dev/null +++ b/src/common/bts_sm.c @@ -0,0 +1,95 @@ +/* BTS support code common to all supported BTS models */ + +/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <osmocom/core/talloc.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/core/fsm.h> + +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/nm_common_fsm.h> + +struct gsm_bts_sm *g_bts_sm; + +static const uint8_t nse_timer_default[] = { 3, 3, 3, 3, 30, 3, 10 }; + +struct gsm_bts *gsm_gprs_nse_get_bts(const struct gsm_gprs_nse *nse) +{ + return gsm_bts_num(g_bts_sm, nse->mo.obj_inst.bts_nr); +} + +static int gsm_bts_sm_talloc_destructor(struct gsm_bts_sm *bts_sm) +{ + struct gsm_bts *bts; + + while ((bts = llist_first_entry_or_null(&bts_sm->bts_list, struct gsm_bts, list))) + talloc_free(bts); + + if (bts_sm->mo.fi) { + osmo_fsm_inst_free(bts_sm->mo.fi); + bts_sm->mo.fi = NULL; + } + + return 0; +} + +struct gsm_bts_sm *gsm_bts_sm_alloc(void *talloc_ctx) +{ + struct gsm_bts_sm *bts_sm = talloc_zero(talloc_ctx, struct gsm_bts_sm); + struct gsm_gprs_nse *nse = &bts_sm->gprs.nse; + unsigned int i; + + if (!bts_sm) + return NULL; + + talloc_set_destructor(bts_sm, gsm_bts_sm_talloc_destructor); + + INIT_LLIST_HEAD(&bts_sm->bts_list); + + /* NM SITE_MGR */ + bts_sm->mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts_sm, bts_sm, + LOGL_INFO, "bts_sm"); + gsm_mo_init(&bts_sm->mo, NULL, NM_OC_SITE_MANAGER, + 0xff, 0xff, 0xff); + oml_mo_state_init(&bts_sm->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + + /* NM GPRS NSE */ + nse->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nse_fsm, bts_sm, nse, + LOGL_INFO, "gprs_nse0"); + gsm_mo_init(&nse->mo, NULL, NM_OC_GPRS_NSE, 0, 0xff, 0xff); + oml_mo_state_init(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + memcpy(&nse->timer, nse_timer_default, sizeof(nse->timer)); + + /* NM GPRS NSVCs */ + for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) { + struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i]; + nsvc->nse = nse; + nsvc->id = i; + nsvc->mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nsvc_fsm, bts_sm, nsvc, + LOGL_INFO, NULL); + osmo_fsm_inst_update_id_f(nsvc->mo.fi, "gprs_nsvc%d-%d", + nse->mo.obj_inst.bts_nr, i); + gsm_mo_init(&nsvc->mo, NULL, NM_OC_GPRS_NSVC, nse->mo.obj_inst.bts_nr, i, 0xff); + oml_mo_state_init(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + } + + return bts_sm; +} diff --git a/src/common/bts_trx.c b/src/common/bts_trx.c index a5d7ed3d..251b6735 100644 --- a/src/common/bts_trx.c +++ b/src/common/bts_trx.c @@ -59,14 +59,7 @@ static void gsm_bts_trx_ts_init_lchan(struct gsm_bts_trx_ts *ts) for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { struct gsm_lchan *lchan = &ts->lchan[ln]; - - lchan->ts = ts; - lchan->nr = ln; - lchan->type = GSM_LCHAN_NONE; - gsm_lchan_name_update(lchan); - - INIT_LLIST_HEAD(&lchan->sapi_cmds); - INIT_LLIST_HEAD(&lchan->dl_tch_queue); + gsm_lchan_init(lchan, ts, ln); } } @@ -81,12 +74,17 @@ static void gsm_bts_trx_init_ts(struct gsm_bts_trx *trx) ts->trx = trx; ts->nr = tn; + ts->tsc_oml_configured = false; + ts->tsc_rsl_configured = false; + ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff; + ts->mo.fi = osmo_fsm_inst_alloc(&nm_chan_fsm, trx, ts, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(ts->mo.fi, "%s-ts%u", trx->bb_transc.mo.fi->id, ts->nr); gsm_mo_init(&ts->mo, trx->bts, NM_OC_CHANNEL, trx->bts->nr, trx->nr, ts->nr); + oml_mo_state_init(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); gsm_bts_trx_ts_init_lchan(ts); } @@ -106,6 +104,10 @@ void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx) ts->trx = trx; ts->nr = tn; + ts->tsc_oml_configured = false; + ts->tsc_rsl_configured = false; + ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff; + /* Link both primary and shadow */ trx->ts[tn].vamos.peer = ts; ts->vamos.peer = &trx->ts[tn]; @@ -119,6 +121,27 @@ void gsm_bts_trx_init_shadow_ts(struct gsm_bts_trx *trx) } } +void gsm_bts_trx_free_shadow_ts(struct gsm_bts_trx *trx) +{ + unsigned int tn; + unsigned int ln; + + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + struct gsm_bts_trx_ts *shadow_ts = trx->ts[tn].vamos.peer; + if (!shadow_ts) + continue; + + /* free lchan related mem allocated on the trx object: */ + for (ln = 0; ln < ARRAY_SIZE(shadow_ts->lchan); ln++) { + struct gsm_lchan *lchan = &shadow_ts->lchan[ln]; + TALLOC_FREE(lchan->name); + } + + talloc_free(shadow_ts); + trx->ts[tn].vamos.peer = NULL; + } +} + struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) { struct gsm_bts_trx *trx = talloc_zero(bts, struct gsm_bts_trx); @@ -134,14 +157,14 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts) trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr); - gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, - bts->nr, trx->nr, 0xff); + gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER, bts->nr, trx->nr, 0xff); + oml_mo_state_init(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr); - gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, - bts->nr, trx->nr, 0xff); + gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC, bts->nr, trx->nr, 0xff); + oml_mo_state_init(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); gsm_bts_trx_init_ts(trx); @@ -206,25 +229,22 @@ const char *gsm_trx_unit_id(struct gsm_bts_trx *trx) /* RSL link is established, send status report */ int trx_link_estab(struct gsm_bts_trx *trx) { - struct e1inp_sign_link *link = trx->rsl_link; int rc; - LOGPTRX(trx, DSUM, LOGL_INFO, "RSL link %s\n", - link ? "up" : "down"); + LOGPTRX(trx, DRSL, LOGL_INFO, "RSL link up\n"); - osmo_fsm_inst_dispatch(trx->mo.fi, link ? NM_EV_RSL_UP : NM_EV_RSL_DOWN, NULL); - osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, link ? NM_EV_RSL_UP : NM_EV_RSL_DOWN, NULL); + osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RSL_UP, NULL); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_UP, NULL); - if (link) + if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED || + trx->bb_transc.mo.nm_state.operational == NM_OPSTATE_ENABLED) { rc = rsl_tx_rf_res(trx); - else - rc = bts_model_trx_deact_rf(trx); - if (rc < 0) { - oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL, - link ? - "Failed to establish RSL link (%d)" : - "Failed to deactivate RF (%d)", rc); + if (rc < 0) + oml_tx_failure_event_rep(&trx->bb_transc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_RSL_FAIL, + "Failed to establish RSL link (%d)", rc); } + if (trx == trx->bts->c0) + load_timer_start(trx->bts); return 0; } diff --git a/src/common/cbch.c b/src/common/cbch.c index ebea60be..363eb672 100644 --- a/src/common/cbch.c +++ b/src/common/cbch.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -139,12 +139,8 @@ static int get_smscb_block(struct bts_smscb_state *bts_ss, uint8_t *out, uint8_t block_type->seq_nr = block_nr; /* determine if this is the last block */ - if (block_nr + 1 == msg->num_segs) - block_type->lb = 1; - else - block_type->lb = 0; - - if (block_nr == 4) { + block_type->lb = (block_nr + 1 == msg->num_segs); + if (block_type->lb) { if (msg != bts_ss->default_msg) { DEBUGPGT(DLSMS, g_time, "%s: deleting fully-transmitted message %p\n", chan_name, msg); @@ -198,7 +194,7 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ return -EINVAL; } - scm = talloc_zero_size(bts, sizeof(*scm)); + scm = talloc_zero(bts, struct smscb_msg); if (!scm) return -1; @@ -233,10 +229,10 @@ int bts_process_smscb_cmd(struct gsm_bts *bts, struct rsl_ie_cb_cmd_type cmd_typ rate_ctr_inc2(bts_ss->ctrs, CBCH_CTR_RCVD_QUEUED); break; case RSL_CB_CMD_TYPE_DEFAULT: - /* old default msg will be free'd in get_smscb_block() if it is currently in transit - * and we set a new default_msg here */ + /* clear the cur_msg pointer if it is the old default message */ if (bts_ss->cur_msg && bts_ss->cur_msg == bts_ss->default_msg) - talloc_free(bts_ss->cur_msg); + bts_ss->cur_msg = NULL; + talloc_free(bts_ss->default_msg); if (cmd_type.def_bcast == RSL_CB_CMD_DEFBCAST_NORMAL) /* def_bcast == 0: normal message */ bts_ss->default_msg = scm; @@ -322,3 +318,25 @@ int bts_cbch_get(struct gsm_bts *bts, uint8_t *outbuf, struct gsm_time *g_time) return rc; } + +static void bts_smscb_state_reset(struct bts_smscb_state *bts_ss) +{ + struct smscb_msg *scm, *tmp; + llist_for_each_entry_safe(scm, tmp, &bts_ss->queue, list) { + llist_del(&scm->list); + talloc_free(scm); + } + bts_ss->queue_len = 0; + rate_ctr_group_reset(bts_ss->ctrs); + /* avoid double-free of default_msg in case cur_msg == default_msg */ + if (bts_ss->cur_msg && bts_ss->cur_msg != bts_ss->default_msg) + talloc_free(bts_ss->cur_msg); + bts_ss->cur_msg = NULL; + TALLOC_FREE(bts_ss->default_msg); +} + +void bts_cbch_reset(struct gsm_bts *bts) +{ + bts_smscb_state_reset(&bts->smscb_basic); + bts_smscb_state_reset(&bts->smscb_extended); +} diff --git a/src/common/csd_v110.c b/src/common/csd_v110.c new file mode 100644 index 00000000..d6c00b03 --- /dev/null +++ b/src/common/csd_v110.c @@ -0,0 +1,188 @@ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> +#include <errno.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> +#include <osmocom/gsm/gsm44021.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/isdn/v110.h> + +#include <osmo-bts/csd_v110.h> +#include <osmo-bts/lchan.h> + +/* key is enum gsm48_chan_mode, so assuming a value in range 0..255 */ +const struct csd_v110_lchan_desc csd_v110_lchan_desc[256] = { +#if 0 + [GSM48_CMODE_DATA_14k5] = { + /* TCH/F14.4: 290 bits every 20 ms (14.5 kbit/s) */ + .fr = { .num_blocks = 1, .num_bits = 290 }, + }, +#endif + [GSM48_CMODE_DATA_12k0] = { + /* TCH/F9.6: 4 * 60 bits every 20 ms (12.0 kbit/s) */ + .fr = { .num_blocks = 4, .num_bits = 60 }, + }, + [GSM48_CMODE_DATA_6k0] = { + /* TCH/F4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */ + .fr = { .num_blocks = 2, .num_bits = 60 }, + /* TCH/H4.8: 4 * 60 bits every 40 ms (6.0 kbit/s) */ + .hr = { .num_blocks = 4, .num_bits = 60 }, + }, + [GSM48_CMODE_DATA_3k6] = { + /* TCH/F2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */ + .fr = { .num_blocks = 2, .num_bits = 36 }, + /* TCH/H2.4: 4 * 36 bits every 40 ms (3.6 kbit/s) */ + .hr = { .num_blocks = 4, .num_bits = 36 }, + }, +}; + +/* 3GPP TS 44.021, Figure 4: Coding of data rates (E1/E2/E3 bits) */ +static const uint8_t e1e2e3_map[_LCHAN_CSD_M_NUM][3] = { + [LCHAN_CSD_M_T_600] = { 1, 0, 0 }, + [LCHAN_CSD_M_T_1200] = { 0, 1, 0 }, + [LCHAN_CSD_M_T_2400] = { 1, 1, 0 }, + [LCHAN_CSD_M_T_4800] = { 0, 1, 1 }, + [LCHAN_CSD_M_T_9600] = { 0, 1, 1 }, +#if 0 + [LCHAN_CSD_M_T_19200] = { 0, 1, 1 }, + [LCHAN_CSD_M_T_38400] = { 0, 1, 1 }, + [LCHAN_CSD_M_T_14400] = { 1, 0, 1 }, + [LCHAN_CSD_M_T_28800] = { 1, 0, 1 }, +#endif +}; + +int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, + const uint8_t *data, size_t data_len) +{ + const struct csd_v110_frame_desc *desc; + ubit_t ra_bits[80 * 4]; + + OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc)); + if (lchan->type == GSM_LCHAN_TCH_F) + desc = &csd_v110_lchan_desc[lchan->tch_mode].fr; + else + desc = &csd_v110_lchan_desc[lchan->tch_mode].hr; + if (OSMO_UNLIKELY(desc->num_blocks == 0)) + return -ENOTSUP; + + /* handle empty/incomplete Uplink frames gracefully */ + if (OSMO_UNLIKELY(data_len < (desc->num_blocks * desc->num_bits))) { + /* encode N idle frames as per 3GPP TS 44.021, section 8.1.6 */ + memset(&ra_bits[0], 0x01, sizeof(ra_bits)); + for (unsigned int i = 0; i < desc->num_blocks; i++) + memset(&ra_bits[i * 80], 0x00, 8); /* alignment pattern */ + goto ra1_ra2; + } + + /* RA1'/RA1: convert from radio rate to an intermediate data rate */ + for (unsigned int i = 0; i < desc->num_blocks; i++) { + struct osmo_v110_decoded_frame df; + + /* convert a V.110 36-/60-bit frame to a V.110 80-bit frame */ + if (desc->num_bits == 60) + osmo_csd_12k_6k_decode_frame(&df, &data[i * 60], 60); + else /* desc->num_bits == 36 */ + osmo_csd_3k6_decode_frame(&df, &data[i * 36], 36); + + /* E1 .. E3 must set by out-of-band knowledge */ + if (lchan->csd_mode == LCHAN_CSD_M_NT) { + /* non-transparent: as per 3GPP TS 48.020, Table 7 */ + df.e_bits[0] = 0; /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */ + df.e_bits[1] = (i >> 1) & 0x01; /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */ + df.e_bits[2] = (i >> 0) & 0x01; /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */ + } else { + /* transparent: as per 3GPP TS 44.021, Figure 4 */ + df.e_bits[0] = e1e2e3_map[lchan->csd_mode][0]; /* E1 */ + df.e_bits[1] = e1e2e3_map[lchan->csd_mode][1]; /* E2 */ + df.e_bits[2] = e1e2e3_map[lchan->csd_mode][2]; /* E3 */ + } + + osmo_v110_encode_frame(&ra_bits[i * 80], 80, &df); + } + +ra1_ra2: + /* RA1/RA2: convert from an intermediate rate to 64 kbit/s */ + if (desc->num_blocks == 4) { + /* 4 * 80 bits (16 kbit/s) => 2 bits per octet */ + for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) { + rtp[i] = (0xff >> 2); + rtp[i] |= (ra_bits[j++] << 7); + rtp[i] |= (ra_bits[j++] << 6); + } + } else { + /* 2 * 80 bits (8 kbit/s) => 1 bit per octet */ + for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++) { + rtp[i] = (0xff >> 1); + rtp[i] |= (ra_bits[i] << 7); + } + } + + return RFC4040_RTP_PLEN; +} + +int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, + const uint8_t *rtp, size_t rtp_len) +{ + const struct csd_v110_frame_desc *desc; + ubit_t ra_bits[80 * 4]; + + OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc)); + if (lchan->type == GSM_LCHAN_TCH_F) + desc = &csd_v110_lchan_desc[lchan->tch_mode].fr; + else + desc = &csd_v110_lchan_desc[lchan->tch_mode].hr; + if (OSMO_UNLIKELY(desc->num_blocks == 0)) + return -ENOTSUP; + + if (OSMO_UNLIKELY(rtp_len != RFC4040_RTP_PLEN)) + return -EINVAL; + + /* RA1/RA2: convert from 64 kbit/s to an intermediate rate */ + if (desc->num_blocks == 4) { + /* 4 * 80 bits (16 kbit/s) => 2 bits per octet */ + for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) { + ra_bits[j++] = (rtp[i] >> 7); + ra_bits[j++] = (rtp[i] >> 6) & 0x01; + } + } else { + /* 2 * 80 bits (8 kbit/s) => 1 bit per octet */ + for (unsigned int i = 0; i < RFC4040_RTP_PLEN; i++) + ra_bits[i] = (rtp[i] >> 7); + } + + /* RA1'/RA1: convert from an intermediate rate to radio rate */ + for (unsigned int i = 0; i < desc->num_blocks; i++) { + struct osmo_v110_decoded_frame df; + + /* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */ + osmo_v110_decode_frame(&df, &ra_bits[i * 80], 80); + if (desc->num_bits == 60) + osmo_csd_12k_6k_encode_frame(&data[i * 60], 60, &df); + else /* desc->num_bits == 36 */ + osmo_csd_3k6_encode_frame(&data[i * 36], 36, &df); + } + + return desc->num_blocks * desc->num_bits; +} diff --git a/src/common/dtx_dl_amr_fsm.c b/src/common/dtx_dl_amr_fsm.c index 38e22c95..bbe1b0ad 100644 --- a/src/common/dtx_dl_amr_fsm.c +++ b/src/common/dtx_dl_amr_fsm.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/common/gsm_data.c b/src/common/gsm_data.c index 36a57115..dad5587b 100644 --- a/src/common/gsm_data.c +++ b/src/common/gsm_data.c @@ -40,6 +40,12 @@ #include <osmo-bts/bts_trx.h> #include <osmo-bts/logging.h> +struct osmo_tdef_group bts_tdef_groups[] = { + { .name = "bts", .tdefs = bts_T_defs, .desc = "BTS process timers" }, + { .name = "abis", .tdefs = abis_T_defs, .desc = "Abis (RSL) related timers" }, + {} +}; + const struct value_string gsm_pchant_names[13] = { { GSM_PCHAN_NONE, "NONE" }, { GSM_PCHAN_CCCH, "CCCH" }, @@ -84,22 +90,6 @@ const char *gsm_lchant_name(enum gsm_chan_t c) return get_value_string(gsm_chan_t_names, c); } -static const struct value_string lchan_s_names[] = { - { LCHAN_S_NONE, "NONE" }, - { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" }, - { LCHAN_S_ACTIVE, "ACTIVE" }, - { LCHAN_S_INACTIVE, "INACTIVE" }, - { LCHAN_S_REL_REQ, "RELEASE REQUESTED" }, - { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" }, - { LCHAN_S_BROKEN, "BROKEN UNUSABLE" }, - { 0, NULL } -}; - -const char *gsm_lchans_name(enum gsm_lchan_state s) -{ - return get_value_string(lchan_s_names, s); -} - static char ts2str[255]; char *gsm_ts_name(const struct gsm_bts_trx_ts *ts) @@ -157,172 +147,6 @@ char *gsm_ts_and_pchan_name(const struct gsm_bts_trx_ts *ts) return ts2str; } -void gsm_lchan_name_update(struct gsm_lchan *lchan) -{ - const struct gsm_bts_trx_ts *ts = lchan->ts; - const struct gsm_bts_trx *trx = ts->trx; - char *name; - - name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)", - GSM_TS_NAME_ARGS(ts), lchan->nr); - if (lchan->name != NULL) - talloc_free(lchan->name); - lchan->name = name; -} - -/* See Table 10.5.25 of GSM04.08 */ -static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan, - uint8_t ts_nr, uint8_t lchan_nr) -{ - uint8_t cbits, chan_nr; - - OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN); - OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH); - - switch (pchan) { - case GSM_PCHAN_TCH_F: - OSMO_ASSERT(lchan_nr == 0); - cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs; - break; - case GSM_PCHAN_PDCH: - OSMO_ASSERT(lchan_nr == 0); - cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH; - break; - case GSM_PCHAN_TCH_H: - OSMO_ASSERT(lchan_nr < 2); - cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr); - break; - case GSM_PCHAN_CCCH_SDCCH4: - case GSM_PCHAN_CCCH_SDCCH4_CBCH: - /* - * As a special hack for BCCH, lchan_nr == 4 may be passed - * here. This should never be sent in an RSL message. - * See osmo-bts-xxx/oml.c:opstart_compl(). - */ - if (lchan_nr == CCCH_LCHAN) - cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH; - else { - OSMO_ASSERT(lchan_nr < 4); - cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr); - } - break; - case GSM_PCHAN_SDCCH8_SACCH8C: - case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: - OSMO_ASSERT(lchan_nr < 8); - cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr); - break; - case GSM_PCHAN_CCCH: - cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH; - break; - case GSM_PCHAN_NONE: - LOGP(DRSL, LOGL_ERROR, "Physical channel %s not expected!\n", - gsm_pchan_name(pchan)); - cbits = 0x00; - break; - default: - LOGP(DRSL, LOGL_ERROR, "Physical channel %s (0x%02x) not expected!\n", - gsm_pchan_name(pchan), (int)pchan); - /* OSMO_ASSERT(lchan_nr == 0); - * FIXME: On octphy and litecell, we hit above assertion (see - * Max's comment at https://gerrit.osmocom.org/589 ); disabled - * for BTS until this is clarified; remove the #ifdef when it - * is fixed. Tracked in OS#2906. - */ -#pragma message "fix caller that passes lchan_nr != 0" - cbits = 0x10; - break; - } - - chan_nr = (cbits << 3) | (ts_nr & 0x7); - - return chan_nr; -} - -uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan) -{ - uint8_t chan_nr; - - switch (lchan->ts->pchan) { - case GSM_PCHAN_OSMO_DYN: - /* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the - * nonstandard value reflecting PDCH for Osmocom style dyn TS. */ - chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is); - break; - case GSM_PCHAN_TCH_F_PDCH: - /* For ip.access style dyn TS, we always want to use the chan_nr as if it was TCH/F. - * We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */ - chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F); - break; - default: - chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr); - break; - } - - /* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect - * this in the channel number. Convert it to Osmocom specific value. */ - if (lchan->ts->vamos.is_shadow) - chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK; - - return chan_nr; -} - -uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan, - enum gsm_phys_chan_config as_pchan) -{ - if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN - && as_pchan == GSM_PCHAN_PDCH) - return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK); - return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr); -} - -/* Called by the model specific code every 104 TDMA frames (SACCH period) */ -void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm) -{ - const uint8_t meas_num = lchan->meas.interf_meas_num; - - if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) { - LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room " - "to store interference report (%ddBm)\n", dbm); - return; - } - - lchan->meas.interf_meas_dbm[meas_num] = dbm; - lchan->meas.interf_meas_num++; -} - -/* Called by the higher layers every Intave * 104 TDMA frames */ -int gsm_lchan_interf_meas_calc_band(struct gsm_lchan *lchan) -{ - const uint8_t meas_num = lchan->meas.interf_meas_num; - const struct gsm_bts *bts = lchan->ts->trx->bts; - int b, meas_avg, meas_sum = 0; - - /* There must be at least one sample */ - if (meas_num == 0) - return -EAGAIN; - - /* Calculate the sum of all collected samples (in -x dBm) */ - while (lchan->meas.interf_meas_num) { - uint8_t i = --lchan->meas.interf_meas_num; - meas_sum += lchan->meas.interf_meas_dbm[i]; - } - - /* Calculate the average of all collected samples */ - meas_avg = meas_sum / (int) meas_num; - - /* Determine the band using interference boundaries from BSC */ - for (b = 0; b < ARRAY_SIZE(bts->interference.boundary); b++) { - if (meas_avg >= bts->interference.boundary[b]) - break; /* Current 'b' is the band value */ - } - - LOGPLCHAN(lchan, DL1C, LOGL_DEBUG, - "Interference AVG: %ddBm (band %d, samples %u)\n", - meas_avg, b, meas_num); - - return b; -} - /* determine logical channel based on TRX and channel number IE */ struct gsm_lchan *rsl_lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, int *rc) @@ -466,61 +290,59 @@ bool ts_is_tch(const struct gsm_bts_trx_ts *ts) return pchan_is_tch(ts_pchan(ts)); } -const struct value_string lchan_ciph_state_names[] = { - { LCHAN_CIPH_NONE, "NONE" }, - { LCHAN_CIPH_RX_REQ, "RX_REQ" }, - { LCHAN_CIPH_RX_CONF, "RX_CONF" }, - { LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" }, - { LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" }, - { LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" }, - { 0, NULL } -}; - -/* determine the ECU codec constant for the codec used by given lchan */ -int lchan2ecu_codec(const struct gsm_lchan *lchan) +bool ts_is_pdch(const struct gsm_bts_trx_ts *ts) { - const struct gsm_bts_trx_ts *ts = lchan->ts; - - switch (lchan->tch_mode) { - case GSM48_CMODE_SPEECH_V1: - if (ts_pchan(ts) == GSM_PCHAN_TCH_H) - return OSMO_ECU_CODEC_HR; - else - return OSMO_ECU_CODEC_FR; - break; - case GSM48_CMODE_SPEECH_EFR: - return OSMO_ECU_CODEC_EFR; - case GSM48_CMODE_SPEECH_AMR: - return OSMO_ECU_CODEC_AMR; + switch (ts->pchan) { + case GSM_PCHAN_PDCH: + return true; + case GSM_PCHAN_TCH_F_PDCH: + return (ts->flags & TS_F_PDCH_ACTIVE) + && !(ts->flags & TS_F_PDCH_PENDING_MASK); + case GSM_PCHAN_OSMO_DYN: + return ts->dyn.pchan_is == GSM_PCHAN_PDCH + && ts->dyn.pchan_want == ts->dyn.pchan_is; default: - return -1; + return false; } } -/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */ -const struct gsm_power_ctrl_params power_ctrl_params_def = { - /* Power increasing/reducing step size (optimal defaults) */ - .inc_step_size_db = 4, /* quickly increase MS/BS power */ - .red_step_size_db = 2, /* slowly decrease MS/BS power */ - - /* RxLev measurement parameters */ - .rxlev_meas = { - /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */ - .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */ - .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */ - - /* NOTE: only Osmocom specific EWMA is supported */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA, - .ewma.alpha = 50, /* Smoothing factor 50% */ - }, +/* Apply ts->tsc based on what was configured coming from different sources. + * Priorities (preferred first, overrides ones afterward): + * 1- RSL OSMO_TSC IE + * 2- OML SetChannelAttr TSC IE + * 3- OML SetBtsAttr BSIC IE + */ +void gsm_ts_apply_configured_tsc(struct gsm_bts_trx_ts *ts) +{ + if (ts->tsc_rsl_configured) { + ts->tsc = ts->tsc_rsl; + return; + } + if (ts->tsc_oml_configured) { + ts->tsc = ts->tsc_oml; + return; + } + if (ts->trx->bts->bsic_configured) { + ts->tsc = BTS_TSC(ts->trx->bts); + return; + } + ts->tsc = 0xff; /* invalid value */ +} - /* RxQual measurement parameters */ - .rxqual_meas = { - /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */ - .lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */ - .upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */ +void gsm_ts_release(struct gsm_bts_trx_ts *ts) +{ + unsigned int ln; - /* FIXME: RxQual averaging is not yet implemented */ - .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, - }, -}; + for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { + struct gsm_lchan *lchan = &ts->lchan[ln]; + gsm_lchan_release(lchan, LCHAN_REL_ACT_OML); + } + ts->pchan = GSM_PCHAN_NONE; + /* Make sure pchan_is is reset, since PCU act_req to release it will be + * ignored as the lchan will already be released. */ + ts->dyn.pchan_is = ts->dyn.pchan_want = GSM_PCHAN_NONE; + + ts->tsc_oml_configured = false; + ts->tsc_rsl_configured = false; + ts->tsc = ts->tsc_oml = ts->tsc_rsl = 0xff; +} diff --git a/src/common/handover.c b/src/common/handover.c index 888649db..4b2e6bec 100644 --- a/src/common/handover.c +++ b/src/common/handover.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -51,7 +51,7 @@ static int ho_tx_phys_info(struct gsm_lchan *lchan) gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh)); gh->proto_discr = GSM48_PDISC_RR; gh->msg_type = GSM48_MT_RR_HANDO_INFO; - msgb_put_u8(msg, lchan->rqd_ta); + msgb_put_u8(msg, lchan->ta_ctrl.current); rsl_rll_push_l3(msg, RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0); @@ -111,7 +111,7 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay) "TA=%u, ref=%u\n", gsm_lchant_name(lchan->type), acc_delay, ra); /* Set timing advance */ - lchan->rqd_ta = acc_delay; + lchan->ta_ctrl.current = acc_delay; lchan->want_dl_sacch_active = true; /* Stop handover detection, wait for valid frame */ @@ -123,7 +123,7 @@ void handover_rach(struct gsm_lchan *lchan, uint8_t ra, uint8_t acc_delay) } /* Send HANDover DETect to BSC */ - rsl_tx_hando_det(lchan, &lchan->rqd_ta); + rsl_tx_hando_det(lchan, &lchan->ta_ctrl.current); /* Send PHYS INFO */ lchan->ho.phys_info_count = 1; diff --git a/src/common/l1sap.c b/src/common/l1sap.c index c028a2c7..5f275cd8 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -33,11 +33,13 @@ #include <osmocom/gsm/l1sap.h> #include <osmocom/gsm/gsm_utils.h> #include <osmocom/gsm/rsl.h> -#include <osmocom/gsm/protocol/gsm_44_004.h> +#include <osmocom/gsm/rlp.h> #include <osmocom/core/gsmtap.h> #include <osmocom/core/gsmtap_util.h> #include <osmocom/core/utils.h> +#include <osmocom/codec/codec.h> + #include <osmocom/trau/osmo_ortp.h> #include <osmo-bts/logging.h> @@ -52,41 +54,17 @@ #include <osmo-bts/abis.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/handover.h> -#include <osmo-bts/power_control.h> #include <osmo-bts/msg_utils.h> +#include <osmo-bts/rtp_input_preen.h> #include <osmo-bts/pcuif_proto.h> #include <osmo-bts/cbch.h> - - -#define CB_FCCH -1 -#define CB_SCH -2 -#define CB_BCCH -3 -#define CB_IDLE -4 - -/* according to TS 05.02 Clause 7 Table 3 of 9 an Figure 8a */ -static const int ccch_block_table[51] = { - CB_FCCH, CB_SCH,/* 0..1 */ - CB_BCCH, CB_BCCH, CB_BCCH, CB_BCCH, /* 2..5: BCCH */ - 0, 0, 0, 0, /* 6..9: B0 */ - CB_FCCH, CB_SCH,/* 10..11 */ - 1, 1, 1, 1, /* 12..15: B1 */ - 2, 2, 2, 2, /* 16..19: B2 */ - CB_FCCH, CB_SCH,/* 20..21 */ - 3, 3, 3, 3, /* 22..25: B3 */ - 4, 4, 4, 4, /* 26..29: B4 */ - CB_FCCH, CB_SCH,/* 30..31 */ - 5, 5, 5, 5, /* 32..35: B5 */ - 6, 6, 6, 6, /* 36..39: B6 */ - CB_FCCH, CB_SCH,/* 40..41 */ - 7, 7, 7, 7, /* 42..45: B7 */ - 8, 8, 8, 8, /* 46..49: B8 */ - -4 /* 50: Idle */ -}; +#include <osmo-bts/asci.h> +#include <osmo-bts/csd_v110.h> /* determine the CCCH block number based on the frame number */ unsigned int l1sap_fn2ccch_block(uint32_t fn) { - int rc = ccch_block_table[fn%51]; + int rc = gsm0502_fn2ccch_block(fn); /* if FN is negative, we were called for something that's not CCCH! */ OSMO_ASSERT(rc >= 0); return rc; @@ -154,27 +132,13 @@ static uint32_t fn_ms_adj(uint32_t fn, const struct gsm_lchan *lchan) return GSM_RTP_DURATION; } -/*! limit number of queue entries to %u; drops any surplus messages */ -static void queue_limit_to(const char *prefix, struct llist_head *queue, unsigned int limit) -{ - unsigned int count = llist_count(queue); - - if (count > limit) - LOGP(DL1P, LOGL_NOTICE, "%s: freeing %d queued frames\n", prefix, count-limit); - while (count > limit) { - struct msgb *tmp = msgb_dequeue(queue); - msgb_free(tmp); - count--; - } -} - /* allocate a msgb containing a osmo_phsap_prim + optional l2 data * in order to wrap femtobts header around l2 data, there must be enough space * in front and behind data pointer */ struct msgb *l1sap_msgb_alloc(unsigned int l2_len) { - int headroom = 128; - int size = headroom + sizeof(struct osmo_phsap_prim) + l2_len; + const int headroom = L1SAP_MSGB_HEADROOM; + const int size = headroom + sizeof(struct osmo_phsap_prim) + l2_len; struct msgb *msg = msgb_alloc_headroom(size, headroom, "l1sap_prim"); if (!msg) @@ -365,7 +329,7 @@ static int gsmtap_ph_data(const struct osmo_phsap_prim *l1sap, uint8_t chan_nr, link_id; *data = msgb_l2(msg); - *len = msgb_l2len(msg); + *len = msgb_l2(msg) ? msgb_l2len(msg) : 0; chan_nr = l1sap->u.data.chan_nr; link_id = l1sap->u.data.link_id; @@ -407,7 +371,7 @@ static int gsmtap_pdch(const struct osmo_phsap_prim *l1sap, struct msgb *msg = l1sap->oph.msg; *data = msgb_l2(msg); - *len = msgb_l2len(msg); + *len = msgb_l2(msg) ? msgb_l2len(msg) : 0; if (L1SAP_IS_PTCCH(fn)) { *chan_type = GSMTAP_CHANNEL_PTCCH; @@ -474,6 +438,9 @@ static bool is_fill_frame(uint8_t chan_type, const uint8_t *data, unsigned int l switch (chan_type) { case GSMTAP_CHANNEL_AGCH: + case GSMTAP_CHANNEL_SDCCH: + case GSMTAP_CHANNEL_TCH_F: + case GSMTAP_CHANNEL_TCH_H: if (!memcmp(data, fill_frame, GSM_MACBLOCK_LEN)) return true; break; @@ -481,6 +448,7 @@ static bool is_fill_frame(uint8_t chan_type, const uint8_t *data, unsigned int l if (!memcmp(data, paging_fill, GSM_MACBLOCK_LEN)) return true; break; + /* FIXME: implement the same for GSMTAP_CHANNEL_PDTCH from/to PCU */ /* don't use 'default' case here as the above only conditionally return true */ } return false; @@ -588,6 +556,34 @@ static unsigned int calc_exprd_rach_frames(struct gsm_bts *bts, uint32_t fn) return rach_frames_expired; } +static void l1sap_interf_meas_calc_avg(struct gsm_bts_trx *trx) +{ + unsigned int tn, ln; + + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (ts->mo.nm_state.availability != NM_AVSTATE_OK) + continue; + + for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { + struct gsm_lchan *lchan = &ts->lchan[ln]; + + lchan->meas.interf_meas_avg_dbm = 0; + lchan->meas.interf_band = 0; + + /* There must be at least one sample */ + if (lchan->meas.interf_meas_num == 0) + continue; + + /* Average all collected samples */ + gsm_lchan_interf_meas_calc_avg(lchan); + } + } +} + static void l1sap_interf_meas_report(struct gsm_bts *bts) { const uint32_t period = bts->interference.intave * 104; @@ -598,8 +594,17 @@ static void l1sap_interf_meas_report(struct gsm_bts *bts) if (bts->gsm_time.fn % period != 0) return; - llist_for_each_entry(trx, &bts->trx_list, list) + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED || + trx->bb_transc.mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + /* Calculate the average of all received samples */ + l1sap_interf_meas_calc_avg(trx); + /* Report to the BSC over the A-bis/RSL */ rsl_tx_rf_res(trx); + /* Report to the PCU over the PCUIF */ + pcu_tx_interf_ind(trx, bts->gsm_time.fn); + } } /* time information received from bts model */ @@ -635,7 +640,8 @@ static int l1sap_info_time_ind(struct gsm_bts *bts, } /* Report interference levels to the BSC */ - l1sap_interf_meas_report(bts); + if (bts_internal_flag_get(bts, BTS_INTERNAL_FLAG_INTERF_MEAS)) + l1sap_interf_meas_report(bts); return 0; } @@ -660,90 +666,81 @@ static inline void set_ms_to_data(struct gsm_lchan *lchan, int16_t data, bool se } } +bool trx_sched_is_sacch_fn(const struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink); + /* measurement information received from bts model */ -static void process_l1sap_meas_data(struct gsm_bts_trx *trx, - struct osmo_phsap_prim *l1sap, +static void process_l1sap_meas_data(struct gsm_lchan *lchan, + const struct osmo_phsap_prim *l1sap, enum osmo_ph_prim ind_type) { struct bts_ul_meas ulm; - struct gsm_lchan *lchan; - struct info_meas_ind_param *info_meas_ind; - struct ph_data_param *ph_data_ind; - struct ph_tch_param *ph_tch_ind; - uint8_t chan_nr; + const struct info_meas_ind_param *info_meas_ind; + const struct ph_data_param *ph_data_ind; + const struct ph_tch_param *ph_tch_ind; uint32_t fn; - uint8_t inv_rssi; - uint8_t is_sub; - int16_t ta_offs_256bits; - uint16_t ber10k; const char *ind_name; + /* Do not process measurement reports from non-active VGCS calls. */ + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt) && lchan->asci.talker_active != VGCS_TALKER_ACTIVE) + return; + switch (ind_type) { case PRIM_MPH_INFO: /* (legacy way, see also OS#2977) */ info_meas_ind = &l1sap->u.info.u.meas_ind; - chan_nr = info_meas_ind->chan_nr; fn = info_meas_ind->fn; - inv_rssi = info_meas_ind->inv_rssi; - is_sub = info_meas_ind->is_sub; - ta_offs_256bits = info_meas_ind->ta_offs_256bits; - ber10k = info_meas_ind->ber10k; ind_name = "MPH INFO"; + ulm = (struct bts_ul_meas) { + .ta_offs_256bits = info_meas_ind->ta_offs_256bits, + .inv_rssi = info_meas_ind->inv_rssi, + .ber10k = info_meas_ind->ber10k, + .ci_cb = info_meas_ind->c_i_cb, + }; + /* additionally treat SACCH frames (match by TDMA FN) as SUB frames */ + if (info_meas_ind->is_sub || trx_sched_is_sacch_fn(lchan->ts, fn, true)) + ulm.is_sub = 1; break; case PRIM_TCH: ph_tch_ind = &l1sap->u.tch; if (ph_tch_ind->rssi == 0) return; - chan_nr = ph_tch_ind->chan_nr; fn = ph_tch_ind->fn; - inv_rssi = abs(ph_tch_ind->rssi); - is_sub = ph_tch_ind->is_sub; - ta_offs_256bits = ph_tch_ind->ta_offs_256bits; - ber10k = ph_tch_ind->ber10k; ind_name = "TCH"; + ulm = (struct bts_ul_meas) { + .ta_offs_256bits = ph_tch_ind->ta_offs_256bits, + .inv_rssi = abs(ph_tch_ind->rssi), + .ber10k = ph_tch_ind->ber10k, + .ci_cb = ph_tch_ind->lqual_cb, + .is_sub = ph_tch_ind->is_sub, + }; + /* PRIM_TCH always carries DCCH, not SACCH */ break; case PRIM_PH_DATA: ph_data_ind = &l1sap->u.data; if (ph_data_ind->rssi == 0) return; - chan_nr = ph_data_ind->chan_nr; fn = ph_data_ind->fn; - inv_rssi = abs(ph_data_ind->rssi); - is_sub = ph_data_ind->is_sub; - ta_offs_256bits = ph_data_ind->ta_offs_256bits; - ber10k = ph_data_ind->ber10k; ind_name = "DATA"; + ulm = (struct bts_ul_meas) { + .ta_offs_256bits = ph_data_ind->ta_offs_256bits, + .inv_rssi = abs(ph_data_ind->rssi), + .ber10k = ph_data_ind->ber10k, + .ci_cb = ph_data_ind->lqual_cb, + }; + /* additionally treat SACCH frames (match by RSL link ID) as SUB frames */ + if (ph_data_ind->is_sub || L1SAP_IS_LINK_SACCH(ph_data_ind->link_id)) + ulm.is_sub = 1; break; default: OSMO_ASSERT(false); } - lchan = get_active_lchan_by_chan_nr(trx, chan_nr); - if (!lchan) { - LOGPFN(DL1P, LOGL_ERROR, fn, - "No lchan for %s MEAS IND (chan_nr=%s)\n", - ind_name, rsl_chan_nr_str(chan_nr)); - return; - } - - DEBUGPFN(DL1P, fn, - "%s %s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u\n", - gsm_lchan_name(lchan), ind_name, ta_offs_256bits, ber10k, - inv_rssi); - - /* in the GPRS case we are not interested in measurement - * processing. The PCU will take care of it */ - if (lchan->type == GSM_LCHAN_PDTCH) - return; - - memset(&ulm, 0, sizeof(ulm)); - ulm.ta_offs_256bits = ta_offs_256bits; - ulm.ber10k = ber10k; - ulm.inv_rssi = inv_rssi; - ulm.is_sub = is_sub; + LOGPLCFN(lchan, fn, DL1P, LOGL_DEBUG, + "%s meas ind, ta_offs_256bits=%d, ber10k=%d, inv_rssi=%u, C/I=%d cB\n", ind_name, + ulm.ta_offs_256bits, ulm.ber10k, ulm.inv_rssi, ulm.ci_cb); /* we assume that symbol period is 1 bit: */ - set_ms_to_data(lchan, ta_offs_256bits / 256, true); + set_ms_to_data(lchan, ulm.ta_offs_256bits / 256, true); lchan_meas_process_measurement(lchan, &ulm, fn); @@ -754,6 +751,8 @@ static void process_l1sap_meas_data(struct gsm_bts_trx *trx, static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct mph_info_param *info) { + const struct info_meas_ind_param *meas_ind; + struct gsm_lchan *lchan; int rc = 0; switch (info->type) { @@ -773,7 +772,17 @@ static int l1sap_mph_info_ind(struct gsm_bts_trx *trx, if (bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB)) OSMO_ASSERT(false); - process_l1sap_meas_data(trx, l1sap, PRIM_MPH_INFO); + meas_ind = &l1sap->u.info.u.meas_ind; + + lchan = get_active_lchan_by_chan_nr(trx, meas_ind->chan_nr); + if (!lchan) { + LOGPFN(DL1P, LOGL_ERROR, meas_ind->fn, + "No lchan for chan_nr=%s\n", + rsl_chan_nr_str(meas_ind->chan_nr)); + return 0; + } + + process_l1sap_meas_data(lchan, l1sap, PRIM_MPH_INFO); break; default: LOGP(DL1P, LOGL_NOTICE, "unknown MPH_INFO ind type %d\n", @@ -878,16 +887,15 @@ static int lchan_pdtch_ph_rts_ind_loop(struct gsm_lchan *lchan, uint8_t *p; /* de-queue response message (loopback) */ - loop_msg = msgb_dequeue(&lchan->dl_tch_queue); + loop_msg = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len); if (!loop_msg) { - LOGPGT(DL1P, LOGL_NOTICE, tm, "%s: no looped PDTCH message, sending empty\n", - gsm_lchan_name(lchan)); + LOGPLCGT(lchan, tm, DL1P, LOGL_NOTICE, "no looped PDTCH message, sending empty\n"); /* empty downlink message */ p = msgb_put(msg, GSM_MACBLOCK_LEN); memset(p, 0, GSM_MACBLOCK_LEN); } else { - LOGPGT(DL1P, LOGL_NOTICE, tm, "%s: looped PDTCH message of %u bytes\n", - gsm_lchan_name(lchan), msgb_l2len(loop_msg)); + LOGPLCGT(lchan, tm, DL1P, LOGL_NOTICE, "looped PDTCH message of %u bytes\n", + msgb_l2len(loop_msg)); /* copy over data from queued response message */ p = msgb_put(msg, msgb_l2len(loop_msg)); memcpy(p, msgb_l2(loop_msg), msgb_l2len(loop_msg)); @@ -896,15 +904,32 @@ static int lchan_pdtch_ph_rts_ind_loop(struct gsm_lchan *lchan, return 0; } -/* Check if given CCCH frame number is for a PCH or for an AGCH (this function is +/* Check if given CCCH frame number is for a NCH, PCH or for an AGCH (this function is * only used internally, it is public to call it from unit-tests) */ -int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn) { +enum ccch_msgt get_ccch_msgt(struct gsm_bts_trx *trx, uint32_t fn) +{ + uint8_t block, first_block, num_blocks; + int rc; + + block = l1sap_fn2ccch_block(fn); + + /* If there is an NCH, check if the block number matches. It has priority over PCH/AGCH. */ + if (trx->bts->asci.pos_nch >= 0) { + rc = osmo_gsm48_si1ro_nch_pos_decode(trx->bts->asci.pos_nch, &num_blocks, &first_block); + if (rc >= 0 && block >= first_block && block < first_block + num_blocks) + return CCCH_MSGT_NCH; + } + /* Note: The number of available access grant channels is set by the * parameter BS_AG_BLKS_RES via system information type 3. This SI is * transferred to osmo-bts via RSL */ - return l1sap_fn2ccch_block(fn) < num_agch(trx, "PH-RTS-IND"); + if (l1sap_fn2ccch_block(fn) < num_agch(trx, "PH-RTS-IND")) + return CCCH_MSGT_AGCH; + + return CCCH_MSGT_PCH; } + /* return the measured average of frame numbers that the RTS clock is running in advance */ int32_t bts_get_avg_fn_advance(const struct gsm_bts *bts) { @@ -933,10 +958,10 @@ static void l1sap_update_fnstats(struct gsm_bts *bts, uint32_t rts_fn) } /* Common dequeueing function */ -static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le) +static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le, uint32_t fn) { struct osmo_phsap_prim pp; - if (lapdm_phsap_dequeue_prim(le, &pp) < 0) + if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0) return NULL; return pp.oph.msg; } @@ -949,17 +974,17 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan /* Note: The repeated version of the FACCH block must be scheduled 8 or 9 bursts after the original * transmission. see 3GPP TS 44.006, section 10.2 for a more detailed explaination. */ - if (lchan->tch.rep_facch[0].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[0].fn) >= 8) { + if (lchan->rep_acch.dl_facch[0].msg && GSM_TDMA_FN_SUB(fn, lchan->rep_acch.dl_facch[0].fn) >= 8) { /* Re-use stored FACCH message buffer from SLOT #0 for repetition. */ - msg = lchan->tch.rep_facch[0].msg; - lchan->tch.rep_facch[0].msg = NULL; - } else if (lchan->tch.rep_facch[1].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[1].fn) >= 8) { + msg = lchan->rep_acch.dl_facch[0].msg; + lchan->rep_acch.dl_facch[0].msg = NULL; + } else if (lchan->rep_acch.dl_facch[1].msg && GSM_TDMA_FN_SUB(fn, lchan->rep_acch.dl_facch[1].fn) >= 8) { /* Re-use stored FACCH message buffer from SLOT #1 for repetition. */ - msg = lchan->tch.rep_facch[1].msg; - lchan->tch.rep_facch[1].msg = NULL; + msg = lchan->rep_acch.dl_facch[1].msg; + lchan->rep_acch.dl_facch[1].msg = NULL; } else { /* Fetch new FACCH from queue ... */ - if (lapdm_phsap_dequeue_prim(le, &pp) < 0) + if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0) return NULL; msg = pp.oph.msg; @@ -968,16 +993,16 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan * If the MS explicitly indicated that repeated ACCH is * supported, than all FACCH frames may be repeated * see also: 3GPP TS 44.006, section 10.3). */ - if (!(lchan->repeated_acch_capability.dl_facch_all || msg->data[0] & 0x02)) + if (!(lchan->rep_acch_cap.dl_facch_all || msg->data[0] & 0x02)) return msg; /* ... and store the message buffer for repetition. */ - if (lchan->tch.rep_facch[0].msg == NULL) { - lchan->tch.rep_facch[0].msg = msgb_copy(msg, "rep_facch_0"); - lchan->tch.rep_facch[0].fn = fn; - } else if (lchan->tch.rep_facch[1].msg == NULL) { - lchan->tch.rep_facch[1].msg = msgb_copy(msg, "rep_facch_1"); - lchan->tch.rep_facch[1].fn = fn; + if (lchan->rep_acch.dl_facch[0].msg == NULL) { + lchan->rep_acch.dl_facch[0].msg = msgb_copy(msg, "rep_facch_0"); + lchan->rep_acch.dl_facch[0].fn = fn; + } else if (lchan->rep_acch.dl_facch[1].msg == NULL) { + lchan->rep_acch.dl_facch[1].msg = msgb_copy(msg, "rep_facch_1"); + lchan->rep_acch.dl_facch[1].fn = fn; } else { /* By definition 3GPP TS 05.02 does not allow more than two (for TCH/H only one) FACCH blocks * to be transmitted simultaniously. */ @@ -988,82 +1013,8 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan return msg; } -/* Decide if repeated FACCH should be applied or not. If RXQUAL level, that the - * MS reports is high enough, FACCH repetition is not needed. */ -void repeated_dl_facch_active_decision(struct gsm_lchan *lchan, const uint8_t *l3, - size_t l3_len) -{ - const struct gsm48_meas_res *meas_res; - uint8_t upper; - uint8_t lower; - uint8_t rxqual; - bool prev_repeated_dl_facch_active = lchan->repeated_dl_facch_active; - - /* This is an optimization so that we exit as quickly as possible if - * there are no FACCH repetition capabilities present. However If the - * repeated FACCH capabilities vanish for whatever reason, we must be - * sure that FACCH repetition is disabled. */ - if (!lchan->repeated_acch_capability.dl_facch_cmd - && !lchan->repeated_acch_capability.dl_facch_all) { - lchan->repeated_dl_facch_active = false; - goto out; - } - - /* Threshold disabled (always on) */ - if (lchan->repeated_acch_capability.rxqual == 0) { - lchan->repeated_dl_facch_active = true; - goto out; - } - - /* When the MS sets the SRR bit in the UL-SACCH L1 header - * (repeated SACCH requested) then it makes sense to enable - * FACCH repetition too. */ - if (lchan->meas.l1_info.srr_sro) { - lchan->repeated_dl_facch_active = true; - goto out; - } - - /* Parse MS measurement results */ - if (l3_len <= sizeof(struct gsm48_meas_res *) + 2) - goto out; - if (l3[0] != GSM48_PDISC_RR) - goto out; - if (l3[1] != GSM48_MT_RR_MEAS_REP) - goto out; - l3 += 2; - meas_res = (struct gsm48_meas_res *)l3; - - /* If the RXQUAL level at the MS drops under a certain threshold - * we enable FACCH repetition. */ - upper = lchan->repeated_acch_capability.rxqual; - if (upper > 2) - lower = lchan->repeated_acch_capability.rxqual - 2; - else - lower = 0; - - /* When downlink DTX is applied, use RXQUAL-SUB, otherwise use - * RXQUAL-FULL. */ - if (meas_res->dtx_used) - rxqual = meas_res->rxqual_sub; - else - rxqual = meas_res->rxqual_full; - - if (rxqual >= upper) - lchan->repeated_dl_facch_active = true; - else if (rxqual <= lower) - lchan->repeated_dl_facch_active = false; - -out: - if (lchan->repeated_dl_facch_active == prev_repeated_dl_facch_active) - return; - if (lchan->repeated_dl_facch_active) - LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: inactive => active\n"); - else - LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: active => inactive\n"); -} - /* Special dequeueing function with SACCH repetition (3GPP TS 44.006, section 11) */ -static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan, struct lapdm_entity *le) +static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan, struct lapdm_entity *le, uint32_t fn) { struct osmo_phsap_prim pp; struct msgb *msg; @@ -1073,21 +1024,21 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan * possible candidates in order to have one ready in case the MS enables * SACCH repetition. */ - if (lchan->rep_sacch) { + if (lchan->rep_acch.dl_sacch_msg) { if (lchan->meas.l1_info.srr_sro == 0) { /* Toss previous repetition candidate */ - msgb_free(lchan->rep_sacch); - lchan->rep_sacch = NULL; + msgb_free(lchan->rep_acch.dl_sacch_msg); + lchan->rep_acch.dl_sacch_msg = NULL; } else { /* Use previous repetition candidate */ - msg = lchan->rep_sacch; - lchan->rep_sacch = NULL; + msg = lchan->rep_acch.dl_sacch_msg; + lchan->rep_acch.dl_sacch_msg = NULL; return msg; } } /* Fetch new repetition candidate from queue */ - if (lapdm_phsap_dequeue_prim(le, &pp) < 0) + if (lapdm_phsap_dequeue_prim_fn(le, &pp, fn) < 0) return NULL; msg = pp.oph.msg; sapi = (msg->data[0] >> 2) & 0x07; @@ -1095,7 +1046,7 @@ static inline struct msgb *lapdm_phsap_dequeue_msg_sacch(struct gsm_lchan *lchan /* Only LAPDm frames for SAPI 0 may become a repetition * candidate. */ if (sapi == 0) - lchan->rep_sacch = msgb_copy(msg, "rep_sacch"); + lchan->rep_acch.dl_sacch_msg = msgb_copy(msg, "rep_sacch"); return msg; } @@ -1116,7 +1067,6 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, struct msgb *pp_msg; bool dtxd_facch = false; int rc; - int is_ag_res; chan_nr = rts_ind->chan_nr; link_id = rts_ind->link_id; @@ -1175,37 +1125,43 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, rsl_chan_nr_str(chan_nr)); return 0; } + if (lchan->pending_rel_ind_msg) { + LOGPLCGT(lchan, &g_time, DRSL, LOGL_INFO, "Forward RLL RELease INDication to the BSC\n"); + abis_bts_rsl_sendmsg(lchan->pending_rel_ind_msg); + lchan->pending_rel_ind_msg = NULL; + } if (L1SAP_IS_LINK_SACCH(link_id)) { p = msgb_put(msg, GSM_MACBLOCK_LEN); /* L1-header, if not set/modified by layer 1 */ p[0] = lchan->ms_power_ctrl.current; - if (lchan->repeated_ul_sacch_active) + if (lchan->rep_acch.ul_sacch_active) p[0] |= 0x40; /* See also: 3GPP TS 44.004, section 7.1 */ - p[1] = lchan->rqd_ta; + p[1] = lchan->ta_ctrl.current; le = &lchan->lapdm_ch.lapdm_acch; - if (lchan->repeated_acch_capability.dl_sacch) { + if (lchan->rep_acch_cap.dl_sacch) { /* Check if MS requests SACCH repetition and update state accordingly */ if (lchan->meas.l1_info.srr_sro) { - if (lchan->repeated_dl_sacch_active == false) + if (lchan->rep_acch.dl_sacch_active == false) LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-SACCH repetition: inactive => active\n"); - lchan->repeated_dl_sacch_active = true; + lchan->rep_acch.dl_sacch_active = true; } else { - if (lchan->repeated_dl_sacch_active == true) + if (lchan->rep_acch.dl_sacch_active == true) LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-SACCH repetition: active => inactive\n"); - lchan->repeated_dl_sacch_active = false; + lchan->rep_acch.dl_sacch_active = false; } - pp_msg = lapdm_phsap_dequeue_msg_sacch(lchan, le); + pp_msg = lapdm_phsap_dequeue_msg_sacch(lchan, le, fn); } else { - pp_msg = lapdm_phsap_dequeue_msg(le); + pp_msg = lapdm_phsap_dequeue_msg(le, fn); } } else { if (lchan->ts->trx->bts->dtxd) dtxd_facch = true; le = &lchan->lapdm_ch.lapdm_dcch; - if (lchan->repeated_dl_facch_active && lchan->rsl_cmode != RSL_CMOD_SPD_SIGN) + if (lchan->rep_acch.dl_facch_active && lchan->rsl_cmode != RSL_CMOD_SPD_SIGN) pp_msg = lapdm_phsap_dequeue_msg_facch(lchan, le, fn); else - pp_msg = lapdm_phsap_dequeue_msg(le); + pp_msg = lapdm_phsap_dequeue_msg(le, fn); + lchan->tch.dtx_fr_hr_efr.dl_facch_stealing = (pp_msg != NULL); } if (!pp_msg) { if (L1SAP_IS_LINK_SACCH(link_id)) { @@ -1216,6 +1172,10 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, memcpy(p + 2, si, GSM_MACBLOCK_LEN - 2); } else memcpy(p + 2, fill_frame, GSM_MACBLOCK_LEN - 2); + } else if (vgcs_is_uplink_free(lchan)) { + /* If UPLINK FREE message is stored, send it with every DCCH frame. */ + p = msgb_put(msg, GSM_MACBLOCK_LEN); + vgcs_uplink_free_get(lchan, p); } else if (L1SAP_IS_CHAN_SDCCH4(chan_nr) || L1SAP_IS_CHAN_SDCCH8(chan_nr) || (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN && !lchan->ts->trx->bts->dtxd)) { /* @@ -1240,13 +1200,20 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, check_for_ciph_cmd(pp_msg, lchan, chan_nr); if (dtxd_facch) dtx_dispatch(lchan, E_FACCH); + if (rsl_chan_rt_is_vgcs(lchan->rsl_chan_rt)) { + /* Check for UPLINK FREE message and store. */ + if (pp_msg->data[0] == GSM48_MT_RR_SH_UL_FREE << 2) + vgcs_uplink_free_set(lchan, pp_msg->data); + /* Keep UPLINK FREE message when sending short header messages. */ + else if ((pp_msg->data[0] & 0x03) != 0x00) + vgcs_uplink_free_reset(lchan); + } } msgb_free(pp_msg); } } else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) { p = msgb_put(msg, GSM_MACBLOCK_LEN); - is_ag_res = is_ccch_for_agch(trx, fn); - rc = bts_ccch_copy_msg(trx->bts, p, &g_time, is_ag_res); + rc = bts_ccch_copy_msg(trx->bts, p, &g_time, get_ccch_msgt(trx, fn)); if (rc <= 0) memcpy(p, fill_frame, GSM_MACBLOCK_LEN); } @@ -1259,45 +1226,267 @@ static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx, return 1; } -static bool rtppayload_is_octet_aligned(const uint8_t *rtp_pl, uint8_t payload_len) -{ - /* - * Logic: If 1st bit padding is not zero, packet is either: - * - bandwidth-efficient AMR payload. - * - malformed packet. - * However, Bandwidth-efficient AMR 4,75 frame last in payload(F=0, FT=0) - * with 4th,5ht,6th AMR payload to 0 matches padding==0. - * Furthermore, both AMR 4,75 bw-efficient and octet alignment are 14 bytes long (AMR 4,75 encodes 95b): - * bw-efficient: 95b, + 4b hdr + 6b ToC = 105b, + padding = 112b = 14B. - * octet-aligned: 1B hdr + 1B ToC + 95b = 111b, + padding = 112b = 14B. - * We cannot use other fields to match since they are inside the AMR - * payload bits which are unknown. - * As a result, this function may return false positive (true) for some AMR - * 4,75 AMR frames, but given the length, CMR and FT read is the same as a - * consequence, the damage in here is harmless other than being unable to - * decode the audio at the other side. - */ - #define AMR_PADDING1(rtp_pl) (rtp_pl[0] & 0x0f) - #define AMR_PADDING2(rtp_pl) (rtp_pl[1] & 0x03) +/* The following static functions are helpers for l1sap_tch_rts_ind(), + * used only for FR/HR/EFR speech modes. For these speech TCH modes, + * if our incoming RTP stream includes SID frames, we need to apply + * the following transformations to the downlink frame stream we actually + * transmit: + * + * - We need to cache the last received SID and retransmit it in + * SACCH-aligned frame positions, or if the SACCH-aligned frame + * position was stolen by FACCH, then right after that FACCH. + * + * - That cached SID needs to be aged and expired, in accord with + * TS 28.062 section C.3.2.1.1 paragraph 5 - the paragraph concerning + * expiration of cached downlink SID. + * + * - In all other frame positions, extraneous SID frames need to be + * dropped - we send an empty payload to the BTS model, causing it + * to transmit an induced BFI condition on the air (fake DTXd), + * or perhaps real DTXd (actually turning off Tx) in the future. + */ - if(payload_len < 2 || AMR_PADDING1(rtp_pl) || AMR_PADDING2(rtp_pl)) +/*! \brief Check if the given FN of TCH-RTS-IND corresponds to a mandatory + * SID position for non-AMR codecs that follow SACCH alignment. + * \param[in] lchan Logical channel on which we check scheduling + * \param[in] fn Frame Number for which we check scheduling + * \returns true if this FN is a mandatory SID position, false otherwise + */ +static inline bool fr_hr_efr_sid_position(struct gsm_lchan *lchan, uint32_t fn) +{ + /* See GSM 05.08 section 8.3 for frame numbers - but we are + * specifically looking for FNs corresponding to the beginning + * of the complete SID frame to be transmitted, rather than all FNs + * where we have to put out a non-suppressed burst. */ + switch (lchan->type) { + case GSM_LCHAN_TCH_F: + return fn % 104 == 52; + case GSM_LCHAN_TCH_H: + switch (lchan->nr) { + case 0: + return fn % 104 == 0 || fn % 104 == 52; + case 1: + return fn % 104 == 14 || fn % 104 == 66; + default: + return false; + } + default: return false; + } +} +/*! \brief This helper function implements DTXd input processing for FR/HR/EFR: + * we got an RTP input frame, now we need to check if it is SID or not, + * and update our DL SID reshaper state accordingly. + * \param[in] lchan Logical channel structure of the TCH we work with + * \param[in] resp_msg The input frame from RTP + * \param[out] sid_result Output flag indicating if the received frame is SID + * \returns true if the frame in resp_msg is good, false otherwise + */ +static bool fr_hr_efr_dtxd_input(struct gsm_lchan *lchan, struct msgb *resp_msg, + bool *sid_result) +{ + enum osmo_gsm631_sid_class sidc; + bool is_sid; + + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_V1: + if (lchan->type == GSM_LCHAN_TCH_F) { + sidc = osmo_fr_sid_classify(msgb_l2(resp_msg)); + switch (sidc) { + case OSMO_GSM631_SID_CLASS_SPEECH: + is_sid = false; + break; + case OSMO_GSM631_SID_CLASS_INVALID: + /* TS 28.062 section C.3.2.1.1: invalid SIDs + * from call leg A UL are treated like BFIs. + * Drop this frame and act as if we got nothing + * at all from RTP for this FN. */ + return false; + case OSMO_GSM631_SID_CLASS_VALID: + is_sid = true; + /* The SID code word may have a one bit error - + * rejuvenate it. */ + osmo_fr_sid_reset(msgb_l2(resp_msg)); + break; + default: + /* SID classification per GSM 06.31 section + * 6.1.1 has only 3 possible outcomes. */ + OSMO_ASSERT(0); + } + } else { + /* The same kind of classification as we do in + * osmo_{fr,efr}_sid_classify() is impossible for HR: + * the equivalent ternary SID classification per + * GSM 06.41 can only be done in the UL-handling BTS, + * directly coupled to the GSM 05.03 channel decoder, + * and cannot be reconstructed downstream from frame + * payload bits. The only kind of SID we can detect + * here is the perfect, error-free kind. However, + * if we received RFC 5993 payload and the sender + * told us it is valid SID, honor that indication + * and rejuvenate the SID codeword. */ + if (rtpmsg_is_rfc5993_sid(resp_msg)) { + is_sid = true; + osmo_hr_sid_reset(msgb_l2(resp_msg)); + } else { + is_sid = osmo_hr_check_sid(msgb_l2(resp_msg), + msgb_l2len(resp_msg)); + } + } + break; + case GSM48_CMODE_SPEECH_EFR: + /* same logic as for FRv1 */ + sidc = osmo_efr_sid_classify(msgb_l2(resp_msg)); + switch (sidc) { + case OSMO_GSM631_SID_CLASS_SPEECH: + is_sid = false; + break; + case OSMO_GSM631_SID_CLASS_INVALID: + return false; + case OSMO_GSM631_SID_CLASS_VALID: + is_sid = true; + osmo_efr_sid_reset(msgb_l2(resp_msg)); + break; + default: + OSMO_ASSERT(0); + } + break; + default: + /* This static function should never be called except for + * V1 and EFR speech modes. */ + OSMO_ASSERT(0); + } + *sid_result = is_sid; + lchan->tch.dtx_fr_hr_efr.last_rtp_input_was_sid = is_sid; + if (is_sid) { + uint8_t copy_len; + + copy_len = OSMO_MIN(msgb_l2len(resp_msg), + ARRAY_SIZE(lchan->tch.dtx_fr_hr_efr.last_sid)); + memcpy(lchan->tch.dtx_fr_hr_efr.last_sid, + msgb_l2(resp_msg), copy_len); + lchan->tch.dtx_fr_hr_efr.last_sid_len = copy_len; + lchan->tch.dtx_fr_hr_efr.last_sid_age = 0; + } else { + /* We got a speech frame, not SID - therefore, the state flag + * of "we already transmitted a SID" needs to be cleared, + * so that the very first SID that follows this talkspurt + * will get transmitted right away, without waiting for + * the next mandatory SID position. */ + lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted = false; + } return true; } -static bool rtppayload_is_valid(struct gsm_lchan *lchan, struct msgb *resp_msg) +/*! \brief This helper function implements DTXd output processing for FR/HR/EFR: + * here we update our state to deal with cached SID aging, mandatory-Tx + * frame positions and FACCH stealing, and we make the desired output + * transformations of either regurgitating a cached SID or vice-versa, + * dropping a SID we received from RTP. + * \param[in] lchan Logical channel structure of the TCH we work with + * \param[in] fn Frame Number for which we are preparing DL + * \param[in] current_input_is_sid Self-explanatory + * \param[in] resp_msg_p Pointer to l1sap_tch_rts_ind() internal variable + * \param[in] resp_l1sap_p ditto + * \param[in] empty_l1sap_p ditto + * + * This function gets called with pointers to l1sap_tch_rts_ind() internal + * variables and cannot be properly understood on its own, without + * understanding the parent function first. This situation is unfortunate, + * but it was the only way to factor the present logic out of + * l1sap_tch_rts_ind() main body. + */ +static void fr_hr_efr_dtxd_output(struct gsm_lchan *lchan, uint32_t fn, + bool current_input_is_sid, + struct msgb **resp_msg_p, + struct osmo_phsap_prim **resp_l1sap_p, + struct osmo_phsap_prim *empty_l1sap_p) { - /* Avoid sending bw-efficient AMR to lower layers, most bts models - * don't support it. */ - if(lchan->tch_mode == GSM48_CMODE_SPEECH_AMR && - !rtppayload_is_octet_aligned(resp_msg->data, resp_msg->len)) { - LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, - "RTP->L1: Dropping unexpected AMR encoding (bw-efficient?) %s\n", - osmo_hexdump(resp_msg->data, resp_msg->len)); - return false; + struct msgb *resp_msg = *resp_msg_p; + bool sid_in_hand = current_input_is_sid; + + /* Are we at a mandatory-Tx frame position? If so, clear the state flag + * of "we already transmitted a SID in this window" - as of right now, + * a SID has _not_ been transmitted in the present window yet, and if + * we are in a DTX pause, we do need to transmit a SID update as soon + * as we are able to, FACCH permitting. */ + if (fr_hr_efr_sid_position(lchan, fn)) + lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted = false; + + /* The next stanza implements logic that was originally meant to reside + * in the TFO block in TRAUs: if the source feeding us RTP is in a DTXu + * pause (resp_msg == NULL, meaning we got nothing from RTP) *and* the + * most recent RTP input we did get was a SID, and that SID hasn't + * expired, then we need to replicate that SID. */ + if (!resp_msg && lchan->tch.dtx_fr_hr_efr.last_rtp_input_was_sid && + lchan->tch.dtx_fr_hr_efr.last_sid_age < 47) { + /* Whatever we do further below, any time another 20 ms window + * has passed since the last SID was received in RTP, we have + * to age that cached SID. */ + lchan->tch.dtx_fr_hr_efr.last_sid_age++; + + /* The following conditional checking dl_sid_transmitted flag + * is peculiar to our sans-E1 architecture. In the original + * T1/E1 Abis architecture the TFO-enabled TRAU would repeat + * the cached SID from call leg A into *every* 20 ms frame in + * its Abis output, and then the BTS would select which ones + * it should transmit per the rules of GSM 06.31/06.81 section + * 5.1.2. But in our architecture it would be silly and + * wasteful to allocate and fill an msgb for this cached SID + * only to toss it later in the same function - hence the + * logic of section 5.1.2 is absorbed into the decision right + * here to proceed with cached SID regurgitation or not, + * in the form of the following conditional. */ + if (!lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted) + resp_msg = l1sap_msgb_alloc(lchan->tch.dtx_fr_hr_efr.last_sid_len); + if (resp_msg) { + resp_msg->l2h = msgb_put(resp_msg, + lchan->tch.dtx_fr_hr_efr.last_sid_len); + memcpy(resp_msg->l2h, lchan->tch.dtx_fr_hr_efr.last_sid, + lchan->tch.dtx_fr_hr_efr.last_sid_len); + *resp_msg_p = resp_msg; + *resp_l1sap_p = msgb_l1sap_prim(resp_msg); + sid_in_hand = true; + } + } else if (resp_msg && sid_in_hand) { + /* This "else if" leg implements the logic of section 5.1.2 + * for cases when a SID is already present in the RTP input, + * as indicated by (resp_msg != NULL) and sid_in_hand being + * true. Because we are in the "else" clause of the big "if" + * above, this path executes only when the SID has come from + * RTP in _this_ frame, rather than regurgitated from cache. + * But be it fresh or cached, the rules of section 5.1.2 still + * apply, and if we've already transmitted a SID in the current + * window, then we need to suppress further SIDs and send + * an empty payload to the BTS model, causing the latter + * to transmit an induced BFI condition on the air. This + * strange-seeming behavior is needed so that the spec-compliant + * Rx DTX handler in the MS will produce the expected output, + * same as if the GSM network were the old-fashioned kind with + * Abis TRAUs and TFO. */ + if (lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted) { + msgb_free(resp_msg); + resp_msg = NULL; + *resp_msg_p = NULL; + *resp_l1sap_p = empty_l1sap_p; + } } - return true; + + /* The following conditional answers this question: are we actually + * transmitting a SID frame on the air right now, at this frame number? + * If we are certain the BTS model is going to transmit this SID, + * we set the state flag so we won't be transmitting any more SIDs + * until we either hit the next mandatory-Tx position or get another + * little talkspurt followed by new SID. The check for FACCH stealing + * is included because if the BTS model is going to transmit FACCH in + * the current FN, then we are not actually transmitting SID right now, + * and we still need to transmit a SID ASAP, as soon as the TCH becomes + * becomes free from FACCH activity. GSM 06.31/06.81 section 5.1.2 + * does mention that if the mandatory-Tx frame position is taken up + * by FACCH, then we need to send SID in the following frame. */ + if (resp_msg && sid_in_hand && !lchan->tch.dtx_fr_hr_efr.dl_facch_stealing) + lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted = true; } /* TCH-RTS-IND prim received from bts model */ @@ -1310,19 +1499,19 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, struct gsm_lchan *lchan; uint8_t chan_nr, marker = 0; uint32_t fn; - int rc; + bool is_fr_hr_efr_sid = false; chan_nr = rts_ind->chan_nr; fn = rts_ind->fn; gsm_fn2gsmtime(&g_time, fn); - DEBUGPGT(DL1P, &g_time, "Rx TCH-RTS.ind chan_nr=%s\n", rsl_chan_nr_str(chan_nr)); - lchan = get_active_lchan_by_chan_nr(trx, chan_nr); if (!lchan) { LOGPGT(DL1P, LOGL_ERROR, &g_time, "No lchan for PH-RTS.ind (chan_nr=%s)\n", rsl_chan_nr_str(chan_nr)); return 0; + } else { + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Rx TCH-RTS.ind\n"); } if (!lchan->loopback && lchan->abis_ip.rtp_socket) { @@ -1336,13 +1525,9 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, lchan->abis_ip.rtp_socket->rx_user_ts += GSM_RTP_DURATION; } /* get a msgb from the dl_tx_queue */ - resp_msg = msgb_dequeue(&lchan->dl_tch_queue); + resp_msg = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len); if (!resp_msg) { - DEBUGPGT(DL1P, &g_time, "%s DL TCH Tx queue underrun\n", gsm_lchan_name(lchan)); - resp_l1sap = &empty_l1sap; - } else if(!rtppayload_is_valid(lchan, resp_msg)) { - msgb_free(resp_msg); - resp_msg = NULL; + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "DL TCH Tx queue underrun\n"); resp_l1sap = &empty_l1sap; } else { /* Obtain RTP header Marker bit from control buffer */ @@ -1352,16 +1537,27 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, msgb_push(resp_msg, sizeof(*resp_l1sap)); resp_msg->l1h = resp_msg->data; resp_l1sap = msgb_l1sap_prim(resp_msg); + + /* FR/HR/EFR SID or non-SID input handling */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1 || + lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) { + bool drop; + + drop = !fr_hr_efr_dtxd_input(lchan, resp_msg, + &is_fr_hr_efr_sid); + if (OSMO_UNLIKELY(drop)) { + msgb_free(resp_msg); + resp_msg = NULL; + resp_l1sap = &empty_l1sap; + } + } } - /* check for pending REL_IND */ - if (lchan->pending_rel_ind_msg) { - LOGPGT(DRSL, LOGL_INFO, &g_time, "%s Forward REL_IND to L3\n", gsm_lchan_name(lchan)); - /* Forward it to L3 */ - rc = abis_bts_rsl_sendmsg(lchan->pending_rel_ind_msg); - lchan->pending_rel_ind_msg = NULL; - if (rc < 0) - return rc; + /* FR/HR/EFR DTXd output stage */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1 || + lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) { + fr_hr_efr_dtxd_output(lchan, fn, is_fr_hr_efr_sid, &resp_msg, + &resp_l1sap, &empty_l1sap); } memset(resp_l1sap, 0, sizeof(*resp_l1sap)); @@ -1371,13 +1567,21 @@ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, resp_l1sap->u.tch.fn = fn; resp_l1sap->u.tch.marker = marker; - DEBUGPGT(DL1P, &g_time, "Tx TCH.req chan_nr=%s\n", rsl_chan_nr_str(chan_nr)); + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Tx TCH.req\n"); l1sap_down(trx, resp_l1sap); return 0; } +/* Reset link timeout to current value. */ +void radio_link_timeout_reset(struct gsm_lchan *lchan) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + + lchan->s = bts->radio_link_timeout.current; +} + /* process radio link timeout counter S. Follows TS 05.08 Section 5.2 * "MS Procedure" as the "BSS Procedure [...] shall be determined by the * network operator." */ @@ -1385,6 +1589,11 @@ static void radio_link_timeout(struct gsm_lchan *lchan, bool bad_frame) { struct gsm_bts *bts = lchan->ts->trx->bts; + /* Bypass radio link timeout on VGCS/VBS channels: There is no + * uplink SACCH on these when talker is not active. */ + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt) && lchan->asci.talker_active != VGCS_TALKER_ACTIVE) + return; + /* Bypass radio link timeout if set to -1 */ if (bts->radio_link_timeout.current < 0) return; @@ -1463,20 +1672,20 @@ static void repeated_ul_sacch_active_decision(struct gsm_lchan *lchan, { uint16_t upper = 0; uint16_t lower = 0; - bool prev_repeated_ul_sacch_active = lchan->repeated_ul_sacch_active; + bool prev_repeated_ul_sacch_active = lchan->rep_acch.ul_sacch_active; /* This is an optimization so that we exit as quickly as possible if * there are no uplink SACCH repetition capabilities present. * However If the repeated UL-SACCH capabilities vanish for whatever * reason, we must be sure that UL-SACCH repetition is disabled. */ - if (!lchan->repeated_acch_capability.ul_sacch) { - lchan->repeated_ul_sacch_active = false; + if (!lchan->rep_acch_cap.ul_sacch) { + lchan->rep_acch.ul_sacch_active = false; goto out; } /* Threshold disabled (repetition is always on) */ - if (lchan->repeated_acch_capability.rxqual == 0) { - lchan->repeated_ul_sacch_active = true; + if (lchan->rep_acch_cap.rxqual == 0) { + lchan->rep_acch.ul_sacch_active = true; goto out; } @@ -1490,19 +1699,19 @@ static void repeated_ul_sacch_active_decision(struct gsm_lchan *lchan, * of the table in GSM 05.08, section 8.2.4. The lower vector is just * the upper vector shifted by 2. */ - upper = ber10k_by_rxqual_upper[lchan->repeated_acch_capability.rxqual]; - lower = ber10k_by_rxqual_lower[lchan->repeated_acch_capability.rxqual]; + upper = ber10k_by_rxqual_upper[lchan->rep_acch_cap.rxqual]; + lower = ber10k_by_rxqual_lower[lchan->rep_acch_cap.rxqual]; /* If upper/rxqual == 0, then repeated UL-SACCH is always on */ if (ber10k >= upper) - lchan->repeated_ul_sacch_active = true; + lchan->rep_acch.ul_sacch_active = true; else if (ber10k <= lower) - lchan->repeated_ul_sacch_active = false; + lchan->rep_acch.ul_sacch_active = false; out: - if (lchan->repeated_ul_sacch_active == prev_repeated_ul_sacch_active) + if (lchan->rep_acch.ul_sacch_active == prev_repeated_ul_sacch_active) return; - if (lchan->repeated_ul_sacch_active) + if (lchan->rep_acch.ul_sacch_active) LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "UL-SACCH repetition: inactive => active\n"); else LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "UL-SACCH repetition: active => inactive\n"); @@ -1521,11 +1730,8 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, uint8_t chan_nr, link_id; uint8_t tn; uint32_t fn; - int8_t rssi; enum osmo_ph_pres_info_type pr_info = data_ind->pdch_presence_info; - struct gsm_sacch_l1_hdr *l1_hdr; - rssi = data_ind->rssi; chan_nr = data_ind->chan_nr; link_id = data_ind->link_id; fn = data_ind->fn; @@ -1536,21 +1742,6 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, DEBUGPGT(DL1P, &g_time, "Rx PH-DATA.ind chan_nr=%s link_id=0x%02x len=%d\n", rsl_chan_nr_str(chan_nr), link_id, len); - /* Actually, there can be no DATA.ind on PTCCH/U (rather RACH.ind instead), - * but some BTS models with buggy implementation may still be sending them - * to us. Let's keep this for backwards compatibility. */ - if (L1SAP_IS_CHAN_PDCH(chan_nr) && L1SAP_IS_PTCCH(fn)) { - LOGPGT(DL1P, LOGL_NOTICE, &g_time, "There can be no DATA.ind on PTCCH/U. " - "This is probably a bug of the BTS model you're using, please fix!\n"); - return -EINVAL; - } - - /* The ph_data_param contained in the l1sap primitive may contain - * measurement data. If this data is present, forward it for - * processing */ - if (bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB)) - process_l1sap_meas_data(trx, l1sap, PRIM_PH_DATA); - if (ts_is_pdch(&trx->ts[tn])) { lchan = get_lchan_by_chan_nr(trx, chan_nr); if (!lchan) @@ -1559,21 +1750,28 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, /* we are in loopback mode (for BER testing) * mode and need to enqeue the frame to be * returned in downlink */ - queue_limit_to(gsm_lchan_name(lchan), &lchan->dl_tch_queue, 1); - msgb_enqueue(&lchan->dl_tch_queue, msg); + lchan_dl_tch_queue_enqueue(lchan, msg, 1); /* Return 1 to signal that we're still using msg * and it should not be freed */ return 1; } + /* There can be no DATA.ind on PTCCH/U (rather RACH.ind instead), but some + * BTS models with buggy implementation may still be sending them to us. */ + if (L1SAP_IS_PTCCH(fn)) { + LOGPGT(DL1P, LOGL_NOTICE, &g_time, "There can be no DATA.ind on PTCCH/U. " + "This is probably a bug of the BTS model you're using, please fix!\n"); + return -EINVAL; + } + /* Drop all data from incomplete UL block */ if (pr_info != PRES_INFO_BOTH) len = 0; /* PDTCH / PACCH frame handling */ pcu_tx_data_ind(&trx->ts[tn], PCU_IF_SAPI_PDTCH, fn, trx->arfcn, - L1SAP_FN2MACBLOCK(fn), data, len, rssi, data_ind->ber10k, + L1SAP_FN2MACBLOCK(fn), data, len, data_ind->rssi, data_ind->ber10k, data_ind->ta_offs_256bits/64, data_ind->lqual_cb); return 0; } @@ -1584,24 +1782,37 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, return 0; } - if (L1SAP_IS_LINK_SACCH(link_id)) + /* The ph_data_param contained in the l1sap primitive may contain + * measurement data. If this data is present, forward it for + * processing */ + if (bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB)) + process_l1sap_meas_data(lchan, l1sap, PRIM_PH_DATA); + + if (L1SAP_IS_LINK_SACCH(link_id)) { repeated_ul_sacch_active_decision(lchan, data_ind->ber10k); + /* Radio Link Timeout counter */ + if (len == 0) { + LOGPLCGT(lchan, &g_time, DL1P, LOGL_INFO, "Lost SACCH block\n"); + radio_link_timeout(lchan, true); + } else { + radio_link_timeout(lchan, false); + } + + /* Trigger the measurement reporting/processing logic */ + lchan_meas_handle_sacch(lchan, msg); + } + + if (L1SAP_IS_LINK_SACCH(link_id)) + le = &lchan->lapdm_ch.lapdm_acch; + else + le = &lchan->lapdm_ch.lapdm_dcch; + /* bad frame */ if (len == 0) { - if (L1SAP_IS_LINK_SACCH(link_id)) { - /* In case we loose a SACCH block, we must take care - * that the related measurement report is sent via RSL. - * This is a fallback method. The report will also - * lack the measurement report from the MS side. See - * also rsl.c:lapdm_rll_tx_cb() */ - LOGPGT(DL1P, LOGL_INFO, &g_time, "Lost SACCH block, faking meas reports and ms pwr\n"); - le = &lchan->lapdm_ch.lapdm_acch; - rsl_tx_meas_res(lchan, NULL, 0, le); + /* Notify current receive FN to lapdm. */ + lapdm_t200_fn(le, fn); - radio_link_timeout(lchan, true); - lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, data_ind->rssi); - } return -EINVAL; } @@ -1609,29 +1820,20 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, if (lchan->ho.active == HANDOVER_WAIT_FRAME) handover_frame(lchan); - if (L1SAP_IS_LINK_SACCH(link_id)) { - radio_link_timeout(lchan, false); - le = &lchan->lapdm_ch.lapdm_acch; - /* save the SACCH L1 header in the lchan struct for RSL MEAS RES */ - if (len != GSM_MACBLOCK_LEN) { - LOGPGT(DL1P, LOGL_NOTICE, &g_time, "SACCH with odd len=%u!?!\n", len); - return -EINVAL; - } - /* Some brilliant engineer decided that the ordering of - * fields on the Um interface is different from the - * order of fields in RSL. See 3GPP TS 44.004 (section 7.2) - * vs. 3GPP TS 48.058 (section 9.3.10). */ - l1_hdr = (struct gsm_sacch_l1_hdr*)data; - lchan->meas.l1_info.ms_pwr = l1_hdr->ms_pwr; - lchan->meas.l1_info.fpc_epc = l1_hdr->fpc_epc; - lchan->meas.l1_info.srr_sro = l1_hdr->srr_sro; - lchan->meas.l1_info.ta = l1_hdr->ta; - lchan->meas.flags |= LC_UL_M_F_L1_VALID; - - lchan_ms_pwr_ctrl(lchan, data[0] & 0x1f, data_ind->rssi); - lchan_bs_pwr_ctrl(lchan, (const struct gsm48_hdr *) &data[5]); - } else - le = &lchan->lapdm_ch.lapdm_dcch; + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + /* report first valid received frame to VGCS talker process */ + if (lchan->asci.talker_active == VGCS_TALKER_WAIT_FRAME) + vgcs_talker_frame(lchan); + /* Do not forward any message that is received on the uplink to LAPD while + * the uplink is not active. If the MS did not recognize (fast enough) that + * the uplink is free, it may continue to transmit LAPD messages. A + * response by LAPD to these messages is not desired and not required. If + * LAPD would respond, it would cause stopping transmission of UPLINK FREE + * messages. No MS could access the uplink anymore. + */ + if (lchan->asci.talker_active != VGCS_TALKER_ACTIVE) + return 0; + } if (check_for_first_ciphrd(lchan, data, len)) l1sap_tx_ciph_req(lchan->ts->trx, chan_nr, 1, 0); @@ -1640,10 +1842,199 @@ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, msgb_pull_to_l2(msg); lapdm_phsap_up(&l1sap->oph, le); + /* Notify current receive FN to lapdm. */ + lapdm_t200_fn(le, fn); + /* don't free, because we forwarded data */ return 1; } +/* process one MAC block of unpacked bits of a non-transparent CSD channel */ +static void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink, + const struct ph_tch_param *tch_ind, + const uint8_t *data, unsigned int data_len) +{ + struct gsm_bts_trx *trx = lchan->ts->trx; + struct gsmtap_inst *inst = trx->bts->gsmtap.inst; + struct osmo_rlp_frame_decoded rlpf; + pbit_t *rlp_buf; + uint16_t arfcn; + int byte_len; + + if (!inst || !trx->bts->gsmtap.rlp) + return; + + if (lchan->csd_mode != LCHAN_CSD_M_NT) + return; + + if (is_uplink) + rlp_buf = lchan->tch.csd.rlp_buf_ul; + else + rlp_buf = lchan->tch.csd.rlp_buf_dl; + + /* TCH/F 9.6: 4x60bit block => 240bit RLP frame + * TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame + * TCH/H 4.8: 4x60bit block => 240bit RLP frame + * TCH/F 2.4: 2x36bit blocks => transparent only + * TCH/H 2.4: 4x36bit blocks => transparent only + * TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame + */ + + if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_6k0) { + /* in this mode we have 120bit MAC blocks; two of them need to be concatenated + * to render a 240-bit RLP frame. The fist block is present in B0/B2/B4. + * The E7 bit is used to indicate the Frame MF0a */ + OSMO_ASSERT(data_len == 120); + ubit_t e7 = data[4*7+3]; + if (e7 == 0) { + osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1); + return; + } else { + osmo_ubit2pbit_ext(rlp_buf, 120, data, 0, data_len, 1); + byte_len = 240/8; + } + } else if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_14k5) { + /* in this mode we have 290bit MAC blocks containing M1, M2 and 288 data bits; + * two of them need to be concatenated to render a + * 576-bit RLP frame. The start of a RLP frame is + * denoted by a block with M1-bit set to 0. */ + OSMO_ASSERT(data_len == 290); + ubit_t m1 = data[0]; + if (m1 == 0) { + osmo_ubit2pbit_ext(rlp_buf, 0, data, 2, data_len, 1); + return; + } else { + osmo_ubit2pbit_ext(rlp_buf, 288, data, 2, data_len, 1); + byte_len = 576/8; + } + } else { + byte_len = osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1); + } + + if (trx->bts->gsmtap.rlp_skip_null) { + int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len); + if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL) + return; + } + + arfcn = trx->arfcn; + if (is_uplink) + arfcn |= GSMTAP_ARFCN_F_UPLINK; + + gsmtap_send_ex(inst, GSMTAP_TYPE_GSM_RLP, arfcn, lchan->ts->nr, + lchan->type == GSM_LCHAN_TCH_H ? GSMTAP_CHANNEL_VOICE_H : GSMTAP_CHANNEL_VOICE_F, + lchan->nr, tch_ind->fn, tch_ind->rssi, 0, rlp_buf, byte_len); + +} + +static void send_ul_rtp_packet_data(struct gsm_lchan *lchan, const struct ph_tch_param *tch_ind, + const uint8_t *data, uint16_t data_len) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + uint8_t rtp_pl[RFC4040_RTP_PLEN]; + int rc; + + gsmtap_csd_rlp_process(lchan, true, tch_ind, data, data_len); + + rc = csd_v110_rtp_encode(lchan, &rtp_pl[0], data, data_len); + if (rc < 0) + return; + + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_TOTAL); + if (lchan->rtp_tx_marker) + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_MARKER); + + osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, + &rtp_pl[0], sizeof(rtp_pl), + fn_ms_adj(tch_ind->fn, lchan), + lchan->rtp_tx_marker); + /* Only clear the marker bit once we have sent a RTP packet with it */ + lchan->rtp_tx_marker = false; +} + +/* a helper function for the logic in l1sap_tch_ind() */ +static void send_ul_rtp_packet_speech(struct gsm_lchan *lchan, uint32_t fn, + const uint8_t *rtp_pl, uint16_t rtp_pl_len) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + + if (lchan->abis_ip.osmux.use) { + lchan_osmux_send_frame(lchan, rtp_pl, rtp_pl_len, + fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + } else if (lchan->abis_ip.rtp_socket) { + osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, + rtp_pl, rtp_pl_len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_TOTAL); + if (lchan->rtp_tx_marker) + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_TX_MARKER); + } + /* Only clear the marker bit once we have sent a RTP packet with it */ + lchan->rtp_tx_marker = false; +} + +/* a helper function for emitting HR1 UL in RFC 5993 format */ +static void send_rtp_rfc5993(struct gsm_lchan *lchan, uint32_t fn, + struct msgb *msg) +{ + uint8_t toc; + + OSMO_ASSERT(msg->len == GSM_HR_BYTES); + /* FIXME: implement proper SID classification per GSM 06.41 section + * 6.1.1; see OS#6036. Until then, detect error-free SID frames + * using our existing osmo_hr_check_sid() function. */ + if (osmo_hr_check_sid(msg->data, msg->len)) + toc = 0x20; + else + toc = 0x00; + msgb_push_u8(msg, toc); + send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); +} + +/* A helper function for l1sap_tch_ind(): handling BFI + * + * Please note that we pass the msgb to this function, even though it is + * currently not used. This msgb passing is a provision for adding + * support for TRAU-UL-like RTP payload formats like TW-TS-001 that allow + * indicating BFI along with deemed-bad frame data bits, just like + * GSM 08.60 and 08.61 TRAU-UL frames. + */ +static void tch_ul_bfi_handler(struct gsm_lchan *lchan, + const struct gsm_time *g_time, struct msgb *msg) +{ + uint32_t fn = g_time->fn; + uint8_t ecu_out[GSM_FR_BYTES]; + int rc; + + /* Are we applying an ECU to this uplink, and are we in a state + * (not DTX pause) where we emit ECU output? */ + if (lchan->ecu_state && !osmo_ecu_is_dtx_pause(lchan->ecu_state)) { + rc = osmo_ecu_frame_out(lchan->ecu_state, ecu_out); + /* did it actually give us some output? */ + if (rc > 0) { + /* yes, send it out in RTP */ + send_ul_rtp_packet_speech(lchan, fn, ecu_out, rc); + return; + } + } + + /* Are we in rtp continuous-streaming special mode? If so, send out + * a BFI packet as zero-length RTP payload. */ + if (lchan->ts->trx->bts->rtp_nogaps_mode) { + send_ul_rtp_packet_speech(lchan, fn, NULL, 0); + return; + } + + /* Most classic form of BFI handling: generate an intentional gap + * in the outgoing RTP stream. */ + LOGPLCGT(lchan, g_time, DRTP, LOGL_DEBUG, + "Skipping RTP frame with lost payload\n"); + if (lchan->abis_ip.osmux.use) + lchan_osmux_skipped_frame(lchan, fn_ms_adj(fn, lchan)); + else if (lchan->abis_ip.rtp_socket) + osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan)); + lchan->rtp_tx_marker = true; +} + /* TCH received from bts model */ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_tch_param *tch_ind) @@ -1660,19 +2051,25 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, gsm_fn2gsmtime(&g_time, fn); - LOGPGT(DL1P, LOGL_DEBUG, &g_time, "Rx TCH.ind chan_nr=%s\n", rsl_chan_nr_str(chan_nr)); - lchan = get_active_lchan_by_chan_nr(trx, chan_nr); if (!lchan) { LOGPGT(DL1P, LOGL_ERROR, &g_time, "No lchan for TCH.ind (chan_nr=%s)\n", rsl_chan_nr_str(chan_nr)); return 0; + } else { + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Rx TCH.ind\n"); } + /* Notify current receive FN to lapdm. + * TCH frames may be indicated before FACCH frames are indicated. To prevent T200 timeout before FACCH is + * received, subtract one frame number, so that timeout is processed next time after FACCH is received. + */ + lapdm_t200_fn(&lchan->lapdm_ch.lapdm_dcch, GSM_TDMA_FN_SUB(fn, 1)); + /* The ph_tch_param contained in the l1sap primitive may contain * measurement data. If this data is present, forward it for * processing */ if (bts_internal_flag_get(trx->bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB)) - process_l1sap_meas_data(trx, l1sap, PRIM_TCH); + process_l1sap_meas_data(lchan, l1sap, PRIM_TCH); msgb_pull_to_l2(msg); @@ -1681,27 +2078,35 @@ static int l1sap_tch_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, * available is expected as empty payload. We also check if quality is * good enough. */ if (msg->len && tch_ind->lqual_cb >= bts->min_qual_norm) { + /* feed the good frame to the ECU, if we are applying one */ + if (lchan->ecu_state) + osmo_ecu_frame_in(lchan->ecu_state, false, msg->data, msg->len); /* hand msg to RTP code for transmission */ - if (lchan->abis_ip.rtp_socket) - osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, - msg->data, msg->len, fn_ms_adj(fn, lchan), lchan->rtp_tx_marker); + switch (lchan->rsl_cmode) { + case RSL_CMOD_SPD_SPEECH: + if (bts->emit_hr_rfc5993 && lchan->type == GSM_LCHAN_TCH_H && + lchan->tch_mode == GSM48_CMODE_SPEECH_V1) + send_rtp_rfc5993(lchan, fn, msg); + else + send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + break; + case RSL_CMOD_SPD_DATA: + send_ul_rtp_packet_data(lchan, tch_ind, msg->data, msg->len); + break; + case RSL_CMOD_SPD_SIGN: + return 0; /* drop stale TCH.ind */ + default: /* shall not happen */ + OSMO_ASSERT(0); + } /* if loopback is enabled, also queue received RTP data */ if (lchan->loopback) { - /* make sure the queue doesn't get too long */ - queue_limit_to(gsm_lchan_name(lchan), &lchan->dl_tch_queue, 1); - /* add new frame to queue */ - msgb_enqueue(&lchan->dl_tch_queue, msg); + /* add new frame to queue, make sure the queue doesn't get too long */ + lchan_dl_tch_queue_enqueue(lchan, msg, 1); /* Return 1 to signal that we're still using msg and it should not be freed */ return 1; } - /* Only clear the marker bit once we have sent a RTP packet with it */ - lchan->rtp_tx_marker = false; } else { - DEBUGPGT(DRTP, &g_time, "Skipping RTP frame with lost payload (chan_nr=0x%02x)\n", - chan_nr); - if (lchan->abis_ip.rtp_socket) - osmo_rtp_skipped_frame(lchan->abis_ip.rtp_socket, fn_ms_adj(fn, lchan)); - lchan->rtp_tx_marker = true; + tch_ul_bfi_handler(lchan, &g_time, msg); } lchan->tch.last_fn = fn; @@ -1746,17 +2151,26 @@ static bool rach_pass_filter(struct ph_rach_ind_param *rach_ind, struct gsm_bts return true; } -/* Special case where handover RACH is detected */ -static int l1sap_handover_rach(struct gsm_bts_trx *trx, struct ph_rach_ind_param *rach_ind) +/* Special case where RACH on DCCH uplink is detected */ +static int l1sap_dcch_rach(struct gsm_bts_trx *trx, struct ph_rach_ind_param *rach_ind) { + struct gsm_lchan *lchan; + /* Filter out noise / interference / ghosts */ - if (!rach_pass_filter(rach_ind, trx->bts, "handover")) { + if (!rach_pass_filter(rach_ind, trx->bts, "DCCH")) { rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RACH_DROP); return 0; } - handover_rach(get_lchan_by_chan_nr(trx, rach_ind->chan_nr), - rach_ind->ra, rach_ind->acc_delay); + lchan = get_lchan_by_chan_nr(trx, rach_ind->chan_nr); + /* Differentiate + dispatch hand-over and VGCS RACH */ + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RACH_VGCS); + vgcs_rach(lchan, rach_ind->ra, rach_ind->acc_delay, rach_ind->fn); + } else { + rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RACH_HO); + handover_rach(lchan, rach_ind->ra, rach_ind->acc_delay); + } /* must return 0, so in case of msg at l1sap, it will be freed */ return 0; @@ -1807,8 +2221,7 @@ static int l1sap_ph_rach_ind(struct gsm_bts_trx *trx, /* TODO: do we need to count Access Bursts on PDCH? */ return l1sap_pdch_rach(trx, rach_ind); default: - rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RACH_HO); - return l1sap_handover_rach(trx, rach_ind); + return l1sap_dcch_rach(trx, rach_ind); } rate_ctr_inc2(trx->bts->ctrs, BTS_CTR_RACH_RCVD); @@ -1941,8 +2354,12 @@ int l1sap_pdch_req(struct gsm_bts_trx_ts *ts, int is_ptcch, uint32_t fn, l1sap->u.data.chan_nr = RSL_CHAN_OSMO_PDCH | ts->nr; l1sap->u.data.link_id = 0x00; l1sap->u.data.fn = fn; - msg->l2h = msgb_put(msg, len); - memcpy(msg->l2h, data, len); + if (len) { + msg->l2h = msgb_put(msg, len); + memcpy(msg->l2h, data, len); + } else { + msg->l2h = NULL; /* Idle block */ + } return l1sap_down(ts->trx, l1sap); } @@ -1953,19 +2370,59 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, uint32_t timestamp, bool marker) { struct gsm_lchan *lchan = rs->priv; + struct gsm_bts *bts = lchan->ts->trx->bts; struct msgb *msg; - struct osmo_phsap_prim *l1sap; + bool rfc5993_sid = false; + + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_TOTAL); + if (marker) + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_MARKER); /* if we're in loopback mode, we don't accept frames from the * RTP socket anymore */ - if (lchan->loopback) + if (lchan->loopback) { + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_LOOPBACK); + return; + } + + /* initial preen */ + switch (rtp_payload_input_preen(lchan, rtp_pl, rtp_pl_len, &rfc5993_sid)) { + case PL_DECISION_DROP: + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_PREEN); return; + case PL_DECISION_ACCEPT: + break; + case PL_DECISION_STRIP_HDR_OCTET: + rtp_pl++; + rtp_pl_len--; + break; + default: + OSMO_ASSERT(0); + } - msg = l1sap_msgb_alloc(rtp_pl_len); + msg = l1sap_msgb_alloc(512); if (!msg) return; - memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); - msgb_pull(msg, sizeof(*l1sap)); + + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) { + int rc = csd_v110_rtp_decode(lchan, msg->tail, + rtp_pl, rtp_pl_len); + if (rc > 0) { + /* 'fake' tch_ind containing all-zero so gsmtap code can be shared + * between UL and DL */ + static const struct ph_tch_param fake_tch_ind = {}; + gsmtap_csd_rlp_process(lchan, false, &fake_tch_ind, msg->tail, rc); + msgb_put(msg, rc); + } else { + rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_DROP_V110_DEC); + msgb_free(msg); + return; + } + } else { + memcpy(msgb_put(msg, rtp_pl_len), rtp_pl, rtp_pl_len); + } + + msgb_pull(msg, sizeof(struct osmo_phsap_prim)); /* Store RTP header Marker bit in control buffer */ rtpmsg_marker_bit(msg) = marker; @@ -1973,11 +2430,11 @@ void l1sap_rtp_rx_cb(struct osmo_rtp_socket *rs, const uint8_t *rtp_pl, rtpmsg_seq(msg) = seq_number; /* Store RTP header Timestamp in control buffer */ rtpmsg_ts(msg) = timestamp; + /* Store RFC 5993 SID flag likewise */ + rtpmsg_is_rfc5993_sid(msg) = rfc5993_sid; /* make sure the queue doesn't get too long */ - queue_limit_to(gsm_lchan_name(lchan), &lchan->dl_tch_queue, 1); - - msgb_enqueue(&lchan->dl_tch_queue, msg); + lchan_dl_tch_queue_enqueue(lchan, msg, 1); } static int l1sap_chan_act_dact_modify(struct gsm_bts_trx *trx, uint8_t chan_nr, @@ -1995,21 +2452,34 @@ static int l1sap_chan_act_dact_modify(struct gsm_bts_trx *trx, uint8_t chan_nr, return l1sap_down(trx, &l1sap); } -int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed *tp) +int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr) { struct gsm_lchan *lchan = get_lchan_by_chan_nr(trx, chan_nr); int rc; - LOGPLCHAN(lchan, DL1C, LOGL_INFO, "activating channel %s\n", rsl_chan_nr_str(chan_nr)); + if (lchan->state == LCHAN_S_ACTIVE) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Trying to activate already active channel %s\n", + rsl_chan_nr_str(chan_nr)); + return -1; + } + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "Activating channel %s\n", rsl_chan_nr_str(chan_nr)); - lchan->s = trx->bts->radio_link_timeout.current; + radio_link_timeout_reset(lchan); rc = l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); if (rc) return -RSL_ERR_EQUIPMENT_FAIL; + /* Is it TCH? If it is, attempt to allocate an Error Concealment Unit + * instance, if available, unless it is disabled by vty config. */ + if (lchan_is_tch(lchan) && trx->bts->use_ul_ecu) + lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan)); + else + lchan->ecu_state = NULL; + /* Init DTX DL FSM if necessary */ - if (trx->bts->dtxd && lchan->type != GSM_LCHAN_SDCCH) { + if (trx->bts->dtxd && lchan_is_tch(lchan)) { lchan->tch.dtx.dl_amr_fsm = osmo_fsm_inst_alloc(&dtx_dl_amr_fsm, tall_bts_ctx, lchan, @@ -2033,14 +2503,31 @@ int l1sap_chan_act(struct gsm_bts_trx *trx, uint8_t chan_nr, struct tlv_parsed * int l1sap_chan_rel(struct gsm_bts_trx *trx, uint8_t chan_nr) { struct gsm_lchan *lchan = get_lchan_by_chan_nr(trx, chan_nr); - LOGPLCHAN(lchan, DL1C, LOGL_INFO, "deactivating channel chan_nr=%s trx=%d\n", - rsl_chan_nr_str(chan_nr), trx->nr); + + if (lchan->state == LCHAN_S_NONE) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Trying to deactivate already deactivated channel %s\n", + rsl_chan_nr_str(chan_nr)); + return -1; + } + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "Deactivating channel %s\n", + rsl_chan_nr_str(chan_nr)); if (lchan->tch.dtx.dl_amr_fsm) { osmo_fsm_inst_free(lchan->tch.dtx.dl_amr_fsm); lchan->tch.dtx.dl_amr_fsm = NULL; } + /* clear ECU state (if any) */ + if (lchan->ecu_state) { + osmo_ecu_destroy(lchan->ecu_state); + lchan->ecu_state = NULL; + } + + /* reset CSD RLP buffers to avoid any user plane data leaking from + * one previous lchan into a later one */ + memset(&lchan->tch.csd, 0, sizeof(lchan->tch.csd)); + return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, 0); } @@ -2049,8 +2536,8 @@ int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr) { struct gsm_lchan *lchan = get_lchan_by_chan_nr(trx, chan_nr); - LOGPLCHAN(lchan, DL1C, LOGL_INFO, "deactivating sacch chan_nr=%s trx=%d\n", - rsl_chan_nr_str(chan_nr), trx->nr); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "Deactivating SACCH on channel %s\n", + rsl_chan_nr_str(chan_nr)); return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_DEACTIVATE, 1); @@ -2058,8 +2545,46 @@ int l1sap_chan_deact_sacch(struct gsm_bts_trx *trx, uint8_t chan_nr) int l1sap_chan_modify(struct gsm_bts_trx *trx, uint8_t chan_nr) { - LOGP(DL1C, LOGL_INFO, "modifying channel chan_nr=%s trx=%d\n", - rsl_chan_nr_str(chan_nr), trx->nr); + struct gsm_lchan *lchan = get_lchan_by_chan_nr(trx, chan_nr); + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "Modifying channel %s\n", + rsl_chan_nr_str(chan_nr)); + + /* Is it TCH? If it is and we are applying internal uplink ECUs, + * the new channel mode calls for a different ECU. Any changes + * in vty config (enabling or disabling this ECU application) + * will also take effect upon channel modification. */ + if (lchan_is_tch(lchan)) { + if (lchan->ecu_state) + osmo_ecu_destroy(lchan->ecu_state); + if (trx->bts->use_ul_ecu) + lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan)); + else + lchan->ecu_state = NULL; + } return l1sap_chan_act_dact_modify(trx, chan_nr, PRIM_INFO_MODIFY, 0); } + +int l1sap_uplink_access(struct gsm_lchan *lchan, bool active) +{ + uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + struct osmo_phsap_prim l1sap; + + if (lchan->state != LCHAN_S_ACTIVE && !rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Channel %s is not an active ASCI type channel.\n", + rsl_chan_nr_str(chan_nr)); + return -EINVAL; + } + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s uplink access detection on channel %s\n", + (active) ? "Activating" : "Deactivating", rsl_chan_nr_str(chan_nr)); + + + memset(&l1sap, 0, sizeof(l1sap)); + osmo_prim_init(&l1sap.oph, SAP_GSM_PH, PRIM_MPH_INFO, PRIM_OP_REQUEST, NULL); + l1sap.u.info.type = (active) ? PRIM_INFO_ACT_UL_ACC : PRIM_INFO_DEACT_UL_ACC; + l1sap.u.info.u.ulacc_req.chan_nr = chan_nr; + + return l1sap_down(lchan->ts->trx, &l1sap); +} diff --git a/src/common/lchan.c b/src/common/lchan.c index 5a3f539a..5b41a158 100644 --- a/src/common/lchan.c +++ b/src/common/lchan.c @@ -12,38 +12,654 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ +#include "btsconfig.h" /* for PACKAGE_VERSION */ + #include <osmocom/core/logging.h> + +#include <osmocom/trau/osmo_ortp.h> + #include <osmo-bts/logging.h> -#include <osmo-bts/gsm_data.h> +#include <osmo-bts/lchan.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/pcu_if.h> +#include <osmo-bts/handover.h> +#include <osmo-bts/l1sap.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/asci.h> +#include <errno.h> + +static const struct value_string lchan_s_names[] = { + { LCHAN_S_NONE, "NONE" }, + { LCHAN_S_ACT_REQ, "ACTIVATION REQUESTED" }, + { LCHAN_S_ACTIVE, "ACTIVE" }, + { LCHAN_S_REL_REQ, "RELEASE REQUESTED" }, + { LCHAN_S_REL_ERR, "RELEASE DUE ERROR" }, + { LCHAN_S_BROKEN, "BROKEN UNUSABLE" }, + { 0, NULL } +}; + +const struct value_string lchan_ciph_state_names[] = { + { LCHAN_CIPH_NONE, "NONE" }, + { LCHAN_CIPH_RX_REQ, "RX_REQ" }, + { LCHAN_CIPH_RX_CONF, "RX_CONF" }, + { LCHAN_CIPH_RXTX_REQ, "RXTX_REQ" }, + { LCHAN_CIPH_RX_CONF_TX_REQ, "RX_CONF_TX_REQ" }, + { LCHAN_CIPH_RXTX_CONF, "RXTX_CONF" }, + { 0, NULL } +}; + +/* prepare the per-SAPI T200 arrays for a given lchan */ +static int t200_by_lchan(uint32_t *t200_fn_dcch, uint32_t *t200_fn_acch, struct gsm_lchan *lchan) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + + switch (lchan->type) { + case GSM_LCHAN_SDCCH: + t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_SDCCH]; + t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_SDCCH_SAPI3]; + t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_SDCCH]; + t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_SDCCH]; + break; + case GSM_LCHAN_TCH_F: + t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_F]; + t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_F]; + t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0]; + t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3]; + break; + case GSM_LCHAN_TCH_H: + t200_fn_dcch[DL_SAPI0] = bts->t200_fn[T200_FACCH_H]; + t200_fn_dcch[DL_SAPI3] = bts->t200_fn[T200_FACCH_H]; + t200_fn_acch[DL_SAPI0] = bts->t200_fn[T200_SACCH_TCH_SAPI0]; + t200_fn_acch[DL_SAPI3] = bts->t200_fn[T200_SACCH_TCH_SAPI3]; + break; + default: + /* Channels such as CCCH don't use lapdm DL, and hence no T200 is needed */ + return -1; + } + + /* Add time of two extra messages frames. */ + if (lchan->rep_acch_cap.dl_facch_all && lchan_is_tch(lchan)) { + t200_fn_acch[DL_SAPI0] += 104 * 2; + t200_fn_acch[DL_SAPI3] += 104 * 2; + } + + return 0; +} + +static void early_rr_ia_delay_cb(void *data) +{ + struct gsm_lchan *lchan = data; + struct gsm_bts *bts = lchan->ts->trx->bts; + + if (!lchan->early_rr_ia) { + /* The IA message has disappeared since the timer was started. */ + return; + } + + if (lchan->state != LCHAN_S_ACTIVE) { + /* Release has happened since the timer was started. */ + msgb_free(lchan->early_rr_ia); + lchan->early_rr_ia = NULL; + return; + } + + /* Activation is done, send the RR IA now. Put RR IA msg into the AGCH queue of the BTS. */ + if (bts_agch_enqueue(bts, lchan->early_rr_ia) < 0) { + /* if there is no space in the queue: send DELETE IND */ + rsl_tx_delete_ind(bts, lchan->early_rr_ia->data, lchan->early_rr_ia->len); + rate_ctr_inc2(bts->ctrs, BTS_CTR_AGCH_DELETED); + msgb_free(lchan->early_rr_ia); + } + lchan->early_rr_ia = NULL; +} + +void gsm_lchan_init(struct gsm_lchan *lchan, struct gsm_bts_trx_ts *ts, unsigned int lchan_nr) +{ + lchan->ts = ts; + lchan->nr = lchan_nr; + lchan->type = GSM_LCHAN_NONE; + gsm_lchan_name_update(lchan); + + osmo_timer_setup(&lchan->early_rr_ia_delay, early_rr_ia_delay_cb, lchan); + + INIT_LLIST_HEAD(&lchan->sapi_cmds); + INIT_LLIST_HEAD(&lchan->dl_tch_queue); + lchan->dl_tch_queue_len = 0; +} + +void gsm_lchan_name_update(struct gsm_lchan *lchan) +{ + const struct gsm_bts_trx_ts *ts = lchan->ts; + const struct gsm_bts_trx *trx = ts->trx; + char *name; + + name = talloc_asprintf(trx, "(" GSM_TS_NAME_FMT ",ss=%u)", + GSM_TS_NAME_ARGS(ts), lchan->nr); + if (lchan->name != NULL) + talloc_free(lchan->name); + lchan->name = name; +} + +int lchan_init_lapdm(struct gsm_lchan *lchan) +{ + struct lapdm_channel *lc = &lchan->lapdm_ch; + uint32_t t200_fn_dcch[_NR_DL_SAPI], t200_fn_acch[_NR_DL_SAPI]; + + if (t200_by_lchan(t200_fn_dcch, t200_fn_acch, lchan) == 0) { + LOGPLCHAN(lchan, DLLAPD, LOGL_DEBUG, + "Setting T200 D0=%u, D3=%u, S0=%u, S3=%u (all in frames)\n", + t200_fn_dcch[DL_SAPI0], t200_fn_dcch[DL_SAPI3], + t200_fn_acch[DL_SAPI0], t200_fn_acch[DL_SAPI3]); + lapdm_channel_init3(lc, LAPDM_MODE_BTS, NULL, NULL, lchan->type, gsm_lchan_name(lchan)); + lapdm_channel_set_flags(lc, LAPDM_ENT_F_POLLING_ONLY | LAPDM_ENT_F_RTS); + lapdm_channel_set_l1(lc, NULL, lchan); + lapdm_channel_set_t200_fn(lc, t200_fn_dcch, t200_fn_acch); + } + /* We still need to set Rx callback to receive RACH requests: */ + lapdm_channel_set_l3(lc, lapdm_rll_tx_cb, lchan); + + return 0; +} + +static int dyn_ts_pdch_release(struct gsm_lchan *lchan) +{ + struct gsm_bts_trx_ts *ts = lchan->ts; + + if (ts->dyn.pchan_is != ts->dyn.pchan_want) { + LOGP(DRSL, LOGL_ERROR, "%s: PDCH release requested but already" + " in switchover\n", gsm_ts_and_pchan_name(ts)); + return -EINVAL; + } + + /* + * Indicate PDCH Disconnect in dyn_pdch.want, let pcu_tx_info_ind() + * pick it up and wait for PCU to disable the channel. + */ + ts->dyn.pchan_want = GSM_PCHAN_NONE; + + if (!pcu_connected()) { + /* PCU not connected yet. Just record the new type and done, + * the PCU will pick it up once connected. */ + ts->dyn.pchan_is = GSM_PCHAN_NONE; + return 1; + } + + return pcu_tx_info_ind(); +} + +void gsm_lchan_release(struct gsm_lchan *lchan, enum lchan_rel_act_kind rel_kind) +{ + int rc; + + if (lchan->abis_ip.rtp_socket) { + rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); + osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO, + "Closing RTP socket on Channel Release "); + lchan_rtp_socket_free(lchan); + } else if (lchan->abis_ip.osmux.use) { + lchan_osmux_release(lchan); + } + /* reset all Abis related config: */ + memset(&lchan->abis_ip, 0, sizeof(lchan->abis_ip)); + + /* FIXME: right now we allow creating the rtp_socket even if chan is not + * activated... Once we check for that, we can move this check at the + * start of the function */ + if (lchan->state == LCHAN_S_NONE) + return; + + /* release handover, listener and talker states */ + handover_reset(lchan); + vgcs_talker_reset(lchan, false); + vgcs_listener_reset(lchan); + vgcs_uplink_free_reset(lchan); + + lchan->rel_act_kind = rel_kind; + + /* Dynamic channel in PDCH mode is released via PCU */ + if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN + && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { + rc = dyn_ts_pdch_release(lchan); + if (rc == 1) { + /* If the PCU is not connected, continue to rel ack right away. */ + lchan->rel_act_kind = LCHAN_REL_ACT_PCU; + rsl_tx_rf_rel_ack(lchan); + return; + } + /* Waiting for PDCH release */ + return; + } + + l1sap_chan_rel(lchan->ts->trx, gsm_lchan2chan_nr(lchan)); +} + +int lchan_deactivate(struct gsm_lchan *lchan) +{ + OSMO_ASSERT(lchan); + + lchan->ciph_state = 0; + return bts_model_lchan_deactivate(lchan); +} + +const char *gsm_lchans_name(enum gsm_lchan_state s) +{ + return get_value_string(lchan_s_names, s); +} + +/* obtain the next to-be transmitted dowlink SACCH frame (L2 hdr + L3); returns pointer to lchan->si buffer */ +uint8_t *lchan_sacch_get(struct gsm_lchan *lchan) +{ + uint32_t tmp, i; + + for (i = 0; i < _MAX_SYSINFO_TYPE; i++) { + tmp = (lchan->si.last + 1 + i) % _MAX_SYSINFO_TYPE; + if (!(lchan->si.valid & (1 << tmp))) + continue; + lchan->si.last = tmp; + return GSM_LCHAN_SI(lchan, tmp); + } + LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "SACCH no SI available\n"); + return NULL; +} void lchan_set_state(struct gsm_lchan *lchan, enum gsm_lchan_state state) { - DEBUGP(DL1C, "%s state %s -> %s\n", - gsm_lchan_name(lchan), - gsm_lchans_name(lchan->state), - gsm_lchans_name(state)); + if (lchan->state == state) + return; + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "state %s -> %s\n", + gsm_lchans_name(lchan->state), gsm_lchans_name(state)); lchan->state = state; + + switch (lchan->state) { + case LCHAN_S_ACT_REQ: + /* Early Immediate Assignment: Activation is requested, keep the + * early IA until active. This allows the BSC to send the IA + * even before a dynamic timeslot is done switching to a + * different pchan kind (experimental). */ + break; + case LCHAN_S_ACTIVE: + lchan_init_lapdm(lchan); + if (lchan->early_rr_ia) { + /* Early Immediate Assignment: Activation is done, send + * the RR IA now. Delay a bit more to give Um time to + * let the lchan light up for the MS */ + osmo_timer_del(&lchan->early_rr_ia_delay); + osmo_timer_schedule(&lchan->early_rr_ia_delay, 0, + osmo_tdef_get(abis_T_defs, -15, OSMO_TDEF_US, -1)); + } + break; + case LCHAN_S_NONE: + lapdm_channel_exit(&lchan->lapdm_ch); + /* Also ensure that there are no leftovers from repeated FACCH or + * repeated SACCH that might cause memory leakage. */ + msgb_free(lchan->rep_acch.dl_facch[0].msg); + msgb_free(lchan->rep_acch.dl_facch[1].msg); + lchan->rep_acch.dl_facch[0].msg = NULL; + lchan->rep_acch.dl_facch[1].msg = NULL; + msgb_free(lchan->rep_acch.dl_sacch_msg); + lchan->rep_acch.dl_sacch_msg = NULL; + /* free() pending messages */ + msgb_free(lchan->pending_rel_ind_msg); + lchan->pending_rel_ind_msg = NULL; + msgb_free(lchan->pending_chan_activ); + lchan->pending_chan_activ = NULL; + /* fall through */ + default: + if (lchan->early_rr_ia) { + /* Early Immediate Assignment: Transition to any other + * state means whatever IA the BSC has sent shall now + * not be relevant anymore. */ + osmo_timer_del(&lchan->early_rr_ia_delay); + msgb_free(lchan->early_rr_ia); + lchan->early_rr_ia = NULL; + } + break; + } } -bool ts_is_pdch(const struct gsm_bts_trx_ts *ts) +/* See 3GPP TS 44.018 Table 10.5.2.5.1 "Channel Description information element" */ +static uint8_t gsm_pchan2chan_nr(enum gsm_phys_chan_config pchan, + uint8_t ts_nr, uint8_t lchan_nr) { - switch (ts->pchan) { + uint8_t cbits, chan_nr; + + OSMO_ASSERT(pchan != GSM_PCHAN_OSMO_DYN); + OSMO_ASSERT(pchan != GSM_PCHAN_TCH_F_PDCH); + + switch (pchan) { + case GSM_PCHAN_TCH_F: + OSMO_ASSERT(lchan_nr == 0); + cbits = ABIS_RSL_CHAN_NR_CBITS_Bm_ACCHs; + break; case GSM_PCHAN_PDCH: - return true; - case GSM_PCHAN_TCH_F_PDCH: - return (ts->flags & TS_F_PDCH_ACTIVE) - && !(ts->flags & TS_F_PDCH_PENDING_MASK); + OSMO_ASSERT(lchan_nr == 0); + cbits = ABIS_RSL_CHAN_NR_CBITS_OSMO_PDCH; + break; + case GSM_PCHAN_TCH_H: + OSMO_ASSERT(lchan_nr < 2); + cbits = ABIS_RSL_CHAN_NR_CBITS_Lm_ACCHs(lchan_nr); + break; + case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH_SDCCH4_CBCH: + /* + * As a special hack for BCCH, lchan_nr == 4 may be passed + * here. This should never be sent in an RSL message. + * See osmo-bts-xxx/oml.c:opstart_compl(). + */ + if (lchan_nr == CCCH_LCHAN) + cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH; + else { + OSMO_ASSERT(lchan_nr < 4); + cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH4_ACCH(lchan_nr); + } + break; + case GSM_PCHAN_SDCCH8_SACCH8C: + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: + OSMO_ASSERT(lchan_nr < 8); + cbits = ABIS_RSL_CHAN_NR_CBITS_SDCCH8_ACCH(lchan_nr); + break; + case GSM_PCHAN_CCCH: + cbits = ABIS_RSL_CHAN_NR_CBITS_BCCH; + break; + case GSM_PCHAN_NONE: + LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s not expected!\n", + ts_nr, lchan_nr, gsm_pchan_name(pchan)); + cbits = 0x00; /* Reserved */ + break; + default: + LOGP(DRSL, LOGL_ERROR, "ts=%u,ss=%u Physical channel %s (0x%02x) not expected!\n", + ts_nr, lchan_nr, gsm_pchan_name(pchan), (int)pchan); + OSMO_ASSERT(0); + break; + } + + chan_nr = (cbits << 3) | (ts_nr & 0x7); + + return chan_nr; +} + +static uint8_t _gsm_lchan2chan_nr(const struct gsm_lchan *lchan, bool rsl) +{ + uint8_t chan_nr; + + switch (lchan->ts->pchan) { case GSM_PCHAN_OSMO_DYN: - return ts->dyn.pchan_is == GSM_PCHAN_PDCH - && ts->dyn.pchan_want == ts->dyn.pchan_is; + /* Return chan_nr reflecting the current TS pchan, either a standard TCH kind, or the + * nonstandard value reflecting PDCH for Osmocom style dyn TS. */ + chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, lchan->ts->dyn.pchan_is); + break; + case GSM_PCHAN_TCH_F_PDCH: + /* For ip.access style dyn TS, on RSL we want to use the chan_nr as if it was TCH/F. + * We're using custom PDCH ACT and DEACT messages that use the usual chan_nr values. */ + if (rsl) + chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F); + else if (~lchan->ts->flags & TS_F_PDCH_ACTIVE) + chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_TCH_F); + else + chan_nr = gsm_lchan_as_pchan2chan_nr(lchan, GSM_PCHAN_PDCH); + break; + default: + chan_nr = gsm_pchan2chan_nr(lchan->ts->pchan, lchan->ts->nr, lchan->nr); + break; + } + + /* VAMOS: if this lchan belongs to a shadow timeslot, we must reflect + * this in the channel number. Convert it to Osmocom specific value. */ + if (lchan->ts->vamos.is_shadow) + chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK; + + return chan_nr; +} + +uint8_t gsm_lchan2chan_nr(const struct gsm_lchan *lchan) +{ + return _gsm_lchan2chan_nr(lchan, false); +} + +uint8_t gsm_lchan2chan_nr_rsl(const struct gsm_lchan *lchan) +{ + return _gsm_lchan2chan_nr(lchan, true); +} + +uint8_t gsm_lchan_as_pchan2chan_nr(const struct gsm_lchan *lchan, + enum gsm_phys_chan_config as_pchan) +{ + if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN + && as_pchan == GSM_PCHAN_PDCH) + return RSL_CHAN_OSMO_PDCH | (lchan->ts->nr & ~RSL_CHAN_NR_MASK); + return gsm_pchan2chan_nr(as_pchan, lchan->ts->nr, lchan->nr); +} + +/* Called by the model specific code every 104 TDMA frames (SACCH period) */ +void gsm_lchan_interf_meas_push(struct gsm_lchan *lchan, int dbm) +{ + const uint8_t meas_num = lchan->meas.interf_meas_num; + + if (meas_num >= ARRAY_SIZE(lchan->meas.interf_meas_dbm)) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Not enough room " + "to store interference report (%ddBm)\n", dbm); + return; + } + + lchan->meas.interf_meas_dbm[meas_num] = dbm; + lchan->meas.interf_meas_num++; +} + +/* Called by the higher layers every Intave * 104 TDMA frames */ +void gsm_lchan_interf_meas_calc_avg(struct gsm_lchan *lchan) +{ + const uint8_t meas_num = lchan->meas.interf_meas_num; + const struct gsm_bts *bts = lchan->ts->trx->bts; + int b, meas_avg, meas_sum = 0; + + /* There must be at least one sample */ + OSMO_ASSERT(meas_num > 0); + + /* Calculate the sum of all collected samples (in -x dBm) */ + while (lchan->meas.interf_meas_num) { + uint8_t i = --lchan->meas.interf_meas_num; + meas_sum += lchan->meas.interf_meas_dbm[i]; + } + + /* Calculate the average of all collected samples */ + meas_avg = meas_sum / (int) meas_num; + + /* 3GPP TS 48.008 defines 5 interference bands, and 6 interference level + * boundaries (0, X1, ... X5). It's not clear how to handle values + * exceeding the outer boundaries (0 or X5), because bands 0 and 6 do + * not exist (sigh). Let's map such values to closest bands 1 and 5. */ + if (bts->interference.boundary[0] < bts->interference.boundary[5]) { + /* Ascending order (band=1 indicates lowest interference) */ + for (b = 1; b < ARRAY_SIZE(bts->interference.boundary) - 1; b++) { + if (meas_avg < bts->interference.boundary[b]) + break; /* Current 'b' is the band value */ + } + } else { + /* Descending order (band=1 indicates highest interference) */ + for (b = 1; b < ARRAY_SIZE(bts->interference.boundary) - 1; b++) { + if (meas_avg >= bts->interference.boundary[b]) + break; /* Current 'b' is the band value */ + } + } + + LOGPLCHAN(lchan, DL1C, LOGL_DEBUG, + "Interference AVG: %ddBm (band %d, samples %u)\n", + meas_avg, b, meas_num); + + lchan->meas.interf_meas_avg_dbm = meas_avg; + lchan->meas.interf_band = b; +} + +/* determine the ECU codec constant for the codec used by given lchan */ +int lchan2ecu_codec(const struct gsm_lchan *lchan) +{ + const struct gsm_bts_trx_ts *ts = lchan->ts; + + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_V1: + if (ts_pchan(ts) == GSM_PCHAN_TCH_H) + return OSMO_ECU_CODEC_HR; + else + return OSMO_ECU_CODEC_FR; + break; + case GSM48_CMODE_SPEECH_EFR: + return OSMO_ECU_CODEC_EFR; + case GSM48_CMODE_SPEECH_AMR: + return OSMO_ECU_CODEC_AMR; default: - return false; + return -1; + } +} + +static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip) +{ + int rc; + unsigned int i; + unsigned int tries; + + tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2; + for (i = 0; i < tries; i++) { + + if (bts->rtp_port_range_next >= bts->rtp_port_range_end) + bts->rtp_port_range_next = bts->rtp_port_range_start; + + rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next); + + bts->rtp_port_range_next += 2; + + if (rc != 0) + continue; + + if (bts->rtp_ip_dscp != -1) { + if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp)) + LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%d: %s\n", + bts->rtp_ip_dscp, strerror(errno)); + } + if (bts->rtp_priority != -1) { + if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority)) + LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n", + bts->rtp_priority, strerror(errno)); + } + return 0; + } + + return -1; +} + +int lchan_rtp_socket_create(struct gsm_lchan *lchan, const char *bind_ip) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + char cname[256+4]; + int rc; + + if (lchan->abis_ip.rtp_socket) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, " + "but we already have socket!\n"); + return -EALREADY; + } + + /* FIXME: select default value depending on speech_mode */ + //if (!payload_type) + lchan->tch.last_fn = LCHAN_FN_DUMMY; + lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx, + OSMO_RTP_F_POLL); + + if (!lchan->abis_ip.rtp_socket) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n"); + oml_tx_failure_event_rep(&lchan->ts->trx->mo, + NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, + "%s IPAC Failed to create RTP/RTCP sockets", + gsm_lchan_name(lchan)); + return -ENOTCONN; + } + + rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket, + bts->rtp_jitter_adaptive ? + OSMO_RTP_P_JIT_ADAP : + OSMO_RTP_P_JITBUF, + bts->rtp_jitter_buf_ms); + if (rc < 0) + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, + "IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc)); + else + LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc); + + lchan->abis_ip.rtp_socket->priv = lchan; + lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb; + + rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, bind_ip); + if (rc < 0) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n"); + oml_tx_failure_event_rep(&lchan->ts->trx->mo, + NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, + "%s IPAC Failed to bind RTP/RTCP sockets", + gsm_lchan_name(lchan)); + lchan_rtp_socket_free(lchan); + return -EBADFD; + } + + /* Ensure RTCP SDES contains some useful information */ + snprintf(cname, sizeof(cname), "bts@%s", bind_ip); + osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname, + gsm_lchan_name(lchan), NULL, NULL, + gsm_trx_unit_id(lchan->ts->trx), + "OsmoBTS-" PACKAGE_VERSION, NULL); + /* FIXME: multiplex connection, BSC proxy */ + return 0; +} + + +int lchan_rtp_socket_connect(struct gsm_lchan *lchan, const struct in_addr *ia, uint16_t connect_port) +{ + int bound_port = 0; + int rc; + + rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket, + inet_ntoa(*ia), connect_port); + if (rc < 0) { + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n"); + return -ECONNREFUSED; + } + /* save IP address and port number */ + lchan->abis_ip.connect_ip = ntohl(ia->s_addr); + lchan->abis_ip.connect_port = connect_port; + + rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket, + &lchan->abis_ip.bound_ip, + &bound_port); + if (rc < 0) + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc); + lchan->abis_ip.bound_port = bound_port; + return 0; +} + +void lchan_rtp_socket_free(struct gsm_lchan *lchan) +{ + osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); + lchan->abis_ip.rtp_socket = NULL; + msgb_queue_free(&lchan->dl_tch_queue); + lchan->dl_tch_queue_len = 0; +} + +/*! limit number of queue entries to %u; drops any surplus messages */ +void lchan_dl_tch_queue_enqueue(struct gsm_lchan *lchan, struct msgb *msg, unsigned int limit) +{ + if (lchan->dl_tch_queue_len > limit) { + unsigned int excess = lchan->dl_tch_queue_len - limit; + LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "freeing %d queued frames\n", excess); + rate_ctr_add2(lchan->ts->trx->bts->ctrs, BTS_CTR_RTP_RX_DROP_OVERFLOW, excess); + } + while (lchan->dl_tch_queue_len > limit) { + struct msgb *tmp = msgb_dequeue_count(&lchan->dl_tch_queue, &lchan->dl_tch_queue_len); + msgb_free(tmp); } + msgb_enqueue_count(&lchan->dl_tch_queue, msg, &lchan->dl_tch_queue_len); } diff --git a/src/common/load_indication.c b/src/common/load_indication.c index c9b26458..c0d6efb1 100644 --- a/src/common/load_indication.c +++ b/src/common/load_indication.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -41,6 +41,10 @@ static void load_timer_cb(void *data) struct gsm_bts *bts = data; unsigned int pch_percent, rach_percent; + /* It makes no sense to send Load Indication if CCCH is still disabled...*/ + if (bts->c0->ts[0].mo.nm_state.operational != NM_OPSTATE_ENABLED) + goto retry_later; + /* compute percentages */ if (bts->load.ccch.pch_total == 0) pch_percent = 0; @@ -73,6 +77,7 @@ static void load_timer_cb(void *data) bts->load.rach.access); } +retry_later: reset_load_counters(bts); /* re-schedule the timer */ @@ -94,3 +99,8 @@ void load_timer_stop(struct gsm_bts *bts) { osmo_timer_del(&bts->load.ccch.timer); } + +bool load_timer_is_running(const struct gsm_bts *bts) +{ + return osmo_timer_pending(&bts->load.ccch.timer); +} diff --git a/src/common/logging.c b/src/common/logging.c index 50a5a1a3..15c126a2 100644 --- a/src/common/logging.c +++ b/src/common/logging.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -84,17 +84,6 @@ static struct log_info_cat bts_log_info_cat[] = { .loglevel = LOGL_NOTICE, .enabled = 1, }, - [DABIS] = { - .name = "DABIS", - .description = "A-bis Intput Subsystem", - .enabled = 1, .loglevel = LOGL_NOTICE, - }, - [DRTP] = { - .name = "DRTP", - .description = "Realtime Transfer Protocol", - .loglevel = LOGL_NOTICE, - .enabled = 1, - }, [DPCU] = { .name = "DPCU", .description = "PCU interface", @@ -116,15 +105,33 @@ static struct log_info_cat bts_log_info_cat[] = { [DLOOP] = { .name = "DLOOP", .description = "Control loops", - .color = "\033[0;34m", + .color = "\033[0;94m", + .enabled = 1, .loglevel = LOGL_NOTICE, + }, + [DABIS] = { + .name = "DABIS", + .description = "A-bis Intput Subsystem", .enabled = 1, .loglevel = LOGL_NOTICE, }, - [DSUM] = { - .name = "DSUM", - .description = "DSUM", + [DRTP] = { + .name = "DRTP", + .description = "Realtime Transfer Protocol", .loglevel = LOGL_NOTICE, .enabled = 1, }, + [DOSMUX] = { + .name = "DOSMUX", + .description = "Osmux (Osmocom RTP multiplexing)", + .loglevel = LOGL_NOTICE, + .enabled = 1, + }, + [DASCI] = { + .name = "DASCI", + .description = "ASCI (Advanced Speech Call Items: VGCS/VBS)", + .loglevel = LOGL_NOTICE, + .enabled = 1, + }, + }; static int osmo_bts_filter_fn(const struct log_context *ctx, struct log_target *tgt) diff --git a/src/common/main.c b/src/common/main.c index 0b7d3fb7..e57885a6 100644 --- a/src/common/main.c +++ b/src/common/main.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -49,6 +49,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/vty.h> #include <osmo-bts/l1sap.h> #include <osmo-bts/bts_model.h> @@ -65,6 +66,7 @@ static int daemonize = 0; static int rt_prio = -1; static char *gsmtap_ip = 0; extern int g_vty_port_num; +static bool vty_test_mode = false; static void print_help() { @@ -80,6 +82,8 @@ static void print_help() "\nVTY reference generation:\n" " --vty-ref-mode MODE VTY reference generation mode (e.g. 'expert').\n" " --vty-ref-xml Generate the VTY reference XML output and exit.\n" + "\nRegression testing:\n" + " --vty-test VTY test mode. Do not connect to BSC, do not exit.\n" ); bts_model_print_help(); } @@ -103,6 +107,9 @@ static void handle_long_options(const char *prog_name, const int long_option) get_value_string(vty_ref_gen_mode_desc, vty_ref_mode)); vty_dump_xml_ref_mode(stdout, (enum vty_ref_gen_mode) vty_ref_mode); exit(0); + case 3: + vty_test_mode = true; + break; default: fprintf(stderr, "%s: error parsing cmdline options\n", prog_name); exit(2); @@ -140,6 +147,7 @@ static void handle_options(int argc, char **argv) { "realtime", 1, 0, 'r' }, { "vty-ref-mode", 1, &long_option, 1 }, { "vty-ref-xml", 0, &long_option, 2 }, + { "vty-test", 0, &long_option, 3 }, { 0, 0, 0, 0 } }; @@ -226,7 +234,7 @@ static void signal_handler(int signum) oml_tx_failure_event_rep(&g_bts->mo, NM_SEVER_CRITICAL, OSMO_EVT_CRIT_PROC_STOP, "BTS: SIGINT received -> shutdown"); - bts_shutdown(g_bts, "SIGINT"); + bts_shutdown_ext(g_bts, "SIGINT", true, false); } quit++; break; @@ -250,29 +258,9 @@ static void signal_handler(int signum) } } -static int write_pid_file(char *procname) -{ - FILE *outf; - char tmp[PATH_MAX+1]; - - snprintf(tmp, sizeof(tmp)-1, "/var/run/%s.pid", procname); - tmp[PATH_MAX-1] = '\0'; - - outf = fopen(tmp, "w"); - if (!outf) - return -1; - - fprintf(outf, "%d\n", getpid()); - - fclose(outf); - - return 0; -} - int bts_main(int argc, char **argv) { struct gsm_bts_trx *trx; - struct e1inp_line *line; int rc; /* Track the use of talloc NULL memory contexts */ @@ -297,11 +285,21 @@ int bts_main(int argc, char **argv) bts_vty_init(tall_bts_ctx); e1inp_vty_init(); + logging_vty_add_deprecated_subsys(tall_bts_ctx, "sum"); + handle_options(argc, argv); fprintf(stderr, "((*))\n |\n / \\ OsmoBTS\n"); + if (vty_test_mode) + fprintf(stderr, "--- VTY test mode: not connecting to BSC, not exiting ---\n"); - g_bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) { + fprintf(stderr, "Failed to create BTS Site Manager structure\n"); + exit(1); + } + + g_bts = gsm_bts_alloc(g_bts_sm, 0); if (!g_bts) { fprintf(stderr, "Failed to create BTS structure\n"); exit(1); @@ -348,8 +346,6 @@ int bts_main(int argc, char **argv) } } - write_pid_file("osmo-bts"); - /* Accept a GSMTAP host from VTY config, but a commandline option overrides that. */ if (gsmtap_ip != NULL) { if (g_bts->gsmtap.remote_host != NULL) { @@ -365,27 +361,26 @@ int bts_main(int argc, char **argv) /* TODO: move this to gsm_bts_alloc() */ if (g_bts->gsmtap.remote_host != NULL) { LOGP(DLGLOBAL, LOGL_NOTICE, - "Setting up GSMTAP Um forwarding to '%s:%u'\n", - g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT); - g_bts->gsmtap.inst = gsmtap_source_init(g_bts->gsmtap.remote_host, - GSMTAP_UDP_PORT, 1); + "Setting up GSMTAP Um forwarding '%s->'%s:%u'\n", + g_bts->gsmtap.local_host, g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT); + g_bts->gsmtap.inst = gsmtap_source_init2(g_bts->gsmtap.local_host, 0, + g_bts->gsmtap.remote_host, GSMTAP_UDP_PORT, 1); if (g_bts->gsmtap.inst == NULL) { - fprintf(stderr, "Failed during gsmtap_source_init()\n"); + fprintf(stderr, "Failed during gsmtap_source_init2()\n"); exit(1); } gsmtap_source_add_sink(g_bts->gsmtap.inst); } - bts_controlif_setup(g_bts, ctrl_vty_get_bind_addr(), OSMO_CTRL_PORT_BTS); + bts_controlif_setup(g_bts, OSMO_CTRL_PORT_BTS); - rc = telnet_init_dynif(tall_bts_ctx, NULL, vty_get_bind_addr(), - g_vty_port_num); + rc = telnet_init_default(tall_bts_ctx, NULL, g_vty_port_num); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); } - if (pcu_sock_init(g_bts->pcu.sock_path)) { + if (pcu_sock_init(g_bts->pcu.sock_path, g_bts->pcu.sock_wqueue_len_max)) { fprintf(stderr, "PCU L1 socket failed\n"); exit(1); } @@ -397,17 +392,24 @@ int bts_main(int argc, char **argv) signal(SIGUSR2, &signal_handler); osmo_init_ignore_signals(); - if (!g_bts->bsc_oml_host) { - fprintf(stderr, "Cannot start BTS without knowing BSC OML IP\n"); + if (bts_osmux_open(g_bts) < 0) { + fprintf(stderr, "Osmux setup failed\n"); exit(1); } - line = abis_open(g_bts, g_bts->bsc_oml_host, "osmo-bts"); - if (!line) { - fprintf(stderr, "unable to connect to BSC\n"); - exit(2); + if (vty_test_mode) { + /* Just select-loop without connecting to the BSC, don't exit. This allows running tests on the VTY + * telnet port. */ + while (!quit) { + log_reset_context(); + osmo_select_main(0); + } + return EXIT_SUCCESS; } + if (abis_open(g_bts, "osmo-bts") != 0) + exit(1); + rc = phy_links_open(); if (rc < 0) { fprintf(stderr, "unable to open PHY link(s)\n"); diff --git a/src/common/measurement.c b/src/common/measurement.c index b5869872..19bff714 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -2,20 +2,40 @@ #include <stdint.h> #include <errno.h> -#include <osmocom/gsm/gsm_utils.h> #include <osmocom/core/utils.h> +#include <osmocom/core/endian.h> + +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/protocol/gsm_44_004.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/logging.h> #include <osmo-bts/measurement.h> #include <osmo-bts/scheduler.h> #include <osmo-bts/rsl.h> +#include <osmo-bts/power_control.h> #include <osmo-bts/ta_control.h> -/* Tables as per TS 45.008 Section 8.3 */ -static const uint8_t ts45008_83_tch_f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }; -static const uint8_t ts45008_83_tch_hs0[] = { 0, 2, 4, 6, 52, 54, 56, 58 }; -static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; +/* Active TDMA frame subset for TCH/H in DTX mode (see 3GPP TS 45.008 Section 8.3). + * This mapping is used to determine if a L2 block starting at the given TDMA FN + * belongs to the SUB set and thus shall always be transmitted in DTX mode. */ +static const uint8_t ts45008_dtx_tchh_speech_fn_map[104] = { + /* TCH/H(0): 0, 2, 4, 6, 52, 54, 56, 58 */ + [0] = 1, /* block { 0, 2, 4, 6} */ + [52] = 1, /* block {52, 54, 56, 58} */ + /* TCH/H(1): 14, 16, 18, 20, 66, 68, 70, 72 */ + [14] = 1, /* block {14, 16, 18, 20} */ + [66] = 1, /* block {66, 68, 70, 72} */ +}; + +static const uint8_t ts45008_dtx_tchh_data_fn_map[104] = { + /* UL TCH/H(0): 52, 54, 56, 58, 60, 62, 65, 67, 69, 71 */ + [52] = 1, /* block {52, 54, 56, 58, 60, 62} */ + [60] = 1, /* block {60, 62, 65, 67, 69, 71} */ + /* UL TCH/H(1): 70, 72, 74, 76, 79, 81, 83, 85, 87, 89 */ + [70] = 1, /* block {70, 72, 74, 76, 79, 81} */ + [79] = 1, /* block {79, 81, 83, 85, 87, 89} */ +}; /* In cases where we less measurements than we expect we must assume that we * just did not receive the block because it was lost due to bad channel @@ -27,22 +47,11 @@ static const uint8_t ts45008_83_tch_hs1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; static const struct bts_ul_meas measurement_dummy = { .ber10k = MEASUREMENT_DUMMY_BER, .ta_offs_256bits = 0, - .c_i = 0, + .ci_cb = 0, .is_sub = 0, .inv_rssi = MEASUREMENT_DUMMY_IRSSI }; -/* find out if an array contains a given key as element */ -#define ARRAY_CONTAINS(arr, val) array_contains(arr, ARRAY_SIZE(arr), val) -static bool array_contains(const uint8_t *arr, unsigned int len, uint8_t val) { - int i; - for (i = 0; i < len; i++) { - if (arr[i] == val) - return true; - } - return false; -} - /* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false) * (this function is only used internally, it is public to call it from unit-tests) */ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn) @@ -50,61 +59,59 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn) uint32_t fn104 = fn % 104; /* See TS 45.008 Sections 8.3 and 8.4 for a detailed descriptions of the rules - * implemented here. We only implement the logic for Voice, not CSD */ + * implemented here. We implement the logic for both speech and data (CSD). */ + + /* AMR is special, SID frames may be scheduled dynamically at any time */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + return false; switch (lchan->type) { case GSM_LCHAN_TCH_F: switch (lchan->tch_mode) { + case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */ case GSM48_CMODE_SPEECH_V1: + case GSM48_CMODE_SPEECH_V1_VAMOS: case GSM48_CMODE_SPEECH_EFR: - if (trx_sched_is_sacch_fn(lchan->ts, fn, true)) - return true; - if (ARRAY_CONTAINS(ts45008_83_tch_f, fn104)) + case GSM48_CMODE_SPEECH_V2_VAMOS: + /* Active TDMA frame subset for TCH/F: 52, 53, 54, 55, 56, 57, 58, 59. + * There is only one *complete* block in this subset starting at FN=52. + * Incomplete blocks {... 52, 53, 54, 55} and {56, 57, 58, 59 ...} + * contain only 50% of the useful bits (partial SID) and thus ~50% BER. */ + if (fn104 == 52) return true; break; - case GSM48_CMODE_SPEECH_AMR: - if (trx_sched_is_sacch_fn(lchan->ts, fn, true)) - return true; - break; - case GSM48_CMODE_SIGN: - /* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are - * SUB */ - return true; + case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */ + case GSM48_CMODE_DATA_6k0: /* TCH/F4.8 */ + /* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on + * the TDMA frames given in the table of subclause 8.3 only if L2 fill frames + * have been received as FACCH/F frames at the corresponding frame positions. */ default: - LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n", - gsm_lchan_name(lchan), lchan->tch_mode); + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) + return fn104 == 52; + LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode); break; } break; case GSM_LCHAN_TCH_H: switch (lchan->tch_mode) { case GSM48_CMODE_SPEECH_V1: - if (trx_sched_is_sacch_fn(lchan->ts, fn, true)) - return true; - switch (lchan->nr) { - case 0: - if (ARRAY_CONTAINS(ts45008_83_tch_hs0, fn104)) - return true; - break; - case 1: - if (ARRAY_CONTAINS(ts45008_83_tch_hs1, fn104)) - return true; - break; - default: - OSMO_ASSERT(0); - } - break; - case GSM48_CMODE_SPEECH_AMR: - if (trx_sched_is_sacch_fn(lchan->ts, fn, true)) + case GSM48_CMODE_SPEECH_V1_VAMOS: + if (ts45008_dtx_tchh_speech_fn_map[fn104]) return true; break; case GSM48_CMODE_SIGN: /* No DTX allowed; SUB=FULL, therefore measurements at all frame numbers are * SUB */ return true; + case GSM48_CMODE_DATA_6k0: /* TCH/H4.8 */ + case GSM48_CMODE_DATA_3k6: /* TCH/H2.4 */ + /* FIXME: The RXQUAL_SUB (not RXLEV!) report shall include measurements on + * the TDMA frames given in the table of subclause 8.3 only if L2 fill frames + * have been received as FACCH/H frames at the corresponding frame positions. */ default: - LOGPFN(DMEAS, LOGL_ERROR, fn, "%s: Unsupported lchan->tch_mode %u\n", - gsm_lchan_name(lchan), lchan->tch_mode); + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) + return ts45008_dtx_tchh_data_fn_map[fn104] == 1; + LOGPLCFN(lchan, fn, DMEAS, LOGL_ERROR, "Unsupported lchan->tch_mode %u\n", lchan->tch_mode); break; } break; @@ -283,9 +290,8 @@ int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn) } if (rc == 1) { - DEBUGP(DMEAS, - "%s meas period end fn:%u, fn_mod:%i, status:%d, pchan:%s\n", - gsm_lchan_name(lchan), fn, fn_mod, rc, gsm_pchan_name(pchan)); + LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "meas period end fn_mod:%d, status:%d, pchan:%s\n", fn_mod, + rc, gsm_pchan_name(pchan)); } return rc; @@ -321,16 +327,15 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *dest; if (lchan->state != LCHAN_S_ACTIVE) { - LOGPFN(DMEAS, LOGL_NOTICE, fn, - "%s measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n", - gsm_lchan_name(lchan), gsm_lchans_name(lchan->state), - lchan->meas.num_ul_meas, fn_mod); + LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE, + "measurement during state: %s, num_ul_meas=%d, fn_mod=%u\n", + gsm_lchans_name(lchan->state), lchan->meas.num_ul_meas, fn_mod); } if (lchan->meas.num_ul_meas >= ARRAY_SIZE(lchan->meas.uplink)) { - LOGPFN(DMEAS, LOGL_NOTICE, fn, - "%s no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", - gsm_lchan_name(lchan), lchan->meas.num_ul_meas, fn_mod); + LOGPLCFN(lchan, fn, DMEAS, LOGL_NOTICE, + "no space for uplink measurement, num_ul_meas=%d, fn_mod=%u\n", lchan->meas.num_ul_meas, + fn_mod); return -ENOSPC; } @@ -342,10 +347,10 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, if (!ulm->is_sub) dest->is_sub = ts45008_83_is_sub(lchan, fn); - DEBUGPFN(DMEAS, fn, "%s adding measurement (ber10k=%u, ta_offs=%d, ci=%0.2f, is_sub=%u, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n", - gsm_lchan_name(lchan), ulm->ber10k, ulm->ta_offs_256bits, - ulm->c_i, dest->is_sub, ulm->inv_rssi, lchan->meas.num_ul_meas, - fn_mod); + LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, + "adding a %s measurement (ber10k=%u, ta_offs=%d, ci_cB=%d, rssi=-%u), num_ul_meas=%d, fn_mod=%u\n", + dest->is_sub ? "SUB" : "FULL", ulm->ber10k, ulm->ta_offs_256bits, ulm->ci_cb, ulm->inv_rssi, + lchan->meas.num_ul_meas, fn_mod); lchan->meas.last_fn = fn; @@ -419,32 +424,50 @@ static unsigned int lchan_meas_num_expected(const struct gsm_lchan *lchan) } /* In DTX a subset of blocks must always be transmitted - * See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) */ -static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan) + * See also: GSM 05.08, chapter 8.3 Aspects of discontinuous transmission (DTX) + * Return value N: (N < 0) -- at least N SUB frames expected; + * (N > 0) -- exactly N SUB frames expected; + * (N == 0) - unknown channel type/mode? */ +static int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan) { enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts); - /* AMR is using a more elaborated model with a dymanic amount of - * DTX blocks so this function is not applicable to determine the - * amount of expected SUB Measurements when AMR is used */ - OSMO_ASSERT(lchan->tch_mode != GSM48_CMODE_SPEECH_AMR); - switch (pchan) { case GSM_PCHAN_TCH_F: - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - /* 1 block SACCH, 24 blocks TCH (see note 1) */ - return 25; - } else { - /* 1 block SACCH, 2 blocks TCH */ - return 3; + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) + return 1 + 1; /* 1 x SACCH + 1 x FACCH */ + /* else: signalling or speech */ + switch (lchan->tch_mode) { + case GSM48_CMODE_SIGN: /* TCH/F sign: DTX *is* permitted */ + case GSM48_CMODE_SPEECH_V1: /* TCH/FS */ + case GSM48_CMODE_SPEECH_V1_VAMOS: + case GSM48_CMODE_SPEECH_EFR: /* TCH/EFS */ + case GSM48_CMODE_SPEECH_V2_VAMOS: + return 1 + 1; /* 1 x SACCH + 1 x TCH */ + case GSM48_CMODE_SPEECH_AMR: /* TCH/AFS */ + case GSM48_CMODE_SPEECH_V3_VAMOS: + case GSM48_CMODE_SPEECH_V4: /* O-TCH/WFS */ + case GSM48_CMODE_SPEECH_V5: /* TCH/WFS */ + case GSM48_CMODE_SPEECH_V5_VAMOS: + default: + return -1; /* at least 1 x SACCH + M x TCH (variable) */ } case GSM_PCHAN_TCH_H: - if (lchan->tch_mode == GSM48_CMODE_SIGN) { - /* 1 block SACCH, 12 blocks TCH (see ynote 1) */ - return 13; - } else { - /* 1 block SACCH, 4 blocks TCH */ - return 5; + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) + return 1 + 2; /* 1 x SACCH + 2 x FACCH */ + /* else: signalling or speech */ + switch (lchan->tch_mode) { + case GSM48_CMODE_SIGN: /* TCH/H sign: DTX *is not* permitted */ + return 1 + 12; /* 1 x SACCH + 12 x TCH */ + case GSM48_CMODE_SPEECH_V1: + case GSM48_CMODE_SPEECH_V1_VAMOS: + return 1 + 2; /* 1 x SACCH + 2 x TCH */ + case GSM48_CMODE_SPEECH_AMR: /* TCH/AHS */ + case GSM48_CMODE_SPEECH_V3_VAMOS: + case GSM48_CMODE_SPEECH_V4: /* O-TCH/WHS */ + case GSM48_CMODE_SPEECH_V6: /* O-TCH/AHS */ + default: + return -1; /* at least 1 x SACCH + M x TCH (variable) */ } case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: @@ -457,8 +480,6 @@ static unsigned int lchan_meas_sub_num_expected(const struct gsm_lchan *lchan) default: return 0; } - - /* Note 1: In signalling mode all blocks count as SUB blocks. */ } /* if we clip the TOA value to 12 bits, i.e. toa256=3200, @@ -556,13 +577,15 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) struct gsm_meas_rep_unidir *mru; uint32_t ber_full_sum = 0; uint32_t irssi_full_sum = 0; + int32_t ci_full_sum = 0; uint32_t ber_sub_sum = 0; uint32_t irssi_sub_sum = 0; + int32_t ci_sub_sum = 0; int32_t ta256b_sum = 0; unsigned int num_meas_sub = 0; unsigned int num_meas_sub_actual = 0; unsigned int num_meas_sub_subst = 0; - unsigned int num_meas_sub_expect; + int num_meas_sub_expect; unsigned int num_ul_meas; unsigned int num_ul_meas_actual = 0; unsigned int num_ul_meas_subst = 0; @@ -582,16 +605,7 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) * intentionally to save energy. It is not necessarly an error * when we get less measurements as we expect. */ num_ul_meas_expect = lchan_meas_num_expected(lchan); - - if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) - num_meas_sub_expect = lchan_meas_sub_num_expected(lchan); - else { - /* When AMR is used, we expect at least one SUB frame, since - * the SACCH will always be SUB frame. There may occur more - * SUB frames but since DTX periods in AMR are dynamic, we - * can not know how much exactly. */ - num_meas_sub_expect = 1; - } + num_meas_sub_expect = lchan_meas_sub_num_expected(lchan); if (lchan->meas.num_ul_meas > num_ul_meas_expect) num_ul_meas_excess = lchan->meas.num_ul_meas - num_ul_meas_expect; @@ -625,22 +639,21 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) m = &lchan->meas.uplink[i + num_ul_meas_excess]; if (m->is_sub) { irssi_sub_sum += m->inv_rssi; + ci_sub_sum += m->ci_cb; num_meas_sub_actual++; is_sub = true; } irssi_full_sum += m->inv_rssi; ta256b_sum += m->ta_offs_256bits; + ci_full_sum += m->ci_cb; num_ul_meas_actual++; } else { m = &measurement_dummy; - /* For AMR the amount of SUB frames is defined by the - * the occurrence of DTX periods, which are dynamically - * negotiated in AMR, so we can not know if and how many - * SUB frames are missing. */ - if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { - if (num_meas_sub <= i) { + /* only if we know the exact number of SUB measurements */ + if (num_meas_sub_expect >= 0) { + if (num_meas_sub < num_meas_sub_expect) { num_meas_sub_subst++; is_sub = true; } @@ -656,16 +669,6 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) } } - if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { - LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, - "Received UL measurements contain %u SUB measurements, expected %u\n", - num_meas_sub_actual, num_meas_sub_expect); - } else { - LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, - "Received UL measurements contain %u SUB measurements, expected at least %u\n", - num_meas_sub_actual, num_meas_sub_expect); - } - LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, "Replaced %u measurements with dummy values, " "from which %u were SUB measurements\n", num_ul_meas_subst, num_meas_sub_subst); @@ -676,17 +679,24 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) * above only adds missing measurements during the calculation * it can not remove excess SUB measurements or add missing SUB * measurements when there is no more room in the interval. */ - if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { - if (num_meas_sub != num_meas_sub_expect) { + if (num_meas_sub_expect < 0) { + num_meas_sub_expect = -num_meas_sub_expect; + LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, + "Received UL measurements contain %u SUB measurements, expected at least %d\n", + num_meas_sub_actual, num_meas_sub_expect); + if (OSMO_UNLIKELY(num_meas_sub < num_meas_sub_expect)) { LOGPLCHAN(lchan, DMEAS, LOGL_ERROR, "Incorrect number of SUB measurements detected! " - "(%u vs exp %u)\n", num_meas_sub, num_meas_sub_expect); + "(%u vs exp >=%d)\n", num_meas_sub, num_meas_sub_expect); } } else { - if (num_meas_sub < num_meas_sub_expect) { + LOGPLCHAN(lchan, DMEAS, LOGL_DEBUG, + "Received UL measurements contain %u SUB measurements, expected %d\n", + num_meas_sub_actual, num_meas_sub_expect); + if (OSMO_UNLIKELY(num_meas_sub != num_meas_sub_expect)) { LOGPLCHAN(lchan, DMEAS, LOGL_ERROR, "Incorrect number of SUB measurements detected! " - "(%u vs exp >=%u)\n", num_meas_sub, num_meas_sub_expect); + "(%u vs exp %d)\n", num_meas_sub, num_meas_sub_expect); } } @@ -698,27 +708,32 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) else irssi_full_sum = irssi_full_sum / num_ul_meas_actual; - if (!num_ul_meas_actual) + if (!num_ul_meas_actual) { ta256b_sum = lchan->meas.ms_toa256; - else + ci_full_sum = lchan->meas.ul_ci_cb_full; + } else { ta256b_sum = ta256b_sum / (signed)num_ul_meas_actual; + ci_full_sum = ci_full_sum / (signed)num_ul_meas_actual; + } if (!num_meas_sub) ber_sub_sum = MEASUREMENT_DUMMY_BER; else ber_sub_sum = ber_sub_sum / num_meas_sub; - if (!num_meas_sub_actual) + if (!num_meas_sub_actual) { irssi_sub_sum = MEASUREMENT_DUMMY_IRSSI; - else + ci_sub_sum = lchan->meas.ul_ci_cb_sub; + } else { irssi_sub_sum = irssi_sub_sum / num_meas_sub_actual; + ci_sub_sum = ci_sub_sum / (signed)num_meas_sub_actual; + } LOGPLCHAN(lchan, DMEAS, LOGL_INFO, - "Computed TA256(% 4d) BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), " - "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm)\n", - ta256b_sum, ber_full_sum / 100, ber_full_sum % 100, - irssi_full_sum, ber_sub_sum / 100, ber_sub_sum % 100, - irssi_sub_sum); + "Computed TA256(% 4d), BER-FULL(%2u.%02u%%), RSSI-FULL(-%3udBm), C/I-FULL(% 4d cB), " + "BER-SUB(%2u.%02u%%), RSSI-SUB(-%3udBm), C/I-SUB(% 4d cB)\n", + ta256b_sum, ber_full_sum / 100, ber_full_sum % 100, irssi_full_sum, ci_full_sum, + ber_sub_sum / 100, ber_sub_sum % 100, irssi_sub_sum, ci_sub_sum); /* store results */ mru = &lchan->meas.ul_res; @@ -727,6 +742,8 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) mru->full.rx_qual = ber10k_to_rxqual(ber_full_sum); mru->sub.rx_qual = ber10k_to_rxqual(ber_sub_sum); lchan->meas.ms_toa256 = ta256b_sum; + lchan->meas.ul_ci_cb_full = ci_full_sum; + lchan->meas.ul_ci_cb_sub = ci_sub_sum; LOGPLCHAN(lchan, DMEAS, LOGL_INFO, "UL MEAS RXLEV_FULL(%u), RXLEV_SUB(%u), RXQUAL_FULL(%u), RXQUAL_SUB(%u), " @@ -739,11 +756,6 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn) lchan_meas_compute_extended(lchan); - /* Compute new ta_req value. This has to be done here since the value - * in lchan->meas.num_ul_meas together with lchan->meas.ms_toa256 - * is needed for the computation. */ - lchan_ms_ta_ctrl(lchan); - lchan->meas.num_ul_meas = 0; /* return 1 to indicate that the computation has been done and the next @@ -771,3 +783,230 @@ void lchan_meas_reset(struct gsm_lchan *lchan) memset(&lchan->meas, 0, sizeof(lchan->meas)); lchan->meas.last_fn = LCHAN_FN_DUMMY; } + +static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, uint8_t ta) +{ + return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - ta); +} + +static inline bool ms_to_valid(const struct gsm_lchan *lchan) +{ + return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0); +} + +/* Decide if repeated FACCH should be applied or not. If RXQUAL level, that the + * MS reports is high enough, FACCH repetition is not needed. */ +static void repeated_dl_facch_active_decision(struct gsm_lchan *lchan, + const struct gsm48_meas_res *meas_res) +{ + uint8_t upper; + uint8_t lower; + uint8_t rxqual; + bool prev_repeated_dl_facch_active = lchan->rep_acch.dl_facch_active; + + /* This is an optimization so that we exit as quickly as possible if + * there are no FACCH repetition capabilities present. However If the + * repeated FACCH capabilities vanish for whatever reason, we must be + * sure that FACCH repetition is disabled. */ + if (!lchan->rep_acch_cap.dl_facch_cmd + && !lchan->rep_acch_cap.dl_facch_all) { + lchan->rep_acch.dl_facch_active = false; + goto out; + } + + /* Threshold disabled (always on) */ + if (lchan->rep_acch_cap.rxqual == 0) { + lchan->rep_acch.dl_facch_active = true; + goto out; + } + + /* When the MS sets the SRR bit in the UL-SACCH L1 header + * (repeated SACCH requested) then it makes sense to enable + * FACCH repetition too. */ + if (lchan->meas.l1_info.srr_sro) { + lchan->rep_acch.dl_facch_active = true; + goto out; + } + + /* Parse MS measurement results */ + if (meas_res == NULL) + goto out; + if (!gsm48_meas_res_is_valid(meas_res)) + goto out; + + /* If the RXQUAL level at the MS drops under a certain threshold + * we enable FACCH repetition. */ + upper = lchan->rep_acch_cap.rxqual; + if (upper > 2) + lower = lchan->rep_acch_cap.rxqual - 2; + else + lower = 0; + + /* When downlink DTX is applied, use RXQUAL-SUB, otherwise use + * RXQUAL-FULL. */ + if (meas_res->dtx_used) + rxqual = meas_res->rxqual_sub; + else + rxqual = meas_res->rxqual_full; + + if (rxqual >= upper) + lchan->rep_acch.dl_facch_active = true; + else if (rxqual <= lower) + lchan->rep_acch.dl_facch_active = false; + +out: + if (lchan->rep_acch.dl_facch_active == prev_repeated_dl_facch_active) + return; + if (lchan->rep_acch.dl_facch_active) + LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: inactive => active\n"); + else + LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "DL-FACCH repetition: active => inactive\n"); +} + +static void acch_overpower_active_decision(struct gsm_lchan *lchan, + const struct gsm48_meas_res *meas_res) +{ + const bool old = lchan->top_acch_active; + uint8_t upper, lower, rxqual; + + /* ACCH overpower is not allowed => nothing to do */ + if (lchan->top_acch_cap.overpower_db == 0) + return; + /* RxQual threshold is disabled => overpower is always on */ + if (lchan->top_acch_cap.rxqual == 0) + return; + + /* If DTx is active on Downlink, use the '-SUB' */ + if (meas_res->dtx_used) + rxqual = meas_res->rxqual_sub; + else /* ... otherwise use the '-FULL' */ + rxqual = meas_res->rxqual_full; + + upper = lchan->top_acch_cap.rxqual; + if (upper > 2) + lower = upper - 2; + else + lower = 0; + + if (rxqual >= upper) + lchan->top_acch_active = true; + else if (rxqual <= lower) + lchan->top_acch_active = false; + + if (lchan->top_acch_active != old) { + LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "Temporary ACCH overpower: %s\n", + lchan->top_acch_active ? "inactive => active" + : "active => inactive"); + } +} + +static bool data_is_rr_meas_rep(const uint8_t *data) +{ + const struct gsm48_hdr *gh = (void *)(data + 5); + const uint8_t *lapdm_hdr = (void *)(data + 2); + + /* LAPDm address field: SAPI=0, C/R=0, EA=1 */ + if (lapdm_hdr[0] != 0x01) + return false; + /* LAPDm control field: U, func=UI */ + if (lapdm_hdr[1] != 0x03) + return false; + /* Protocol discriminator: RR */ + if (gh->proto_discr != GSM48_PDISC_RR) + return false; + + switch (gh->msg_type) { + case GSM48_MT_RR_EXT_MEAS_REP: + case GSM48_MT_RR_MEAS_REP: + return true; + default: + return false; + } +} + +/* Called every time a SACCH block is received from lower layers */ +void lchan_meas_handle_sacch(struct gsm_lchan *lchan, struct msgb *msg) +{ + const struct gsm48_meas_res *mr = NULL; + const struct gsm48_hdr *gh = NULL; + int timing_offset, rc; + bool dtxu_used = true; /* safe default assumption */ + uint8_t ms_pwr; + uint8_t ms_ta; + int8_t ul_rssi; + int16_t ul_ci_cb; + uint8_t *l3; + unsigned int l3_len; + + if (msgb_l2len(msg) == GSM_MACBLOCK_LEN) { + /* Some brilliant engineer decided that the ordering of + * fields on the Um interface is different from the + * order of fields in RSL. See 3GPP TS 44.004 (section 7.2) + * vs. 3GPP TS 48.058 (section 9.3.10). */ + const struct gsm_sacch_l1_hdr *l1h = msgb_l2(msg); + lchan->meas.l1_info.ms_pwr = l1h->ms_pwr; + lchan->meas.l1_info.fpc_epc = l1h->fpc_epc; + lchan->meas.l1_info.srr_sro = l1h->srr_sro; + lchan->meas.l1_info.ta = l1h->ta; + lchan->meas.flags |= LC_UL_M_F_L1_VALID; + + /* Check if this is a Measurement Report */ + if (data_is_rr_meas_rep(msgb_l2(msg))) { + /* Skip both L1 SACCH and LAPDm headers */ + msg->l3h = (void *)(msg->l2h + 2 + 3); + gh = msgb_l3(msg); + } + + ms_pwr = lchan->meas.l1_info.ms_pwr; + ms_ta = lchan->meas.l1_info.ta; + } else { + lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; + ms_pwr = lchan->ms_power_ctrl.current; + ms_ta = lchan->ta_ctrl.current; + } + + timing_offset = ms_to_valid(lchan) ? ms_to2rsl(lchan, ms_ta) : -1; + l3 = msgb_l3(msg); + l3_len = l3 ? msgb_l3len(msg) : 0; + rc = rsl_tx_meas_res(lchan, l3, l3_len, timing_offset); + if (rc == 0) /* Count successful transmissions */ + lchan->meas.res_nr++; + + /* Run control loops now that we have all the information: */ + /* 3GPP TS 45.008 sec 4.2: UL L1 SACCH Header contains TA and + * MS_PWR used "for the last burst of the previous SACCH + * period". Since MS must use the values provided in DL SACCH + * starting at next meas period, the value of the "last burst" + * is actually the value used in the entire meas period. Since + * it contains info about the previous meas period, we want to + * feed the Control Loop with the measurements for the same + * period (the previous one), which is stored in lchan->meas(.ul_res): + */ + if (gh && gh->msg_type == GSM48_MT_RR_MEAS_REP) { + mr = (const struct gsm48_meas_res *)gh->data; + if (gsm48_meas_res_is_valid(mr)) + dtxu_used = mr->dtx_used; + } + + if (dtxu_used) { + ul_rssi = rxlev2dbm(lchan->meas.ul_res.sub.rx_lev); + ul_ci_cb = lchan->meas.ul_ci_cb_sub; + } else { + ul_rssi = rxlev2dbm(lchan->meas.ul_res.full.rx_lev); + ul_ci_cb = lchan->meas.ul_ci_cb_full; + } + lchan_ms_ta_ctrl(lchan, ms_ta, lchan->meas.ms_toa256); + lchan_ms_pwr_ctrl(lchan, ms_pwr, ul_rssi, ul_ci_cb); + if (mr && gsm48_meas_res_is_valid(mr)) { + lchan_bs_pwr_ctrl(lchan, mr); + acch_overpower_active_decision(lchan, mr); + } + + repeated_dl_facch_active_decision(lchan, mr); + + /* Reset state for next iteration */ + lchan->tch.dtx.dl_active = false; + lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID; + lchan->ms_t_offs = -1; + lchan->p_offs = -1; +} diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c index 1817849f..04a0c344 100644 --- a/src/common/msg_utils.c +++ b/src/common/msg_utils.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -321,17 +321,17 @@ static inline bool dtx_amr_sid_optional(struct gsm_lchan *lchan, uint32_t fn) already: we rely here on the order of RTS arrival from L1 - we expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the same FN */ - if(lchan->type == GSM_LCHAN_TCH_H) { + if (lchan->type == GSM_LCHAN_TCH_H) { if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY && lchan->tch.dtx.fn != LCHAN_FN_WAIT) { /* FACCH interruption is over */ dtx_dispatch(lchan, E_COMPL); return false; - } else if(lchan->tch.dtx.fn == LCHAN_FN_DUMMY) { + } else if (lchan->tch.dtx.fn == LCHAN_FN_DUMMY) { lchan->tch.dtx.fn = LCHAN_FN_WAIT; } else lchan->tch.dtx.fn = fn; - } else if(lchan->type == GSM_LCHAN_TCH_F) { + } else if (lchan->type == GSM_LCHAN_TCH_F) { if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) { /* FACCH interruption is over */ dtx_dispatch(lchan, E_COMPL); @@ -380,15 +380,19 @@ static inline bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn) static const uint8_t f[] = { 52, 53, 54, 55, 56, 57, 58, 59 }, h0[] = { 0, 2, 4, 6, 52, 54, 56, 58 }, h1[] = { 14, 16, 18, 20, 66, 68, 70, 72 }; - if (lchan->tch_mode == GSM48_CMODE_SPEECH_V1) { + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_V1: if (lchan->type == GSM_LCHAN_TCH_F) return fn_chk(f, fn, ARRAY_SIZE(f)); else return fn_chk(lchan->nr ? h1 : h0, fn, lchan->nr ? ARRAY_SIZE(h1) : ARRAY_SIZE(h0)); + case GSM48_CMODE_SPEECH_EFR: + return fn_chk(f, fn, ARRAY_SIZE(f)); + default: + return false; } - return false; } /*! \brief Check if DTX DL AMR is enabled for a given lchan (it have proper type, @@ -466,10 +470,6 @@ void dtx_int_signal(struct gsm_lchan *lchan) */ uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn) { - /* FIXME: add EFR support */ - if (lchan->tch_mode == GSM48_CMODE_SPEECH_EFR) - return 0; - if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { if (dtx_sched_optional(lchan, fn)) return 0; diff --git a/src/common/nm_bb_transc_fsm.c b/src/common/nm_bb_transc_fsm.c index 936451ff..b173102e 100644 --- a/src/common/nm_bb_transc_fsm.c +++ b/src/common/nm_bb_transc_fsm.c @@ -1,6 +1,6 @@ /* NM Radio Carrier FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -41,6 +41,17 @@ #define nm_bb_transc_fsm_state_chg(fi, NEXT_STATE) \ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) +static void ev_dispatch_children(struct gsm_bts_bb_trx *bb_transc, uint32_t event) +{ + struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); + uint8_t tn; + + for (tn = 0; tn < TRX_NR_TS; tn++) { + struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + osmo_fsm_inst_dispatch(ts->mo.fi, event, NULL); + } +} + ////////////////////////// // FSM STATE ACTIONS ////////////////////////// @@ -48,24 +59,28 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv; + /* Reset state: */ + TALLOC_FREE(bb_transc->mo.nm_attr); + + bb_transc->mo.setattr_success = false; bb_transc->mo.opstart_success = false; - oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); } static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv; - struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); - int i; switch (event) { case NM_EV_SW_ACT: oml_mo_tx_sw_act_rep(&bb_transc->mo); nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE); - for (i = 0; i < TRX_NR_TS; i++) { - struct gsm_bts_trx_ts *ts = &trx->ts[i]; - osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_BBTRANSC_INSTALLED, NULL); - } + ev_dispatch_children(bb_transc, event); + return; + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&bb_transc->mo); + ev_dispatch_children(bb_transc, event); return; case NM_EV_RSL_UP: return; @@ -88,8 +103,9 @@ static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t p struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); int i; + bb_transc->mo.setattr_success = false; bb_transc->mo.opstart_success = false; - oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); if (prev_state == NM_BBTRANSC_ST_OP_ENABLED) { for (i = 0; i < TRX_NR_TS; i++) { @@ -103,10 +119,48 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi { struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv; struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); + struct gsm_bts *bts = trx->bts; + struct nm_fsm_ev_setattr_data *setattr_data; bool phy_state_connected; bool rsl_link_connected; + int rc; switch (event) { + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&bb_transc->mo); + ev_dispatch_children(bb_transc, event); + return; + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(trx->bts, setattr_data->msg, + &bb_transc->mo, bb_transc); + bb_transc->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + return; + case NM_EV_RX_OPSTART: +#if 0 + /* Disabled because osmo-bsc doesn't send SetAttr on BB_TRANSC object */ + if (!bb_transc->mo.setattr_success) { + oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM); + return; + } +#endif + /* Connect RSL link: */ + if (bts->variant == BTS_OSMO_OMLDUMMY) { + LOGPFSML(fi, LOGL_NOTICE, "Not connecting RSL in OML-DUMMY!\n"); + } else { + rc = e1inp_ipa_bts_rsl_connect_n(bts->oml_link->ts->line, + bb_transc->rsl.rem_addrstr.ip, + bb_transc->rsl.rem_addrstr.port, trx->nr); + if (rc < 0) { + LOGPFSML(fi, LOGL_NOTICE, "Error connecting IPA RSL: %d\n", rc); + oml_mo_opstart_nack(&bb_transc->mo, NM_NACK_CANT_PERFORM); + return; + } + } + bts_model_opstart(trx->bts, &bb_transc->mo, bb_transc); + return; case NM_EV_OPSTART_ACK: bb_transc->mo.opstart_success = true; oml_mo_opstart_ack(&bb_transc->mo); @@ -130,23 +184,24 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi } - if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */ + if (bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */ struct phy_instance *pinst = trx_phy_instance(trx); phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED; - rsl_link_connected = !!trx->rsl_link; + rsl_link_connected = !!trx->bb_transc.rsl.link; } else { phy_state_connected = true; rsl_link_connected = true; } + /* We so far don't expect any SetAttributes for this NM object */ if (rsl_link_connected && phy_state_connected && bb_transc->mo.opstart_success) { nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_ENABLED); } else { LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s\n", - rsl_link_connected ? "": " rsl", - phy_state_connected ? "": " phy", - bb_transc->mo.opstart_success ? "": " opstart"); + rsl_link_connected ? "" : " rsl", + phy_state_connected ? "" : " phy", + bb_transc->mo.opstart_success ? "" : " opstart"); } } @@ -157,7 +212,7 @@ static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); uint8_t tn; - oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); + oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); /* Mark Dependency TS as Offline (ready to be Opstarted) */ for (tn = 0; tn < TRX_NR_TS; tn++) { struct gsm_bts_trx_ts *ts = &trx->ts[tn]; @@ -181,15 +236,40 @@ static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE); } +static void nm_bb_transc_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&bb_transc->mo, -1, -1, NM_STATE_SHUTDOWN); + + /* Propagate event to children: */ + ev_dispatch_children(bb_transc, event); + break; + case NM_EV_SHUTDOWN_FINISH: + /* Propagate event to children: */ + ev_dispatch_children(bb_transc, event); + nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + static struct osmo_fsm_state nm_bb_transc_fsm_states[] = { [NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = { .in_event_mask = X(NM_EV_SW_ACT) | + X(NM_EV_OML_UP) | X(NM_EV_RSL_UP) | X(NM_EV_RSL_DOWN) | X(NM_EV_PHYLINK_UP) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE), .name = "DISABLED_NOTINSTALLED", .onenter = st_op_disabled_notinstalled_on_enter, @@ -197,13 +277,18 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = { }, [NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = + X(NM_EV_OML_UP) | + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | X(NM_EV_OPSTART_ACK) | X(NM_EV_OPSTART_NACK) | X(NM_EV_RSL_UP) | X(NM_EV_RSL_DOWN) | X(NM_EV_PHYLINK_UP) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BBTRANSC_ST_OP_ENABLED), .name = "DISABLED_OFFLINE", .onenter = st_op_disabled_offline_on_enter, @@ -212,8 +297,10 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = { [NM_BBTRANSC_ST_OP_ENABLED] = { .in_event_mask = X(NM_EV_RSL_DOWN) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE), .name = "ENABLED", .onenter = st_op_enabled_on_enter, @@ -226,6 +313,9 @@ struct osmo_fsm nm_bb_transc_fsm = { .states = nm_bb_transc_fsm_states, .num_states = ARRAY_SIZE(nm_bb_transc_fsm_states), .event_names = nm_fsm_event_names, + .allstate_action = nm_bb_transc_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), .log_subsys = DOML, }; diff --git a/src/common/nm_bts_fsm.c b/src/common/nm_bts_fsm.c index 12f1a612..36aad733 100644 --- a/src/common/nm_bts_fsm.c +++ b/src/common/nm_bts_fsm.c @@ -1,6 +1,6 @@ /* NM BTS FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -35,12 +35,23 @@ #include <osmo-bts/rsl.h> #include <osmo-bts/nm_common_fsm.h> #include <osmo-bts/phy_link.h> +#include <osmo-bts/cbch.h> +#include <osmo-bts/notification.h> #define X(s) (1 << (s)) #define nm_bts_fsm_state_chg(fi, NEXT_STATE) \ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) +static void ev_dispatch_children(struct gsm_bts *bts, uint32_t event) +{ + struct gsm_bts_trx *trx; + llist_for_each_entry(trx, &bts->trx_list, list) { + osmo_fsm_inst_dispatch(trx->mo.fi, event, NULL); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, event, NULL); + } +} + ////////////////////////// // FSM STATE ACTIONS ////////////////////////// @@ -48,18 +59,46 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + /* Reset state: */ + bts->si_valid = 0; + bts->bsic_configured = false; + bts->bsic = 0xff; /* invalid value */ + TALLOC_FREE(bts->mo.nm_attr); + bts_cbch_reset(bts); + bts_asci_notification_reset(bts); + if (bts->c0_power_red_db > 0) + bts_set_c0_pwr_red(bts, 0); + + bts->mo.setattr_success = false; bts->mo.opstart_success = false; - oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); } static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + struct gsm_bts_trx *trx; switch (event) { - case NM_EV_SW_ACT: + case NM_EV_OML_UP: + /* automatic SW_ACT upon OML link establishment: */ oml_mo_tx_sw_act_rep(&bts->mo); + + llist_for_each_entry(trx, &bts->trx_list, list) { + if (trx->bts->variant == BTS_OSMO_OMLDUMMY) /* In OMLDUMMY, phy=NULL */ + continue; + /* During startup, phy_links are already opened, but if we are + * re-connecting, phy_link was closed when disconnected from + * previous BSC, so let's re-open it. + */ + struct phy_instance *pinst = trx_phy_instance(trx); + struct phy_link *plink = pinst->phy_link; + if (phy_link_state_get(plink) == PHY_LINK_SHUTDOWN) + bts_model_phy_link_open(plink); + } + nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_OFFLINE); + ev_dispatch_children(bts, event); return; default: OSMO_ASSERT(0); @@ -69,15 +108,31 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + bts->mo.setattr_success = false; bts->mo.opstart_success = false; - oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_chg(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); } static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, &bts->mo, bts); + bts->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!bts->mo.setattr_success) { + oml_mo_opstart_nack(&bts->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &bts->mo, bts); + break; case NM_EV_OPSTART_ACK: bts->mo.opstart_success = true; oml_mo_opstart_ack(&bts->mo); @@ -95,18 +150,41 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts *bts = (struct gsm_bts *)fi->priv; - oml_mo_state_chg(&bts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); + oml_mo_state_chg(&bts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); } static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) { } +static void nm_bts_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts *bts = (struct gsm_bts *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&bts->mo, -1, -1, NM_STATE_SHUTDOWN); + + /* Propagate event to children: */ + ev_dispatch_children(bts, event); + break; + case NM_EV_SHUTDOWN_FINISH: + /* Propagate event to children: */ + ev_dispatch_children(bts, event); + nm_bts_fsm_state_chg(fi, NM_BTS_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + static struct osmo_fsm_state nm_bts_fsm_states[] = { [NM_BTS_ST_OP_DISABLED_NOTINSTALLED] = { .in_event_mask = - X(NM_EV_SW_ACT), + X(NM_EV_OML_UP), .out_state_mask = + X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BTS_ST_OP_DISABLED_OFFLINE), .name = "DISABLED_NOTINSTALLED", .onenter = st_op_disabled_notinstalled_on_enter, @@ -114,9 +192,12 @@ static struct osmo_fsm_state nm_bts_fsm_states[] = { }, [NM_BTS_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | X(NM_EV_OPSTART_ACK) | X(NM_EV_OPSTART_NACK), .out_state_mask = + X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BTS_ST_OP_ENABLED), .name = "DISABLED_OFFLINE", .onenter = st_op_disabled_offline_on_enter, @@ -124,7 +205,8 @@ static struct osmo_fsm_state nm_bts_fsm_states[] = { }, [NM_BTS_ST_OP_ENABLED] = { .in_event_mask = 0, - .out_state_mask = 0, + .out_state_mask = + X(NM_BTS_ST_OP_DISABLED_NOTINSTALLED), .name = "ENABLED", .onenter = st_op_enabled_on_enter, .action = st_op_enabled, @@ -136,6 +218,9 @@ struct osmo_fsm nm_bts_fsm = { .states = nm_bts_fsm_states, .num_states = ARRAY_SIZE(nm_bts_fsm_states), .event_names = nm_fsm_event_names, + .allstate_action = nm_bts_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), .log_subsys = DOML, }; diff --git a/src/common/nm_bts_sm_fsm.c b/src/common/nm_bts_sm_fsm.c index dedbacbd..9ac0edd9 100644 --- a/src/common/nm_bts_sm_fsm.c +++ b/src/common/nm_bts_sm_fsm.c @@ -1,6 +1,6 @@ /* NM BTS Site Manager FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -32,6 +32,7 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/rsl.h> #include <osmo-bts/nm_common_fsm.h> #include <osmo-bts/phy_link.h> @@ -41,6 +42,16 @@ #define nm_bts_sm_fsm_state_chg(fi, NEXT_STATE) \ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) + +static void ev_dispatch_children(struct gsm_bts_sm *site_mgr, uint32_t event) +{ + struct gsm_bts *bts; + osmo_fsm_inst_dispatch(site_mgr->gprs.nse.mo.fi, event, NULL); + llist_for_each_entry(bts, &site_mgr->bts_list, list) { + osmo_fsm_inst_dispatch(bts->mo.fi, event, NULL); + } +} + ////////////////////////// // FSM STATE ACTIONS ////////////////////////// @@ -48,8 +59,9 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; + site_mgr->mo.setattr_success = false; site_mgr->mo.opstart_success = false; - oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); } static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -57,9 +69,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; switch (event) { - case NM_EV_SW_ACT: + case NM_EV_OML_UP: + /* automatic SW_ACT upon OML link establishment: */ oml_mo_tx_sw_act_rep(&site_mgr->mo); nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_DISABLED_OFFLINE); + ev_dispatch_children(site_mgr, event); return; default: OSMO_ASSERT(0); @@ -69,15 +83,35 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; + site_mgr->mo.setattr_success = false; site_mgr->mo.opstart_success = false; - oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); } static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + /* No bts_model_apply_oml() needed yet for site_mgr obj yet: */ + rc = 0; + site_mgr->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: +#if 0 + /* Disabled because osmo-bsc doesn't send SetAttr on SITE_MGR object */ + if (!site_mgr->mo.setattr_success) { + oml_mo_opstart_nack(&site_mgr->mo, NM_NACK_CANT_PERFORM); + return; + } +#endif + bts_model_opstart(NULL, &site_mgr->mo, site_mgr); + break; case NM_EV_OPSTART_ACK: site_mgr->mo.opstart_success = true; oml_mo_opstart_ack(&site_mgr->mo); @@ -95,18 +129,41 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; - oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); + oml_mo_state_chg(&site_mgr->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); } static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) { } +static void nm_bts_sm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts_sm *site_mgr = (struct gsm_bts_sm *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&site_mgr->mo, -1, -1, NM_STATE_SHUTDOWN); + + /* Propagate event to children: */ + ev_dispatch_children(site_mgr, event); + break; + case NM_EV_SHUTDOWN_FINISH: + /* Propagate event to children: */ + ev_dispatch_children(site_mgr, event); + nm_bts_sm_fsm_state_chg(fi, NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + static struct osmo_fsm_state nm_bts_sm_fsm_states[] = { [NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED] = { .in_event_mask = - X(NM_EV_SW_ACT), + X(NM_EV_OML_UP), .out_state_mask = + X(NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BTS_SM_ST_OP_DISABLED_OFFLINE), .name = "DISABLED_NOTINSTALLED", .onenter = st_op_disabled_notinstalled_on_enter, @@ -114,9 +171,12 @@ static struct osmo_fsm_state nm_bts_sm_fsm_states[] = { }, [NM_BTS_SM_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | X(NM_EV_OPSTART_ACK) | X(NM_EV_OPSTART_NACK), .out_state_mask = + X(NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BTS_SM_ST_OP_ENABLED), .name = "DISABLED_OFFLINE", .onenter = st_op_disabled_offline_on_enter, @@ -124,7 +184,8 @@ static struct osmo_fsm_state nm_bts_sm_fsm_states[] = { }, [NM_BTS_SM_ST_OP_ENABLED] = { .in_event_mask = 0, - .out_state_mask = 0, + .out_state_mask = + X(NM_BTS_SM_ST_OP_DISABLED_NOTINSTALLED), .name = "ENABLED", .onenter = st_op_enabled_on_enter, .action = st_op_enabled, @@ -136,6 +197,9 @@ struct osmo_fsm nm_bts_sm_fsm = { .states = nm_bts_sm_fsm_states, .num_states = ARRAY_SIZE(nm_bts_sm_fsm_states), .event_names = nm_fsm_event_names, + .allstate_action = nm_bts_sm_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), .log_subsys = DOML, }; diff --git a/src/common/nm_channel_fsm.c b/src/common/nm_channel_fsm.c index 15be6c6a..d41fcd11 100644 --- a/src/common/nm_channel_fsm.c +++ b/src/common/nm_channel_fsm.c @@ -1,6 +1,6 @@ /* NM Radio Carrier FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -55,8 +55,15 @@ static bool ts_can_be_enabled(const struct gsm_bts_trx_ts *ts) static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; + /* Reset state: */ + gsm_ts_release(ts); + if (ts->vamos.peer) + gsm_ts_release(ts->vamos.peer); + TALLOC_FREE(ts->mo.nm_attr); + + ts->mo.setattr_success = false; ts->mo.opstart_success = false; - oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); } static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -64,7 +71,11 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; switch (event) { - case NM_EV_BBTRANSC_INSTALLED: + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&ts->mo); + return; + case NM_EV_SW_ACT: oml_mo_tx_sw_act_rep(&ts->mo); if (ts_can_be_enabled(ts)) nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_OFFLINE); @@ -80,17 +91,37 @@ static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_ { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; ts->mo.opstart_success = false; - oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); + oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY, -1); } static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; switch (event) { + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&ts->mo); + return; + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg, + &ts->mo, ts); + ts->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + LOGPFSML(fi, LOGL_NOTICE, "BSC trying to activate TS while still in avail=dependency. " + "Allowing it to stay backward-compatible with older osmo-bts versions, but BSC is wrong.\n"); + if (!ts->mo.setattr_success) { + oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(ts->trx->bts, &ts->mo, ts); + break; case NM_EV_OPSTART_ACK: - LOGPFSML(fi, LOGL_NOTICE, "BSC trying to activate TS while still in avail=dependency. " - "Allowing it to stay backward-compatible with older osmo-bts versions, but BSC is wrong.\n"); ts->mo.opstart_success = true; oml_mo_opstart_ack(&ts->mo); nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED); @@ -117,14 +148,34 @@ static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t p { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; ts->mo.opstart_success = false; - oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); } static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; switch (event) { + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&ts->mo); + return; + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(ts->trx->bts, setattr_data->msg, + &ts->mo, ts); + ts->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!ts->mo.setattr_success) { + oml_mo_opstart_nack(&ts->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(ts->trx->bts, &ts->mo, ts); + break; case NM_EV_OPSTART_ACK: ts->mo.opstart_success = true; oml_mo_opstart_ack(&ts->mo); @@ -147,7 +198,7 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; - oml_mo_state_chg(&ts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); + oml_mo_state_chg(&ts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); } static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -168,11 +219,30 @@ static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) } } +static void nm_chan_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts_trx_ts *ts = (struct gsm_bts_trx_ts *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&ts->mo, -1, -1, NM_STATE_SHUTDOWN); + break; + case NM_EV_SHUTDOWN_FINISH: + nm_chan_fsm_state_chg(fi, NM_CHAN_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + static struct osmo_fsm_state nm_chan_fsm_states[] = { [NM_CHAN_ST_OP_DISABLED_NOTINSTALLED] = { .in_event_mask = - X(NM_EV_BBTRANSC_INSTALLED), + X(NM_EV_SW_ACT) | + X(NM_EV_OML_UP), .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | X(NM_CHAN_ST_OP_DISABLED_DEPENDENCY), .name = "DISABLED_NOTINSTALLED", @@ -181,13 +251,17 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = { }, [NM_CHAN_ST_OP_DISABLED_DEPENDENCY] = { .in_event_mask = - X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ - X(NM_EV_OPSTART_NACK) | + X(NM_EV_OML_UP) | + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_NACK) | /* backward compatibility, buggy BSC */ X(NM_EV_BBTRANSC_ENABLED) | X(NM_EV_RCARRIER_ENABLED) | X(NM_EV_BBTRANSC_DISABLED) | X(NM_EV_RCARRIER_DISABLED), .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | X(NM_CHAN_ST_OP_ENABLED), /* backward compatibility, buggy BSC */ .name = "DISABLED_DEPENDENCY", @@ -196,11 +270,15 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = { }, [NM_CHAN_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = + X(NM_EV_OML_UP) | + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | X(NM_EV_OPSTART_ACK) | X(NM_EV_OPSTART_NACK) | X(NM_EV_BBTRANSC_DISABLED) | X(NM_EV_RCARRIER_DISABLED), .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | X(NM_CHAN_ST_OP_ENABLED) | X(NM_CHAN_ST_OP_DISABLED_DEPENDENCY), .name = "DISABLED_OFFLINE", @@ -213,6 +291,7 @@ static struct osmo_fsm_state nm_chan_fsm_states[] = { X(NM_EV_RCARRIER_DISABLED) | X(NM_EV_DISABLE), .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | X(NM_CHAN_ST_OP_DISABLED_DEPENDENCY), .name = "ENABLED", @@ -226,6 +305,9 @@ struct osmo_fsm nm_chan_fsm = { .states = nm_chan_fsm_states, .num_states = ARRAY_SIZE(nm_chan_fsm_states), .event_names = nm_fsm_event_names, + .allstate_action = nm_chan_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), .log_subsys = DOML, }; diff --git a/src/common/nm_common_fsm.c b/src/common/nm_common_fsm.c index 7273e22f..aa9bda4c 100644 --- a/src/common/nm_common_fsm.c +++ b/src/common/nm_common_fsm.c @@ -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 @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -25,14 +25,18 @@ const struct value_string nm_fsm_event_names[] = { { NM_EV_SW_ACT, "SW_ACT" }, + { NM_EV_RX_SETATTR, "RX_SETATTR" }, + { NM_EV_RX_OPSTART, "RX_OPSTART" }, { NM_EV_OPSTART_ACK, "OPSTART_ACK" }, { NM_EV_OPSTART_NACK, "OPSTART_NACK" }, + { NM_EV_SHUTDOWN_START, "SHUTDOWN_START" }, + { NM_EV_SHUTDOWN_FINISH, "SHUTDOWN_FINISH" }, + { NM_EV_OML_UP, "OML_UP" }, { NM_EV_RSL_UP, "RSL_UP" }, { NM_EV_RSL_DOWN, "RSL_DOWN" }, { NM_EV_PHYLINK_UP, "PHYLINK_UP" }, { NM_EV_PHYLINK_DOWN, "PHYLINK_DOWN" }, { NM_EV_DISABLE, "DISABLE" }, - { NM_EV_BBTRANSC_INSTALLED, "BBTRANSC_INSTALLED" }, { NM_EV_BBTRANSC_ENABLED, "BBTRANSC_ENABLED" }, { NM_EV_BBTRANSC_DISABLED, "BBTRANSC_DISABLED" }, { NM_EV_RCARRIER_ENABLED, "RCARRIER_ENABLED" }, diff --git a/src/common/nm_gprs_cell_fsm.c b/src/common/nm_gprs_cell_fsm.c new file mode 100644 index 00000000..95f46e31 --- /dev/null +++ b/src/common/nm_gprs_cell_fsm.c @@ -0,0 +1,260 @@ +/* NM GPRS Cell FSM */ + +/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/tdef.h> +#include <osmocom/gsm/protocol/gsm_12_21.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/nm_common_fsm.h> + +#define X(s) (1 << (s)) + +#define nm_gprs_cell_fsm_state_chg(fi, NEXT_STATE) \ + osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) + +/* Can the GPRS Cell be enabled (OPSTARTed)? aka should it stay in "Disabled Dependency" state? */ +static bool gprs_cell_can_be_enabled(struct gsm_gprs_cell *cell) +{ + struct gsm_bts *bts = gsm_gprs_cell_get_bts(cell); + return bts->site_mgr->gprs.nse.mo.nm_state.operational == NM_OPSTATE_ENABLED; +} + + +////////////////////////// +// FSM STATE ACTIONS +////////////////////////// + +static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + /* Reset state here: */ + + cell->mo.setattr_success = false; + cell->mo.opstart_success = false; + oml_mo_state_chg(&cell->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); +} + +static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + + switch (event) { + case NM_EV_OML_UP: + /* automatic SW_ACT upon OML link establishment: */ + oml_mo_tx_sw_act_rep(&cell->mo); + if (gprs_cell_can_be_enabled(cell)) + nm_gprs_cell_fsm_state_chg(fi, NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE); + else + nm_gprs_cell_fsm_state_chg(fi, NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + cell->mo.setattr_success = false; + cell->mo.opstart_success = false; + oml_mo_state_chg(&cell->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY, -1); +} + +static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + struct gsm_bts *bts = gsm_gprs_cell_get_bts(cell); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, + &cell->mo, cell); + cell->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!cell->mo.setattr_success) { + oml_mo_opstart_nack(&cell->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &cell->mo, cell); + break; + case NM_EV_OPSTART_ACK: + cell->mo.opstart_success = true; + oml_mo_opstart_ack(&cell->mo); + nm_gprs_cell_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED); + return; + case NM_EV_OPSTART_NACK: + cell->mo.opstart_success = false; + oml_mo_opstart_nack(&cell->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + cell->mo.opstart_success = false; + oml_mo_state_chg(&cell->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); +} + +static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + struct gsm_bts *bts = gsm_gprs_cell_get_bts(cell); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, &cell->mo, bts); + cell->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!cell->mo.setattr_success) { + oml_mo_opstart_nack(&cell->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &cell->mo, bts); + break; + case NM_EV_OPSTART_ACK: + cell->mo.opstart_success = true; + oml_mo_opstart_ack(&cell->mo); + nm_gprs_cell_fsm_state_chg(fi, NM_GPRS_CELL_ST_OP_ENABLED); + break; /* check statechg below */ + case NM_EV_OPSTART_NACK: + cell->mo.opstart_success = false; + oml_mo_opstart_nack(&cell->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + oml_mo_state_chg(&cell->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); +} + +static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ +} + +static void nm_gprs_cell_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_cell *cell = (struct gsm_gprs_cell *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&cell->mo, -1, -1, NM_STATE_SHUTDOWN); + break; + case NM_EV_SHUTDOWN_FINISH: + nm_gprs_cell_fsm_state_chg(fi, NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + +static struct osmo_fsm_state nm_gprs_cell_fsm_states[] = { + [NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED] = { + .in_event_mask = + X(NM_EV_OML_UP), + .out_state_mask = + X(NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY) | + X(NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE), + .name = "DISABLED_NOTINSTALLED", + .onenter = st_op_disabled_notinstalled_on_enter, + .action = st_op_disabled_notinstalled, + }, + [NM_GPRS_CELL_ST_OP_DISABLED_DEPENDENCY] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_NACK), /* backward compatibility, buggy BSC */ + .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | + X(NM_CHAN_ST_OP_ENABLED), /* backward compatibility, buggy BSC */ + .name = "DISABLED_DEPENDENCY", + .onenter = st_op_disabled_dependency_on_enter, + .action = st_op_disabled_dependency, + }, + [NM_GPRS_CELL_ST_OP_DISABLED_OFFLINE] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | + X(NM_EV_OPSTART_ACK) | + X(NM_EV_OPSTART_NACK), + .out_state_mask = + X(NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_CELL_ST_OP_ENABLED), + .name = "DISABLED_OFFLINE", + .onenter = st_op_disabled_offline_on_enter, + .action = st_op_disabled_offline, + }, + [NM_GPRS_CELL_ST_OP_ENABLED] = { + .in_event_mask = 0, + .out_state_mask = + X(NM_GPRS_CELL_ST_OP_DISABLED_NOTINSTALLED), + .name = "ENABLED", + .onenter = st_op_enabled_on_enter, + .action = st_op_enabled, + }, +}; + +struct osmo_fsm nm_gprs_cell_fsm = { + .name = "NM_GPRS_CELL_OP", + .states = nm_gprs_cell_fsm_states, + .num_states = ARRAY_SIZE(nm_gprs_cell_fsm_states), + .event_names = nm_fsm_event_names, + .allstate_action = nm_gprs_cell_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), + .log_subsys = DOML, +}; + +static __attribute__((constructor)) void nm_gprs_cell_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&nm_gprs_cell_fsm) == 0); +} diff --git a/src/common/nm_gprs_nse_fsm.c b/src/common/nm_gprs_nse_fsm.c new file mode 100644 index 00000000..2818c868 --- /dev/null +++ b/src/common/nm_gprs_nse_fsm.c @@ -0,0 +1,280 @@ +/* NM GPRS NSE FSM */ + +/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/tdef.h> +#include <osmocom/gsm/protocol/gsm_12_21.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/nm_common_fsm.h> +#include <osmo-bts/phy_link.h> +#include <osmo-bts/cbch.h> + +#define X(s) (1 << (s)) + +#define nm_gprs_nse_fsm_state_chg(fi, NEXT_STATE) \ + osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) + +static void ev_dispatch_children(struct gsm_gprs_nse *nse, uint32_t event) +{ + unsigned int i; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + + osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, event, NULL); + for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) { + struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i]; + osmo_fsm_inst_dispatch(nsvc->mo.fi, event, NULL); + } +} + +/* Can the NSE be enabled (OPSTARTed)? aka should it stay in "Disabled Dependency" state? */ +static bool nse_can_be_enabled(struct gsm_gprs_nse *nse) +{ + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED; +} + + +////////////////////////// +// FSM STATE ACTIONS +////////////////////////// + +static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + /* Reset state here: */ + + nse->mo.setattr_success = false; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); +} + +static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + + switch (event) { + case NM_EV_OML_UP: + /* automatic SW_ACT upon OML link establishment: */ + oml_mo_tx_sw_act_rep(&nse->mo); + ev_dispatch_children(nse, event); + if (nse_can_be_enabled(nse)) + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE); + else + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + nse->mo.setattr_success = false; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY, -1); +} + +static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, + &nse->mo, nse); + nse->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nse->mo.setattr_success) { + oml_mo_opstart_nack(&nse->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nse->mo, nse); + break; + case NM_EV_OPSTART_ACK: + nse->mo.opstart_success = true; + oml_mo_opstart_ack(&nse->mo); + nm_gprs_nse_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED); + return; + case NM_EV_OPSTART_NACK: + nse->mo.opstart_success = false; + oml_mo_opstart_nack(&nse->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); +} + +static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, &nse->mo, bts); + nse->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nse->mo.setattr_success) { + oml_mo_opstart_nack(&nse->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nse->mo, bts); + break; + case NM_EV_OPSTART_ACK: + nse->mo.opstart_success = true; + oml_mo_opstart_ack(&nse->mo); + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_ENABLED); + break; /* check statechg below */ + case NM_EV_OPSTART_NACK: + nse->mo.opstart_success = false; + oml_mo_opstart_nack(&nse->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); +} + +static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ +} + +static void nm_gprs_nse_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&nse->mo, -1, -1, NM_STATE_SHUTDOWN); + + /* Propagate event to children: */ + ev_dispatch_children(nse, event); + break; + case NM_EV_SHUTDOWN_FINISH: + /* Propagate event to children: */ + ev_dispatch_children(nse, event); + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + +static struct osmo_fsm_state nm_gprs_nse_fsm_states[] = { + [NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED] = { + .in_event_mask = + X(NM_EV_OML_UP), + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY) | + X(NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE), + .name = "DISABLED_NOTINSTALLED", + .onenter = st_op_disabled_notinstalled_on_enter, + .action = st_op_disabled_notinstalled, + }, + [NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_NACK), /* backward compatibility, buggy BSC */ + .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | + X(NM_CHAN_ST_OP_ENABLED), /* backward compatibility, buggy BSC */ + .name = "DISABLED_DEPENDENCY", + .onenter = st_op_disabled_dependency_on_enter, + .action = st_op_disabled_dependency, + }, + [NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | + X(NM_EV_OPSTART_ACK) | + X(NM_EV_OPSTART_NACK), + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSE_ST_OP_ENABLED), + .name = "DISABLED_OFFLINE", + .onenter = st_op_disabled_offline_on_enter, + .action = st_op_disabled_offline, + }, + [NM_GPRS_NSE_ST_OP_ENABLED] = { + .in_event_mask = 0, + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED), + .name = "ENABLED", + .onenter = st_op_enabled_on_enter, + .action = st_op_enabled, + }, +}; + +struct osmo_fsm nm_gprs_nse_fsm = { + .name = "NM_GPRS_NSE_OP", + .states = nm_gprs_nse_fsm_states, + .num_states = ARRAY_SIZE(nm_gprs_nse_fsm_states), + .event_names = nm_fsm_event_names, + .allstate_action = nm_gprs_nse_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), + .log_subsys = DOML, +}; + +static __attribute__((constructor)) void nm_gprs_nse_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&nm_gprs_nse_fsm) == 0); +} diff --git a/src/common/nm_gprs_nsvc_fsm.c b/src/common/nm_gprs_nsvc_fsm.c new file mode 100644 index 00000000..cbfd97af --- /dev/null +++ b/src/common/nm_gprs_nsvc_fsm.c @@ -0,0 +1,259 @@ +/* NM GPRS NSVC FSM */ + +/* (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/tdef.h> +#include <osmocom/gsm/protocol/gsm_12_21.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/nm_common_fsm.h> + +#define X(s) (1 << (s)) + +#define nm_gprs_nsvc_fsm_state_chg(fi, NEXT_STATE) \ + osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) + +/* Can the GPRS Cell be enabled (OPSTARTed)? aka should it stay in "Disabled Dependency" state? */ +static bool gprs_nsvc_can_be_enabled(struct gsm_gprs_nsvc *nsvc) +{ + return nsvc->nse->mo.nm_state.operational == NM_OPSTATE_ENABLED; +} + + +////////////////////////// +// FSM STATE ACTIONS +////////////////////////// + +static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + /* Reset state here: */ + + nsvc->mo.setattr_success = false; + nsvc->mo.opstart_success = false; + oml_mo_state_chg(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); +} + +static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + + switch (event) { + case NM_EV_OML_UP: + /* automatic SW_ACT upon OML link establishment: */ + oml_mo_tx_sw_act_rep(&nsvc->mo); + if (gprs_nsvc_can_be_enabled(nsvc)) + nm_gprs_nsvc_fsm_state_chg(fi, NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE); + else + nm_gprs_nsvc_fsm_state_chg(fi, NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + nsvc->mo.setattr_success = false; + nsvc->mo.opstart_success = false; + oml_mo_state_chg(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY, -1); +} + +static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nsvc->nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, + &nsvc->mo, nsvc); + nsvc->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nsvc->mo.setattr_success) { + oml_mo_opstart_nack(&nsvc->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nsvc->mo, nsvc); + break; + case NM_EV_OPSTART_ACK: + nsvc->mo.opstart_success = true; + oml_mo_opstart_ack(&nsvc->mo); + nm_gprs_nsvc_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED); + return; + case NM_EV_OPSTART_NACK: + nsvc->mo.opstart_success = false; + oml_mo_opstart_nack(&nsvc->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + nsvc->mo.opstart_success = false; + oml_mo_state_chg(&nsvc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); +} + +static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nsvc->nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, &nsvc->mo, bts); + nsvc->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nsvc->mo.setattr_success) { + oml_mo_opstart_nack(&nsvc->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nsvc->mo, bts); + break; + case NM_EV_OPSTART_ACK: + nsvc->mo.opstart_success = true; + oml_mo_opstart_ack(&nsvc->mo); + nm_gprs_nsvc_fsm_state_chg(fi, NM_GPRS_NSVC_ST_OP_ENABLED); + break; /* check statechg below */ + case NM_EV_OPSTART_NACK: + nsvc->mo.opstart_success = false; + oml_mo_opstart_nack(&nsvc->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + oml_mo_state_chg(&nsvc->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); +} + +static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ +} + +static void nm_gprs_nsvc_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nsvc *nsvc = (struct gsm_gprs_nsvc *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&nsvc->mo, -1, -1, NM_STATE_SHUTDOWN); + break; + case NM_EV_SHUTDOWN_FINISH: + nm_gprs_nsvc_fsm_state_chg(fi, NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + +static struct osmo_fsm_state nm_gprs_nsvc_fsm_states[] = { + [NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED] = { + .in_event_mask = + X(NM_EV_OML_UP), + .out_state_mask = + X(NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY) | + X(NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE), + .name = "DISABLED_NOTINSTALLED", + .onenter = st_op_disabled_notinstalled_on_enter, + .action = st_op_disabled_notinstalled, + }, + [NM_GPRS_NSVC_ST_OP_DISABLED_DEPENDENCY] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_NACK), /* backward compatibility, buggy BSC */ + .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | + X(NM_CHAN_ST_OP_ENABLED), /* backward compatibility, buggy BSC */ + .name = "DISABLED_DEPENDENCY", + .onenter = st_op_disabled_dependency_on_enter, + .action = st_op_disabled_dependency, + }, + [NM_GPRS_NSVC_ST_OP_DISABLED_OFFLINE] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | + X(NM_EV_OPSTART_ACK) | + X(NM_EV_OPSTART_NACK), + .out_state_mask = + X(NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSVC_ST_OP_ENABLED), + .name = "DISABLED_OFFLINE", + .onenter = st_op_disabled_offline_on_enter, + .action = st_op_disabled_offline, + }, + [NM_GPRS_NSVC_ST_OP_ENABLED] = { + .in_event_mask = 0, + .out_state_mask = + X(NM_GPRS_NSVC_ST_OP_DISABLED_NOTINSTALLED), + .name = "ENABLED", + .onenter = st_op_enabled_on_enter, + .action = st_op_enabled, + }, +}; + +struct osmo_fsm nm_gprs_nsvc_fsm = { + .name = "NM_GPRS_NSVC_OP", + .states = nm_gprs_nsvc_fsm_states, + .num_states = ARRAY_SIZE(nm_gprs_nsvc_fsm_states), + .event_names = nm_fsm_event_names, + .allstate_action = nm_gprs_nsvc_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), + .log_subsys = DOML, +}; + +static __attribute__((constructor)) void nm_gprs_nsvc_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&nm_gprs_nsvc_fsm) == 0); +} diff --git a/src/common/nm_radio_carrier_fsm.c b/src/common/nm_radio_carrier_fsm.c index 4cbdf682..f9589532 100644 --- a/src/common/nm_radio_carrier_fsm.c +++ b/src/common/nm_radio_carrier_fsm.c @@ -1,6 +1,6 @@ /* NM Radio Carrier FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -48,8 +48,12 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) { struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv; + /* Reset state: */ + TALLOC_FREE(trx->mo.nm_attr); + + trx->mo.setattr_success = false; trx->mo.opstart_success = false; - oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); } static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -61,6 +65,10 @@ static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event oml_mo_tx_sw_act_rep(&trx->mo); nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_OFFLINE); return; + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&trx->mo); + return; case NM_EV_RSL_UP: return; case NM_EV_RSL_DOWN: @@ -81,8 +89,9 @@ static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t p struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv; unsigned int i; + trx->mo.setattr_success = false; trx->mo.opstart_success = false; - oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE); + oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); if (prev_state == NM_RCARRIER_ST_OP_ENABLED) { for (i = 0; i < TRX_NR_TS; i++) { @@ -95,10 +104,30 @@ static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t p static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv; + struct nm_fsm_ev_setattr_data *setattr_data; bool phy_state_connected; bool rsl_link_connected; + int rc; switch (event) { + case NM_EV_OML_UP: + /* Report current state: */ + oml_tx_state_changed(&trx->mo); + return; + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(trx->bts, setattr_data->msg, + &trx->mo, trx); + trx->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; /* check statechg below */ + case NM_EV_RX_OPSTART: + if (!trx->mo.setattr_success) { + oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(trx->bts, &trx->mo, trx); + return; case NM_EV_OPSTART_ACK: trx->mo.opstart_success = true; oml_mo_opstart_ack(&trx->mo); @@ -124,20 +153,21 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */ struct phy_instance *pinst = trx_phy_instance(trx); phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED; - rsl_link_connected = !!trx->rsl_link; + rsl_link_connected = !!trx->bb_transc.rsl.link; } else { phy_state_connected = true; rsl_link_connected = true; } if (rsl_link_connected && phy_state_connected && - trx->mo.opstart_success) { + trx->mo.setattr_success && trx->mo.opstart_success) { nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_ENABLED); } else { - LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s\n", - rsl_link_connected ? "": " rsl", - phy_state_connected ? "": " phy", - trx->mo.opstart_success ? "": " opstart"); + LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s%s\n", + rsl_link_connected ? "" : " rsl", + phy_state_connected ? "" : " phy", + trx->mo.setattr_success ? "" : " setattr", + trx->mo.opstart_success ? "" : " opstart"); } } @@ -147,7 +177,7 @@ static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv; unsigned int tn; - oml_mo_state_chg(&trx->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); + oml_mo_state_chg(&trx->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); /* Mark Dependency TS as Offline (ready to be Opstarted) */ for (tn = 0; tn < TRX_NR_TS; tn++) { struct gsm_bts_trx_ts *ts = &trx->ts[tn]; @@ -171,15 +201,35 @@ static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_OFFLINE); } +static void nm_rcarrier_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&trx->mo, -1, -1, NM_STATE_SHUTDOWN); + break; + case NM_EV_SHUTDOWN_FINISH: + nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + static struct osmo_fsm_state nm_rcarrier_fsm_states[] = { [NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED] = { .in_event_mask = X(NM_EV_SW_ACT) | + X(NM_EV_OML_UP) | X(NM_EV_RSL_UP) | X(NM_EV_RSL_DOWN) | X(NM_EV_PHYLINK_UP) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED) | X(NM_RCARRIER_ST_OP_DISABLED_OFFLINE), .name = "DISABLED_NOTINSTALLED", .onenter = st_op_disabled_notinstalled_on_enter, @@ -187,13 +237,18 @@ static struct osmo_fsm_state nm_rcarrier_fsm_states[] = { }, [NM_RCARRIER_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = + X(NM_EV_OML_UP) | + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | X(NM_EV_OPSTART_ACK) | X(NM_EV_OPSTART_NACK) | X(NM_EV_RSL_UP) | X(NM_EV_RSL_DOWN) | X(NM_EV_PHYLINK_UP) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED) | X(NM_RCARRIER_ST_OP_ENABLED), .name = "DISABLED_OFFLINE", .onenter = st_op_disabled_offline_on_enter, @@ -202,8 +257,10 @@ static struct osmo_fsm_state nm_rcarrier_fsm_states[] = { [NM_RCARRIER_ST_OP_ENABLED] = { .in_event_mask = X(NM_EV_RSL_DOWN) | - X(NM_EV_PHYLINK_DOWN), + X(NM_EV_PHYLINK_DOWN) | + X(NM_EV_DISABLE), .out_state_mask = + X(NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED) | X(NM_RCARRIER_ST_OP_DISABLED_OFFLINE), .name = "ENABLED", .onenter = st_op_enabled_on_enter, @@ -216,6 +273,9 @@ struct osmo_fsm nm_rcarrier_fsm = { .states = nm_rcarrier_fsm_states, .num_states = ARRAY_SIZE(nm_rcarrier_fsm_states), .event_names = nm_fsm_event_names, + .allstate_action = nm_rcarrier_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), .log_subsys = DOML, }; diff --git a/src/common/notification.c b/src/common/notification.c new file mode 100644 index 00000000..9351ec04 --- /dev/null +++ b/src/common/notification.c @@ -0,0 +1,256 @@ +/* Maintain and generate ASCI notifications */ + +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * + * SPDX-License-Identifier: AGPL-3.0+ + * + * Author: Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <errno.h> + +#include <osmocom/core/bitvec.h> +#include <osmocom/core/linuxlist.h> +#include <osmocom/gsm/protocol/gsm_08_58.h> + +#include <osmo-bts/bts.h> +#include <osmo-bts/logging.h> +#include <osmo-bts/notification.h> + +static struct asci_notification *bts_asci_notification_find(struct gsm_bts *bts, const uint8_t *group_call_ref) +{ + struct asci_notification *n; + llist_for_each_entry(n, &bts->asci.notifications, list) { + if (!memcmp(n->group_call_ref, group_call_ref, sizeof(n->group_call_ref))) + return n; + } + return NULL; +} + +int bts_asci_notification_add(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc, + uint8_t chan_desc_len, const struct rsl_ie_nch_drx_info *nch_drx_info) +{ + struct asci_notification *n; + + if (bts_asci_notification_find(bts, group_call_ref)) + return -EEXIST; + + n = talloc_zero(bts, struct asci_notification); + if (!n) + return -ENOMEM; + + memcpy(n->group_call_ref, group_call_ref, sizeof(n->group_call_ref)); + if (chan_desc && chan_desc_len) { + n->chan_desc.present = true; + n->chan_desc.len = chan_desc_len; + memcpy(&n->chan_desc.value, chan_desc, chan_desc_len); + } + if (nch_drx_info) { + n->nch_drx_info.present = true; + n->nch_drx_info.value = *nch_drx_info; + } + + LOGP(DASCI, LOGL_INFO, "Added ASCI Notification for group call reference %s\n", + osmo_hexdump_nospc(n->group_call_ref, ARRAY_SIZE(n->group_call_ref))); + + /* add at beginning of "queue" to make sure a new call is notified first */ + llist_add(&n->list, &bts->asci.notifications); + + bts->asci.notification_entries++; + bts->asci.notification_count = 0; + bts->asci.nln = (bts->asci.nln + 1) % 4; + + return 0; +} + +int bts_asci_notification_del(struct gsm_bts *bts, const uint8_t *group_call_ref) +{ + struct asci_notification *n = bts_asci_notification_find(bts, group_call_ref); + if (!n) + return -ENODEV; + + LOGP(DASCI, LOGL_INFO, "Deleting ASCI Notification for group call reference %s\n", + osmo_hexdump_nospc(n->group_call_ref, ARRAY_SIZE(n->group_call_ref))); + + llist_del(&n->list); + talloc_free(n); + + bts->asci.notification_entries--; + bts->asci.notification_count = 0; + bts->asci.nln_status = (bts->asci.nln_status + 1) % 2; + + return 0; +} + +int bts_asci_notification_reset(struct gsm_bts *bts) +{ + struct asci_notification *n, *n2; + + LOGP(DASCI, LOGL_INFO, "Deleting all %u ASCI Notifications of BTS\n", + llist_count(&bts->asci.notifications)); + + llist_for_each_entry_safe(n, n2, &bts->asci.notifications, list) { + llist_del(&n->list); + talloc_free(n); + } + + bts->asci.notification_entries = 0; + bts->asci.notification_count = 0; + bts->asci.nln_status = (bts->asci.nln_status + 1) % 2; + + return 0; +} + +const struct asci_notification *bts_asci_notification_get_next(struct gsm_bts *bts) +{ + struct asci_notification *n; + + n = llist_first_entry_or_null(&bts->asci.notifications, struct asci_notification, list); + if (!n) + return NULL; + + /* move to end of list to iterate over them */ + llist_del(&n->list); + llist_add_tail(&n->list, &bts->asci.notifications); + + return n; +} + + +/*! append a "Group Call Information" CSN.1 structure to the caller-provided bit-vector. + * \param[out] bv caller-provided output bit-vector + * \param[in] gcr 5-byte group call reference + * \param[in] ch_desc optional group channel description (may be NULL) + * \param[in] ch_desc_len length of group channel description (in bytes) */ +void append_group_call_information(struct bitvec *bv, const uint8_t *gcr, const uint8_t *ch_desc, uint8_t ch_desc_len) +{ + /* spec reference: TS 44.018 Section 9.1.21a */ + + /* <Group Call Reference : bit(36)> */ + struct bitvec *gcr_bv = bitvec_alloc(5*8, NULL); + OSMO_ASSERT(gcr_bv); + bitvec_unpack(gcr_bv, gcr); + for (unsigned int i = 0; i < 36; i++) + bitvec_set_bit(bv, bitvec_get_bit_pos(gcr_bv, i)); + + /* Group Channel Description */ + if (ch_desc && ch_desc_len) { + struct bitvec *chd_bv = bitvec_alloc(ch_desc_len*8, NULL); + OSMO_ASSERT(chd_bv); + bitvec_unpack(chd_bv, ch_desc); + bitvec_set_bit(bv, 1); + /* <Channel Description : bit(24)> */ + for (unsigned int i = 0; i < ch_desc_len * 8; i++) + bitvec_set_bit(bv, bitvec_get_bit_pos(chd_bv, i)); + bitvec_free(chd_bv); + /* FIXME: hopping */ + bitvec_set_bit(bv, 0); + } else { + bitvec_set_bit(bv, 0); + } + + bitvec_free(gcr_bv); +} + +#define L2_PLEN(len) (((len - 1) << 2) | 0x01) + +int bts_asci_notify_nch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf) +{ + struct gsm48_notification_nch *nn = (struct gsm48_notification_nch *) out_buf; + const struct asci_notification *notif; + unsigned int ro_len; + + notif = bts_asci_notification_get_next(bts); + + *nn = (struct gsm48_notification_nch) { + .proto_discr = GSM48_PDISC_RR, + .msg_type = GSM48_MT_RR_NOTIF_NCH, + }; + + nn->l2_plen = L2_PLEN(nn->data - out_buf); + + /* Pad remaining octets with constant '2B'O */ + ro_len = GSM_MACBLOCK_LEN - (nn->data - out_buf); + memset(nn->data, GSM_MACBLOCK_PADDING, ro_len); + + struct bitvec bv = { + .data_len = ro_len, + .data = nn->data, + }; + + /* {0 | 1 < NLN(NCH) : bit (2) >} + * Only send NLN, at the last notifications. + * When the phone receives two NLN with the same value, it knows that all notifications has been received. + * Also send NLN if no notification is available. */ + if (bts->asci.notification_count >= bts->asci.notification_entries - 1) { + bitvec_set_bit(&bv, 1); + bitvec_set_uint(&bv, bts->asci.nln, 2); + } else { + bitvec_set_bit(&bv, 0); + } + + /* Count NLN. */ + if (++bts->asci.notification_count >= bts->asci.notification_entries) + bts->asci.notification_count = 0; + + /* < List of Group Call NCH information > ::= + * { 0 | 1 < Group Call information > < List of Group Call NCH information > } ; */ + if (notif) { + bitvec_set_bit(&bv, 1); + append_group_call_information(&bv, notif->group_call_ref, + notif->chan_desc.present ? notif->chan_desc.value : NULL, + notif->chan_desc.len); + } + bitvec_set_bit(&bv, 0); /* End of list */ + + /* TODO: Additions in Release 6 */ + /* TODO: Additions in Release 7 */ + + return GSM_MACBLOCK_LEN; +} + +int bts_asci_notify_facch_gen_msg(struct gsm_bts *bts, uint8_t *out_buf, const uint8_t *group_call_ref, + const uint8_t *chan_desc, uint8_t chan_desc_len) +{ + struct gsm48_hdr_sh *sh = (struct gsm48_hdr_sh *) out_buf; + unsigned int ro_len; + + *sh = (struct gsm48_hdr_sh) { + .rr_short_pd = GSM48_PDISC_SH_RR, + .msg_type = GSM48_MT_RR_SH_FACCH, + .l2_header = 0, + }; + + /* Pad remaining octets with constant '2B'O */ + ro_len = GSM_MACBLOCK_LEN - (sh->data - out_buf); + memset(sh->data, GSM_MACBLOCK_PADDING, ro_len); + + struct bitvec bv = { + .data_len = ro_len, + .data = sh->data, + }; + + /* 0 < Group Call information > */ + bitvec_set_bit(&bv, 0); + append_group_call_information(&bv, group_call_ref, chan_desc, chan_desc_len); + + /* TODO: Additions in Release 6 */ + /* TODO: Additions in Release 7 */ + + return GSM_MACBLOCK_LEN; +} diff --git a/src/common/oml.c b/src/common/oml.c index 819b033a..a9e13b52 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -34,6 +34,7 @@ #include <osmocom/core/talloc.h> #include <osmocom/core/msgb.h> +#include <osmocom/core/utils.h> #include <osmocom/gsm/protocol/gsm_12_21.h> #include <osmocom/gsm/abis_nm.h> #include <osmocom/gsm/tlv.h> @@ -46,8 +47,10 @@ #include <osmo-bts/oml.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/signal.h> #include <osmo-bts/phy_link.h> +#include <osmo-bts/nm_common_fsm.h> #define LOGPFOH(ss, lvl, foh, fmt, args ...) LOGP(ss, lvl, "%s: " fmt, abis_nm_dump_foh(foh), ## args) #define DEBUGPFOH(ss, foh, fmt, args ...) LOGPFOH(ss, LOGL_DEBUG, foh, fmt, ## args) @@ -131,6 +134,7 @@ int oml_send_msg(struct msgb *msg, int is_manuf) int oml_mo_send_msg(const struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type) { struct abis_om_fom_hdr *foh; + struct gsm_bts *bts; msg->l3h = msgb_push(msg, sizeof(*foh)); foh = (struct abis_om_fom_hdr *) msg->l3h; @@ -138,17 +142,31 @@ int oml_mo_send_msg(const struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_ foh->obj_class = mo->obj_class; memcpy(&foh->obj_inst, &mo->obj_inst, sizeof(foh->obj_inst)); - /* FIXME: This assumption may not always be correct */ - msg->trx = mo->bts->c0; + /* Find and set OML TRX on msg: */ + switch (mo->obj_class) { + case NM_OC_SITE_MANAGER: + /* Pick the first BTS: */ + bts = gsm_bts_num(g_bts_sm, 0); + break; + default: + /* Other objects should have a valid BTS available: */ + bts = gsm_bts_num(g_bts_sm, mo->obj_inst.bts_nr); + } + if (OSMO_UNLIKELY(!bts)) { + LOGPFOH(DOML, LOGL_NOTICE, foh, + "Sending FOM failed (no related BTS object found)\n"); + return -EINVAL; + } + msg->trx = bts->c0; DEBUGPFOH(DOML, foh, "Tx %s\n", get_value_string(abis_nm_msgtype_names, foh->msg_type)); return oml_send_msg(msg, 0); } -static inline void add_bts_attrs(struct msgb *msg, const struct gsm_bts *bts) +/* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration" */ +static int add_att_sw_config(struct msgb *msg, const struct gsm_abis_mo *mo) { - uint16_t total_len = 0; uint8_t *len; /* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration". */ @@ -157,17 +175,39 @@ static inline void add_bts_attrs(struct msgb *msg, const struct gsm_bts *bts) /* We don't know the length yet, so we update it later. */ len = msgb_put(msg, 2); - total_len += abis_nm_put_sw_file(msg, "osmobts", PACKAGE_VERSION, true); - total_len += abis_nm_put_sw_file(msg, btsatttr2str(BTS_TYPE_VARIANT), - btsvariant2str(bts->variant), true); + switch (mo->obj_class) { + case NM_OC_BTS: + { + const struct gsm_bts *bts = mo->bts; + + abis_nm_put_sw_file(msg, "osmobts", PACKAGE_VERSION, true); + abis_nm_put_sw_file(msg, btsatttr2str(BTS_TYPE_VARIANT), + btsvariant2str(bts->variant), true); + if (strlen(bts->sub_model)) { + abis_nm_put_sw_file(msg, btsatttr2str(BTS_SUB_MODEL), + bts->sub_model, true); + } + break; + } + case NM_OC_BASEB_TRANSC: + { + const struct gsm_bts_trx *trx = container_of(mo, struct gsm_bts_trx, bb_transc.mo); + const struct phy_instance *pinst = trx->pinst; + const char *phy_version; - if (strlen(bts->sub_model)) { - total_len += abis_nm_put_sw_file(msg, btsatttr2str(BTS_SUB_MODEL), - bts->sub_model, true); + phy_version = pinst && strlen(pinst->version) ? pinst->version : "Unknown"; + abis_nm_put_sw_file(msg, btsatttr2str(TRX_PHY_VERSION), phy_version, true); + break; + } + default: + msgb_get(msg, 1 + 2); /* TL16 */ + return -ENOTSUP; } /* Finally, update the length */ - osmo_store16be(total_len, len); + osmo_store16be((uint16_t)(msg->tail - (len + 2)), len); + + return 0; } /* Add BTS features as 3GPP TS 52.021 §9.4.30 Manufacturer Id */ @@ -177,98 +217,249 @@ static inline void add_bts_feat(struct msgb *msg, const struct gsm_bts *bts) msgb_tl16v_put(msg, NM_ATT_MANUF_ID, len, bts->features->data); } -static inline void add_trx_attr(struct msgb *msg, const struct gsm_bts_trx *trx) +/* Add ip.access feature flags for the given MO */ +static int add_att_ipacc_features(struct msgb *msg, const struct gsm_abis_mo *mo) { - const struct phy_instance *pinst = trx_phy_instance(trx); - const char *phy_version; - uint16_t total_len; + const struct gsm_bts *bts = mo->bts; + const struct gsm_bts_trx *trx; + uint32_t val; uint8_t *len; - /* Put NM_ATT_SW_CONFIG as per 9.4.61 "SW Configuration". */ - msgb_v_put(msg, NM_ATT_SW_CONFIG); + msgb_v_put(msg, NM_ATT_IPACC_SUPP_FEATURES); /* We don't know the length yet, so we update it later. */ len = msgb_put(msg, 2); - phy_version = pinst && strlen(pinst->version) ? pinst->version : "Unknown"; - total_len = abis_nm_put_sw_file(msg, btsatttr2str(TRX_PHY_VERSION), phy_version, true); + switch (mo->obj_class) { + case NM_OC_BTS: + msgb_tv16_put(msg, NM_IPAC_EIE_MAX_TA, 1); /* TL16 */ + msgb_put_u8(msg, (bts->support.max_ta >> 0) & 0xff); + break; + case NM_OC_RADIO_CARRIER: + trx = container_of(mo, struct gsm_bts_trx, mo); + msgb_tv16_put(msg, NM_IPAC_EIE_FREQ_BANDS, 1); /* TL16 */ + msgb_put_u8(msg, (trx->support.freq_bands >> 0) & 0xff); + break; + case NM_OC_BASEB_TRANSC: + trx = container_of(mo, struct gsm_bts_trx, bb_transc.mo); + msgb_tv16_put(msg, NM_IPAC_EIE_CIPH_ALGOS, 1); /* TL16 */ + msgb_put_u8(msg, bts->support.ciphers); /* LSB is A5/1 */ + + msgb_tv16_put(msg, NM_IPAC_EIE_CHAN_TYPES, 2); /* TL16 */ + msgb_put_u8(msg, (trx->support.chan_types >> 0) & 0xff); + msgb_put_u8(msg, (trx->support.chan_types >> 8) & 0xff); + + msgb_tv16_put(msg, NM_IPAC_EIE_CHAN_MODES, 3); /* TL16 */ + msgb_put_u8(msg, (trx->support.chan_modes >> 0) & 0xff); + msgb_put_u8(msg, (trx->support.chan_modes >> 8) & 0xff); + msgb_put_u8(msg, (trx->support.chan_modes >> 16) & 0xff); + + msgb_tv16_put(msg, NM_IPAC_EIE_RTP_FEATURES, 1); /* TL16 */ + val = NM_IPAC_F_RTP_FEAT_IR_64k; + msgb_put_u8(msg, (val >> 0) & 0xff); + + msgb_tv16_put(msg, NM_IPAC_EIE_RSL_FEATURES, 1); /* TL16 */ + val = NM_IPAC_F_RSL_FEAT_DYN_PDCH_ACT + | NM_IPAC_F_RSL_FEAT_RTP_PT2; + msgb_put_u8(msg, (val >> 0) & 0xff); + break; + case NM_OC_GPRS_CELL: + msgb_tv16_put(msg, NM_IPAC_EIE_GPRS_CODING, 2); /* TL16 */ + msgb_put_u8(msg, (bts->gprs.cell.support.gprs_codings >> 0) & 0xff); + msgb_put_u8(msg, (bts->gprs.cell.support.gprs_codings >> 8) & 0xff); + break; + default: + msgb_get(msg, 1 + 2); /* TL16 */ + return -ENOTSUP; + } /* Finally, update the length */ - osmo_store16be(total_len, len); + osmo_store16be((uint16_t)(msg->tail - (len + 2)), len); + + return 0; } -/* Handle a list of attributes requested by the BSC, compose - * TRX-specific Get Attribute Response IE as per 9.4.64. */ -static inline int handle_attrs_trx(struct msgb *out_msg, const struct gsm_bts_trx *trx, - const uint8_t *attr, uint16_t attr_len) +/* Add attribute 9.4.8 BCCH ARFCN for BTS class */ +static inline void add_att_bcch_arfcn(struct msgb *msg, const struct gsm_bts *bts) { - uint8_t num_unsupported = 0; - uint8_t *buf; - int i; + /* type + 16 bit value */ + msgb_tv16_put(msg, NM_ATT_BCCH_ARFCN, bts->c0->arfcn); +} - if (!trx) { - LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes for unknown TRX\n", gsm_trx_name(trx)); - return -NM_NACK_TRXNR_UNKN; - } +/* Add attribute 9.4.25 Interference Level Boundaries for BTS class */ +static inline void add_att_interf_bound(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit values */ + msgb_put_u8(msg, NM_ATT_INTERF_BOUND); + for (int j = 0; j < ARRAY_SIZE(bts->interference.boundary); j++) + msgb_put_u8(msg, abs(bts->interference.boundary[j])); +} - for (i = 0; i < attr_len; i++) { - switch (attr[i]) { - case NM_ATT_SW_CONFIG: - add_trx_attr(out_msg, trx); - break; - default: - LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes [%u], %s is unsupported by TRX.\n", - gsm_trx_name(trx), i, get_value_string(abis_nm_att_names, attr[i])); - /* Push this tag to the list of unsupported attributes */ - buf = msgb_push(out_msg, 1); - *buf = attr[i]; - num_unsupported++; - } - } +/* Add attribute 9.4.24 Intave Parameter for BTS class */ +static inline void add_att_intave_param(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_INTAVE_PARAM, bts->interference.intave); +} - /* Push the amount of unsupported attributes */ - buf = msgb_push(out_msg, 1); - *buf = num_unsupported; +/* Add attribute 9.4.14 Connection Failure Criterion for BTS class */ +static inline void add_att_conn_fail_crit(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + length + values */ + msgb_tv16_put(msg, NM_ATT_CONN_FAIL_CRIT, 2); + msgb_put_u8(msg, 0x01); + msgb_put_u8(msg, bts->radio_link_timeout.current); +} + +/* Add attribute 9.4.31 Maximum Timing Advance for BTS class */ +static inline void add_att_max_ta(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_MAX_TA, bts->max_ta); +} + +/* Add attribute 9.4.39 Overload Period for BTS class */ +static inline void add_att_overl_period(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + length + value */ + msgb_tv16_put(msg, NM_ATT_OVERL_PERIOD, 1); + msgb_put_u8(msg, bts->load.overload_period); +} + +/* Add attribute 9.4.12 CCCH Load Threshold for BTS class */ +static inline void add_att_ccch_l_t(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_CCCH_L_T, bts->load.ccch.load_ind_thresh); +} + +/* Add attribute 9.4.11 CCCH Load Indication Period for BTS class */ +static inline void add_att_ccch_l_i_p(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_CCCH_L_I_P, bts->load.ccch.load_ind_period); +} + +/* Add attribute 9.4.44 RACH Busy Threshold for BTS class */ +static inline void add_att_rach_b_thresh(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_RACH_B_THRESH, abs(bts->load.rach.busy_thresh)); +} + +/* Add attribute 9.4.45 RACH Load Averaging Slots for BTS class */ +static inline void add_att_ldavg_slots(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 16 bit value */ + msgb_tv16_put(msg, NM_ATT_LDAVG_SLOTS, bts->load.rach.averaging_slots); +} + +/* Add attribute 9.4.10 BTS Air Timer for BTS class */ +static inline void add_att_bts_air_timer(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_BTS_AIR_TIMER, bts->t3105_ms / 10); +} + +/* Add attribute 9.4.37 NY1 for BTS class */ +static inline void add_att_ny1(struct msgb *msg, const struct gsm_bts *bts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_NY1, bts->ny1); +} +/* Add attribute 9.4.9 BSIC for BTS class */ +static inline int add_att_bsic(struct msgb *msg, const struct gsm_bts *bts) +{ + /* BSIC must be configured. */ + if (!bts->bsic_configured) + return -EINVAL; + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_BSIC, bts->bsic); return 0; } -/* Handle a list of attributes requested by the BSC, compose - * BTS-specific Get Attribute Response IE as per 9.4.64. */ -static inline int handle_attrs_bts(struct msgb *out_msg, const struct gsm_bts *bts, - const uint8_t *attr, uint16_t attr_len) +/* Add attribute 9.4.20 GSM Time for BTS class */ +static inline void add_att_gsm_time(struct msgb *msg, const struct gsm_bts *bts) { - uint8_t num_unsupported = 0; - uint8_t *buf; - int i; + /* type + 16 bit value */ + msgb_tv16_put(msg, NM_ATT_GSM_TIME, bts->gsm_time.fn % GSM_RFN_MODULUS); +} - if (!bts) { - LOGP(DOML, LOGL_ERROR, "O&M Get Attributes for unknown BTS\n"); - return -NM_NACK_BTSNR_UNKN; - } +/* Add attribute 9.4.47 RF Max Power Reduction for radio carrier class */ +static inline void add_att_rf_maxpowr_r(struct msgb *msg, const struct gsm_bts_trx *trx) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_RF_MAXPOWR_R, trx->max_power_red / 2); +} - for (i = 0; i < attr_len; i++) { - switch (attr[i]) { - case NM_ATT_SW_CONFIG: - add_bts_attrs(out_msg, bts); - break; - case NM_ATT_MANUF_ID: - add_bts_feat(out_msg, bts); - break; - default: - LOGP(DOML, LOGL_ERROR, "O&M Get Attributes [%u], %s is unsupported by BTS.\n", i, - get_value_string(abis_nm_att_names, attr[i])); - /* Push this tag to the list of unsupported attributes */ - buf = msgb_push(out_msg, 1); - *buf = attr[i]; - num_unsupported++; - } +/* Add attribute 9.4.5 ARFCN List for radio carrier class */ +static inline void add_att_arfcn_list(struct msgb *msg, const struct gsm_bts_trx *trx) +{ +#if 0 + /* type + length + values */ + msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, trx->arfcn_num * 2); + for (int j = 0; j < trx->arfcn_num; j++) + msgb_put_u16(msg, trx->arfcn_list[j]); +#else + /* type + length + values */ + msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, 2); + msgb_put_u16(msg, trx->arfcn); +#endif +} + +/* Add attribute 9.4.5 ARFCN List for channel class */ +static inline void add_att_arfcn_list_ts(struct msgb *msg, const struct gsm_bts_trx_ts *ts) +{ + if (ts->hopping.enabled) { + /* type + length + values */ + msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, ts->hopping.arfcn_num * 2); + for (int j = 0; j < ts->hopping.arfcn_num; j++) + msgb_put_u16(msg, ts->hopping.arfcn_list[j]); + } else { + /* type + length + values */ + msgb_tv16_put(msg, NM_ATT_ARFCN_LIST, 2); + msgb_put_u16(msg, ts->trx->arfcn); } +} - /* Push the amount of unsupported attributes */ - buf = msgb_push(out_msg, 1); - *buf = num_unsupported; +/* Add attribute 9.4.13 Channel Combination for channel class */ +static inline int add_att_chan_comb(struct msgb *msg, const struct gsm_bts_trx_ts *ts) +{ + int comb = abis_nm_chcomb4pchan(ts->pchan); + + /* If current channel combination is not yet set, 0xff is returned. */ + if (comb < 0 || comb == 0xff) + return -EINVAL; + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_CHAN_COMB, comb); + return 0; +} + +/* Add attribute 9.4.60 TSC for channel class */ +static inline void add_att_tsc(struct msgb *msg, const struct gsm_bts_trx_ts *ts) +{ + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_TSC, ts->tsc); +} + +/* Add attribute 9.4.60 HSN for channel class */ +static inline int add_att_hsn(struct msgb *msg, const struct gsm_bts_trx_ts *ts) +{ + if (!ts->hopping.enabled) + return -EINVAL; + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_HSN, ts->hopping.hsn); + return 0; +} +/* Add attribute 9.4.21 MAIO for channel class */ +static inline int add_att_maio(struct msgb *msg, const struct gsm_bts_trx_ts *ts) +{ + if (!ts->hopping.enabled) + return -EINVAL; + /* type + 8 bit value */ + msgb_tv_put(msg, NM_ATT_MAIO, ts->hopping.maio); return 0; } @@ -277,32 +468,177 @@ static int oml_tx_attr_resp(const struct gsm_abis_mo *mo, const uint8_t *attr, uint16_t attr_len) { struct msgb *nmsg = oml_msgb_alloc(); - const char *mo_name = gsm_abis_mo_name(mo); + unsigned int num_unsupported = 0; + struct gsm_bts_trx *trx = NULL; + struct gsm_bts_trx_ts *ts = NULL; int rc; if (!nmsg) return -NM_NACK_CANT_PERFORM; + /* Set TRX, if object class is Radio Carrier, Baseband Transceiver or Channel. */ switch (mo->obj_class) { - case NM_OC_BTS: - rc = handle_attrs_bts(nmsg, mo->bts, attr, attr_len); - break; + case NM_OC_RADIO_CARRIER: case NM_OC_BASEB_TRANSC: - rc = handle_attrs_trx(nmsg, gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr), attr, attr_len); + case NM_OC_CHANNEL: + trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr); break; - default: - LOGP(DOML, LOGL_ERROR, "%s: Unsupported MO class in Get Attribute Response\n", - mo_name); - rc = -NM_NACK_OBJCLASS_NOTSUPP; } - if (rc < 0) { - LOGP(DOML, LOGL_ERROR, "%s: Tx Get Attribute Response FAILED with rc=%d\n", - mo_name, rc); - msgb_free(nmsg); - return rc; + /* Set TS, if object class is Channel. */ + if (mo->obj_class == NM_OC_CHANNEL && trx) + ts = &trx->ts[mo->obj_inst.ts_nr]; + + for (unsigned int i = 0; i < attr_len; i++) { + switch (attr[i]) { + case NM_ATT_OPER_STATE: + msgb_tv16_put(nmsg, attr[i], 1); + msgb_put_u8(nmsg, mo->nm_state.operational); + break; + case NM_ATT_ADM_STATE: + msgb_tv16_put(nmsg, attr[i], 1); + msgb_put_u8(nmsg, mo->nm_state.administrative); + break; + case NM_ATT_AVAIL_STATUS: + msgb_tv16_put(nmsg, attr[i], 1); + msgb_put_u8(nmsg, mo->nm_state.availability); + break; + case NM_ATT_SW_CONFIG: + if (add_att_sw_config(nmsg, mo) != 0) + goto unsupported; + break; + case NM_ATT_MANUF_ID: + if (mo->obj_class == NM_OC_BTS) + add_bts_feat(nmsg, mo->bts); + else + goto unsupported; + break; + case NM_ATT_IPACC_SUPP_FEATURES: + if (add_att_ipacc_features(nmsg, mo) != 0) + goto unsupported; + break; + case NM_ATT_BCCH_ARFCN: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_bcch_arfcn(nmsg, mo->bts); + break; + case NM_ATT_INTERF_BOUND: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_interf_bound(nmsg, mo->bts); + break; + case NM_ATT_INTAVE_PARAM: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_intave_param(nmsg, mo->bts); + break; + case NM_ATT_CONN_FAIL_CRIT: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_conn_fail_crit(nmsg, mo->bts); + break; + case NM_ATT_MAX_TA: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_max_ta(nmsg, mo->bts); + break; + case NM_ATT_OVERL_PERIOD: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_overl_period(nmsg, mo->bts); + break; + case NM_ATT_CCCH_L_T: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_ccch_l_t(nmsg, mo->bts); + break; + case NM_ATT_CCCH_L_I_P: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_ccch_l_i_p(nmsg, mo->bts); + break; + case NM_ATT_RACH_B_THRESH: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_rach_b_thresh(nmsg, mo->bts); + break; + case NM_ATT_LDAVG_SLOTS: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_ldavg_slots(nmsg, mo->bts); + break; + case NM_ATT_BTS_AIR_TIMER: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_bts_air_timer(nmsg, mo->bts); + break; + case NM_ATT_NY1: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_ny1(nmsg, mo->bts); + break; + case NM_ATT_BSIC: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + if (add_att_bsic(nmsg, mo->bts) != 0) + goto unsupported; + break; + case NM_ATT_GSM_TIME: + if (mo->obj_class != NM_OC_BTS) + goto unsupported; + add_att_gsm_time(nmsg, mo->bts); + break; + case NM_ATT_RF_MAXPOWR_R: + if (mo->obj_class != NM_OC_RADIO_CARRIER || !trx) + goto unsupported; + add_att_rf_maxpowr_r(nmsg, trx); + break; + case NM_ATT_ARFCN_LIST: + if (mo->obj_class == NM_OC_RADIO_CARRIER && trx) { + add_att_arfcn_list(nmsg, trx); + break; + } + if (mo->obj_class == NM_OC_CHANNEL && ts) { + add_att_arfcn_list_ts(nmsg, ts); + break; + } + goto unsupported; + case NM_ATT_CHAN_COMB: + if (mo->obj_class != NM_OC_CHANNEL || !ts) + goto unsupported; + if (add_att_chan_comb(nmsg, ts) != 0) + goto unsupported; + break; + case NM_ATT_TSC: + if (mo->obj_class != NM_OC_CHANNEL || !ts) + goto unsupported; + add_att_tsc(nmsg, ts); + break; + case NM_ATT_HSN: + if (mo->obj_class != NM_OC_CHANNEL || !ts) + goto unsupported; + if (add_att_hsn(nmsg, ts) != 0) + goto unsupported; + break; + case NM_ATT_MAIO: + if (mo->obj_class != NM_OC_CHANNEL || !ts) + goto unsupported; + if (add_att_maio(nmsg, ts) != 0) + goto unsupported; + break; + default: +unsupported: + LOGP(DOML, LOGL_ERROR, "%s: O&M Get Attributes [%u], %s is unsupported\n", + gsm_abis_mo_name(mo), i, get_value_string(abis_nm_att_names, attr[i])); + /* Push this tag to the list of unsupported attributes */ + msgb_push_u8(nmsg, attr[i]); + num_unsupported++; + } } + /* Push the amount of unsupported attributes */ + msgb_push_u8(nmsg, num_unsupported); + /* Push Get Attribute Response Info TL (actually TV where V is L) */ msgb_tv16_push(nmsg, NM_ATT_GET_ARI, msgb_length(nmsg)); @@ -340,12 +676,13 @@ void oml_mo_state_init(struct gsm_abis_mo *mo, int op_state, int avail_state) mo->nm_state.operational = op_state; } -int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state) +int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state, int adm_state) { int rc = 0; if ((op_state != -1 && mo->nm_state.operational != op_state) || - (avail_state != -1 && mo->nm_state.availability != avail_state)) { + (avail_state != -1 && mo->nm_state.availability != avail_state) || + (adm_state != -1 && mo->nm_state.administrative != adm_state)) { if (avail_state != -1) { LOGP(DOML, LOGL_INFO, "%s AVAIL STATE %s -> %s\n", gsm_abis_mo_name(mo), @@ -354,14 +691,26 @@ int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state) mo->nm_state.availability = avail_state; } if (op_state != -1) { + struct nm_statechg_signal_data nsd; LOGP(DOML, LOGL_INFO, "%s OPER STATE %s -> %s\n", gsm_abis_mo_name(mo), abis_nm_opstate_name(mo->nm_state.operational), abis_nm_opstate_name(op_state)); + nsd.mo = mo; + nsd.old_state = mo->nm_state.operational; + nsd.new_state = op_state; mo->nm_state.operational = op_state; - osmo_signal_dispatch(SS_GLOBAL, S_NEW_OP_STATE, NULL); + osmo_signal_dispatch(SS_GLOBAL, S_NEW_OP_STATE, &nsd); + } + if (adm_state != -1) { + LOGP(DOML, LOGL_INFO, "%s ADMIN STATE %s -> %s\n", + gsm_abis_mo_name(mo), + abis_nm_admin_name(mo->nm_state.administrative), + abis_nm_admin_name(adm_state)); + mo->nm_state.administrative = adm_state; } + /* send state change report */ rc = oml_tx_state_changed(mo); } @@ -437,13 +786,13 @@ int oml_fom_ack_nack(struct msgb *msg, uint8_t cause) /* alter message type */ if (cause) { - LOGPFOH(DOML, LOGL_NOTICE, foh, "Sending FOM NACK with cause %s.\n", + LOGPFOH(DOML, LOGL_NOTICE, foh, "Sending FOM NACK with cause %s\n", abis_nm_nack_cause_name(cause)); foh->msg_type += 2; /* nack */ /* add cause */ msgb_tv_put(msg, NM_ATT_NACK_CAUSES, cause); } else { - LOGPFOH(DOML, LOGL_DEBUG, foh, "Sending FOM ACK.\n"); + LOGPFOH(DOML, LOGL_DEBUG, foh, "Sending FOM ACK\n"); foh->msg_type++; /* ack */ } @@ -459,6 +808,15 @@ int oml_fom_ack_nack(struct msgb *msg, uint8_t cause) return 1; } +/* Copy msg before calling oml_fom_ack_nack(), which takes its ownership */ +int oml_fom_ack_nack_copy_msg(const struct msgb *old_msg, uint8_t cause) +{ + struct msgb *msg = msgb_copy(old_msg, "OML-ack_nack"); + msg->trx = old_msg->trx; + oml_fom_ack_nack(msg, cause); + return 0; +} + /* * Formatted O&M messages */ @@ -475,16 +833,21 @@ int oml_mo_tx_sw_act_rep(const struct gsm_abis_mo *mo) return oml_mo_send_msg(mo, nmsg, NM_MT_SW_ACTIVATED_REP); } -/* The defaults below correspond to various sources/recommendations that could be found online. - * The BSC should override this via OML anyway. */ -const unsigned int oml_default_t200_ms[7] = { - [T200_SDCCH] = 1000, - [T200_FACCH_F] = 1000, - [T200_FACCH_H] = 1000, - [T200_SACCH_TCH_SAPI0] = 2000, - [T200_SACCH_SDCCH] = 2000, - [T200_SDCCH_SAPI3] = 1000, - [T200_SACCH_TCH_SAPI3] = 2000, +/* The defaults below correspond to the number of frames until a response from the MS is expected. + * It defines the FN distance between the frame number when a message is sent (first frame) and when the response is + * received (first frame). On SACCH the duration is two frames, because SAPI0 and SAPI3 are are transmitted in + * alternating order. On DCCH with SAPI3 the duration is two seconds, because SAPI0 has priority over SAPI3. + * + * See Table 8 if 3GPP TS 44.006. Note that the table only shows the FN distance between frames. + */ +const uint32_t oml_default_t200_fn[7] = { + [T200_SDCCH] = 4+32, + [T200_FACCH_F] = 8+9, + [T200_FACCH_H] = 6+10, + [T200_SACCH_TCH_SAPI0] = 79+25+104, + [T200_SACCH_SDCCH] = 4+32+51, + [T200_SDCCH_SAPI3] = 4+32+408, /* two seconds */ + [T200_SACCH_TCH_SAPI3] = 79+25+104, }; /* 3GPP TS 52.021 §8.11.1 Get Attributes has been received */ @@ -494,6 +857,7 @@ static int oml_rx_get_attr(struct gsm_bts *bts, struct msgb *msg) const struct gsm_abis_mo *mo; struct tlv_parsed tp; int rc; + enum abis_nm_nack_cause c; if (!foh || !bts) return -EINVAL; @@ -501,10 +865,9 @@ static int oml_rx_get_attr(struct gsm_bts *bts, struct msgb *msg) DEBUGPFOH(DOML, foh, "Rx GET ATTR\n"); /* Determine which OML object is addressed */ - mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); - if (!mo) { + if ((mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) { LOGPFOH(DOML, LOGL_ERROR, foh, "Get Attributes for unknown Object Instance\n"); - return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); + return oml_fom_ack_nack(msg, c); } rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); @@ -536,6 +899,7 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) struct tlv_parsed tp, *tp_merged; int rc, i; const uint8_t *payload; + struct nm_fsm_ev_setattr_data ev_data; DEBUGPFOH(DOML, foh, "Rx SET BTS ATTR\n"); @@ -553,7 +917,7 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN, "Given ARFCN %u is not supported", arfcn); - LOGPFOH(DOML, LOGL_ERROR, foh, "Given ARFCN %u is not supported.\n", arfcn); + LOGPFOH(DOML, LOGL_ERROR, foh, "Given ARFCN %u is not supported\n", arfcn); return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL); } } @@ -567,6 +931,7 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) /* merge existing BTS attributes with new attributes */ tp_merged = osmo_tlvp_copy(bts->mo.nm_attr, bts); + talloc_set_name_const(tp_merged, "oml_bts_attr"); osmo_tlvp_merge(tp_merged, &tp); /* Ask BTS driver to validate new merged attributes */ @@ -585,7 +950,7 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) /* 9.4.25 Interference Level Boundaries */ if (TLVP_PRES_LEN(&tp, NM_ATT_INTERF_BOUND, 6)) { payload = TLVP_VAL(&tp, NM_ATT_INTERF_BOUND); - for (i = 0; i < 6; i++) { + for (i = 0; i < ARRAY_SIZE(bts->interference.boundary); i++) { const int16_t boundary = payload[i]; bts->interference.boundary[i] = -1 * boundary; } @@ -625,25 +990,26 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) } /* 9.4.53 T200 */ - if (TLVP_PRES_LEN(&tp, NM_ATT_T200, ARRAY_SIZE(bts->t200_ms))) { + if (TLVP_PRES_LEN(&tp, NM_ATT_T200, ARRAY_SIZE(bts->t200_fn))) { + /* The OML message NM_ATT_T200 is ignored, because T200 timeouts are set to + * the minimal response time. Longer timeouts would cause lower throughput + * in case of lost frames. Shorter timeouts would cause LAPDm to fail. */ + DEBUGPFOH(DOML, foh, "Ignoring T200 BTS attribute.\n"); +#if 0 payload = TLVP_VAL(&tp, NM_ATT_T200); - for (i = 0; i < ARRAY_SIZE(bts->t200_ms); i++) { + for (i = 0; i < ARRAY_SIZE(bts->t200_fn); i++) { uint32_t t200_ms = payload[i] * abis_nm_t200_ms[i]; -#if 0 - bts->t200_ms[i] = t200_ms; - DEBUGPFOH(DOML, foh, "T200[%u]: OML=%u, mult=%u => %u ms\n", + uint32_t t200_fn = t200_ms * 1000 + (GSM_TDMA_FN_DURATION_uS - 1) / GSM_TDMA_FN_DURATION_uS; + /* Values must not be less than absolute minimum. */ + if (oml_default_t200_fn[i] <= t200_fn) + bts->t200_fn[i] = t200_fn; + else + bts->t200_fn[i] = oml_default_t200_fn[i]; + DEBUGPFOH(DOML, foh, "T200[%u]: OML=%u, mult=%u => %u ms -> %u fn\n", i, payload[i], abis_nm_t200_ms[i], - bts->t200_ms[i]); -#else - /* we'd rather use the 1s/2s (long) defaults by - * libosmocore, as we appear to have some bug(s) - * related to handling T200 expiration in - * libosmogsm lapd(m) code? */ - LOGPFOH(DOML, LOGL_NOTICE, foh, "Ignoring T200[%u] (%u ms) " - "as sent by BSC due to suspected LAPDm bug!\n", - i, t200_ms); -#endif + t200_ms, bts->t200_fn[i]); } +#endif } /* 9.4.31 Maximum Timing Advance */ @@ -661,7 +1027,10 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) /* 9.4.11 CCCH Load Indication Period */ if (TLVP_PRES_LEN(&tp, NM_ATT_CCCH_L_I_P, 1)) { bts->load.ccch.load_ind_period = *TLVP_VAL(&tp, NM_ATT_CCCH_L_I_P); - load_timer_start(bts); + if (load_timer_is_running(bts)) { + load_timer_stop(bts); + load_timer_start(bts); + } } /* 9.4.44 RACH Busy Threshold */ @@ -680,26 +1049,64 @@ static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg) if (TLVP_PRES_LEN(&tp, NM_ATT_BTS_AIR_TIMER, 1)) { uint8_t t3105 = *TLVP_VAL(&tp, NM_ATT_BTS_AIR_TIMER); if (t3105 == 0) { - LOGPFOH(DOML, LOGL_NOTICE, foh, "T3105 must have a value != 0.\n"); + LOGPFOH(DOML, LOGL_NOTICE, foh, "T3105 must have a value != 0\n"); return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE); } bts->t3105_ms = t3105 * 10; + /* there are no OML IEs for T3115; let's use T3105 as HO detection is a similar procedure */ + bts->t3115_ms = bts->t3105_ms; } /* 9.4.37 NY1 */ - if (TLVP_PRES_LEN(&tp, NM_ATT_NY1, 1)) + if (TLVP_PRES_LEN(&tp, NM_ATT_NY1, 1)) { bts->ny1 = *TLVP_VAL(&tp, NM_ATT_NY1); + /* there are no OML IEs for NY2; let's use NY1 as HO detection is a similar procedure */ + bts->ny2 = bts->ny1; + } /* 9.4.8 BCCH ARFCN */ if (TLVP_PRES_LEN(&tp, NM_ATT_BCCH_ARFCN, 2)) bts->c0->arfcn = ntohs(tlvp_val16_unal(&tp, NM_ATT_BCCH_ARFCN)); /* 9.4.9 BSIC */ - if (TLVP_PRES_LEN(&tp, NM_ATT_BSIC, 1)) + if (TLVP_PRES_LEN(&tp, NM_ATT_BSIC, 1)) { + struct gsm_bts_trx *trx; + uint8_t bts_tsc; + bts->bsic = *TLVP_VAL(&tp, NM_ATT_BSIC); + bts->bsic_configured = true; + bts_tsc = BTS_TSC(bts); + + /* Apply TSC update on each TS if required: */ + llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */ + unsigned int tn; + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + + /* First some config validation: */ + if (ts->tsc_oml_configured && + ts->tsc_oml != bts_tsc && + !osmo_bts_has_feature(bts->features, BTS_FEAT_MULTI_TSC)) { + LOGPFOH(DOML, LOGL_ERROR, foh, "SET BTS ATTR: this BTS model does not " + "support TSC %u != BSIC-BCC %u (TSC %u)\n", + ts->tsc_oml, bts->bsic, bts_tsc); + return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE); + } + + /* Now update TS TSC if needed: */ + gsm_ts_apply_configured_tsc(ts); + } + } + } - /* call into BTS driver to apply new attributes to hardware */ - return bts_model_apply_oml(bts, msg, tp_merged, NM_OC_BTS, bts); + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + + rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); + return rc; } /* 8.6.2 Set Radio Attributes has been received */ @@ -708,6 +1115,7 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg) struct abis_om_fom_hdr *foh = msgb_l3(msg); struct tlv_parsed tp, *tp_merged; int rc; + struct nm_fsm_ev_setattr_data ev_data; DEBUGPFOH(DOML, foh, "Rx SET RADIO CARRIER ATTR\n"); @@ -719,8 +1127,9 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg) return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); } - /* merge existing BTS attributes with new attributes */ - tp_merged = osmo_tlvp_copy(trx->mo.nm_attr, trx->bts); + /* merge existing TRX attributes with new attributes */ + tp_merged = osmo_tlvp_copy(trx->mo.nm_attr, trx); + talloc_set_name_const(tp_merged, "oml_trx_attr"); osmo_tlvp_merge(tp_merged, &tp); /* Ask BTS driver to validate new merged attributes */ @@ -730,7 +1139,7 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg) return oml_fom_ack_nack(msg, -rc); } - /* Success: replace old BTS attributes with new */ + /* Success: replace old TRX attributes with new */ talloc_free(trx->mo.nm_attr); trx->mo.nm_attr = tp_merged; @@ -779,14 +1188,22 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg) if (arfcn >= 1024) { /* 0 .. 1023 (1024 channels total) */ oml_tx_failure_event_rep(&trx->bts->mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN, "Given ARFCN %u is unsupported", arfcn); - LOGPFOH(DOML, LOGL_NOTICE, foh, "Given ARFCN %u is unsupported.\n", arfcn); + LOGPFOH(DOML, LOGL_NOTICE, foh, "Given ARFCN %u is unsupported\n", arfcn); return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL); } trx->arfcn = arfcn; } #endif - /* call into BTS driver to apply new attributes to hardware */ - return bts_model_apply_oml(trx->bts, msg, tp_merged, NM_OC_RADIO_CARRIER, trx); + + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + + rc = osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); + return rc; + } static int handle_chan_comb(struct gsm_bts_trx_ts *ts, const uint8_t comb) @@ -882,6 +1299,7 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) struct gsm_bts *bts = ts->trx->bts; struct tlv_parsed tp, *tp_merged; int rc, i; + struct nm_fsm_ev_setattr_data ev_data; DEBUGPFOH(DOML, foh, "Rx SET CHAN ATTR\n"); @@ -895,7 +1313,7 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) /* Check frequency hopping parameters (HSN, MAIO, ARFCN list) */ if (TLVP_PRESENT(&tp, NM_ATT_HSN) || TLVP_PRESENT(&tp, NM_ATT_MAIO)) { if (!osmo_bts_has_feature(bts->features, BTS_FEAT_HOPPING)) { - LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: Frequency hopping not supported.\n"); + LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: Frequency hopping not supported\n"); return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); } @@ -929,12 +1347,13 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) /* 9.4.52 Starting Time */ if (TLVP_PRESENT(&tp, NM_ATT_START_TIME)) { - LOGPFOH(DOML, LOGL_NOTICE, foh, "SET CHAN ATTR: Starting time not supported.\n"); + LOGPFOH(DOML, LOGL_NOTICE, foh, "SET CHAN ATTR: Starting time not supported\n"); return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP); } - /* merge existing BTS attributes with new attributes */ - tp_merged = osmo_tlvp_copy(ts->mo.nm_attr, bts); + /* merge existing CHAN attributes with new attributes */ + tp_merged = osmo_tlvp_copy(ts->mo.nm_attr, ts->trx); + talloc_set_name_const(tp_merged, "oml_chan_attr"); osmo_tlvp_merge(tp_merged, &tp); /* Call into BTS driver to check attribute values */ @@ -946,7 +1365,7 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) return oml_fom_ack_nack(msg, -rc); } - /* Success: replace old BTS attributes with new */ + /* Success: replace old CHAN attributes with new */ talloc_free(ts->mo.nm_attr); ts->mo.nm_attr = tp_merged; @@ -965,27 +1384,38 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg) /* 9.4.60 TSC */ if (TLVP_PRES_LEN(&tp, NM_ATT_TSC, 1)) { - ts->tsc_oml = ts->tsc = *TLVP_VAL(&tp, NM_ATT_TSC); - if (ts->tsc != BTS_TSC(bts) && + ts->tsc_oml = *TLVP_VAL(&tp, NM_ATT_TSC); + ts->tsc_oml_configured = true; + } + + if (ts->tsc_oml_configured) { + if (bts->bsic_configured && + ts->tsc_oml != BTS_TSC(bts) && !osmo_bts_has_feature(bts->features, BTS_FEAT_MULTI_TSC)) { LOGPFOH(DOML, LOGL_ERROR, foh, "SET CHAN ATTR: this BTS model does not " - "support TSC %u != BSIC-BCC %u\n", ts->tsc, BTS_TSC(bts)); + "support TSC %u != BSIC-BCC %u\n", ts->tsc_oml, BTS_TSC(bts)); talloc_free(tp_merged); return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE); } - } else { - /* If there is no TSC specified, use the BCC */ - ts->tsc_oml = ts->tsc = BTS_TSC(bts); + gsm_ts_apply_configured_tsc(ts); } - LOGPFOH(DOML, LOGL_INFO, foh, "SET CHAN ATTR (TSC=%u pchan=%s", - ts->tsc, gsm_pchan_name(ts->pchan)); + + LOGPFOH(DOML, LOGL_INFO, foh, "SET CHAN ATTR (TSC=%d pchan=%s", + ts->tsc_oml_configured ? (int)ts->tsc_oml : -1, + gsm_pchan_name(ts->pchan)); if (ts->hopping.enabled) LOGPC(DOML, LOGL_INFO, " hsn=%u maio=%u chan_num=%u", ts->hopping.hsn, ts->hopping.maio, ts->hopping.arfcn_num); LOGPC(DOML, LOGL_INFO, ")\n"); - /* call into BTS driver to apply new attributes to hardware */ - return bts_model_apply_oml(bts, msg, tp_merged, NM_OC_CHANNEL, ts); + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + + rc = osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); + return rc; } /* 8.9.2 Opstart has been received */ @@ -994,14 +1424,16 @@ static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg) struct abis_om_fom_hdr *foh = msgb_l3(msg); struct gsm_abis_mo *mo; void *obj; + int rc; + enum abis_nm_nack_cause c; DEBUGPFOH(DOML, foh, "Rx OPSTART\n"); /* Step 1: Resolve MO by obj_class/obj_inst */ - mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); - obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst); - if (!mo || !obj) - return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); + if ((mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); + if ((obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); /* Step 2: Do some global dependency/consistency checking */ if (mo->nm_state.operational == NM_OPSTATE_ENABLED) { @@ -1009,8 +1441,13 @@ static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg) return oml_mo_opstart_ack(mo); } - /* Step 3: Ask BTS driver to apply the opstart */ - return bts_model_opstart(bts, mo, obj); + /* Make sure all NM objects already have an FSM implemented: */ + OSMO_ASSERT(mo->fi); + + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_RX_OPSTART, NULL); + if (rc < 0) + return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); + return rc; } static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg) @@ -1021,6 +1458,7 @@ static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg) uint8_t adm_state; void *obj; int rc; + enum abis_nm_nack_cause c; DEBUGPFOH(DOML, foh, "Rx CHG ADM STATE\n"); @@ -1038,10 +1476,10 @@ static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg) adm_state = *TLVP_VAL(&tp, NM_ATT_ADM_STATE); /* Step 1: Resolve MO by obj_class/obj_inst */ - mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); - obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst); - if (!mo || !obj) - return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); + if ((mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); + if ((obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); /* Step 2: Do some global dependency/consistency checking */ if (mo->nm_state.administrative == adm_state) { @@ -1163,16 +1601,21 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg) * manufacturer related messages */ -static int oml_ipa_mo_set_attr_nse(void *obj, const struct tlv_parsed *tp) +static int oml_ipa_mo_set_attr_nse(void *obj, + const struct msgb *msg, + const struct tlv_parsed *tp) { - struct gsm_bts *bts = container_of(obj, struct gsm_bts, gprs.nse); + struct gsm_gprs_nse *nse = obj; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data ev_data; + int rc; if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_NSEI, 2)) - bts->gprs.nse.nsei = + nse->nsei = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_NSEI)); if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_NS_CFG, 7)) { - memcpy(&bts->gprs.nse.timer, + memcpy(&nse->timer, TLVP_VAL(tp, NM_ATT_IPACC_NS_CFG), 7); } @@ -1181,15 +1624,27 @@ static int oml_ipa_mo_set_attr_nse(void *obj, const struct tlv_parsed *tp) TLVP_VAL(tp, NM_ATT_IPACC_BSSGP_CFG), 11); } + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + rc = osmo_fsm_inst_dispatch(nse->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return NM_NACK_CANT_PERFORM; + osmo_signal_dispatch(SS_GLOBAL, S_NEW_NSE_ATTR, bts); return 0; } -static int oml_ipa_mo_set_attr_cell(void *obj, const struct tlv_parsed *tp) +static int oml_ipa_mo_set_attr_cell(void *obj, + const struct msgb *msg, + const struct tlv_parsed *tp) { - struct gsm_bts *bts = container_of(obj, struct gsm_bts, gprs.cell); - struct gprs_rlc_cfg *rlcc = &bts->gprs.cell.rlc_cfg; + struct gsm_gprs_cell *gprs_cell = obj; + struct gsm_bts *bts = gsm_gprs_cell_get_bts(gprs_cell); + struct gprs_rlc_cfg *rlcc = &gprs_cell->rlc_cfg; + struct nm_fsm_ev_setattr_data ev_data; + int rc; const uint8_t *cur; uint16_t _cur_s; @@ -1203,8 +1658,7 @@ static int oml_ipa_mo_set_attr_cell(void *obj, const struct tlv_parsed *tp) } if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_BVCI, 2)) - bts->gprs.cell.bvci = - ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_BVCI)); + gprs_cell->bvci = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_BVCI)); if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_RLC_CFG, 9)) { cur = TLVP_VAL(tp, NM_ATT_IPACC_RLC_CFG); @@ -1251,14 +1705,25 @@ static int oml_ipa_mo_set_attr_cell(void *obj, const struct tlv_parsed *tp) rlcc->initial_mcs = *TLVP_VAL(tp, NM_ATT_IPACC_RLC_CFG_3); } + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + rc = osmo_fsm_inst_dispatch(gprs_cell->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return NM_NACK_CANT_PERFORM; + osmo_signal_dispatch(SS_GLOBAL, S_NEW_CELL_ATTR, bts); return 0; } -static int oml_ipa_mo_set_attr_nsvc(struct gsm_bts_gprs_nsvc *nsvc, +static int oml_ipa_mo_set_attr_nsvc(struct gsm_gprs_nsvc *nsvc, + const struct msgb *msg, const struct tlv_parsed *tp) { + struct nm_fsm_ev_setattr_data ev_data; + int rc; + if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_NSVCI, 2)) nsvc->nsvci = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_NSVCI)); @@ -1320,34 +1785,18 @@ static int oml_ipa_mo_set_attr_nsvc(struct gsm_bts_gprs_nsvc *nsvc, } } + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + rc = osmo_fsm_inst_dispatch(nsvc->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return NM_NACK_CANT_PERFORM; osmo_signal_dispatch(SS_GLOBAL, S_NEW_NSVC_ATTR, nsvc); return 0; } -static int oml_ipa_mo_set_attr(struct gsm_bts *bts, const struct gsm_abis_mo *mo, - void *obj, const struct tlv_parsed *tp) -{ - int rc; - - switch (mo->obj_class) { - case NM_OC_GPRS_NSE: - rc = oml_ipa_mo_set_attr_nse(obj, tp); - break; - case NM_OC_GPRS_CELL: - rc = oml_ipa_mo_set_attr_cell(obj, tp); - break; - case NM_OC_GPRS_NSVC: - rc = oml_ipa_mo_set_attr_nsvc(obj, tp); - break; - default: - rc = NM_NACK_OBJINST_UNKN; - } - - return rc; -} - static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg) { struct abis_om_fom_hdr *foh = msgb_l3(msg); @@ -1355,48 +1804,66 @@ static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg) struct tlv_parsed tp, *tp_merged; void *obj; int rc; + enum abis_nm_nack_cause c; DEBUGPFOH(DOML, foh, "Rx IPA SET ATTR\n"); rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh)); if (rc < 0) { - mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); - if (!mo) - return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); + if ((mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); oml_tx_failure_event_rep(mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UNSUP_ATTR, "New value for IPAC Set Attribute not supported\n"); return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT); } /* Resolve MO by obj_class/obj_inst */ - mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst); - obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst); - if (!mo || !obj) - return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); + if ((mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); + if ((obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst, &c)) == NULL) + return oml_fom_ack_nack(msg, c); + - rc = oml_ipa_mo_set_attr(bts, mo, obj, &tp); - if (rc == 0) { - /* Success: replace old MO attributes with new */ - /* merge existing MO attributes with new attributes */ - tp_merged = osmo_tlvp_copy(mo->nm_attr, bts); - osmo_tlvp_merge(tp_merged, &tp); - talloc_free(mo->nm_attr); - mo->nm_attr = tp_merged; + switch (mo->obj_class) { + case NM_OC_GPRS_NSE: + rc = oml_ipa_mo_set_attr_nse(obj, msg, &tp); + break; + case NM_OC_GPRS_CELL: + rc = oml_ipa_mo_set_attr_cell(obj, msg, &tp); + break; + case NM_OC_GPRS_NSVC: + rc = oml_ipa_mo_set_attr_nsvc(obj, msg, &tp); + break; + default: + rc = NM_NACK_OBJINST_UNKN; } - return oml_fom_ack_nack(msg, rc); + if (rc != 0) + return oml_fom_ack_nack(msg, rc); + + /* Success: replace old MO attributes with new */ + /* merge existing MO attributes with new attributes */ + tp_merged = osmo_tlvp_copy(mo->nm_attr, bts); + talloc_set_name_const(tp_merged, "oml_ipa_attr"); + osmo_tlvp_merge(tp_merged, &tp); + talloc_free(mo->nm_attr); + mo->nm_attr = tp_merged; + + return rc; } -static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg, +static int rx_oml_ipa_rsl_connect(struct gsm_bts *bts, struct msgb *msg, const struct tlv_parsed *tp) { - struct e1inp_sign_link *oml_link = trx->bts->oml_link; - uint16_t port = IPA_TCP_PORT_RSL; - const char *trx_name = gsm_trx_name(trx); + struct e1inp_sign_link *oml_link = bts->oml_link; + const struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr); + struct gsm_bts_bb_trx *bb_transc; + const char *trx_name; struct in_addr in; - int rc; - + uint16_t port = IPA_TCP_PORT_RSL; uint8_t stream_id = 0; + int rc; if (TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP)) in.s_addr = tlvp_val32_unal(tp, NM_ATT_IPACC_DST_IP); @@ -1405,20 +1872,29 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg, if (TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP_PORT)) port = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_DST_IP_PORT)); + if (TLVP_PRESENT(tp, NM_ATT_IPACC_STREAM_ID)) stream_id = *TLVP_VAL(tp, NM_ATT_IPACC_STREAM_ID); + if (!trx) { + LOGP(DOML, LOGL_ERROR, "Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x for unknown TRX_NR=%u\n", + inet_ntoa(in), port, stream_id, foh->obj_inst.trx_nr); + rc = NM_NACK_TRXNR_UNKN; + goto tx_ack_nack; + } + + bb_transc = &trx->bb_transc; + osmo_sockaddr_str_from_in_addr(&bb_transc->rsl.rem_addrstr, &in, port); + bb_transc->rsl.tei = stream_id; + + trx_name = gsm_trx_name(trx); LOGP(DOML, LOGL_INFO, "%s: Rx IPA RSL CONNECT IP=%s PORT=%u STREAM=0x%02x\n", - trx_name, inet_ntoa(in), port, stream_id); + trx_name, bb_transc->rsl.rem_addrstr.ip, bb_transc->rsl.rem_addrstr.port, + bb_transc->rsl.tei); - if (trx->bts->variant == BTS_OSMO_OMLDUMMY) { - rc = 0; - LOGP(DOML, LOGL_NOTICE, "%s: Not connecting RSL in OML-DUMMY!\n", trx_name); - } else { - trx->rsl_tei = stream_id; - rc = e1inp_ipa_bts_rsl_connect_n(oml_link->ts->line, inet_ntoa(in), port, trx->nr); - } + rc = 0; +tx_ack_nack: /* The ACK/NACK is expected to contain all IEs */ if (!TLVP_PRESENT(tp, NM_ATT_IPACC_DST_IP)) /* TV32 */ msgb_tv_fixed_put(msg, NM_ATT_IPACC_DST_IP, sizeof(in), @@ -1428,12 +1904,7 @@ static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg, if (!TLVP_PRESENT(tp, NM_ATT_IPACC_STREAM_ID)) /* TV */ msgb_tv_put(msg, NM_ATT_IPACC_STREAM_ID, stream_id); - if (rc < 0) { - LOGP(DOML, LOGL_ERROR, "%s: Error in abis_open(RSL): %d\n", trx_name, rc); - return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM); - } - - return oml_fom_ack_nack(msg, 0); + return oml_fom_ack_nack(msg, rc); } static int down_mom(struct gsm_bts *bts, struct msgb *msg) @@ -1482,8 +1953,7 @@ static int down_mom(struct gsm_bts *bts, struct msgb *msg) switch (foh->msg_type) { case NM_MT_IPACC_RSL_CONNECT: - trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr); - ret = rx_oml_ipa_rsl_connect(trx, msg, &tp); + ret = rx_oml_ipa_rsl_connect(bts, msg, &tp); break; case NM_MT_IPACC_SET_ATTR: ret = oml_ipa_set_attr(bts, msg); @@ -1587,122 +2057,112 @@ void gsm_mo_init(struct gsm_abis_mo *mo, struct gsm_bts *bts, mo->nm_state.administrative = NM_STATE_LOCKED; } -/* obtain the MO structure for a given object instance */ -struct gsm_abis_mo * -gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst) +/* Obtain the MO structure for a given object instance + * \param[out] c nack cause for reply in case of error. Ignored if NULL */ +struct gsm_abis_mo *gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class, + const struct abis_om_obj_inst *obj_inst, + enum abis_nm_nack_cause *c) { struct gsm_bts_trx *trx; - struct gsm_abis_mo *mo = NULL; - switch (obj_class) { + switch ((enum abis_nm_obj_class)obj_class) { case NM_OC_BTS: - mo = &bts->mo; - break; + return &bts->mo; case NM_OC_RADIO_CARRIER: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); - mo = &trx->mo; - break; + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; + return &trx->mo; case NM_OC_BASEB_TRANSC: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); - mo = &trx->bb_transc.mo; - break; + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; + return &trx->bb_transc.mo; case NM_OC_CHANNEL: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; if (obj_inst->ts_nr >= TRX_NR_TS) - return NULL; - mo = &trx->ts[obj_inst->ts_nr].mo; - break; + goto nm_nack_objinst_unkn; + return &trx->ts[obj_inst->ts_nr].mo; case NM_OC_SITE_MANAGER: - mo = &bts->site_mgr.mo; - break; + return &g_bts_sm->mo; case NM_OC_GPRS_NSE: - mo = &bts->gprs.nse.mo; - break; + if (obj_inst->bts_nr > 0) + goto nm_nack_objinst_unkn; + return &g_bts_sm->gprs.nse.mo; case NM_OC_GPRS_CELL: - mo = &bts->gprs.cell.mo; - break; + return &bts->gprs.cell.mo; case NM_OC_GPRS_NSVC: - if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc)) - return NULL; - mo = &bts->gprs.nsvc[obj_inst->trx_nr].mo; - break; - } - return mo; -} - -/* obtain the gsm_nm_state data structure for a given object instance */ -struct gsm_nm_state * -gsm_objclass2nmstate(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst) -{ - struct gsm_abis_mo *mo; - - mo = gsm_objclass2mo(bts, obj_class, obj_inst); - if (!mo) + if (obj_inst->bts_nr > 0) + goto nm_nack_objinst_unkn; + if (obj_inst->trx_nr >= ARRAY_SIZE(g_bts_sm->gprs.nse.nsvc)) + goto nm_nack_objinst_unkn; + return &g_bts_sm->gprs.nse.nsvc[obj_inst->trx_nr].mo; + default: + if (c != NULL) + *c = NM_NACK_OBJCLASS_NOTSUPP; return NULL; + } - return &mo->nm_state; +nm_nack_trxnr_unkn: + if (c != NULL) + *c = NM_NACK_TRXNR_UNKN; + return NULL; +nm_nack_objinst_unkn: + if (c != NULL) + *c = NM_NACK_OBJINST_UNKN; + return NULL; } -/* obtain the in-memory data structure of a given object instance */ -void * -gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class, - const struct abis_om_obj_inst *obj_inst) +/* Obtain the in-memory data structure of a given object instance + * \param[out] c nack cause for reply in case of error. Ignored if NULL */ +void *gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class, + const struct abis_om_obj_inst *obj_inst, + enum abis_nm_nack_cause *c) { struct gsm_bts_trx *trx; - void *obj = NULL; - switch (obj_class) { + switch ((enum abis_nm_obj_class)obj_class) { case NM_OC_BTS: - obj = bts; - break; + return bts; case NM_OC_RADIO_CARRIER: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); - obj = trx; - break; + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; + return trx; case NM_OC_BASEB_TRANSC: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); - obj = &trx->bb_transc; - break; + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; + return &trx->bb_transc; case NM_OC_CHANNEL: - if (obj_inst->trx_nr >= bts->num_trx) { - return NULL; - } - trx = gsm_bts_trx_num(bts, obj_inst->trx_nr); + if (!(trx = gsm_bts_trx_num(bts, obj_inst->trx_nr))) + goto nm_nack_trxnr_unkn; if (obj_inst->ts_nr >= TRX_NR_TS) - return NULL; - obj = &trx->ts[obj_inst->ts_nr]; - break; + goto nm_nack_objinst_unkn; + return &trx->ts[obj_inst->ts_nr]; case NM_OC_SITE_MANAGER: - obj = &bts->site_mgr; - break; + return g_bts_sm; case NM_OC_GPRS_NSE: - obj = &bts->gprs.nse; - break; + if (obj_inst->bts_nr > 0) + goto nm_nack_objinst_unkn; + return &g_bts_sm->gprs.nse; case NM_OC_GPRS_CELL: - obj = &bts->gprs.cell; - break; + return &bts->gprs.cell; case NM_OC_GPRS_NSVC: - if (obj_inst->trx_nr >= ARRAY_SIZE(bts->gprs.nsvc)) - return NULL; - obj = &bts->gprs.nsvc[obj_inst->trx_nr]; - break; + if (obj_inst->bts_nr > 0) + goto nm_nack_objinst_unkn; + if (obj_inst->trx_nr >= ARRAY_SIZE(g_bts_sm->gprs.nse.nsvc)) + goto nm_nack_objinst_unkn; + return &g_bts_sm->gprs.nse.nsvc[obj_inst->trx_nr]; + default: + if (c != NULL) + *c = NM_NACK_OBJCLASS_NOTSUPP; + return NULL; } - return obj; + +nm_nack_trxnr_unkn: + if (c != NULL) + *c = NM_NACK_TRXNR_UNKN; + return NULL; +nm_nack_objinst_unkn: + if (c != NULL) + *c = NM_NACK_OBJINST_UNKN; + return NULL; } diff --git a/src/common/osmux.c b/src/common/osmux.c new file mode 100644 index 00000000..9513bdc4 --- /dev/null +++ b/src/common/osmux.c @@ -0,0 +1,545 @@ +/* Osmux related routines & logic */ + +/* (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * All Rights Reserved + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * 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 <errno.h> +#include <sys/socket.h> +#include <stdint.h> +#include <stdbool.h> +#include <inttypes.h> +#include <unistd.h> + +#include <osmocom/core/logging.h> +#include <osmocom/core/utils.h> +#include <osmocom/core/msgb.h> +#include <osmocom/core/socket.h> +#include <osmocom/netif/rtp.h> + +#include <osmo-bts/bts.h> +#include <osmo-bts/logging.h> +#include <osmo-bts/osmux.h> +#include <osmo-bts/lchan.h> +#include <osmo-bts/msg_utils.h> +#include <osmo-bts/l1sap.h> + +/* Bitmask containing Allocated Osmux circuit ID. +7 to round up to 8 bit boundary. */ +static uint8_t osmux_cid_bitmap[OSMO_BYTES_FOR_BITS(OSMUX_CID_MAX + 1)]; + +/*! Find and reserve a free OSMUX cid. Keep state of last allocated CID to + * rotate allocated CIDs over time. This helps in letting CIDs unused for some + * time after last use. + * \returns OSMUX cid */ +static int osmux_get_local_cid(void) +{ + static uint8_t next_free_osmux_cid_lookup = 0; + uint8_t start_i, start_j; + uint8_t i, j, cid; + + /* i = octet index, j = bit index inside ith octet */ + start_i = next_free_osmux_cid_lookup >> 3; + start_j = next_free_osmux_cid_lookup & 0x07; + + for (i = start_i; i < sizeof(osmux_cid_bitmap); i++) { + for (j = start_j; j < 8; j++) { + if (osmux_cid_bitmap[i] & (1 << j)) + continue; + goto found; + } + } + + for (i = 0; i <= start_i; i++) { + for (j = 0; j < start_j; j++) { + if (osmux_cid_bitmap[i] & (1 << j)) + continue; + goto found; + } + } + + LOGP(DOSMUX, LOGL_ERROR, "All Osmux circuits are in use!\n"); + return -1; + +found: + osmux_cid_bitmap[i] |= (1 << j); + cid = (i << 3) | j; + next_free_osmux_cid_lookup = (cid + 1) & 0xff; + LOGP(DOSMUX, LOGL_DEBUG, + "Allocating Osmux CID %u from pool\n", cid); + return cid; +} + +/*! put back a no longer used OSMUX cid. + * \param[in] osmux_cid OSMUX cid */ +void osmux_put_local_cid(uint8_t osmux_cid) +{ + LOGP(DOSMUX, LOGL_DEBUG, "Osmux CID %u is back to the pool\n", osmux_cid); + osmux_cid_bitmap[osmux_cid / 8] &= ~(1 << (osmux_cid % 8)); +} + +/* Deliver OSMUX batch to the remote end */ +static void osmux_deliver_cb(struct msgb *batch_msg, void *data) +{ + struct osmux_handle *handle = data; + struct gsm_bts *bts = handle->bts; + socklen_t dest_len; + ssize_t rc; + + switch (handle->rem_addr.u.sa.sa_family) { + case AF_INET6: + dest_len = sizeof(handle->rem_addr.u.sin6); + break; + case AF_INET: + default: + dest_len = sizeof(handle->rem_addr.u.sin); + break; + } + rc = sendto(bts->osmux.fd.fd, batch_msg->data, batch_msg->len, 0, + (struct sockaddr *)&handle->rem_addr.u.sa, dest_len); + if (rc < 0) { + char errbuf[129]; + strerror_r(errno, errbuf, sizeof(errbuf)); + LOGP(DOSMUX, LOGL_ERROR, "osmux sendto(%s) failed: %s\n", + osmo_sockaddr_to_str(&handle->rem_addr), errbuf); + } + msgb_free(batch_msg); +} + +/* Lookup existing OSMUX handle for specified destination address. */ +static struct osmux_handle *osmux_handle_find_get(const struct gsm_bts *bts, + const struct osmo_sockaddr *rem_addr) +{ + struct osmux_handle *h; + + llist_for_each_entry(h, &bts->osmux.osmux_handle_list, head) { + if (osmo_sockaddr_cmp(&h->rem_addr, rem_addr) == 0) { + LOGP(DOSMUX, LOGL_DEBUG, + "Using existing OSMUX handle for rem_addr=%s\n", + osmo_sockaddr_to_str(rem_addr)); + h->refcnt++; + return h; + } + } + + return NULL; +} + +/* Put down no longer needed OSMUX handle */ +static void osmux_handle_put(struct gsm_bts *bts, struct osmux_in_handle *in) +{ + struct osmux_handle *h; + + llist_for_each_entry(h, &bts->osmux.osmux_handle_list, head) { + if (h->in == in) { + if (--h->refcnt == 0) { + LOGP(DOSMUX, LOGL_INFO, + "Releasing unused osmux handle for %s\n", + osmo_sockaddr_to_str(&h->rem_addr)); + llist_del(&h->head); + TALLOC_FREE(h->in); + talloc_free(h); + } + return; + } + } + LOGP(DOSMUX, LOGL_ERROR, "Cannot find Osmux input handle %p\n", in); +} + +/* Allocate free OSMUX handle */ +static struct osmux_handle *osmux_handle_alloc(struct gsm_bts *bts, const struct osmo_sockaddr *rem_addr) +{ + struct osmux_handle *h; + char name[128] = "r="; + + h = talloc_zero(bts, struct osmux_handle); + if (!h) + return NULL; + h->bts = bts; + h->rem_addr = *rem_addr; + h->refcnt++; + + h->in = osmux_xfrm_input_alloc(h); + if (!h->in) { + talloc_free(h); + return NULL; + } + + osmo_sockaddr_to_str_buf(name + 2, sizeof(name) - 2, rem_addr); + osmux_xfrm_input_set_name(h->in, name); + /* sequence number to start OSMUX message from */ + osmux_xfrm_input_set_initial_seqnum(h->in, 0); + osmux_xfrm_input_set_batch_factor(h->in, bts->osmux.batch_factor); + /* If batch size is zero, the library defaults to 1472 bytes. */ + osmux_xfrm_input_set_batch_size(h->in, bts->osmux.batch_size); + osmux_xfrm_input_set_deliver_cb(h->in, osmux_deliver_cb, h); + + llist_add(&h->head, &bts->osmux.osmux_handle_list); + + LOGP(DOSMUX, LOGL_DEBUG, "Created new OSMUX handle for rem_addr=%s\n", + osmo_sockaddr_to_str(rem_addr)); + + return h; +} + +/* Lookup existing handle for a specified address, if the handle can not be + * found, the function will automatically allocate one */ +static struct osmux_in_handle * +osmux_handle_find_or_create(struct gsm_bts *bts, const struct osmo_sockaddr *rem_addr) +{ + struct osmux_handle *h; + + if (rem_addr->u.sa.sa_family != AF_INET) { + LOGP(DOSMUX, LOGL_DEBUG, "IPv6 not supported in osmux yet!\n"); + return NULL; + } + + h = osmux_handle_find_get(bts, rem_addr); + if (h != NULL) + return h->in; + + h = osmux_handle_alloc(bts, rem_addr); + if (h == NULL) + return NULL; + + return h->in; +} + + +static struct msgb *osmux_recv(struct osmo_fd *ofd, struct osmo_sockaddr *addr) +{ + struct msgb *msg; + socklen_t slen = sizeof(addr->u.sas); + int ret; + + msg = msgb_alloc(4096, "OSMUX"); /* TODO: pool? */ + if (!msg) { + LOGP(DOSMUX, LOGL_ERROR, "cannot allocate message\n"); + return NULL; + } + ret = recvfrom(ofd->fd, msg->data, msg->data_len, 0, &addr->u.sa, &slen); + if (ret <= 0) { + msgb_free(msg); + LOGP(DOSMUX, LOGL_ERROR, "cannot receive message\n"); + return NULL; + } + msgb_put(msg, ret); + + return msg; +} + +static struct gsm_lchan *osmux_lchan_find(struct gsm_bts *bts, const struct osmo_sockaddr *rem_addr, uint8_t osmux_cid) +{ + /* TODO: Optimize this by maintaining a hashmap local_cid->lchan in bts */ + struct gsm_bts_trx *trx; + + llist_for_each_entry(trx, &bts->trx_list, list) { /* C0..n */ + unsigned int tn; + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + uint8_t subslot, subslots; + if (!ts_is_tch(ts)) + continue; + + subslots = ts_subslots(ts); + for (subslot = 0; subslot < subslots; subslot++) { + struct gsm_lchan *lchan = &ts->lchan[subslot]; + struct osmux_handle *h; + if (!lchan->abis_ip.osmux.use) + continue; + if (!lchan_osmux_connected(lchan)) + continue; + if (lchan->abis_ip.osmux.local_cid != osmux_cid) + continue; + h = osmux_xfrm_input_get_deliver_cb_data(lchan->abis_ip.osmux.in); + if (osmo_sockaddr_cmp(&h->rem_addr, rem_addr) != 0) + continue; + return lchan; /* Found it! */ + } + } + } + return NULL; +} + +static int osmux_read_fd_cb(struct osmo_fd *ofd, unsigned int what) +{ + struct msgb *msg; + struct osmux_hdr *osmuxh; + struct osmo_sockaddr rem_addr; + struct gsm_bts *bts = ofd->data; + + msg = osmux_recv(ofd, &rem_addr); + if (!msg) + return -1; + + while ((osmuxh = osmux_xfrm_output_pull(msg)) != NULL) { + struct gsm_lchan *lchan = osmux_lchan_find(bts, &rem_addr, osmuxh->circuit_id); + if (!lchan) { + char addr_str[64]; + osmo_sockaddr_to_str_buf(addr_str, sizeof(addr_str), &rem_addr); + LOGP(DOSMUX, LOGL_DEBUG, + "Cannot find lchan for %s CID=%d\n", + addr_str, osmuxh->circuit_id); + continue; + } + osmux_xfrm_output_sched(lchan->abis_ip.osmux.out, osmuxh); + } + msgb_free(msg); + return 0; +} + +/* Called before config file read, set defaults */ +int bts_osmux_init(struct gsm_bts *bts) +{ + bts->osmux.use = OSMUX_USAGE_OFF; + bts->osmux.local_addr = talloc_strdup(bts, "127.0.0.1"); + bts->osmux.local_port = OSMUX_DEFAULT_PORT; + bts->osmux.batch_factor = 4; + bts->osmux.batch_size = OSMUX_BATCH_DEFAULT_MAX; + bts->osmux.dummy_padding = false; + INIT_LLIST_HEAD(&bts->osmux.osmux_handle_list); + bts->osmux.fd.fd = -1; + return 0; +} + +void bts_osmux_release(struct gsm_bts *bts) +{ + /* bts->osmux.osmux_handle_list should end up empty when all lchans are + * released/freed upon talloc_free(bts). */ + /* If bts->osmux.fd.data is NULL, bts is being released/freed without + * passing bts_osmux_init()/through bts_osmux_open() and hence fd is + * probably 0 (memzeored). Avoid accessing it if not initialized. */ + if (bts->osmux.fd.fd != -1 && bts->osmux.fd.data) + osmo_fd_close(&bts->osmux.fd); +} + +/* Called after config file read, start services */ +int bts_osmux_open(struct gsm_bts *bts) +{ + int rc; + + /* If Osmux is not enabled by VTY, don't initialize stuff */ + if (bts->osmux.use == OSMUX_USAGE_OFF) + return 0; + + bts->osmux.fd.cb = osmux_read_fd_cb; + bts->osmux.fd.data = bts; + rc = osmo_sock_init2_ofd(&bts->osmux.fd, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, + bts->osmux.local_addr, bts->osmux.local_port, + NULL, 0, OSMO_SOCK_F_BIND); + if (rc < 0) { + LOGP(DOSMUX, LOGL_ERROR, + "Failed binding Osmux socket to %s:%u\n", + bts->osmux.local_addr ? : "*", bts->osmux.local_port); + return rc; + } + + LOGP(DOSMUX, LOGL_INFO, + "Osmux socket listening on %s:%u\n", + bts->osmux.local_addr ? : "*", bts->osmux.local_port); + + osmo_bts_set_feature(bts->features, BTS_FEAT_OSMUX); + return rc; +} + +static struct msgb *osmux_rtp_msgb_alloc_cb(void *rtp_msgb_alloc_priv_data, + unsigned int msg_len) +{ + struct msgb *msg; + msg = l1sap_msgb_alloc(msg_len); + /* We have size for "struct osmo_phsap_prim" reserved & aligned at the + * start of the msg. Osmux will start filling RTP Header at the tail. + * Later on, when pushing it down the stack (scheduled_from_osmux_tx_rtp_cb) + * we'll want to get rid of the RTP header and have RTP payload + * immediately follow the the struct osmo_phsap_prim. Hence, we rework + * reserved space so that end of RTP header (12 bytes) filled by Osmux + * ends up at the same position where "struct osmo_phsap_prim" currently + * ends up */ + msg->l2h = msgb_get(msg, sizeof(struct rtp_hdr)); + return msg; +} + +static void scheduled_from_osmux_tx_rtp_cb(struct msgb *msg, void *data) +{ + struct gsm_lchan *lchan = data; + struct rtp_hdr *rtph; + + /* if we're in loopback mode, we don't accept frames from the + * RTP socket anymore */ + if (lchan->loopback) { + msgb_free(msg); + return; + } + + /* This is where start of rtp_hdr was prepared in osmux_rtp_msgb_alloc_cb() */ + rtph = (struct rtp_hdr *)msg->l2h; + if (msgb_l2len(msg) < sizeof(*rtph)) { + LOGPLCHAN(lchan, DOSMUX, LOGL_ERROR, "received RTP frame too short (len = %d)\n", + msgb_l2len(msg)); + msgb_free(msg); + return; + } + + /* Store RTP header Marker bit in control buffer */ + rtpmsg_marker_bit(msg) = rtph->marker; + /* Store RTP header Sequence Number in control buffer */ + rtpmsg_seq(msg) = ntohs(rtph->sequence); + /* Store RTP header Timestamp in control buffer */ + rtpmsg_ts(msg) = ntohl(rtph->timestamp); + + /* No need to pull() rtph out of msg here, because it was written inside + * initial space reserved for "struct osmo_phsap_prim". We need to pull + * the whole "struct osmo_phsap_prim" since it will be pushed and filled + * by lower layers: + */ + msgb_pull(msg, sizeof(struct osmo_phsap_prim)); + + /* enqueue making sure the queue doesn't get too long */ + lchan_dl_tch_queue_enqueue(lchan, msg, 16); +} + +int lchan_osmux_init(struct gsm_lchan *lchan, uint8_t rtp_payload) +{ + struct gsm_bts_trx *trx = lchan->ts->trx; + int local_cid = osmux_get_local_cid(); + struct in_addr ia; + + if (local_cid < 0) + return local_cid; + + if (inet_pton(AF_INET, trx->bts->osmux.local_addr, &ia) != 1) + return -1; + + lchan->abis_ip.osmux.out = osmux_xfrm_output_alloc(trx); + osmux_xfrm_output_set_rtp_ssrc(lchan->abis_ip.osmux.out, random() /*TODO: SSRC */); + osmux_xfrm_output_set_rtp_pl_type(lchan->abis_ip.osmux.out, rtp_payload); + osmux_xfrm_output_set_tx_cb(lchan->abis_ip.osmux.out, scheduled_from_osmux_tx_rtp_cb, lchan); + osmux_xfrm_output_set_rtp_msgb_alloc_cb(lchan->abis_ip.osmux.out, osmux_rtp_msgb_alloc_cb, lchan); + + lchan->abis_ip.bound_ip = ntohl(ia.s_addr); + lchan->abis_ip.bound_port = trx->bts->osmux.local_port; + lchan->abis_ip.osmux.local_cid = local_cid; + lchan->abis_ip.osmux.rtpst = osmo_rtp_handle_create(trx); + lchan->abis_ip.osmux.use = true; + return 0; +} + +void lchan_osmux_release(struct gsm_lchan *lchan) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; + OSMO_ASSERT(lchan->abis_ip.osmux.use); + /* We are closing, we don't need pending RTP packets to be transmitted */ + osmux_xfrm_output_set_tx_cb(lchan->abis_ip.osmux.out, NULL, NULL); + TALLOC_FREE(lchan->abis_ip.osmux.out); + + msgb_queue_free(&lchan->dl_tch_queue); + lchan->dl_tch_queue_len = 0; + + osmux_put_local_cid(lchan->abis_ip.osmux.local_cid); + + /* Now the remote / tx part, if ever set (connected): */ + if (lchan->abis_ip.osmux.in) { + osmux_xfrm_input_close_circuit(lchan->abis_ip.osmux.in, + lchan->abis_ip.osmux.remote_cid); + osmux_handle_put(bts, lchan->abis_ip.osmux.in); + lchan->abis_ip.osmux.in = NULL; + } + if (lchan->abis_ip.osmux.rtpst) { + osmo_rtp_handle_free(lchan->abis_ip.osmux.rtpst); + lchan->abis_ip.osmux.rtpst = NULL; + } + + lchan->abis_ip.osmux.use = false; +} + +bool lchan_osmux_connected(const struct gsm_lchan *lchan) +{ + return lchan->abis_ip.osmux.in != NULL; +} + +int lchan_osmux_connect(struct gsm_lchan *lchan) +{ + struct osmo_sockaddr rem_addr; + struct gsm_bts *bts = lchan->ts->trx->bts; + OSMO_ASSERT(lchan->abis_ip.connect_ip != 0); + OSMO_ASSERT(lchan->abis_ip.connect_port != 0); + + memset(&rem_addr, 0, sizeof(rem_addr)); + rem_addr.u.sa.sa_family = AF_INET; + rem_addr.u.sin.sin_addr.s_addr = lchan->abis_ip.connect_ip; + rem_addr.u.sin.sin_port = htons(lchan->abis_ip.connect_port); + lchan->abis_ip.osmux.in = osmux_handle_find_or_create(bts, &rem_addr); + if (!lchan->abis_ip.osmux.in) { + LOGPLCHAN(lchan, DOSMUX, LOGL_ERROR, "Cannot allocate input osmux handle\n"); + return -1; + } + if (osmux_xfrm_input_open_circuit(lchan->abis_ip.osmux.in, + lchan->abis_ip.osmux.remote_cid, + bts->osmux.dummy_padding) < 0) { + LOGPLCHAN(lchan, DOSMUX, LOGL_ERROR, "Cannot open osmux circuit %u\n", + lchan->abis_ip.osmux.remote_cid); + osmux_handle_put(bts, lchan->abis_ip.osmux.in); + lchan->abis_ip.osmux.in = NULL; + return -1; + } + return 0; +} + +/* Create RTP packet from l1sap payload and feed it to osmux */ +int lchan_osmux_send_frame(struct gsm_lchan *lchan, const uint8_t *payload, + unsigned int payload_len, unsigned int duration, bool marker) +{ + struct msgb *msg; + struct rtp_hdr *rtph; + int rc; + + msg = osmo_rtp_build(lchan->abis_ip.osmux.rtpst, lchan->abis_ip.rtp_payload, + payload_len, payload, duration); + if (!msg) + return -1; + + /* Set marker bit: */ + rtph = (struct rtp_hdr *)msgb_data(msg); + rtph->marker = marker; + + /* Avoid using the osmux.in if not yet connected. */ + if (!lchan_osmux_connected(lchan)) { + msgb_free(msg); + return -1; + } + + while ((rc = osmux_xfrm_input(lchan->abis_ip.osmux.in, msg, + lchan->abis_ip.osmux.remote_cid)) > 0) { + /* batch full, build and deliver it */ + osmux_xfrm_input_deliver(lchan->abis_ip.osmux.in); + } + return 0; +} + +int lchan_osmux_skipped_frame(struct gsm_lchan *lchan, unsigned int duration) +{ + struct msgb *msg; + + /* Let osmo_rtp_handle take care of updating state, and send nothing: */ + msg = osmo_rtp_build(lchan->abis_ip.osmux.rtpst, lchan->abis_ip.rtp_payload, + 0, NULL, duration); + if (!msg) + return -1; + msgb_free(msg); + return 0; +} diff --git a/src/common/paging.c b/src/common/paging.c index 54d72635..bdd51801 100644 --- a/src/common/paging.c +++ b/src/common/paging.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -43,13 +43,14 @@ #include <osmo-bts/paging.h> #include <osmo-bts/signal.h> #include <osmo-bts/pcu_if.h> +#include <osmo-bts/notification.h> #define MAX_PAGING_BLOCKS_CCCH 9 #define MAX_BS_PA_MFRMS 9 enum paging_record_type { - PAGING_RECORD_PAGING, - PAGING_RECORD_IMM_ASS + PAGING_RECORD_NORMAL, + PAGING_RECORD_MACBLOCK }; struct paging_record { @@ -60,10 +61,12 @@ struct paging_record { time_t expiration_time; uint8_t chan_needed; uint8_t identity_lv[9]; - } paging; + } normal; struct { uint8_t msg[GSM_MACBLOCK_LEN]; - } imm_ass; + bool confirm; + uint32_t msg_id; /* used as identifier for confirmation */ + } macblock; } u; }; @@ -88,9 +91,9 @@ struct paging_state { /* The prioritization of cs pagings is controlled by a hysteresis. When the * fill state of the paging queue exceeds the upper fill level - * THRESHOLD_CONGESTED [%], then PS pagings (immediate assignments) will be - * dropped until fill state of the paging queue drops under the lower fill - * level THRESHOLD_CLEAR [%]. */ + * THRESHOLD_CONGESTED [%], then PS pagings (immediate assignments and pagings + * from the PCU) will be dropped until fill state of the paging queue drops + * under the lower fill level THRESHOLD_CLEAR [%]. */ #define THRESHOLD_CONGESTED 66 /* (percent of num_paging_max) */ #define THRESHOLD_CLEAR 50 /* (percent of num_paging_max) */ @@ -230,13 +233,13 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group, /* Check if we already have this identity */ llist_for_each_entry(pr, group_q, list) { - if (pr->type != PAGING_RECORD_PAGING) + if (pr->type != PAGING_RECORD_NORMAL) continue; - if (identity_lv[0] == pr->u.paging.identity_lv[0] && - !memcmp(identity_lv+1, pr->u.paging.identity_lv+1, + if (identity_lv[0] == pr->u.normal.identity_lv[0] && + !memcmp(identity_lv+1, pr->u.normal.identity_lv+1, identity_lv[0])) { LOGP(DPAG, LOGL_INFO, "Ignoring duplicate paging\n"); - pr->u.paging.expiration_time = + pr->u.normal.expiration_time = time(NULL) + ps->paging_lifetime; return -EEXIST; } @@ -245,9 +248,9 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group, pr = talloc_zero(ps, struct paging_record); if (!pr) return -ENOMEM; - pr->type = PAGING_RECORD_PAGING; + pr->type = PAGING_RECORD_NORMAL; - if (*identity_lv + 1 > sizeof(pr->u.paging.identity_lv)) { + if (*identity_lv + 1 > sizeof(pr->u.normal.identity_lv)) { talloc_free(pr); return -E2BIG; } @@ -255,9 +258,9 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group, LOGP(DPAG, LOGL_INFO, "Add paging to queue (group=%u, queue_len=%u)\n", paging_group, ps->num_paging+1); - pr->u.paging.expiration_time = time(NULL) + ps->paging_lifetime; - pr->u.paging.chan_needed = chan_needed; - memcpy(&pr->u.paging.identity_lv, identity_lv, identity_lv[0]+1); + pr->u.normal.expiration_time = time(NULL) + ps->paging_lifetime; + pr->u.normal.chan_needed = chan_needed; + memcpy(&pr->u.normal.identity_lv, identity_lv, identity_lv[0]+1); /* enqueue the new identity to the HEAD of the queue, * to ensure it will be paged quickly at least once. */ @@ -267,44 +270,59 @@ int paging_add_identity(struct paging_state *ps, uint8_t paging_group, return 0; } -/* Add an IMM.ASS message to the paging queue */ -int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, - uint8_t len, bool from_pcu) +/* Convert the last three digits of a given IMSI string to their decimal representation. In case the given IMSI string + * is shorter than three or zero digits, it will be assumed as "000" */ +static uint16_t convert_imsi_to_decimal(const char *imsi) +{ + uint16_t _imsi; + size_t imsi_len = strlen(imsi); + + /* Tha paging group is calculated from the last three digits of the IMSI */ + if (imsi_len < 3) { + LOGP(DPAG, LOGL_ERROR, "short IMSI (%zu digits), will assume \"000\" to calculate paging group\n", imsi_len); + _imsi = 0; + } else { + imsi = imsi + imsi_len - 3; + _imsi = 100 * ((*(imsi++)) - '0'); + _imsi += 10 * ((*(imsi++)) - '0'); + _imsi += (*(imsi++)) - '0'; + } + + return _imsi; +} + +/* Add a ready formatted MAC block message to the paging queue, this can be an IMMEDIATE ASSIGNMENT, or a + * PAGING COMMAND (from the PCU) */ +int paging_add_macblock(struct paging_state *ps, uint32_t msg_id, const char *imsi, bool confirm, const uint8_t *macblock) { struct llist_head *group_q; struct paging_record *pr; - uint16_t imsi, paging_group; + uint16_t paging_group; + uint16_t _imsi; check_congestion(ps); - if (ps->cs_priority_active && from_pcu) { + if (ps->cs_priority_active) { LOGP(DPAG, LOGL_NOTICE, "Dropping paging for PS, queue congested (%u)\n", ps->num_paging); rate_ctr_inc2(ps->bts->ctrs, BTS_CTR_PAGING_DROP_PS); return -ENOSPC; } - if (len != GSM_MACBLOCK_LEN + 3) { - LOGP(DPAG, LOGL_ERROR, "IMM.ASS invalid length %d\n", len); - return -EINVAL; - } - len -= 3; - - imsi = 100 * ((*(data++)) - '0'); - imsi += 10 * ((*(data++)) - '0'); - imsi += (*(data++)) - '0'; - paging_group = gsm0502_calc_paging_group(&ps->chan_desc, imsi); - + _imsi = convert_imsi_to_decimal(imsi); + paging_group = gsm0502_calc_paging_group(&ps->chan_desc, _imsi); group_q = &ps->paging_queue[paging_group]; pr = talloc_zero(ps, struct paging_record); if (!pr) return -ENOMEM; - pr->type = PAGING_RECORD_IMM_ASS; + pr->type = PAGING_RECORD_MACBLOCK; - LOGP(DPAG, LOGL_INFO, "Add IMM.ASS to queue (group=%u)\n", + LOGP(DPAG, LOGL_INFO, "Add MAC block to paging queue (group=%u)\n", paging_group); - memcpy(pr->u.imm_ass.msg, data, GSM_MACBLOCK_LEN); + memcpy(pr->u.macblock.msg, macblock, GSM_MACBLOCK_LEN); + pr->u.macblock.confirm = confirm; + pr->u.macblock.msg_id = msg_id; /* enqueue the new message to the HEAD of the queue */ llist_add(&pr->list, group_q); @@ -314,22 +332,6 @@ int paging_add_imm_ass(struct paging_state *ps, const uint8_t *data, #define L2_PLEN(len) (((len - 1) << 2) | 0x01) -/* abstract representation of P1 rest octets; we only implement those parts we need for now */ -struct p1_rest_octets { - bool packet_page_ind[2]; - bool r8_present; - struct { - bool prio_ul_access; - bool etws_present; - struct { - bool is_first; - uint8_t page_nr; - const uint8_t *page; - size_t page_bytes; - } etws; - } r8; -}; - /* 3GPP TS 44.018 10.5.2.23 append a segment/page of an ETWS primary notification to given bitvec */ static void append_etws_prim_notif(struct bitvec *bv, bool is_first, uint8_t page_nr, const uint8_t *etws, ssize_t etws_len) @@ -356,13 +358,27 @@ static void append_etws_prim_notif(struct bitvec *bv, bool is_first, uint8_t pag } /* 3GPP TS 44.018 10.5.2.23 append P1 Rest Octets to given bit-vector */ -static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro) +void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets *p1ro, + const struct asci_notification *notif) { /* Paging 1 RO (at least 10 bits before ETWS struct) */ - bitvec_set_bit(bv, L); /* no NLN */ + if (p1ro->nln_pch.present) { + bitvec_set_bit(bv, H); + bitvec_set_uint(bv, p1ro->nln_pch.nln, 2); + bitvec_set_uint(bv, p1ro->nln_pch.nln_status, 1); + } else { + bitvec_set_bit(bv, L); /* no NLN */ + } bitvec_set_bit(bv, L); /* no Priority1 */ bitvec_set_bit(bv, L); /* no Priority2 */ - bitvec_set_bit(bv, L); /* no Group Call Info */ + if (notif) { + bitvec_set_bit(bv, H); /* Group Call Info */ + append_group_call_information(bv, notif->group_call_ref, + notif->chan_desc.present ? notif->chan_desc.value : NULL, + notif->chan_desc.len); + } else { + bitvec_set_bit(bv, L); /* no Group Call Info */ + } if (p1ro->packet_page_ind[0]) bitvec_set_bit(bv, H); /* Packet Page Indication 1 */ else @@ -387,9 +403,53 @@ static void append_p1_rest_octets(struct bitvec *bv, const struct p1_rest_octets } } +/* 3GPP TS 44.018 10.5.2.24 append P2 Rest Octets to given bit-vector */ +void append_p2_rest_octets(struct bitvec *bv, const struct p2_rest_octets *p2ro) +{ + /* {L | H <CN3: bit (2)>} */ + if (p2ro->cneed.present) { + bitvec_set_bit(bv, H); + bitvec_set_uint(bv, p2ro->cneed.cn3, 2); + } else + bitvec_set_bit(bv, L); /* no CN3 */ + + /* {L | H < NLN(PCH) : bit (2) <NLN status(PCH) : bit>} */ + if (p2ro->nln_pch.present) { + bitvec_set_bit(bv, H); + bitvec_set_uint(bv, p2ro->nln_pch.nln, 2); + bitvec_set_uint(bv, p2ro->nln_pch.nln_status, 1); + } else + bitvec_set_bit(bv, L); /* no NLN */ + + /* Note: If this needs to be extended in the future, check if it actually fits into rest of P2! */ +} + +/* 3GPP TS 44.018 10.5.2.25 append P3 Rest Octets to given bit-vector */ +void append_p3_rest_octets(struct bitvec *bv, const struct p3_rest_octets *p3ro) +{ + /* {L | H <CN3: bit (2)> <CN3: bit (2)>} */ + if (p3ro->cneed.present) { + bitvec_set_bit(bv, H); + bitvec_set_uint(bv, p3ro->cneed.cn3, 2); + bitvec_set_uint(bv, p3ro->cneed.cn4, 2); + } else + bitvec_set_bit(bv, L); /* no CN3/CN4 */ + + /* {L | H < NLN(PCH) : bit (2) <NLN status(PCH) : bit>} */ + if (p3ro->nln_pch.present) { + bitvec_set_bit(bv, H); + bitvec_set_uint(bv, p3ro->nln_pch.nln, 2); + bitvec_set_uint(bv, p3ro->nln_pch.nln_status, 1); + } else + bitvec_set_bit(bv, L); /* no NLN */ + + /* Note: If this needs to be extended in the future, check if it actually fits into 3 octets! */ +} + static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv, uint8_t chan1, const uint8_t *identity2_lv, - uint8_t chan2, const struct p1_rest_octets *p1ro) + uint8_t chan2, const struct p1_rest_octets *p1ro, + const struct asci_notification *notif) { struct gsm48_paging1 *pt1 = (struct gsm48_paging1 *) out_buf; unsigned int ro_len; @@ -420,7 +480,7 @@ static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv, .data = cur, }; - append_p1_rest_octets(&bv, p1ro); + append_p1_rest_octets(&bv, p1ro, notif); } return GSM_MACBLOCK_LEN; @@ -428,10 +488,12 @@ static int fill_paging_type_1(uint8_t *out_buf, const uint8_t *identity1_lv, static int fill_paging_type_2(uint8_t *out_buf, const uint8_t *tmsi1_lv, uint8_t cneed1, const uint8_t *tmsi2_lv, - uint8_t cneed2, const uint8_t *identity3_lv) + uint8_t cneed2, const uint8_t *identity3_lv, + const struct p2_rest_octets *p2ro) { struct gsm48_paging2 *pt2 = (struct gsm48_paging2 *) out_buf; uint32_t tmsi; + unsigned int ro_len; uint8_t *cur; int rc; @@ -455,16 +517,32 @@ static int fill_paging_type_2(uint8_t *out_buf, const uint8_t *tmsi1_lv, pt2->l2_plen = L2_PLEN(cur - out_buf); - return cur - out_buf; + /* Pad remaining octets with constant '2B'O */ + ro_len = GSM_MACBLOCK_LEN - (cur - out_buf); + memset(cur, GSM_MACBLOCK_PADDING, ro_len); + + /* Optional P2 Rest Octets */ + if (p2ro) { + struct bitvec bv = { + .data_len = ro_len, + .data = cur, + }; + + append_p2_rest_octets(&bv, p2ro); + } + + return GSM_MACBLOCK_LEN; } static int fill_paging_type_3(uint8_t *out_buf, const uint8_t *tmsi1_lv, uint8_t cneed1, const uint8_t *tmsi2_lv, uint8_t cneed2, - const uint8_t *tmsi3_lv, uint8_t cneed3, - const uint8_t *tmsi4_lv, uint8_t cneed4) + const uint8_t *tmsi3_lv, const uint8_t *tmsi4_lv, + const struct p3_rest_octets *p3ro) { struct gsm48_paging3 *pt3 = (struct gsm48_paging3 *) out_buf; uint32_t tmsi; + unsigned int ro_len; + uint8_t *cur; int rc; memset(out_buf, 0, sizeof(*pt3)); @@ -486,13 +564,25 @@ static int fill_paging_type_3(uint8_t *out_buf, const uint8_t *tmsi1_lv, uint8_t rc = tmsi_mi_to_uint(&tmsi, tmsi4_lv); if (rc == 0) pt3->tmsi4 = tmsi; + cur = out_buf + 20; /* Cannot use sizeof(*pt3), because it has more octets. */ + + pt3->l2_plen = L2_PLEN(cur - out_buf); - /* The structure definition in libosmocore is wrong. It includes as last - * byte some invalid definition of chneed3/chneed4, so we must do this by hand - * here and cannot rely on sizeof(*pt3) */ - out_buf[20] = (0x23 & ~0xf8) | 0x80 | (cneed3 & 3) << 5 | (cneed4 & 3) << 3; + /* Pad remaining octets with constant '2B'O */ + ro_len = GSM_MACBLOCK_LEN - (cur - out_buf); + memset(cur, GSM_MACBLOCK_PADDING, ro_len); - return 21; + /* Optional P3 Rest Octets */ + if (p3ro) { + struct bitvec bv = { + .data_len = ro_len, + .data = cur, + }; + + append_p3_rest_octets(&bv, p3ro); + } + + return GSM_MACBLOCK_LEN; } static const uint8_t empty_id_lv[] = { 0x01, 0xF0 }; @@ -509,7 +599,7 @@ static struct paging_record *dequeue_pr(struct llist_head *group_q) static int pr_is_imsi(struct paging_record *pr) { - if ((pr->u.paging.identity_lv[1] & 7) == GSM_MI_TYPE_IMSI) + if ((pr->u.normal.identity_lv[1] & 7) == GSM_MI_TYPE_IMSI) return 1; else return 0; @@ -538,6 +628,7 @@ static void sort_pr_tmsi_imsi(struct paging_record *pr[], unsigned int n) static void build_p1_rest_octets(struct p1_rest_octets *p1ro, struct gsm_bts *bts) { memset(p1ro, 0, sizeof(*p1ro)); + p1ro->nln_pch.present = false; p1ro->packet_page_ind[0] = false; p1ro->packet_page_ind[1] = false; p1ro->r8_present = true; @@ -590,16 +681,24 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g if (ps->bts->etws.prim_notif) { struct p1_rest_octets p1ro; build_p1_rest_octets(&p1ro, bts); - len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, &p1ro); + /* we intentioanally don't try to add notifications here, as ETWS is more critical */ + len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, &p1ro, NULL); } else if (llist_empty(group_q)) { + struct p1_rest_octets p1ro; + memset(&p1ro, 0, sizeof(p1ro)); + /* Use NLN to notify MS about ongoing VGCS/VBS calls. + * This is required to make the phone read the NCH to get an updated list of ongoing calls. + * Without this the phone will not allow making VGCS/VBS calls. */ + p1ro.nln_pch.present = (bts->asci.pos_nch >= 0); + p1ro.nln_pch.nln = bts->asci.nln; + p1ro.nln_pch.nln_status = bts->asci.nln_status; /* There is nobody to be paged, send Type1 with two empty ID */ //DEBUGP(DPAG, "Tx PAGING TYPE 1 (empty)\n"); - len = fill_paging_type_1(out_buf, empty_id_lv, 0, - NULL, 0, NULL); + len = fill_paging_type_1(out_buf, empty_id_lv, 0, NULL, 0, &p1ro, NULL); *is_empty = 1; } else { struct paging_record *pr[4]; - unsigned int num_pr = 0, imm_ass = 0; + unsigned int num_pr = 0, macblock = 0; time_t now = time(NULL); unsigned int i, num_imsi = 0; @@ -611,9 +710,9 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g break; pr[i] = dequeue_pr(group_q); - /* check for IMM.ASS */ - if (pr[i]->type == PAGING_RECORD_IMM_ASS) { - imm_ass = 1; + /* check for MAC block */ + if (pr[i]->type == PAGING_RECORD_MACBLOCK) { + macblock = 1; break; } @@ -624,17 +723,18 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g num_imsi++; } - /* if we have an IMMEDIATE ASSIGNMENT */ - if (imm_ass) { - /* re-add paging records */ + /* Handle MAC block (from the PCU) */ + if (macblock) { + /* re-add normal paging records */ for (i = 0; i < num_pr; i++) llist_add(&pr[i]->list, group_q); - /* get message and free record */ - memcpy(out_buf, pr[num_pr]->u.imm_ass.msg, - GSM_MACBLOCK_LEN); - pcu_tx_pch_data_cnf(gt->fn, pr[num_pr]->u.imm_ass.msg, + /* get MAC block message and free record */ + memcpy(out_buf, pr[num_pr]->u.macblock.msg, GSM_MACBLOCK_LEN); + /* send a confirmation back (if required) */ + if (pr[num_pr]->u.macblock.confirm) + pcu_tx_data_cnf(pr[num_pr]->u.macblock.msg_id, PCU_IF_SAPI_PCH_2); talloc_free(pr[num_pr]); return GSM_MACBLOCK_LEN; } @@ -645,24 +745,39 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g if (num_pr == 4 && num_imsi == 0) { /* No IMSI: easy case, can use TYPE 3 */ DEBUGP(DPAG, "Tx PAGING TYPE 3 (4 TMSI)\n"); + struct p3_rest_octets p3ro; + memset(&p3ro, 0, sizeof(p3ro)); + p3ro.cneed.present = true; + p3ro.cneed.cn3 = pr[2]->u.normal.chan_needed; + p3ro.cneed.cn4 = pr[3]->u.normal.chan_needed; + p3ro.nln_pch.present = (bts->asci.pos_nch >= 0); + p3ro.nln_pch.nln = bts->asci.nln; + p3ro.nln_pch.nln_status = bts->asci.nln_status; len = fill_paging_type_3(out_buf, - pr[0]->u.paging.identity_lv, - pr[0]->u.paging.chan_needed, - pr[1]->u.paging.identity_lv, - pr[1]->u.paging.chan_needed, - pr[2]->u.paging.identity_lv, - pr[2]->u.paging.chan_needed, - pr[3]->u.paging.identity_lv, - pr[3]->u.paging.chan_needed); + pr[0]->u.normal.identity_lv, + pr[0]->u.normal.chan_needed, + pr[1]->u.normal.identity_lv, + pr[1]->u.normal.chan_needed, + pr[2]->u.normal.identity_lv, + pr[3]->u.normal.identity_lv, + &p3ro); } else if (num_pr >= 3 && num_imsi <= 1) { /* 3 or 4, of which only up to 1 is IMSI */ DEBUGP(DPAG, "Tx PAGING TYPE 2 (2 TMSI,1 xMSI)\n"); + struct p2_rest_octets p2ro; + memset(&p2ro, 0, sizeof(p2ro)); + p2ro.cneed.present = true; + p2ro.cneed.cn3 = pr[2]->u.normal.chan_needed; + p2ro.nln_pch.present = (bts->asci.pos_nch >= 0); + p2ro.nln_pch.nln = bts->asci.nln; + p2ro.nln_pch.nln_status = bts->asci.nln_status; len = fill_paging_type_2(out_buf, - pr[0]->u.paging.identity_lv, - pr[0]->u.paging.chan_needed, - pr[1]->u.paging.identity_lv, - pr[1]->u.paging.chan_needed, - pr[2]->u.paging.identity_lv); + pr[0]->u.normal.identity_lv, + pr[0]->u.normal.chan_needed, + pr[1]->u.normal.identity_lv, + pr[1]->u.normal.chan_needed, + pr[2]->u.normal.identity_lv, + &p2ro); if (num_pr == 4) { /* re-add #4 for next time */ llist_add(&pr[3]->list, group_q); @@ -670,19 +785,21 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g } } else if (num_pr == 1) { DEBUGP(DPAG, "Tx PAGING TYPE 1 (1 xMSI,1 empty)\n"); + /* TODO: check if we can include an ASCI notification */ len = fill_paging_type_1(out_buf, - pr[0]->u.paging.identity_lv, - pr[0]->u.paging.chan_needed, - NULL, 0, NULL); + pr[0]->u.normal.identity_lv, + pr[0]->u.normal.chan_needed, + NULL, 0, NULL, NULL); } else { /* 2 (any type) or * 3 or 4, of which only 2 will be sent */ DEBUGP(DPAG, "Tx PAGING TYPE 1 (2 xMSI)\n"); + /* TODO: check if we can include an ASCI notification */ len = fill_paging_type_1(out_buf, - pr[0]->u.paging.identity_lv, - pr[0]->u.paging.chan_needed, - pr[1]->u.paging.identity_lv, - pr[1]->u.paging.chan_needed, NULL); + pr[0]->u.normal.identity_lv, + pr[0]->u.normal.chan_needed, + pr[1]->u.normal.identity_lv, + pr[1]->u.normal.chan_needed, NULL, NULL); if (num_pr >= 3) { /* re-add #4 for next time */ llist_add(&pr[2]->list, group_q); @@ -702,7 +819,7 @@ int paging_gen_msg(struct paging_state *ps, uint8_t *out_buf, struct gsm_time *g rate_ctr_inc2(bts->ctrs, BTS_CTR_PAGING_SENT); /* check if we can expire the paging record, * or if we need to re-queue it */ - if (pr[i]->u.paging.expiration_time <= now) { + if (pr[i]->u.normal.expiration_time <= now) { talloc_free(pr[i]); ps->num_paging--; LOGP(DPAG, LOGL_INFO, "Removed paging record, queue_len=%u\n", diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index 03f1a05d..048e7668 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -15,10 +15,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * */ #include <stdio.h> @@ -32,8 +28,10 @@ #include <inttypes.h> #include <osmocom/core/talloc.h> +#include <osmocom/core/utils.h> #include <osmocom/core/select.h> #include <osmocom/core/socket.h> +#include <osmocom/core/write_queue.h> #include <osmocom/gsm/gsm23003.h> #include <osmocom/gsm/abis_nm.h> #include <osmo-bts/logging.h> @@ -41,6 +39,7 @@ #include <osmo-bts/pcu_if.h> #include <osmo-bts/pcuif_proto.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/rsl.h> #include <osmo-bts/signal.h> #include <osmo-bts/l1sap.h> @@ -49,18 +48,17 @@ uint32_t trx_get_hlayer1(const struct gsm_bts_trx *trx); -extern struct gsm_network bts_gsmnet; int pcu_direct = 0; static int avail_lai = 0, avail_nse = 0, avail_cell = 0, avail_nsvc[2] = {0, 0}; static const char *sapi_string[] = { [PCU_IF_SAPI_RACH] = "RACH", - [PCU_IF_SAPI_AGCH] = "AGCH", - [PCU_IF_SAPI_PCH] = "PCH", [PCU_IF_SAPI_BCCH] = "BCCH", [PCU_IF_SAPI_PDTCH] = "PDTCH", [PCU_IF_SAPI_PRACH] = "PRACH", [PCU_IF_SAPI_PTCCH] = "PTCCH", + [PCU_IF_SAPI_PCH_2] = "PCH_2", + [PCU_IF_SAPI_AGCH_2] = "AGCH_2", }; /* @@ -207,7 +205,7 @@ static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info, return; } - for (tn = 0; tn < 8; tn++) { + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) @@ -232,9 +230,27 @@ static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info, } } +static enum gsm_pcuif_bts_model bts_model_from_variant(enum gsm_bts_type_variant variant) +{ + switch (variant) { + case BTS_OSMO_LITECELL15: + return PCU_IF_BTS_MODEL_LC15; + case BTS_OSMO_OC2G: + return PCU_IF_BTS_MODEL_OC2G; + case BTS_OSMO_OCTPHY: + return PCU_IF_BTS_MODEL_OCTPHY; + case BTS_OSMO_SYSMO: + return PCU_IF_BTS_MODEL_SYSMO; + case BTS_OSMO_TRX: + case BTS_OSMO_VIRTUAL: + return PCU_IF_BTS_MODEL_TRX; + default: + return PCU_IF_BTS_MODEL_UNSPEC; + } +} + int pcu_tx_info_ind(void) { - struct gsm_network *net = &bts_gsmnet; struct msgb *msg; struct gsm_pcu_if *pcu_prim; struct gsm_pcu_if_info_ind *info_ind; @@ -242,11 +258,13 @@ int pcu_tx_info_ind(void) struct gprs_rlc_cfg *rlcc; struct gsm_bts_trx *trx; int i; + struct gsm_gprs_nse *nse; LOGP(DPCU, LOGL_INFO, "Sending info\n"); + nse = &g_bts_sm->gprs.nse; /* FIXME: allow multiple BTS */ - bts = llist_entry(net->bts_list.next, struct gsm_bts, list); + bts = llist_entry(g_bts_sm->bts_list.next, struct gsm_bts, list); rlcc = &bts->gprs.cell.rlc_cfg; msg = pcu_msgb_alloc(PCU_IF_MSG_INFO_IND, bts->nr); @@ -263,19 +281,19 @@ int pcu_tx_info_ind(void) LOGP(DPCU, LOGL_INFO, "BTS is down\n"); if (pcu_direct) - info_ind->flags |= PCU_IF_FLAG_SYSMO; + info_ind->flags |= PCU_IF_FLAG_DIRECT_PHY; info_ind->bsic = bts->bsic; /* RAI */ - info_ind->mcc = net->plmn.mcc; - info_ind->mnc = net->plmn.mnc; - info_ind->mnc_3_digits = net->plmn.mnc_3_digits; + info_ind->mcc = g_bts_sm->plmn.mcc; + info_ind->mnc = g_bts_sm->plmn.mnc; + info_ind->mnc_3_digits = g_bts_sm->plmn.mnc_3_digits; info_ind->lac = bts->location_area_code; info_ind->rac = bts->gprs.rac; /* NSE */ - info_ind->nsei = bts->gprs.nse.nsei; - memcpy(info_ind->nse_timer, bts->gprs.nse.timer, 7); + info_ind->nsei = nse->nsei; + memcpy(info_ind->nse_timer, nse->timer, 7); memcpy(info_ind->cell_timer, bts->gprs.cell.timer, 11); /* cell attributes */ @@ -318,16 +336,16 @@ int pcu_tx_info_ind(void) info_ind->flags |= PCU_IF_FLAG_MCS8; if (rlcc->cs_mask & (1 << GPRS_MCS9)) info_ind->flags |= PCU_IF_FLAG_MCS9; -#warning "isn't dl_tbf_ext wrong?: * 10 and no ntohs" + /* FIXME: isn't dl_tbf_ext wrong?: * 10 and no ntohs */ info_ind->dl_tbf_ext = rlcc->parameter[T_DL_TBF_EXT]; -#warning "isn't ul_tbf_ext wrong?: * 10 and no ntohs" + /* FIXME: isn't ul_tbf_ext wrong?: * 10 and no ntohs */ info_ind->ul_tbf_ext = rlcc->parameter[T_UL_TBF_EXT]; info_ind->initial_cs = rlcc->initial_cs; info_ind->initial_mcs = rlcc->initial_mcs; /* NSVC */ - for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { - const struct gsm_bts_gprs_nsvc *nsvc = &bts->gprs.nsvc[i]; + for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) { + const struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i]; info_ind->nsvci[i] = nsvc->nsvci; /* PCUIF beauty: the NSVC addresses are sent in the network byte order, * while the port numbers need to be send in the host order. Sigh. */ @@ -353,20 +371,21 @@ int pcu_tx_info_ind(void) LOGPTRX(trx, DPCU, LOGL_NOTICE, "PCU interface (version %u) " "cannot handle more than %zu transceivers => skipped\n", PCU_IF_VERSION, ARRAY_SIZE(info_ind->trx)); - continue; + break; } info_ind_fill_trx(&info_ind->trx[trx->nr], trx); } - return pcu_sock_send(net, msg); + info_ind->bts_model = bts_model_from_variant(bts->variant); + + return pcu_sock_send(msg); } static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal, void *hdlr_data, void *signal_data) { - struct gsm_network *net = &bts_gsmnet; - struct gsm_bts_gprs_nsvc *nsvc; + struct gsm_gprs_nsvc *nsvc; struct gsm_bts *bts; struct gsm48_system_information_type_3 *si3; int id; @@ -381,7 +400,7 @@ static int pcu_if_signal_cb(unsigned int subsys, unsigned int signal, break; si3 = (struct gsm48_system_information_type_3 *) bts->si_buf[SYSINFO_TYPE_3]; - osmo_plmn_from_bcd(si3->lai.digits, &net->plmn); + osmo_plmn_from_bcd(si3->lai.digits, &g_bts_sm->plmn); bts->location_area_code = ntohs(si3->lai.lac); bts->cell_identity = ntohs(si3->cell_identity); avail_lai = 1; @@ -437,7 +456,7 @@ int pcu_tx_app_info_req(struct gsm_bts *bts, uint8_t app_type, uint8_t len, cons ai_req->len = len; memcpy(ai_req->data, app_data, ai_req->len); - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, @@ -464,7 +483,7 @@ int pcu_tx_rts_req(struct gsm_bts_trx_ts *ts, uint8_t is_ptcch, uint32_t fn, rts_req->ts_nr = ts->nr; rts_req->block_nr = block_nr; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn, @@ -479,12 +498,6 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn, LOGP(DPCU, LOGL_DEBUG, "Sending data indication: sapi=%s arfcn=%d block=%d data=%s\n", sapi_string[sapi], arfcn, block_nr, osmo_hexdump(data, len)); - if (lqual < bts->min_qual_norm) { - LOGP(DPCU, LOGL_DEBUG, "Link quality %"PRId16" is below threshold %d, dropping packet\n", - lqual, bts->min_qual_norm); - return 0; - } - msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_IND, bts->nr); if (!msg) return -ENOMEM; @@ -505,7 +518,7 @@ int pcu_tx_data_ind(struct gsm_bts_trx_ts *ts, uint8_t sapi, uint32_t fn, memcpy(data_ind->data, data, len); data_ind->len = len; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, @@ -534,7 +547,7 @@ int pcu_tx_rach_ind(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, rach_ind->trx_nr = trx_nr; rach_ind->ts_nr = ts_nr; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } int pcu_tx_time_ind(uint32_t fn) @@ -556,33 +569,45 @@ int pcu_tx_time_ind(uint32_t fn) time_ind->fn = fn; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } -int pcu_tx_interf_ind(uint8_t bts_nr, uint8_t trx_nr, uint32_t fn, - const uint8_t *pdch_interf) +int pcu_tx_interf_ind(const struct gsm_bts_trx *trx, uint32_t fn) { struct gsm_pcu_if_interf_ind *interf_ind; struct gsm_pcu_if *pcu_prim; struct msgb *msg; + unsigned int tn; - msg = pcu_msgb_alloc(PCU_IF_MSG_INTERF_IND, bts_nr); + msg = pcu_msgb_alloc(PCU_IF_MSG_INTERF_IND, trx->bts->nr); if (!msg) return -ENOMEM; pcu_prim = (struct gsm_pcu_if *) msg->data; interf_ind = &pcu_prim->u.interf_ind; - interf_ind->trx_nr = trx_nr; + interf_ind->trx_nr = trx->nr; interf_ind->fn = fn; - memcpy(&interf_ind->interf[0], &pdch_interf[0], - sizeof(interf_ind->interf)); - return pcu_sock_send(&bts_gsmnet, msg); + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + const struct gsm_lchan *lchan = &ts->lchan[0]; + + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (ts->mo.nm_state.availability != NM_AVSTATE_OK) + continue; + if (ts_pchan(ts) != GSM_PCHAN_PDCH) + continue; + + interf_ind->interf[tn] = -1 * lchan->meas.interf_meas_avg_dbm; + } + + return pcu_sock_send(msg); } int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed) { - struct pcu_sock_state *state = bts_gsmnet.pcu_state; + struct pcu_sock_state *state = g_bts_sm->gprs.pcu_state; struct msgb *msg; struct gsm_pcu_if *pcu_prim; struct gsm_pcu_if_pag_req *pag_req; @@ -610,34 +635,31 @@ int pcu_tx_pag_req(const uint8_t *identity_lv, uint8_t chan_needed) pag_req->chan_needed = chan_needed; memcpy(pag_req->identity_lv, identity_lv, identity_lv[0] + 1); - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } -int pcu_tx_pch_data_cnf(uint32_t fn, uint8_t *data, uint8_t len) +int pcu_tx_data_cnf(uint32_t msg_id, uint8_t sapi) { - struct gsm_network *net = &bts_gsmnet; struct gsm_bts *bts; struct msgb *msg; struct gsm_pcu_if *pcu_prim; - struct gsm_pcu_if_data *data_cnf; /* FIXME: allow multiple BTS */ - bts = llist_entry(net->bts_list.next, struct gsm_bts, list); + bts = llist_entry(g_bts_sm->bts_list.next, struct gsm_bts, list); - LOGP(DPCU, LOGL_DEBUG, "Sending PCH confirm\n"); + LOGP(DPCU, LOGL_DEBUG, "Sending DATA.cnf: sapi=%s msg_id=%08x\n", + sapi_string[sapi], msg_id); - msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_CNF, 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 = &pcu_prim->u.data_cnf; - - data_cnf->sapi = PCU_IF_SAPI_PCH; - data_cnf->fn = fn; - memcpy(data_cnf->data, data, len); - data_cnf->len = len; + pcu_prim->u.data_cnf2 = (struct gsm_pcu_if_data_cnf) { + .sapi = sapi, + .msg_id = msg_id, + }; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } /* forward data from a RR GPRS SUSPEND REQ towards PCU */ @@ -654,7 +676,7 @@ int pcu_tx_susp_req(struct gsm_lchan *lchan, uint32_t tlli, const uint8_t *ra_id memcpy(pcu_prim->u.susp_req.ra_id, ra_id, sizeof(pcu_prim->u.susp_req.ra_id)); pcu_prim->u.susp_req.cause = cause; - return pcu_sock_send(&bts_gsmnet, msg); + return pcu_sock_send(msg); } static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, @@ -672,22 +694,45 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, osmo_hexdump(data_req->data, data_req->len)); switch (data_req->sapi) { - case PCU_IF_SAPI_PCH: - paging_add_imm_ass(bts->paging_state, data_req->data, data_req->len, true); + case PCU_IF_SAPI_PCH_2: + { + const struct gsm_pcu_if_pch *gsm_pcu_if_pch; + + if (OSMO_UNLIKELY(data_req->len != sizeof(*gsm_pcu_if_pch))) { + LOGP(DPCU, LOGL_ERROR, "Rx malformed DATA.req for PCH\n"); + rc = -EINVAL; + break; + } + + gsm_pcu_if_pch = (struct gsm_pcu_if_pch *)data_req->data; + rc = paging_add_macblock(bts->paging_state, gsm_pcu_if_pch->msg_id, + gsm_pcu_if_pch->imsi, gsm_pcu_if_pch->confirm, gsm_pcu_if_pch->data); break; - case PCU_IF_SAPI_AGCH: - msg = msgb_alloc(data_req->len, "pcu_agch"); + } + case PCU_IF_SAPI_AGCH_2: + { + const struct gsm_pcu_if_agch *gsm_pcu_if_agch; + struct bts_agch_msg_cb *msg_cb; + + gsm_pcu_if_agch = (struct gsm_pcu_if_agch *)data_req->data; + + msg = msgb_alloc(GSM_MACBLOCK_LEN, "pcu_agch"); if (!msg) { rc = -ENOMEM; break; } - msg->l3h = msgb_put(msg, data_req->len); - memcpy(msg->l3h, data_req->data, data_req->len); + msg->l3h = msgb_put(msg, GSM_MACBLOCK_LEN); + memcpy(msg->l3h, gsm_pcu_if_agch->data, GSM_MACBLOCK_LEN); + + msg_cb = (struct bts_agch_msg_cb *) msg->cb; + msg_cb->confirm = gsm_pcu_if_agch->confirm; + msg_cb->msg_id = gsm_pcu_if_agch->msg_id; if (bts_agch_enqueue(bts, msg) < 0) { msgb_free(msg); rc = -EIO; } break; + } case PCU_IF_SAPI_PDTCH: case PCU_IF_SAPI_PTCCH: trx = gsm_bts_trx_num(bts, data_req->trx_nr); @@ -876,7 +921,7 @@ static int pcu_rx_act_req(struct gsm_bts *bts, return -EINVAL; } if (act_req->activate) - l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan), NULL); + l1sap_chan_act(trx, gsm_lchan2chan_nr(lchan)); else l1sap_chan_rel(trx, gsm_lchan2chan_nr(lchan)); @@ -891,15 +936,14 @@ static int pcu_rx_act_req(struct gsm_bts *bts, "size is %zu, discarding\n", prim_len, #prim_msg, _len); \ return -EINVAL; \ } \ - } while(0); -static int pcu_rx(struct gsm_network *net, uint8_t msg_type, - struct gsm_pcu_if *pcu_prim, size_t prim_len) + } while (0) +static int pcu_rx(uint8_t msg_type, struct gsm_pcu_if *pcu_prim, size_t prim_len) { int rc = 0; struct gsm_bts *bts; size_t exp_len; - if ((bts = gsm_bts_num(net, pcu_prim->bts_nr)) == NULL) { + if ((bts = gsm_bts_num(g_bts_sm, pcu_prim->bts_nr)) == NULL) { LOGP(DPCU, LOGL_ERROR, "Received PCU Prim for non-existent BTS %u\n", pcu_prim->bts_nr); return -EINVAL; } @@ -946,17 +990,18 @@ static int pcu_rx(struct gsm_network *net, uint8_t msg_type, */ struct pcu_sock_state { - struct gsm_network *net; struct osmo_fd listen_bfd; /* fd for listen socket */ - struct osmo_fd conn_bfd; /* fd for connection to lcr */ - struct llist_head upqueue; /* queue for sending messages */ + struct osmo_wqueue upqueue; /* For sending messages; has fd for conn. to PCU */ }; -int pcu_sock_send(struct gsm_network *net, struct msgb *msg) +static void pcu_sock_close(struct pcu_sock_state *state); + +int pcu_sock_send(struct msgb *msg) { - struct pcu_sock_state *state = net->pcu_state; + struct pcu_sock_state *state = g_bts_sm->gprs.pcu_state; struct osmo_fd *conn_bfd; struct gsm_pcu_if *pcu_prim = (struct gsm_pcu_if *) msg->data; + int rc; if (!state) { if (pcu_prim->msg_type != PCU_IF_MSG_TIME_IND && @@ -966,7 +1011,7 @@ int pcu_sock_send(struct gsm_network *net, struct msgb *msg) msgb_free(msg); return -EINVAL; } - conn_bfd = &state->conn_bfd; + conn_bfd = &state->upqueue.bfd; if (conn_bfd->fd <= 0) { if (pcu_prim->msg_type != PCU_IF_MSG_TIME_IND && pcu_prim->msg_type != PCU_IF_MSG_INTERF_IND) @@ -975,21 +1020,28 @@ int pcu_sock_send(struct gsm_network *net, struct msgb *msg) msgb_free(msg); return -EIO; } - msgb_enqueue(&state->upqueue, msg); - osmo_fd_write_enable(conn_bfd); + rc = osmo_wqueue_enqueue(&state->upqueue, msg); + if (rc < 0) { + if (rc == -ENOSPC) + LOGP(DPCU, LOGL_NOTICE, "PCU not reacting (more than %u messages waiting). Closing connection\n", + state->upqueue.max_length); + pcu_sock_close(state); + msgb_free(msg); + return rc; + } return 0; } static void pcu_sock_close(struct pcu_sock_state *state) { - struct osmo_fd *bfd = &state->conn_bfd; + struct osmo_fd *bfd = &state->upqueue.bfd; struct gsm_bts *bts; struct gsm_bts_trx *trx; unsigned int tn; /* FIXME: allow multiple BTS */ - bts = llist_entry(state->net->bts_list.next, struct gsm_bts, list); + bts = llist_entry(g_bts_sm->bts_list.next, struct gsm_bts, list); LOGP(DPCU, LOGL_NOTICE, "PCU socket has LOST connection\n"); oml_tx_failure_event_rep(&bts->gprs.cell.mo, NM_SEVER_MAJOR, OSMO_EVT_PCU_VERS, @@ -997,9 +1049,9 @@ static void pcu_sock_close(struct pcu_sock_state *state) bts->pcu_version[0] = '\0'; + osmo_fd_unregister(bfd); close(bfd->fd); bfd->fd = -1; - osmo_fd_unregister(bfd); /* patch SI3 to remove GPRS indicator */ regenerate_si3_restoctets(bts); @@ -1029,11 +1081,7 @@ static void pcu_sock_close(struct pcu_sock_state *state) } } - /* flush the queue */ - while (!llist_empty(&state->upqueue)) { - struct msgb *msg = msgb_dequeue(&state->upqueue); - msgb_free(msg); - } + osmo_wqueue_clear(&state->upqueue); } static int pcu_sock_read(struct osmo_fd *bfd) @@ -1068,7 +1116,7 @@ static int pcu_sock_read(struct osmo_fd *bfd) return 0; } - rc = pcu_rx(state->net, pcu_prim->msg_type, pcu_prim, rc); + rc = pcu_rx(pcu_prim->msg_type, pcu_prim, rc); /* as we always synchronously process the message in pcu_rx() and * its callbacks, we can free the message here. */ @@ -1082,99 +1130,57 @@ close: return -1; } -static int pcu_sock_write(struct osmo_fd *bfd) +static int pcu_sock_write(struct osmo_fd *bfd, struct msgb *msg) { struct pcu_sock_state *state = bfd->data; int rc; - while (!llist_empty(&state->upqueue)) { - struct msgb *msg, *msg2; - struct gsm_pcu_if *pcu_prim; - - /* peek at the beginning of the queue */ - msg = llist_entry(state->upqueue.next, struct msgb, list); - pcu_prim = (struct gsm_pcu_if *)msg->data; - - osmo_fd_write_disable(bfd); - - /* bug hunter 8-): maybe someone forgot msgb_put(...) ? */ - if (!msgb_length(msg)) { - LOGP(DPCU, LOGL_ERROR, "message type (%d) with ZERO " - "bytes!\n", pcu_prim->msg_type); - goto dontsend; - } - - /* try to send it over the socket */ - rc = write(bfd->fd, msgb_data(msg), msgb_length(msg)); - if (rc == 0) - goto close; - if (rc < 0) { - if (errno == EAGAIN) { - osmo_fd_write_enable(bfd); - break; - } - goto close; - } - -dontsend: - /* _after_ we send it, we can deueue */ - msg2 = msgb_dequeue(&state->upqueue); - assert(msg == msg2); - msgb_free(msg); + /* bug hunter 8-): maybe someone forgot msgb_put(...) ? */ + OSMO_ASSERT(msgb_length(msg) > 0); + /* try to send it over the socket */ + rc = write(bfd->fd, msgb_data(msg), msgb_length(msg)); + if (OSMO_UNLIKELY(rc == 0)) + goto close; + if (OSMO_UNLIKELY(rc < 0)) { + if (errno == EAGAIN) + return -EAGAIN; + return -1; } return 0; close: pcu_sock_close(state); - return -1; } -static int pcu_sock_cb(struct osmo_fd *bfd, unsigned int flags) -{ - int rc = 0; - - if (flags & OSMO_FD_READ) - rc = pcu_sock_read(bfd); - if (rc < 0) - return rc; - - if (flags & OSMO_FD_WRITE) - rc = pcu_sock_write(bfd); - - return rc; -} - /* 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 osmo_fd *conn_bfd = &state->upqueue.bfd; struct sockaddr_un un_addr; 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 */ - state->listen_bfd.when &= ~OSMO_FD_READ; - close(rc); + osmo_fd_read_disable(&state->listen_bfd); + 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, osmo_wqueue_bfd_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; @@ -1188,19 +1194,20 @@ static int pcu_sock_accept(struct osmo_fd *bfd, unsigned int flags) return 0; } -int pcu_sock_init(const char *path) +int pcu_sock_init(const char *path, int qlength_max) { struct pcu_sock_state *state; struct osmo_fd *bfd; int rc; - state = talloc_zero(NULL, struct pcu_sock_state); + state = talloc_zero(g_bts_sm, struct pcu_sock_state); if (!state) return -ENOMEM; - INIT_LLIST_HEAD(&state->upqueue); - state->net = &bts_gsmnet; - state->conn_bfd.fd = -1; + osmo_wqueue_init(&state->upqueue, qlength_max); + state->upqueue.read_cb = pcu_sock_read; + state->upqueue.write_cb = pcu_sock_write; + state->upqueue.bfd.fd = -1; bfd = &state->listen_bfd; @@ -1225,39 +1232,38 @@ int pcu_sock_init(const char *path) osmo_signal_register_handler(SS_GLOBAL, pcu_if_signal_cb, NULL); - bts_gsmnet.pcu_state = state; + g_bts_sm->gprs.pcu_state = state; - 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, path); return 0; } void pcu_sock_exit(void) { - struct pcu_sock_state *state = bts_gsmnet.pcu_state; + struct pcu_sock_state *state = g_bts_sm->gprs.pcu_state; struct osmo_fd *bfd, *conn_bfd; if (!state) return; osmo_signal_unregister_handler(SS_GLOBAL, pcu_if_signal_cb, NULL); - conn_bfd = &state->conn_bfd; + conn_bfd = &state->upqueue.bfd; if (conn_bfd->fd > 0) pcu_sock_close(state); bfd = &state->listen_bfd; close(bfd->fd); osmo_fd_unregister(bfd); talloc_free(state); - bts_gsmnet.pcu_state = NULL; + g_bts_sm->gprs.pcu_state = NULL; } bool pcu_connected(void) { - struct gsm_network *net = &bts_gsmnet; - struct pcu_sock_state *state = net->pcu_state; + struct pcu_sock_state *state = g_bts_sm->gprs.pcu_state; if (!state) return false; - if (state->conn_bfd.fd <= 0) + if (state->upqueue.bfd.fd <= 0) return false; return true; } diff --git a/src/common/phy_link.c b/src/common/phy_link.c index 5ad72ac7..352d8f72 100644 --- a/src/common/phy_link.c +++ b/src/common/phy_link.c @@ -129,10 +129,12 @@ void phy_instance_destroy(struct phy_instance *pinst) /* remove from list of instances in the link */ llist_del(&pinst->list); - /* remove reverse link from TRX */ - OSMO_ASSERT(pinst->trx->pinst == pinst); - pinst->trx->pinst = NULL; - pinst->trx = NULL; + /* remove reverse link from TRX (if associated) */ + if (pinst->trx != NULL) { + OSMO_ASSERT(pinst->trx->pinst == pinst); + pinst->trx->pinst = NULL; + pinst->trx = NULL; + } talloc_free(pinst); } diff --git a/src/common/power_control.c b/src/common/power_control.c index 4f5d15e3..7f98a417 100644 --- a/src/common/power_control.c +++ b/src/common/power_control.c @@ -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 @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -36,6 +36,8 @@ /* We don't want to deal with floating point, so we scale up */ #define EWMA_SCALE_FACTOR 100 +/* EWMA_SCALE_FACTOR/2 = +50: Round to nearest value when downscaling, otherwise floor() is applied. */ +#define EWMA_ROUND_FACTOR (EWMA_SCALE_FACTOR / 2) /* Base Low-Pass Single-Pole IIR Filter (EWMA) formula: * @@ -84,49 +86,45 @@ static int do_pf_ewma(const struct gsm_power_ctrl_meas_params *mp, return Val; } - *Avg100 += A * (Val - *Avg100 / EWMA_SCALE_FACTOR); - return *Avg100 / EWMA_SCALE_FACTOR; + *Avg100 += A * (Val - (*Avg100 + EWMA_ROUND_FACTOR) / EWMA_SCALE_FACTOR); + return (*Avg100 + EWMA_ROUND_FACTOR) / EWMA_SCALE_FACTOR; } /* Calculate target RxLev value from lower/upper thresholds */ #define CALC_TARGET(mp) \ - (mp.lower_thresh + mp.upper_thresh) / 2 + ((mp).lower_thresh + (mp).upper_thresh) / 2 -/* Calculate a 'delta' value (for the given MS/BS power control state and parameters) - * to be applied to the current Tx power level to approach the target level. */ -static int calc_delta(const struct gsm_power_ctrl_params *params, - struct lchan_power_ctrl_state *state, - const int rxlev_dbm) +static int do_avg_algo(const struct gsm_power_ctrl_meas_params *mp, + struct gsm_power_ctrl_meas_proc_state *mps, + const int val) { - int rxlev_dbm_avg; - uint8_t rxlev_avg; - int delta; - - /* Filter RxLev value to reduce unnecessary Tx power oscillations */ - switch (params->rxlev_meas.algo) { + int val_avg; + switch (mp->algo) { case GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA: - rxlev_dbm_avg = do_pf_ewma(¶ms->rxlev_meas, - &state->rxlev_meas_proc, - rxlev_dbm); + val_avg = do_pf_ewma(mp, mps, val); break; /* TODO: implement other pre-processing methods */ case GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE: default: /* No filtering (pass through) */ - rxlev_dbm_avg = rxlev_dbm; + val_avg = val; } - - /* FIXME: avoid this conversion, accept RxLev as-is */ - rxlev_avg = dbm2rxlev(rxlev_dbm_avg); + return val_avg; +} +/* Calculate a 'delta' value (for the given MS/BS power control parameters) + * to be applied to the current Tx power level to approach the target level. */ +static int calc_delta_rxlev(const struct gsm_power_ctrl_params *params, const uint8_t rxlev) +{ + int delta; /* Check if RxLev is within the threshold window */ - if (rxlev_avg >= params->rxlev_meas.lower_thresh && - rxlev_avg <= params->rxlev_meas.upper_thresh) + if (rxlev >= params->rxlev_meas.lower_thresh && + rxlev <= params->rxlev_meas.upper_thresh) return 0; /* How many dBs measured power should be increased (+) or decreased (-) * to reach expected power. */ - delta = CALC_TARGET(params->rxlev_meas) - rxlev_avg; + delta = CALC_TARGET(params->rxlev_meas) - rxlev; /* Don't ever change more than PWR_{LOWER,RAISE}_MAX_DBM during one loop * iteration, i.e. reduce the speed at which the MS transmit power can @@ -139,14 +137,57 @@ static int calc_delta(const struct gsm_power_ctrl_params *params, return delta; } +/* Shall we skip current block based on configured interval? */ +static bool ctrl_interval_skip_block(const struct gsm_power_ctrl_params *params, + struct lchan_power_ctrl_state *state) +{ + /* Power control interval: how many blocks do we skip? */ + if (state->skip_block_num-- > 0) + return true; + + /* Reset the number of SACCH blocks to be skipped: + * ctrl_interval=0 => 0 blocks to skip, + * ctrl_interval=1 => 1 blocks to skip, + * ctrl_interval=2 => 3 blocks to skip, + * so basically ctrl_interval * 2 - 1. */ + state->skip_block_num = params->ctrl_interval * 2 - 1; + return false; +} + +static const struct gsm_power_ctrl_meas_params *lchan_get_ci_thresholds(const struct gsm_lchan *lchan) +{ + const struct gsm_power_ctrl_params *params = lchan->ms_power_ctrl.dpc_params; + + switch (lchan->type) { + case GSM_LCHAN_SDCCH: + return ¶ms->ci_sdcch_meas; + case GSM_LCHAN_PDTCH: + return ¶ms->ci_gprs_meas; + case GSM_LCHAN_TCH_F: + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + return ¶ms->ci_amr_fr_meas; + else + return ¶ms->ci_fr_meas; + case GSM_LCHAN_TCH_H: + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) + return ¶ms->ci_amr_hr_meas; + else + return ¶ms->ci_hr_meas; + default: + OSMO_ASSERT(0); + } +} + /*! compute the new MS POWER LEVEL communicated to the MS and store it in lchan. * \param lchan logical channel for which to compute (and in which to store) new power value. * \param[in] ms_power_lvl MS Power Level received from Uplink L1 SACCH Header in SACCH block. * \param[in] ul_rssi_dbm Signal level of the received SACCH block, in dBm. + * \param[in] ul_lqual_cb C/I of the received SACCH block, in dB. */ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, const uint8_t ms_power_lvl, - const int8_t ul_rssi_dbm) + const int8_t ul_rssi_dbm, + const int16_t ul_lqual_cb) { struct lchan_power_ctrl_state *state = &lchan->ms_power_ctrl; const struct gsm_power_ctrl_params *params = state->dpc_params; @@ -155,23 +196,20 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, enum gsm_band band = bts->band; int8_t new_power_lvl; /* TS 05.05 power level */ int8_t ms_dbm, new_dbm, current_dbm, bsc_max_dbm; + uint8_t rxlev_avg; + int16_t ul_lqual_cb_avg; + const struct gsm_power_ctrl_meas_params *ci_meas; + bool ignore, ci_on; if (!trx_ms_pwr_ctrl_is_osmo(trx)) return 0; if (params == NULL) return 0; - /* Power control interval: how many blocks do we skip? */ - if (state->skip_block_num-- > 0) + /* Shall we skip current block based on configured interval? */ + if (ctrl_interval_skip_block(params, state)) return 0; - /* Reset the number of SACCH blocks to be skipped: - * ctrl_interval=0 => 0 blocks to skip, - * ctrl_interval=1 => 1 blocks to skip, - * ctrl_interval=2 => 3 blocks to skip, - * so basically ctrl_interval * 2 - 1. */ - state->skip_block_num = params->ctrl_interval * 2 - 1; - ms_dbm = ms_pwr_dbm(band, ms_power_lvl); if (ms_dbm < 0) { LOGPLCHAN(lchan, DLOOP, LOGL_NOTICE, @@ -187,8 +225,24 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, return 0; } - /* Calculate the new Tx power value (in dBm) */ - new_dbm = ms_dbm + calc_delta(params, state, ul_rssi_dbm); + ci_meas = lchan_get_ci_thresholds(lchan); + + /* Is C/I based algo enabled by config? + * FIXME: this can later be generalized when properly implementing P & N counting. */ + ci_on = ci_meas->lower_cmp_n && ci_meas->upper_cmp_n; + + ul_lqual_cb_avg = do_avg_algo(ci_meas, &state->ci_meas_proc, ul_lqual_cb); + rxlev_avg = do_avg_algo(¶ms->rxlev_meas, &state->rxlev_meas_proc, dbm2rxlev(ul_rssi_dbm)); + + /* If computed C/I is enabled and out of acceptable thresholds: */ + if (ci_on && ul_lqual_cb_avg < ci_meas->lower_thresh * 10) { + new_dbm = ms_dbm + params->inc_step_size_db; + } else if (ci_on && ul_lqual_cb_avg > ci_meas->upper_thresh * 10) { + new_dbm = ms_dbm - params->red_step_size_db; + } else { + /* Calculate the new Tx power value (in dBm) */ + new_dbm = ms_dbm + calc_delta_rxlev(params, rxlev_avg); + } /* Make sure new_dbm is never negative. ms_pwr_ctl_lvl() can later on cope with any unsigned dbm value, regardless of band minimal value. */ @@ -207,23 +261,46 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, return 0; } - /* FIXME: this is only needed for logging, print thresholds instead */ - int target_dbm = rxlev2dbm(CALC_TARGET(params->rxlev_meas)); + current_dbm = ms_pwr_dbm(band, state->current); - if (state->current == new_power_lvl) { - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping MS power at control level %d, %d dBm " - "(rx-ms-pwr-lvl %" PRIu8 ", max-ms-pwr-lvl %" PRIu8 ", rx-current %d dBm, rx-target %d dBm)\n", - new_power_lvl, new_dbm, ms_power_lvl, state->max, - ul_rssi_dbm, target_dbm); + /* In this Power Control Loop, we infer a new good MS Power Level based + * on the previous MS Power Level announced by the MS (not the previous + * one we requested!) together with the related computed measurements. + * Hence, and since we allow for several good MS Power Levels falling into our + * thresholds, we could finally converge into an oscillation loop where + * the MS bounces between 2 different correct MS Power levels all the + * time, due to the fact that we "accept" and "request back" whatever + * good MS Power Level we received from the MS, but at that time the MS + * will be transmitting using the previous MS Power Level we + * requested, which we will later "accept" and "request back" on next loop + * iteration. As a result MS effectively bounces between those 2 MS + * Power Levels. + * In order to fix this permanent oscillation, if current MS_PWR used/announced + * by MS is good ("ms_dbm == new_dbm", hence within thresholds and no change + * required) but has higher Tx power than the one we last requested, we ignore + * it and keep requesting for one with lower Tx power. This way we converge to + * the lowest good Tx power avoiding oscillating over values within thresholds. + */ + ignore = (ms_dbm == new_dbm && ms_dbm > current_dbm); + + if (state->current == new_power_lvl || ignore) { + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping MS power at control level %d (%d dBm): " + "ms-pwr-lvl[curr %" PRIu8 ", max %" PRIu8 "], RSSI[curr %d, avg %d, thresh %d..%d] dBm," + " C/I[curr %d, avg %d, thresh %d..%d] dB\n", + new_power_lvl, new_dbm, ms_power_lvl, state->max, ul_rssi_dbm, rxlev2dbm(rxlev_avg), + rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh), + ul_lqual_cb/10, ul_lqual_cb_avg/10, ci_meas->lower_thresh, ci_meas->upper_thresh); return 0; } - current_dbm = ms_pwr_dbm(band, state->current); - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "%s MS power from control level %d (%d dBm) to %d, %d dBm " - "(rx-ms-pwr-lvl %" PRIu8 ", max-ms-pwr-lvl %" PRIu8 ", rx-current %d dBm, rx-target %d dBm)\n", + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "%s MS power control level %d (%d dBm) => %d (%d dBm): " + "ms-pwr-lvl[curr %" PRIu8 ", max %" PRIu8 "], RSSI[curr %d, avg %d, thresh %d..%d] dBm," + " C/I[curr %d, avg %d, thresh %d..%d] dB\n", (new_dbm > current_dbm) ? "Raising" : "Lowering", - state->current, current_dbm, new_power_lvl, new_dbm, - ms_power_lvl, state->max, ul_rssi_dbm, target_dbm); + state->current, current_dbm, new_power_lvl, new_dbm, ms_power_lvl, + state->max, ul_rssi_dbm, rxlev2dbm(rxlev_avg), + rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh), + ul_lqual_cb/10, ul_lqual_cb_avg/10, ci_meas->lower_thresh, ci_meas->upper_thresh); /* store the resulting new MS power level in the lchan */ state->current = new_power_lvl; @@ -234,129 +311,265 @@ int lchan_ms_pwr_ctrl(struct gsm_lchan *lchan, /*! compute the new Downlink attenuation value for the given logical channel. * \param lchan logical channel for which to compute (and in which to store) new power value. - * \param[in] gh pointer to the beginning of (presumably) a Measurement Report. + * \param[in] mr pointer to a *valid* Measurement Report. */ int lchan_bs_pwr_ctrl(struct gsm_lchan *lchan, - const struct gsm48_hdr *gh) + const struct gsm48_meas_res *mr) { struct lchan_power_ctrl_state *state = &lchan->bs_power_ctrl; const struct gsm_power_ctrl_params *params = state->dpc_params; - uint8_t rxqual_full, rxqual_sub; - uint8_t rxlev_full, rxlev_sub; - uint8_t rxqual, rxlev; - int delta, new; + uint8_t rxqual, rxqual_avg, rxlev, rxlev_avg; + int new_att; /* Check if dynamic BS Power Control is enabled */ if (params == NULL) return 0; - /* Check if this is a Measurement Report */ - if (gh->proto_discr != GSM48_PDISC_RR) - return 0; - if (gh->msg_type != GSM48_MT_RR_MEAS_REP) - return 0; - - /* Check if the measurement results are valid */ - if ((gh->data[1] & 0x40) == 0x40) { - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, - "The measurement results are not valid\n"); - return 0; - } - - /* See 3GPP TS 44.018, section 10.5.2.20 */ - rxqual_full = (gh->data[2] >> 4) & 0x7; - rxqual_sub = (gh->data[2] >> 1) & 0x7; - - rxlev_full = gh->data[0] & 0x3f; - rxlev_sub = gh->data[1] & 0x3f; LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Rx DL Measurement Report: " "RXLEV-FULL(%02u), RXQUAL-FULL(%u), " "RXLEV-SUB(%02u), RXQUAL-SUB(%u), " "DTx is %s => using %s\n", - rxlev_full, rxqual_full, rxlev_sub, rxqual_sub, + mr->rxlev_full, mr->rxqual_full, + mr->rxlev_sub, mr->rxqual_sub, lchan->tch.dtx.dl_active ? "enabled" : "disabled", lchan->tch.dtx.dl_active ? "SUB" : "FULL"); - /* Power control interval: how many blocks do we skip? */ - if (state->skip_block_num-- > 0) + /* Shall we skip current block based on configured interval? */ + if (ctrl_interval_skip_block(params, state)) return 0; - /* Reset the number of SACCH blocks to be skipped: - * ctrl_interval=0 => 0 blocks to skip, - * ctrl_interval=1 => 1 blocks to skip, - * ctrl_interval=2 => 3 blocks to skip, - * so basically ctrl_interval * 2 - 1. */ - state->skip_block_num = params->ctrl_interval * 2 - 1; - /* If DTx is active on Downlink, use the '-SUB' */ if (lchan->tch.dtx.dl_active) { - rxqual = rxqual_sub; - rxlev = rxlev_sub; + rxqual = mr->rxqual_sub; + rxlev = mr->rxlev_sub; } else { /* ... otherwise use the '-FULL' */ - rxqual = rxqual_full; - rxlev = rxlev_full; + rxqual = mr->rxqual_full; + rxlev = mr->rxlev_full; } + rxlev_avg = do_avg_algo(¶ms->rxlev_meas, &state->rxlev_meas_proc, rxlev); + rxqual_avg = do_avg_algo(¶ms->rxqual_meas, &state->rxqual_meas_proc, rxqual); /* If RxQual > L_RXQUAL_XX_P, try to increase Tx power */ - if (rxqual > params->rxqual_meas.lower_thresh) { - uint8_t old = state->current; - - /* Tx power has reached the maximum, nothing to do */ - if (state->current == 0) - return 0; - + if (rxqual_avg > params->rxqual_meas.lower_thresh) { /* Increase Tx power by reducing Tx attenuation */ - if (state->current >= params->inc_step_size_db) - state->current -= params->inc_step_size_db; - else - state->current = 0; - - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Reducing Downlink attenuation: " - "%u -> %d dB due to RxQual %u worse than L_RXQUAL_XX_P %u\n", - old, state->current, rxqual, params->rxqual_meas.lower_thresh); - return 1; + new_att = state->current - params->inc_step_size_db; + } else if (rxqual_avg < params->rxqual_meas.upper_thresh) { + /* Increase Tx power by Increasing Tx attenuation */ + new_att = state->current + params->red_step_size_db; + } else { + /* Basic signal transmission / reception formula: + * + * RxLev = TxPwr - (PathLoss + TxAtt) + * + * Here we want to change RxLev at the MS side, so: + * + * RxLev + Delta = TxPwr - (PathLoss + TxAtt) + Delta + * + * The only parameter we can change here is TxAtt, so: + * + * RxLev + Delta = TxPwr - PathLoss - TxAtt + Delta + * RxLev + Delta = TxPwr - PathLoss - (TxAtt - Delta) + */ + new_att = state->current - calc_delta_rxlev(params, rxlev_avg); } - /* Calculate a 'delta' for the current attenuation level */ - delta = calc_delta(params, state, rxlev2dbm(rxlev)); - - /* Basic signal transmission / reception formula: - * - * RxLev = TxPwr - (PathLoss + TxAtt) - * - * Here we want to change RxLev at the MS side, so: - * - * RxLev + Delta = TxPwr - (PathLoss + TxAtt) + Delta - * - * The only parameter we can change here is TxAtt, so: - * - * RxLev + Delta = TxPwr - PathLoss - TxAtt + Delta - * RxLev + Delta = TxPwr - PathLoss - (TxAtt - Delta) - */ - new = state->current - delta; - if (new > state->max) - new = state->max; - if (new < 0) - new = 0; - - if (state->current != new) { - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Changing Downlink attenuation: " - "%u -> %u dB (maximum %u dB, suggested delta %d dB, " - "RxLev current %u (%d dBm), thresholds %u .. %u)\n", - state->current, new, state->max, - -delta, rxlev, rxlev2dbm(rxlev), - params->rxlev_meas.lower_thresh, - params->rxlev_meas.upper_thresh); - state->current = new; - return 1; - } else { - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping Downlink attenuation " - "at %u dB (maximum %u dB, suggested delta %d dB, " - "RxLev current %u (%d dBm), thresholds %u .. %u)\n", - state->current, state->max, - -delta, rxlev, rxlev2dbm(rxlev), - params->rxlev_meas.lower_thresh, - params->rxlev_meas.upper_thresh); + /* Make sure new TxAtt is never negative: */ + if (new_att < 0) + new_att = 0; + + /* Don't ask for higher TxAtt than permitted: */ + if (new_att > state->max) + new_att = state->max; + + if (state->current == new_att) { + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Keeping DL attenuation at %u dB: " + "max %u dB, RSSI[curr %d, avg %d, thresh %d..%d] dBm, " + "RxQual[curr %d, avg %d, thresh %d..%d]\n", + state->current, state->max, rxlev2dbm(rxlev), rxlev2dbm(rxlev_avg), + rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh), + rxqual, rxqual_avg, params->rxqual_meas.lower_thresh, params->rxqual_meas.upper_thresh); return 0; } + + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "%s DL attenuation %u dB => %u dB:" + "max %u dB, RSSI[curr %d, avg %d, thresh %d..%d] dBm, " + "RxQual[curr %d, avg %d, thresh %d..%d]\n", + (new_att > state->current) ? "Raising" : "Lowering", + state->current, new_att, state->max, rxlev2dbm(rxlev), rxlev2dbm(rxlev_avg), + rxlev2dbm(params->rxlev_meas.lower_thresh), rxlev2dbm(params->rxlev_meas.upper_thresh), + rxqual, rxqual_avg, params->rxqual_meas.lower_thresh, params->rxqual_meas.upper_thresh); + state->current = new_att; + return 1; +} + +/* Default MS/BS Power Control parameters (see 3GPP TS 45.008, table A.1) */ +const struct gsm_power_ctrl_params power_ctrl_params_def = { + /* Power increasing/reducing step size (optimal defaults) */ + .inc_step_size_db = 4, /* quickly increase MS/BS power */ + .red_step_size_db = 2, /* slowly decrease MS/BS power */ + + /* RxLev measurement parameters */ + .rxlev_meas = { + /* Thresholds for RxLev (see 3GPP TS 45.008, A.3.2.1) */ + .lower_thresh = 32, /* L_RXLEV_XX_P (-78 dBm) */ + .upper_thresh = 38, /* U_RXLEV_XX_P (-72 dBm) */ + + /* NOTE: only Osmocom specific EWMA is supported */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_OSMO_EWMA, + .ewma.alpha = 50, /* Smoothing factor 50% */ + }, + + /* RxQual measurement parameters */ + .rxqual_meas = { + /* Thresholds for RxQual (see 3GPP TS 45.008, A.3.2.1) */ + .lower_thresh = 3, /* L_RXQUAL_XX_P (0.8% <= BER < 1.6%) */ + .upper_thresh = 0, /* U_RXQUAL_XX_P (BER < 0.2%) */ + + /* No averaging (filtering) by default. + * NOTE: only Osmocom specific EWMA is supported */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + }, + + /* C/I measurement parameters. + * Target C/I retrieved from "GSM/EDGE: Evolution and Performance" Table 10.3. + * Set lower and upper so that (lower + upper) / 2 is equal or slightly + * above the target. + */ + .ci_fr_meas = { /* FR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ + .lower_thresh = 13, + .upper_thresh = 17, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_FR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_FR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_hr_meas = { /* HR: Target C/I = 18 dB, Soft blocking threshold = 13 dB */ + .lower_thresh = 16, + .upper_thresh = 21, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_HR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_HR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_amr_fr_meas = { /* AMR-FR: Target C/I = 9 dB, Soft blocking threshold = 4 dB */ + .lower_thresh = 7, + .upper_thresh = 11, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_AMR_FR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_AMR_FR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_amr_hr_meas = { /* AMR-HR: Target C/I = 15 dB, Soft blocking threshold = 10 dB */ + .lower_thresh = 13, + .upper_thresh = 17, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_AMR_HR_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_AMR_HR_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_sdcch_meas = { /* SDCCH: Target C/I = 14 dB, Soft blocking threshold = 9 dB */ + .lower_thresh = 12, + .upper_thresh = 16, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_SDCCH_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_SDCCH_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, + .ci_gprs_meas = { /* GPRS: Target C/I = 20 dB, Soft blocking threshold = 15 dB */ + .lower_thresh = 18, + .upper_thresh = 24, + + /* Increase {UL,DL}_TXPWR if at least LOWER_CMP_P averages + * out of LOWER_CMP_N averages are lower than L_CI_GPRS_XX_P */ + .lower_cmp_p = 5, /* P3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + .lower_cmp_n = 7, /* N3 as in 3GPP TS 45.008, A.3.2.1 (case c) */ + /* Decrease {UL,DL}_TXPWR if at least UPPER_CMP_P averages + * out of UPPER_CMP_N averages are greater than L_CI_GPRS_XX_P */ + .upper_cmp_p = 15, /* P4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + .upper_cmp_n = 18, /* N4 as in 3GPP TS 45.008, A.3.2.1 (case d) */ + + /* No averaging (filtering) by default */ + .algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE, + + /* Hreqave: the period over which an average is produced */ + .h_reqave = 4, /* TODO: investigate a reasonable default value */ + /* Hreqt: the number of averaged results maintained */ + .h_reqt = 6, /* TODO: investigate a reasonable default value */ + }, +}; + +void power_ctrl_params_def_reset(struct gsm_power_ctrl_params *params, bool is_bs_pwr) +{ + *params = power_ctrl_params_def; + + /* Trigger loop every N-th SACCH block. See 3GPP TS 45.008 section 4.7.1. */ + if (!is_bs_pwr) + params->ctrl_interval = 2; /* N=4 (1.92s) */ + else + params->ctrl_interval = 1; /* N=2 (0.960) */ } diff --git a/src/common/probes.d b/src/common/probes.d new file mode 100644 index 00000000..aaf9030e --- /dev/null +++ b/src/common/probes.d @@ -0,0 +1,2 @@ +provider osmo_bts { +}; diff --git a/src/common/rsl.c b/src/common/rsl.c index 18c03491..fa5f495a 100644 --- a/src/common/rsl.c +++ b/src/common/rsl.c @@ -2,7 +2,7 @@ /* (C) 2011 by Andreas Eversberg <jolly@eversberg.eu> * (C) 2011-2019 by Harald Welte <laforge@gnumonks.org> - * (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -14,15 +14,13 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ -#include "btsconfig.h" /* for PACKAGE_VERSION */ - #include <stdio.h> #include <errno.h> #include <netdb.h> @@ -58,6 +56,8 @@ #include <osmo-bts/l1sap.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/pcuif_proto.h> +#include <osmo-bts/notification.h> +#include <osmo-bts/asci.h> //#define FAKE_CIPH_MODE_COMPL @@ -65,6 +65,31 @@ #define BS_POWER2DB(bs_power) \ ((bs_power & 0x0f) * 2) +bool rsl_chan_rt_is_asci(enum rsl_cmod_crt chan_rt) +{ + switch (chan_rt) { + case RSL_CMOD_CRT_TCH_GROUP_Bm: + case RSL_CMOD_CRT_TCH_GROUP_Lm: + case RSL_CMOD_CRT_TCH_BCAST_Bm: + case RSL_CMOD_CRT_TCH_BCAST_Lm: + return true; + default: + return false; + } +} + +bool rsl_chan_rt_is_vgcs(enum rsl_cmod_crt chan_rt) +{ + switch (chan_rt) { + case RSL_CMOD_CRT_TCH_GROUP_Bm: + case RSL_CMOD_CRT_TCH_GROUP_Lm: + return true; + default: + return false; + } +} + + static int rsl_tx_error_report(struct gsm_bts_trx *trx, uint8_t cause, const uint8_t *chan_nr, const uint8_t *link_id, const struct msgb *orig_msg); @@ -74,6 +99,7 @@ static const unsigned int rsl_sacch_sitypes[] = { RSL_SYSTEM_INFO_6, RSL_SYSTEM_INFO_5bis, RSL_SYSTEM_INFO_5ter, + RSL_SYSTEM_INFO_10, RSL_EXT_MEAS_ORDER, RSL_MEAS_INFO, }; @@ -90,19 +116,6 @@ int osmo_in_array(unsigned int search, const unsigned int *arr, unsigned int siz } #define OSMO_IN_ARRAY(search, arr) osmo_in_array(search, arr, ARRAY_SIZE(arr)) -int msgb_queue_flush(struct llist_head *list) -{ - struct msgb *msg, *msg2; - int count = 0; - - llist_for_each_entry_safe(msg, msg2, list, list) { - msgb_free(msg); - count++; - } - - return count; -} - /* FIXME: move this to libosmocore */ void gsm48_gen_starting_time(uint8_t *out, struct gsm_time *gtime) { @@ -126,6 +139,7 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan, cm = (const struct rsl_ie_chan_mode *) TLVP_VAL(tp, RSL_IE_CHAN_MODE); lchan->rsl_cmode = cm->spd_ind; + lchan->rsl_chan_rt = cm->chan_rt; lchan->ts->trx->bts->dtxd = (cm->dtx_dtu & RSL_CMOD_DTXd) ? true : false; /* Octet 5: Channel rate and type */ @@ -133,6 +147,10 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan, case RSL_CMOD_CRT_SDCCH: case RSL_CMOD_CRT_TCH_Bm: case RSL_CMOD_CRT_TCH_Lm: + case RSL_CMOD_CRT_TCH_GROUP_Bm: + case RSL_CMOD_CRT_TCH_GROUP_Lm: + case RSL_CMOD_CRT_TCH_BCAST_Bm: + case RSL_CMOD_CRT_TCH_BCAST_Lm: break; case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Bm: case RSL_CMOD_CRT_OSMO_TCH_VAMOS_Lm: @@ -175,14 +193,14 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan, lchan->tch_mode = GSM48_CMODE_SPEECH_AMR; break; case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM4): + lchan->tch_mode = GSM48_CMODE_SPEECH_V4; + break; case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM5): + lchan->tch_mode = GSM48_CMODE_SPEECH_V5; + break; case RSL_CMODE(RSL_CMOD_SPD_SPEECH, RSL_CMOD_SP_GSM6): - /* TODO: also handle RSL_CMOD_SP_{GSM4,GSM5,GSM6} */ - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains " - "unhandled speech coding algorithm 0x%02x\n", - cm->chan_rate); - *cause = RSL_ERR_IE_CONTENT; - return -ENOTSUP; + lchan->tch_mode = GSM48_CMODE_SPEECH_V6; + break; /* If octet 4 indicates non-transparent data */ case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_14k5): @@ -195,35 +213,77 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan, lchan->tch_mode = GSM48_CMODE_DATA_6k0; break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_43k5): + lchan->tch_mode = GSM48_CMODE_DATA_43k5; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NT_28k8): + /* 28.8 kbit/s services, 29.0 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_29k0; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_14k5): + lchan->tch_mode = GSM48_CMODE_DATA_43k5_14k5; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_14k5): + lchan->tch_mode = GSM48_CMODE_DATA_29k0_14k5; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_43k5_29k0): + lchan->tch_mode = GSM48_CMODE_DATA_43k5_29k0; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_43k5): + lchan->tch_mode = GSM48_CMODE_DATA_14k5_43k5; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_14k5_29k0): + lchan->tch_mode = GSM48_CMODE_DATA_14k5_29k0; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_NTA_29k0_43k5): - /* TODO: also handle other non-transparent data rates */ - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains " - "unhandled non-transparent CSD data rate 0x%02x\n", - cm->chan_rate & 0x3f); - *cause = RSL_ERR_IE_CONTENT; - return -ENOTSUP; + lchan->tch_mode = GSM48_CMODE_DATA_29k0_43k5; + break; /* If octet 4 indicates transparent data */ - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_32000): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_29000): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_14400): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_9600): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_4800): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_2400): - case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200): + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_32k0): + /* 32.0 kbit/s services, 32.0 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_32k0; + lchan->csd_mode = LCHAN_CSD_M_T_32000; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_29k0): + /* 29.0 kbit/s services, 29.0 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_29k0; + lchan->csd_mode = LCHAN_CSD_M_T_29000; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_14k4): + /* 14.4 kbit/s services, 14.5 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_14k5; + lchan->csd_mode = LCHAN_CSD_M_T_14400; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_9k6): + /* 9.6 kbit/s services, 12.0 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_12k0; + lchan->csd_mode = LCHAN_CSD_M_T_9600; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_4k8): + /* 4.8 kbit/s services, 6.0 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_6k0; + lchan->csd_mode = LCHAN_CSD_M_T_4800; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_2k4): + /* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_3k6; + lchan->csd_mode = LCHAN_CSD_M_T_2400; + break; + case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1k2): + /* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_3k6; + lchan->csd_mode = LCHAN_CSD_M_T_1200; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_600): + /* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_3k6; + lchan->csd_mode = LCHAN_CSD_M_T_600; + break; case RSL_CMODE(RSL_CMOD_SPD_DATA, RSL_CMOD_CSD_T_1200_75): - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains " - "unhandled transparent CSD data rate 0x%02x\n", - cm->chan_rate & 0x3f); - *cause = RSL_ERR_IE_CONTENT; - return -ENOTSUP; + /* 2.4 kbit/s *and less* services, 3.6 kbit/s radio interface rate */ + lchan->tch_mode = GSM48_CMODE_DATA_3k6; + lchan->csd_mode = LCHAN_CSD_M_T_1200_75; + break; default: LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel Mode IE contains " @@ -237,7 +297,7 @@ static int rsl_handle_chan_mod_ie(struct gsm_lchan *lchan, #undef RSL_CMODE - if (bts_supports_cm(lchan->ts->trx->bts, cm) != 1) { + if (!bts_supports_cm(lchan->ts->trx->bts, cm)) { LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Channel type=0x%02x/mode=%s " "is not supported by the PHY\n", cm->chan_rt, gsm48_chan_mode_name(lchan->tch_mode)); @@ -284,11 +344,14 @@ static int rsl_handle_osmo_tsc_ie(struct gsm_lchan *lchan, if (TLVP_PRES_LEN(tp, RSL_IE_OSMO_TRAINING_SEQUENCE, 2)) { const uint8_t *ie = TLVP_VAL(tp, RSL_IE_OSMO_TRAINING_SEQUENCE); lchan->ts->tsc_set = ie[0] & 0x03; /* Range: 0..3 */ - lchan->ts->tsc = ie[1] & 0x07; /* Range: 0..7 */ + lchan->ts->tsc_rsl = ie[1] & 0x07; /* Range: 0..7 */ + lchan->ts->tsc_rsl_configured = true; } else { - lchan->ts->tsc = lchan->ts->tsc_oml; + lchan->ts->tsc_rsl_configured = false; + lchan->ts->tsc_rsl = 0xff; lchan->ts->tsc_set = 0; } + gsm_ts_apply_configured_tsc(lchan->ts); return 0; } @@ -308,6 +371,16 @@ static bool chan_nr_is_dchan(uint8_t chan_nr) return true; } +static struct gsm_bts_trx *trx_lookup_by_arfcn(struct llist_head *trx_list, uint16_t arfcn) +{ + struct gsm_bts_trx *trx; + llist_for_each_entry(trx, trx_list, list) { + if (trx->arfcn == arfcn) + return trx; + } + return NULL; +} + static struct gsm_lchan *lchan_lookup(struct gsm_bts_trx *trx, uint8_t chan_nr, const char *log_name) { @@ -440,29 +513,37 @@ int rsl_tx_rf_res(struct gsm_bts_trx *trx) uint8_t *len = msgb_tl_put(nmsg, RSL_IE_RESOURCE_INFO); for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { - struct gsm_bts_trx_ts *ts = &trx->ts[tn]; + const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; - for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { - struct gsm_lchan *lchan = &ts->lchan[ln]; + if (ts->mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; + if (ts->mo.nm_state.availability != NM_AVSTATE_OK) + continue; - /* We're not interested in active lchans */ - if (lchan->state == LCHAN_S_ACTIVE) { - /* Avoid potential buffer overflow */ - lchan->meas.interf_meas_num = 0; - continue; - } + for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { + const struct gsm_lchan *lchan = &ts->lchan[ln]; - /* Only for GSM_LCHAN_{SDCCH,TCH_F,TCH_H} */ - if (!lchan_is_dcch(lchan)) + /* No average interference value => no band */ + if (lchan->meas.interf_meas_avg_dbm == 0) continue; - /* Average all collected samples */ - int band = gsm_lchan_interf_meas_calc_band(lchan); - if (band < 0) + /* Only for GSM_LCHAN_{SDCCH,TCH_F,TCH_H,PDTCH} */ + switch (lchan->type) { + case GSM_LCHAN_SDCCH: + case GSM_LCHAN_TCH_F: + case GSM_LCHAN_TCH_H: + /* We're not interested in active CS lchans */ + if (lchan->state == LCHAN_S_ACTIVE) + continue; + break; + case GSM_LCHAN_PDTCH: + break; + default: continue; + } - msgb_v_put(nmsg, gsm_lchan2chan_nr(lchan)); - msgb_v_put(nmsg, (band & 0x07) << 5); + msgb_v_put(nmsg, gsm_lchan2chan_nr_rsl(lchan)); + msgb_v_put(nmsg, (lchan->meas.interf_band & 0x07) << 5); } } @@ -490,7 +571,12 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) struct gsm48_system_information_type_2quater *si2q; struct bitvec bv; const uint8_t *si_buf; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + uint8_t prev_bs_ag_blks_res = 0xff; /* 0xff = unknown */ + + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } /* 9.3.30 System Info Type */ if (!TLVP_PRESENT(&tp, RSL_IE_SYSINFO_TYPE)) @@ -517,7 +603,8 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) LOGP(DRSL, LOGL_INFO, " Rx RSL BCCH INFO (SI%s, %u bytes)\n", get_value_string(osmo_sitype_strs, osmo_si), len); - if (SYSINFO_TYPE_2quater == osmo_si) { + switch (osmo_si) { + case SYSINFO_TYPE_2quater: si2q = (struct gsm48_system_information_type_2quater *) TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO); bv.data = si2q->rest_octets; bv.data_len = GSM_MACBLOCK_LEN; @@ -545,7 +632,15 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) memset(GSM_BTS_SI2Q(bts, bts->si2q_index), GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t)); memcpy(GSM_BTS_SI2Q(bts, bts->si2q_index), TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); - } else { + break; + case SYSINFO_TYPE_3: + /* Keep previous BS_AG_BLKS_RES, used below */ + if (GSM_BTS_HAS_SI(bts, SYSINFO_TYPE_3)) { + const struct gsm48_system_information_type_3 *si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3); + prev_bs_ag_blks_res = si3->control_channel_desc.bs_ag_blks_res; + } + /* fall-through */ + default: memset(bts->si_buf[osmo_si], GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t)); memcpy(bts->si_buf[osmo_si], TLVP_VAL(&tp, RSL_IE_FULL_BCCH_INFO), len); } @@ -554,11 +649,15 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) switch (osmo_si) { case SYSINFO_TYPE_3: - if (trx->nr == 0 && num_agch(trx, "RSL") != 1) { - lchan_deactivate(&trx->bts->c0->ts[0].lchan[CCCH_LCHAN]); - /* will be reactivated by sapi_deactivate_cb() */ + /* If CCCH config on TS0 changed, reactivate the chan with the new config: */ + if (trx->nr == 0 && trx->bts->c0->ts[0].lchan[CCCH_LCHAN].state != LCHAN_S_NONE && + num_agch(trx, "RSL") != prev_bs_ag_blks_res) { trx->bts->c0->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_REACT; + lchan_deactivate(&trx->bts->c0->ts[0].lchan[CCCH_LCHAN]); + /* will be reactivated by (see OS#1575): + * - bts-trx: lchan_deactivate() + * - sysmo,lc15,oc2g: lchan_deactivate()....[async]...sapi_deactivate_cb() */ } /* decode original SI3 Rest Octets as sent by BSC */ si_buf = (const uint8_t *) GSM_BTS_SI(bts, osmo_si); @@ -583,6 +682,10 @@ static int rsl_rx_bcch_info(struct gsm_bts_trx *trx, struct msgb *msg) } break; case SYSINFO_TYPE_1: + /* Get the position of the NCH, if enabled. */ + trx->bts->asci.pos_nch = pos_nch(trx, "BCCH INFO"); + pcu_tx_si(trx->bts, SYSINFO_TYPE_1, true); + break; case SYSINFO_TYPE_2: case SYSINFO_TYPE_13: pcu_tx_si(trx->bts, osmo_si, true); @@ -687,7 +790,10 @@ static int rsl_rx_paging_cmd(struct gsm_bts_trx *trx, struct msgb *msg) const uint8_t *identity_lv; int rc; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } if (!TLVP_PRESENT(&tp, RSL_IE_PAGING_GROUP) || !TLVP_PRESENT(&tp, RSL_IE_MS_IDENTITY)) @@ -722,7 +828,10 @@ static int rsl_rx_sms_bcast_cmd(struct gsm_bts_trx *trx, struct msgb *msg) bool extended_cbch = false; int rc; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } if (!TLVP_PRESENT(&tp, RSL_IE_CB_CMD_TYPE) || !TLVP_PRESENT(&tp, RSL_IE_SMSCB_MSG)) @@ -744,6 +853,100 @@ static int rsl_rx_sms_bcast_cmd(struct gsm_bts_trx *trx, struct msgb *msg) return 0; } +/* Broadcast notification about new VGCS/VBS call on every dedicated channel. + * This is required for MSs that are currently in dedicated mode that there is an ongoing call and on which channel + * the call is active. Most MSs in dedicated mode may not be able to receive the NCH otherwise. + * MSs that do not support ASCI will ignore it, as it is an unsupported message for them. + */ +static int asci_broadcast_facch(struct gsm_bts *bts, const uint8_t *group_call_ref, const uint8_t *chan_desc, + uint8_t chan_desc_len, unsigned int count) +{ + uint8_t notif[23]; + struct msgb *msg, *cmsg; + struct gsm_bts_trx *trx; + struct gsm_lchan *lchan; + unsigned int tn, ln, n; + int rc; + + rc = bts_asci_notify_facch_gen_msg(bts, notif, group_call_ref, chan_desc, chan_desc_len); + if (rc < 0) + return rc; + + llist_for_each_entry(trx, &bts->trx_list, list) { + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { + for (ln = 0; ln < ARRAY_SIZE(trx->ts[tn].lchan); ln++) { + lchan = &trx->ts[tn].lchan[ln]; + if (!lchan_is_dcch(lchan)) + continue; + if (lchan->state != LCHAN_S_ACTIVE) + continue; + msg = rsl_rll_simple(RSL_MT_UNIT_DATA_REQ, gsm_lchan2chan_nr(lchan), 0x00, 0); + msg->l3h = msg->tail; /* emulate rsl_rx_rll() behaviour */ + msgb_tl16v_put(msg, RSL_IE_L3_INFO, sizeof(notif), (uint8_t *) ¬if); + for (n = 1; n < count; n++) { + cmsg = msgb_copy(msg, "FACCH copy"); + lapdm_rslms_recvmsg(cmsg, &lchan->lapdm_ch); + } + lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch); + } + } + } + + return 0; +} + +/* Number of times to broadcast ASCI call on every dedicated channel. */ +#define ASCI_BROADCAST_NUM 3 + +/* 8.5.10 NOTIFICATION COMMAND */ +static int rsl_rx_notification_cmd(struct gsm_bts_trx *trx, struct msgb *msg) +{ + struct abis_rsl_cchan_hdr *cch = msgb_l2(msg); + struct tlv_parsed tp; + uint8_t command_indicator; + int rc; + + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } + + if (cch->chan_nr != RSL_CHAN_PCH_AGCH) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): chan nr is not Downlink CCCH\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, &cch->chan_nr, NULL, msg); + } + + if (!TLVP_PRES_LEN(&tp, RSL_IE_CMD_INDICATOR, 1)) + return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR, &cch->chan_nr, NULL, msg); + command_indicator = *TLVP_VAL(&tp, RSL_IE_CMD_INDICATOR); + + switch (command_indicator) { + case RSL_CMD_INDICATOR_START: + /* we need at least a Group Call Reference to start notification */ + if (!TLVP_PRES_LEN(&tp, RSL_IE_GROUP_CALL_REF, 5)) + return rsl_tx_error_report(trx, RSL_ERR_OPT_IE_ERROR, &cch->chan_nr, NULL, msg); + rc = bts_asci_notification_add(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF), + TLVP_VAL(&tp, RSL_IE_CHAN_DESC), TLVP_LEN(&tp, RSL_IE_CHAN_DESC), + (struct rsl_ie_nch_drx_info *) TLVP_VAL(&tp, RSL_IE_NCH_DRX_INFO)); + /* Broadcast to FACCH */ + asci_broadcast_facch(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF), TLVP_VAL(&tp, RSL_IE_CHAN_DESC), + TLVP_LEN(&tp, RSL_IE_CHAN_DESC), ASCI_BROADCAST_NUM); + break; + case RSL_CMD_INDICATOR_STOP: + if (!TLVP_PRES_LEN(&tp, RSL_IE_GROUP_CALL_REF, 5)) { + /* interpret this as stopping of all notification */ + rc = bts_asci_notification_reset(trx->bts); + } else { + rc = bts_asci_notification_del(trx->bts, TLVP_VAL(&tp, RSL_IE_GROUP_CALL_REF)); + } + break; + default: + return rsl_tx_error_report(trx, RSL_ERR_IE_CONTENT, &cch->chan_nr, NULL, msg); + } + + return rc; +} + /* OSMO_ETWS_CMD - proprietary extension as TS 48.058 has no standardized way to do this :( */ static int rsl_rx_osmo_etws_cmd(struct gsm_bts_trx *trx, struct msgb *msg) { @@ -751,7 +954,10 @@ static int rsl_rx_osmo_etws_cmd(struct gsm_bts_trx *trx, struct msgb *msg) struct gsm_bts *bts = trx->bts; struct tlv_parsed tp; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } if (!TLVP_PRESENT(&tp, RSL_IE_SMSCB_MSG)) return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR, &cch->chan_nr, NULL, msg); @@ -797,6 +1003,15 @@ static int rsl_rx_osmo_etws_cmd(struct gsm_bts_trx *trx, struct msgb *msg) * \param[in] len length of \a current in octets */ static inline void lapdm_ui_prefix(uint8_t *buf, uint32_t *valid, const uint8_t *current, uint8_t osmo_si, uint16_t len) { + /* Special case for short header SI. Do not pre-fix the two-byte UI header. */ + switch (osmo_si) { + case SYSINFO_TYPE_10: + (*valid) |= (1 << osmo_si); + memset(buf, GSM_MACBLOCK_PADDING, sizeof(sysinfo_buf_t)); + memcpy(buf, current, len); + return; + } + /* We have to pre-fix with the two-byte LAPDM UI header */ if (len > sizeof(sysinfo_buf_t) - 2) { LOGP(DRSL, LOGL_ERROR, "Truncating received SI%s (%u -> %zu) to prepend LAPDM UI header (2 bytes)\n", @@ -840,7 +1055,10 @@ static int rsl_rx_sacch_fill(struct gsm_bts_trx *trx, struct msgb *msg) uint8_t rsl_si; enum osmo_sysinfo_type osmo_si; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, NULL, NULL, msg); + } /* 9.3.30 System Info Type */ if (!TLVP_PRESENT(&tp, RSL_IE_SYSINFO_TYPE)) @@ -909,7 +1127,7 @@ static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params, const uint8_t *data, size_t data_len) { const struct tlv_p_entry *ie; - struct tlv_parsed tp[2]; + struct tlv_parsed tp[3]; unsigned int i; int rc; @@ -938,6 +1156,30 @@ static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params, params->rxqual_meas.upper_thresh = thresh->u_rxqual; } + /* Osmocom extension, C/I related thresholds: */ + if (TLVP_PRES_LEN(&tp[0], RSL_IPAC_EIE_OSMO_MS_PWR_CTL, sizeof(struct osmo_preproc_pc_thresh))) { + const struct osmo_preproc_pc_thresh *osmo_thresh; + ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_OSMO_MS_PWR_CTL); + osmo_thresh = (const struct osmo_preproc_pc_thresh *) ie->val; + params->ci_fr_meas.lower_thresh = osmo_thresh->l_ci_fr; + params->ci_fr_meas.upper_thresh = osmo_thresh->u_ci_fr; + + params->ci_hr_meas.lower_thresh = osmo_thresh->l_ci_hr; + params->ci_hr_meas.upper_thresh = osmo_thresh->u_ci_hr; + + params->ci_amr_fr_meas.lower_thresh = osmo_thresh->l_ci_amr_fr; + params->ci_amr_fr_meas.upper_thresh = osmo_thresh->u_ci_amr_fr; + + params->ci_amr_hr_meas.lower_thresh = osmo_thresh->l_ci_amr_hr; + params->ci_amr_hr_meas.upper_thresh = osmo_thresh->u_ci_amr_hr; + + params->ci_sdcch_meas.lower_thresh = osmo_thresh->l_ci_sdcch; + params->ci_sdcch_meas.upper_thresh = osmo_thresh->u_ci_sdcch; + + params->ci_gprs_meas.lower_thresh = osmo_thresh->l_ci_gprs; + params->ci_gprs_meas.upper_thresh = osmo_thresh->u_ci_gprs; + } + /* (TV) PC Threshold Comparators */ if ((ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_PC_THRESH_COMP)) != NULL) { const struct ipac_preproc_pc_comp *thresh_comp; @@ -964,12 +1206,31 @@ static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params, params->red_step_size_db = thresh_comp->red_step_size; } + /* Osmocom extension, C/I related thresholds: */ + if (TLVP_PRES_LEN(&tp[0], RSL_IPAC_EIE_OSMO_PC_THRESH_COMP, sizeof(struct osmo_preproc_pc_thresh))) { + const struct osmo_preproc_pc_comp *osmo_thresh_comp; + ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_OSMO_PC_THRESH_COMP); + osmo_thresh_comp = (const struct osmo_preproc_pc_comp *) ie->val; + #define SET_PREPROC_PC(PARAMS, FROM, TYPE) \ + (PARAMS)->TYPE##_meas.lower_cmp_p = (FROM)->TYPE.lower_p; \ + (PARAMS)->TYPE##_meas.lower_cmp_n = (FROM)->TYPE.lower_n; \ + (PARAMS)->TYPE##_meas.upper_cmp_p = (FROM)->TYPE.upper_p; \ + (PARAMS)->TYPE##_meas.upper_cmp_n = (FROM)->TYPE.upper_n + SET_PREPROC_PC(params, osmo_thresh_comp, ci_fr); + SET_PREPROC_PC(params, osmo_thresh_comp, ci_hr); + SET_PREPROC_PC(params, osmo_thresh_comp, ci_amr_fr); + SET_PREPROC_PC(params, osmo_thresh_comp, ci_amr_hr); + SET_PREPROC_PC(params, osmo_thresh_comp, ci_sdcch); + SET_PREPROC_PC(params, osmo_thresh_comp, ci_gprs); + #undef SET_PREPROC_PC + } + /* (TLV) Measurement Averaging parameters for RxLev/RxQual */ for (i = 0; i < ARRAY_SIZE(tp); i++) { const struct ipac_preproc_ave_cfg *ave_cfg; struct gsm_power_ctrl_meas_params *mp; - ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_MEAS_AVG_CFG); + ie = TLVP_GET(&tp[i], RSL_IPAC_EIE_MEAS_AVG_CFG); if (ie == NULL) break; @@ -1008,6 +1269,42 @@ static int parse_power_ctrl_params(struct gsm_power_ctrl_params *params, } } + /* (TLV) Measurement Averaging parameters for C/I (Osmocom extension)*/ + if (TLVP_PRES_LEN(&tp[0], RSL_IPAC_EIE_OSMO_MEAS_AVG_CFG, sizeof(struct osmo_preproc_ave_cfg))) { + ie = TLVP_GET(&tp[0], RSL_IPAC_EIE_OSMO_MEAS_AVG_CFG); + const struct osmo_preproc_ave_cfg *cfg = (const struct osmo_preproc_ave_cfg *) ie->val; + unsigned params_offset = 0; + #define SET_AVE_CFG(PARAMS, FROM, TYPE, PARAM_OFFSET) do {\ + if ((FROM)->TYPE.ave_enabled) { \ + (PARAMS)->TYPE##_meas.h_reqave = (FROM)->TYPE.h_reqave; \ + (PARAMS)->TYPE##_meas.h_reqt = (FROM)->TYPE.h_reqt; \ + (PARAMS)->TYPE##_meas.algo = (FROM)->TYPE.ave_method + 1; \ + switch ((FROM)->TYPE.ave_method) { \ + case IPAC_OSMO_EWMA_AVE: \ + if (ie->len > sizeof(*cfg) + (PARAM_OFFSET)) { \ + (PARAMS)->TYPE##_meas.ewma.alpha = (FROM)->params[PARAM_OFFSET]; \ + (PARAM_OFFSET)++; \ + } \ + break; \ + /* FIXME: not implemented */ \ + case IPAC_UNWEIGHTED_AVE: \ + case IPAC_WEIGHTED_AVE: \ + case IPAC_MEDIAN_AVE: \ + break; \ + } \ + } else { \ + (PARAMS)->TYPE##_meas.algo = GSM_PWR_CTRL_MEAS_AVG_ALGO_NONE; \ + } \ + } while(0) + SET_AVE_CFG(params, cfg, ci_fr, params_offset); + SET_AVE_CFG(params, cfg, ci_hr, params_offset); + SET_AVE_CFG(params, cfg, ci_amr_fr, params_offset); + SET_AVE_CFG(params, cfg, ci_amr_hr, params_offset); + SET_AVE_CFG(params, cfg, ci_sdcch, params_offset); + SET_AVE_CFG(params, cfg, ci_gprs, params_offset); + #undef SET_AVE_CFG + } + return 0; } @@ -1018,21 +1315,19 @@ static int rsl_rx_meas_preproc_dft(struct gsm_bts_trx *trx, struct msgb *msg) struct gsm_power_ctrl_params *params; const struct tlv_p_entry *ie; struct tlv_parsed tp; - int rc; LOGPTRX(trx, DRSL, LOGL_INFO, "Rx Measurement Pre-processing Defaults\n"); - rc = rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); - if (rc < 0) { - LOGPTRX(trx, DRSL, LOGL_ERROR, "Failed to parse ip.access specific " - "Measurement Pre-processing Defaults for MS/BS Power control\n"); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); return rsl_tx_error_report(trx, RSL_ERR_PROTO, NULL, NULL, msg); } /* TLV (O) BS Power Parameters IE */ if ((ie = TLVP_GET(&tp, RSL_IE_BS_POWER_PARAM)) != NULL) { /* Allocate a new chunk and initialize with default values */ - params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params)); + params = talloc(trx, struct gsm_power_ctrl_params); + power_ctrl_params_def_reset(params, true); if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) { /* Initially it points to the global defaults */ @@ -1049,7 +1344,8 @@ static int rsl_rx_meas_preproc_dft(struct gsm_bts_trx *trx, struct msgb *msg) /* TLV (O) MS Power Parameters IE */ if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) { /* Allocate a new chunk and initialize with default values */ - params = talloc_memdup(trx, &power_ctrl_params_def, sizeof(*params)); + params = talloc(trx, struct gsm_power_ctrl_params); + power_ctrl_params_def_reset(params, false); if (ie->len && parse_power_ctrl_params(params, ie->val, ie->len) == 0) { /* Initially it points to the global defaults */ @@ -1072,7 +1368,10 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg) struct abis_rsl_cchan_hdr *cch = msgb_l2(msg); struct tlv_parsed tp; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPTRX(trx, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &cch->chan_nr, NULL, msg); + } if (!TLVP_PRESENT(&tp, RSL_IE_FULL_IMM_ASS_INFO)) return rsl_tx_error_report(trx, RSL_ERR_MAND_IE_ERROR, &cch->chan_nr, NULL, msg); @@ -1085,6 +1384,45 @@ static int rsl_rx_imm_ass(struct gsm_bts_trx *trx, struct msgb *msg) msg->l2h = NULL; msg->len = TLVP_LEN(&tp, RSL_IE_FULL_IMM_ASS_INFO); + /* Early Immediate Assignment: when there is a lot of latency on Abis, the Abis roundtrip of Chan Activ -> Chan + * Activ ACK -> Immediate Assignment may take so long that each MS sends a second RACH for Chan Rqd, reserving + * two SDCCH for each request but using only one. To help with that, the Early IA feature in osmo-bsc sends the + * Immediate Assignment without waiting for the Channel Activation ACK. This may then be too early, and the MS + * may not be able to establish a channel. So to help with Early IA, look up whether the target lchan is already + * active. If not, then hold back the RR Immediate Assignment message, and send it once L1 has confirmed that + * the channel is active. Hence we still wait for the activation, but don't need the Abis roundtrip of Activ ACK + * -> Immediate Assignment via the BSC. + * If anything is wrong with the sizes or the lchan lookup, behave normally, i.e. do not do the RR IA caching, + * but just send the RR message to the MS as-is. + * 'trx' here is the TRX of the BCCH channel. To find the correct TRX for the IMM ASS target, we need to look up + * the ARFCN that is contained in the IMM ASS message. When frequency hopping is enabled, there will not be an + * ARFCN, so we cannot support early-IA with frequency hopping enabled. */ + if (msg->len >= sizeof(struct gsm48_imm_ass)) { + struct gsm48_imm_ass *rr_ia = (void*)msg->data; + if (rr_ia->chan_desc.h0.h == 0) { + /* hopping is disabled. */ + struct gsm_bts_trx *ia_target_trx; + uint16_t arfcn; + arfcn = (rr_ia->chan_desc.h0.arfcn_high << 8) + rr_ia->chan_desc.h0.arfcn_low; + + ia_target_trx = trx_lookup_by_arfcn(&trx->bts->trx_list, arfcn); + if (ia_target_trx) { + /* found the ARFCN's trx */ + struct gsm_lchan *ia_target_lchan; + ia_target_lchan = lchan_lookup(ia_target_trx, rr_ia->chan_desc.chan_nr, "Early IA check: "); + if (ia_target_lchan && ia_target_lchan->state != LCHAN_S_ACTIVE) { + /* Target lchan is not yet active. Cache the IA. + * If a previous IA is still lingering, free it. */ + msgb_free(ia_target_lchan->early_rr_ia); + ia_target_lchan->early_rr_ia = msg; + + /* return 1 means: don't msgb_free() the msg */ + return 1; + } + } + } + } + /* put into the AGCH queue of the BTS */ if (bts_agch_enqueue(trx->bts, msg) < 0) { /* if there is no space in the queue: send DELETE IND */ @@ -1122,7 +1460,7 @@ static int tx_rf_rel_ack(struct gsm_lchan *lchan, uint8_t chan_nr) /* 8.4.19 sending RF CHANnel RELease ACKnowledge */ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan) { - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); bool send_rel_ack; switch (lchan->rel_act_kind) { @@ -1180,29 +1518,14 @@ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan) } if (!send_rel_ack) { - LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "%s not sending REL ACK\n", gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "not sending REL ACK\n"); return 0; } - LOGP(DRSL, LOGL_NOTICE, "%s (ss=%d) %s Tx CHAN REL ACK\n", + LOGP(DRSL, LOGL_INFO, "%s (ss=%d) %s Tx CHAN REL ACK\n", gsm_ts_and_pchan_name(lchan->ts), lchan->nr, gsm_lchant_name(lchan->type)); - /* - * Free the LAPDm resources now that the BTS - * has released all the resources. - */ - lapdm_channel_exit(&lchan->lapdm_ch); - - /* Also ensure that there are no leftovers from repeated FACCH or - * repeated SACCH that might cause memory leakage. */ - msgb_free(lchan->tch.rep_facch[0].msg); - msgb_free(lchan->tch.rep_facch[1].msg); - lchan->tch.rep_facch[0].msg = NULL; - lchan->tch.rep_facch[1].msg = NULL; - msgb_free(lchan->rep_sacch); - lchan->rep_sacch = NULL; - return tx_rf_rel_ack(lchan, chan_nr); } @@ -1211,10 +1534,10 @@ static int rsl_tx_chan_act_ack(struct gsm_lchan *lchan) { struct gsm_time *gtime = get_time(lchan->ts->trx->bts); struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); uint8_t ie[2]; - LOGP(DRSL, LOGL_NOTICE, "%s (ss=%d) %s Tx CHAN ACT ACK\n", + LOGP(DRSL, LOGL_INFO, "%s (ss=%d) %s Tx CHAN ACT ACK\n", gsm_ts_and_pchan_name(lchan->ts), lchan->nr, gsm_lchant_name(lchan->type)); @@ -1233,28 +1556,50 @@ static int rsl_tx_chan_act_ack(struct gsm_lchan *lchan) return abis_bts_rsl_sendmsg(msg); } -/* 8.4.7 sending HANDOver DETection */ -int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay) +/* common helper function for *_DETECT */ +static int _rsl_tx_detect(struct gsm_lchan *lchan, uint8_t msg_type, uint8_t *acc_delay) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); - - LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Sending HANDOver DETect\n"); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr)); if (!msg) return -ENOMEM; /* 9.3.17 Access Delay */ - if (ho_delay) - msgb_tv_put(msg, RSL_IE_ACCESS_DELAY, *ho_delay); + if (acc_delay) + msgb_tv_put(msg, RSL_IE_ACCESS_DELAY, *acc_delay); - rsl_dch_push_hdr(msg, RSL_MT_HANDO_DET, chan_nr); + rsl_dch_push_hdr(msg, msg_type, chan_nr); msg->trx = lchan->ts->trx; return abis_bts_rsl_sendmsg(msg); } +/* 8.4.7 sending HANDOver DETection */ +int rsl_tx_hando_det(struct gsm_lchan *lchan, uint8_t *ho_delay) +{ + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Sending HANDOver DETect\n"); + + return _rsl_tx_detect(lchan, RSL_MT_HANDO_DET, ho_delay); +} + +/* 8.4.22 sending LISTENER DETection */ +int rsl_tx_listener_det(struct gsm_lchan *lchan, uint8_t *acc_delay) +{ + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Sending LISTENER DETect\n"); + + return _rsl_tx_detect(lchan, RSL_MT_LISTENER_DET, acc_delay); +} + +/* 8.4.21 sending TALKER DETection */ +int rsl_tx_talker_det(struct gsm_lchan *lchan, uint8_t *acc_delay) +{ + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Sending TALKER DETect\n"); + + return _rsl_tx_detect(lchan, RSL_MT_TALKER_DET, acc_delay); +} + /* 8.4.3 sending CHANnel ACTIVation Negative ACK */ static int _rsl_tx_chan_act_nack(struct gsm_bts_trx *trx, uint8_t chan_nr, uint8_t cause, struct gsm_lchan *lchan) @@ -1262,7 +1607,7 @@ static int _rsl_tx_chan_act_nack(struct gsm_bts_trx *trx, uint8_t chan_nr, uint8 struct msgb *msg; if (lchan) - LOGP(DRSL, LOGL_NOTICE, "%s: ", gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, ""); else LOGP(DRSL, LOGL_NOTICE, "0x%02x: ", chan_nr); LOGPC(DRSL, LOGL_NOTICE, "Sending Channel Activated NACK: cause = 0x%02x\n", cause); @@ -1279,14 +1624,14 @@ static int _rsl_tx_chan_act_nack(struct gsm_bts_trx *trx, uint8_t chan_nr, uint8 return abis_bts_rsl_sendmsg(msg); } static int rsl_tx_chan_act_nack(struct gsm_lchan *lchan, uint8_t cause) { - return _rsl_tx_chan_act_nack(lchan->ts->trx, gsm_lchan2chan_nr(lchan), cause, lchan); + return _rsl_tx_chan_act_nack(lchan->ts->trx, gsm_lchan2chan_nr_rsl(lchan), cause, lchan); } /* Send an RSL Channel Activation Ack if cause is zero, a Nack otherwise. */ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause) { if (lchan->rel_act_kind != LCHAN_REL_ACT_RSL) { - LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "not sending CHAN ACT %s\n", + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "not sending CHAN ACT %s\n", cause ? "NACK" : "ACK"); return 0; } @@ -1300,7 +1645,7 @@ int rsl_tx_chan_act_acknack(struct gsm_lchan *lchan, uint8_t cause) int rsl_tx_conn_fail(const struct gsm_lchan *lchan, uint8_t cause) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "Sending Connection Failure: cause = 0x%02x\n", cause); @@ -1409,7 +1754,7 @@ static void clear_lchan_for_pdch_activ(struct gsm_lchan *lchan) memset(&lchan->ho, 0, sizeof(lchan->ho)); memset(&lchan->ms_power_ctrl, 0, sizeof(lchan->ms_power_ctrl)); memset(&lchan->bs_power_ctrl, 0, sizeof(lchan->bs_power_ctrl)); - lchan->rqd_ta = 0; + lchan->ta_ctrl.current = 0; copy_sacch_si_to_lchan(lchan); memset(&lchan->tch, 0, sizeof(lchan->tch)); } @@ -1418,7 +1763,7 @@ static void clear_lchan_for_pdch_activ(struct gsm_lchan *lchan) * Store the CHAN_ACTIV msg, connect the L1 timeslot in the proper type and * then invoke rsl_rx_chan_activ() with msg. */ -static int dyn_ts_l1_reconnect(struct gsm_bts_trx_ts *ts, struct msgb *msg) +static int dyn_ts_l1_reconnect(struct gsm_bts_trx_ts *ts) { DEBUGP(DRSL, "%s dyn_ts_l1_reconnect\n", gsm_ts_and_pchan_name(ts)); @@ -1439,9 +1784,6 @@ static int dyn_ts_l1_reconnect(struct gsm_bts_trx_ts *ts, struct msgb *msg) return -EINVAL; } - /* We will feed this back to rsl_rx_chan_activ() later */ - ts->dyn.pending_chan_activ = msg; - /* Disconnect, continue connecting from cb_ts_disconnected(). */ DEBUGP(DRSL, "%s Disconnect\n", gsm_ts_and_pchan_name(ts)); return bts_model_ts_disconnect(ts); @@ -1476,7 +1818,7 @@ static enum gsm_phys_chan_config dyn_pchan_from_chan_nr(uint8_t chan_nr) } /* Parse RSL_IE_OSMO_REP_ACCH_CAP */ -static void parse_repeated_acch_capability(struct gsm_lchan *lchan, struct tlv_parsed *tp) +static int parse_repeated_acch_capability(struct gsm_lchan *lchan, struct tlv_parsed *tp) { /* 3GPP TS 24.008, section 10.5.1.7 defines a Repeated ACCH Capability * bit that indicates if REPEATED FACCH/SACCH is supported or not. @@ -1484,15 +1826,81 @@ static void parse_repeated_acch_capability(struct gsm_lchan *lchan, struct tlv_p * should be communicated in the RSL CHANNEL ACTIVATION. For osmo-bts * we will use a propritary IE. */ - memset(&lchan->repeated_acch_capability, 0, sizeof(lchan->repeated_acch_capability)); + memset(&lchan->rep_acch_cap, 0, sizeof(lchan->rep_acch_cap)); - if (!TLVP_PRESENT(tp, RSL_IE_OSMO_REP_ACCH_CAP)) - return; - if (TLVP_LEN(tp, RSL_IE_OSMO_REP_ACCH_CAP) != sizeof(lchan->repeated_acch_capability)) - return; + if (!TLVP_PRES_LEN(tp, RSL_IE_OSMO_REP_ACCH_CAP, sizeof(lchan->rep_acch_cap))) + return 0; + + if (!osmo_bts_has_feature(lchan->ts->trx->bts->features, BTS_FEAT_ACCH_REP)) + return -RSL_ERR_OPT_IE_ERROR; + + memcpy(&lchan->rep_acch_cap, TLVP_VAL(tp, RSL_IE_OSMO_REP_ACCH_CAP), + sizeof(lchan->rep_acch_cap)); + + return 0; +} + +/* Parse RSL_IE_OSMO_TOP_ACCH_CAP */ +static int parse_temporary_overpower_acch_capability(struct gsm_lchan *lchan, + const struct tlv_parsed *tp) +{ + memset(&lchan->top_acch_cap, 0, sizeof(lchan->top_acch_cap)); + + if (!TLVP_PRES_LEN(tp, RSL_IE_OSMO_TEMP_OVP_ACCH_CAP, sizeof(lchan->top_acch_cap))) + return 0; + + if (!osmo_bts_has_feature(lchan->ts->trx->bts->features, BTS_FEAT_ACCH_TEMP_OVP)) + return -RSL_ERR_OPT_IE_ERROR; + + memcpy(&lchan->top_acch_cap, + TLVP_VAL(tp, RSL_IE_OSMO_TEMP_OVP_ACCH_CAP), + sizeof(lchan->top_acch_cap)); + + /* Simplify checking whether the overpower is enabled at all: allow + * testing just one parameter (overpower_db > 0) instead of all three. */ + if (!lchan->top_acch_cap.sacch_enable && !lchan->top_acch_cap.facch_enable) + lchan->top_acch_cap.overpower_db = 0; + + return 0; +} + +/* Parse (O) MultiRate configuration IE (see 9.3.52) */ +static int parse_multirate_config(struct gsm_lchan *lchan, + const struct tlv_parsed *tp) +{ + int rc; + + if (!TLVP_PRESENT(tp, RSL_IE_MR_CONFIG)) { + /* Included if the Channel Mode indicates that a multi-rate codec is used */ + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) { + LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "Missing MultiRate conf IE " + "(TCH mode is %s)\n", gsm48_chan_mode_name(lchan->tch_mode)); + /* Init lchan->tch.amr_mr with hard-coded default values */ + amr_init_mr_conf_def(lchan); + goto parsed; + } + return 0; + } + + /* Included if the Channel Mode indicates that a multi-rate codec is used */ + if (lchan->tch_mode != GSM48_CMODE_SPEECH_AMR) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Unexpected MultiRate conf IE " + "(TCH mode is %s)\n", gsm48_chan_mode_name(lchan->tch_mode)); + return -RSL_ERR_OPT_IE_ERROR; + } - memcpy(&lchan->repeated_acch_capability, TLVP_VAL(tp, RSL_IE_OSMO_REP_ACCH_CAP), - sizeof(lchan->repeated_acch_capability)); + rc = amr_parse_mr_conf(&lchan->tch.amr_mr, + TLVP_VAL(tp, RSL_IE_MR_CONFIG), + TLVP_LEN(tp, RSL_IE_MR_CONFIG)); + if (rc < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Error parsing MultiRate conf IE\n"); + return -RSL_ERR_IE_CONTENT; + } + +parsed: + amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr); + lchan->tch.last_cmr = AMR_CMR_NONE; + return 0; } /* 8.4.1 CHANnel ACTIVation is received */ @@ -1501,17 +1909,52 @@ static int rsl_rx_chan_activ(struct msgb *msg) struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); struct gsm_lchan *lchan = msg->lchan; struct gsm_bts_trx_ts *ts = lchan->ts; + struct gsm_bts_trx_ts *primary_ts; struct tlv_parsed tp; const struct tlv_p_entry *ie; uint8_t type, cause; + bool reactivation = false; int rc; - if (lchan->state != LCHAN_S_NONE) { + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_chan_act_nack(lchan, RSL_ERR_PROTO); + } + + /* 9.3.3 Activation Type */ + if (!TLVP_PRESENT(&tp, RSL_IE_ACT_TYPE)) { + LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "missing Activation Type\n"); + return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); + } + type = *TLVP_VAL(&tp, RSL_IE_ACT_TYPE); + if ((type & RSL_ACT_TYPE_REACT)) { + type -= RSL_ACT_TYPE_REACT; + reactivation = true; + } + + /* If Activation Type is IMMEDIATE ASSIGNMENT, we expect L3 info with establishment. */ + lchan->l3_info_estab = (type == RSL_ACT_INTRA_IMM_ASS); + + if (!reactivation && lchan->state != LCHAN_S_NONE) { LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "error: lchan is not available, but in state: %s.\n", gsm_lchans_name(lchan->state)); return rsl_tx_chan_act_nack(lchan, RSL_ERR_EQUIPMENT_FAIL); } + if (reactivation && lchan->state == LCHAN_S_NONE) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "error: reactivation on inactive lchan.\n"); + return rsl_tx_chan_act_nack(lchan, RSL_ERR_EQUIPMENT_FAIL); + } + + /* We need to pick the real TS here to check NM state: */ + primary_ts = ts->vamos.is_shadow ? ts->vamos.peer : ts; + if (primary_ts->mo.nm_state.operational != NM_OPSTATE_ENABLED || + primary_ts->mo.nm_state.availability != NM_AVSTATE_OK) { + LOGP(DRSL, LOGL_ERROR, "%s rx chan activ but TS not in nm_state oper=ENABLED avail=OK, nack!\n", + gsm_ts_and_pchan_name(ts)); + return rsl_tx_chan_act_nack(lchan, RSL_ERR_RR_UNAVAIL); + } + if (ts->pchan == GSM_PCHAN_OSMO_DYN) { ts->dyn.pchan_want = dyn_pchan_from_chan_nr(dch->chan_nr); DEBUGP(DRSL, "%s rx chan activ\n", gsm_ts_and_pchan_name(ts)); @@ -1522,17 +1965,17 @@ static int rsl_rx_chan_activ(struct msgb *msg) * mode than this activation needs it to be. * Re-connect, then come back to rsl_rx_chan_activ(). */ - rc = dyn_ts_l1_reconnect(ts, msg); + rc = dyn_ts_l1_reconnect(ts); if (rc) return rsl_tx_chan_act_nack(lchan, RSL_ERR_NORMAL_UNSPEC); + /* will be fed back to rsl_rx_chan_activ() later */ + OSMO_ASSERT(lchan->pending_chan_activ == NULL); + lchan->pending_chan_activ = msg; /* indicate that the msgb should not be freed. */ return 1; } } - LOGPLCHAN(lchan, DRSL, LOGL_DEBUG, "rx Channel Activation in state: %s.\n", - gsm_lchans_name(lchan->state)); - /* Initialize MS Power Control defaults */ lchan->ms_power_ctrl = (struct lchan_power_ctrl_state) { .max = ms_pwr_ctl_lvl(lchan->ts->trx->bts->band, 0), @@ -1545,15 +1988,6 @@ static int rsl_rx_chan_activ(struct msgb *msg) .current = 0, }; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); - - /* 9.3.3 Activation Type */ - if (!TLVP_PRESENT(&tp, RSL_IE_ACT_TYPE)) { - LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "missing Activation Type\n"); - return rsl_tx_chan_act_nack(lchan, RSL_ERR_MAND_IE_ERROR); - } - type = *TLVP_VAL(&tp, RSL_IE_ACT_TYPE); - /* 9.3.6 Channel Mode */ if (type != RSL_ACT_OSMO_PDCH) { if (rsl_handle_chan_mod_ie(lchan, &tp, &cause) != 0) @@ -1618,7 +2052,7 @@ static int rsl_rx_chan_activ(struct msgb *msg) } /* 9.3.24 Timing Advance */ if (TLVP_PRES_LEN(&tp, RSL_IE_TIMING_ADVANCE, 1)) - lchan->rqd_ta = *TLVP_VAL(&tp, RSL_IE_TIMING_ADVANCE); + lchan->ta_ctrl.current = *TLVP_VAL(&tp, RSL_IE_TIMING_ADVANCE); /* 9.3.31 (TLV) MS Power Parameters IE (vendor specific) */ if ((ie = TLVP_GET(&tp, RSL_IE_MS_POWER_PARAM)) != NULL) { @@ -1698,20 +2132,12 @@ static int rsl_rx_chan_activ(struct msgb *msg) /* use standard SACCH filling of the BTS */ copy_sacch_si_to_lchan(lchan); } + /* 9.3.52 MultiRate Configuration */ - if (TLVP_PRESENT(&tp, RSL_IE_MR_CONFIG)) { - rc = amr_parse_mr_conf(&lchan->tch.amr_mr, - TLVP_VAL(&tp, RSL_IE_MR_CONFIG), - TLVP_LEN(&tp, RSL_IE_MR_CONFIG)); - if (rc < 0) { - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Error parsing MultiRate conf IE\n"); - rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT, &dch->chan_nr, NULL, msg); - return rsl_tx_chan_act_acknack(lchan, RSL_ERR_IE_CONTENT); - } + rc = parse_multirate_config(lchan, &tp); + if (rc < 0) + return rsl_tx_chan_act_acknack(lchan, -rc); - amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr); - lchan->tch.last_cmr = AMR_CMR_NONE; - } /* 9.3.53 MultiRate Control */ /* 9.3.54 Supported Codec Types */ @@ -1770,21 +2196,21 @@ static int rsl_rx_chan_activ(struct msgb *msg) /* Indicate which SAPIs should be enabled before the first RACH is received, for handover. See 3GPP TS 48.058 * 4.1.3 and 4.1.4. * - * | | Access || transmit | activate | This implementation - * | MS Power | Delay || on main channel | dl SACCH | activates DL SACCH + * | | Timing || transmit | activate | This implementation + * | MS Power | Advance || on main channel | dl SACCH | activates DL SACCH * ----------------------------------------------------------------------------------------- - * async ho no * --> yes no no - * async ho yes * --> yes may be started no - * async ho yes yes --> yes may be started yes - * sync ho no no --> yes no no - * sync ho yes no --> yes may be started no - * sync ho yes yes --> yes shall be started yes + * async ho no * --> yes no no + * async ho yes * --> yes may be started no + * async ho yes yes --> yes may be started yes + * sync ho no no --> yes no no + * sync ho yes no --> yes may be started no + * sync ho yes yes --> yes shall be started yes */ switch (type) { case RSL_ACT_INTER_ASYNC: case RSL_ACT_INTER_SYNC: lchan->want_dl_sacch_active = (TLVP_PRES_LEN(&tp, RSL_IE_MS_POWER, 1) - && TLVP_PRES_LEN(&tp, RSL_IE_ACCESS_DELAY, 1)); + && TLVP_PRES_LEN(&tp, RSL_IE_TIMING_ADVANCE, 1)); break; default: lchan->want_dl_sacch_active = true; @@ -1794,47 +2220,48 @@ static int rsl_rx_chan_activ(struct msgb *msg) /* Remember to send an RSL ACK once the lchan is active */ lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - parse_repeated_acch_capability(lchan, &tp); - - /* actually activate the channel in the BTS */ - rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr, &tp); + rc = parse_repeated_acch_capability(lchan, &tp); + if (rc < 0) + return rsl_tx_chan_act_acknack(lchan, -rc); + rc = parse_temporary_overpower_acch_capability(lchan, &tp); if (rc < 0) return rsl_tx_chan_act_acknack(lchan, -rc); - return 0; -} - -static int dyn_ts_pdch_release(struct gsm_lchan *lchan) -{ - struct gsm_bts_trx_ts *ts = lchan->ts; + /* Take the first ACCH overpower decision (if allowed): it can be + * enabled immediately if the RxQual threshold is disabled (0). */ + if (lchan->top_acch_cap.overpower_db > 0) + lchan->top_acch_active = !lchan->top_acch_cap.rxqual; + else + lchan->top_acch_active = false; - if (ts->dyn.pchan_is != ts->dyn.pchan_want) { - LOGP(DRSL, LOGL_ERROR, "%s: PDCH release requested but already" - " in switchover\n", gsm_ts_and_pchan_name(ts)); - return -EINVAL; + /* set ASCI channel into right state */ + if (rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) { + if (reactivation) + vgcs_lchan_react(lchan); + else + vgcs_lchan_activate(lchan); } - /* - * Indicate PDCH Disconnect in dyn_pdch.want, let pcu_tx_info_ind() - * pick it up and wait for PCU to disable the channel. - */ - ts->dyn.pchan_want = GSM_PCHAN_NONE; - - if (!pcu_connected()) { - /* PCU not connected yet. Just record the new type and done, - * the PCU will pick it up once connected. */ - ts->dyn.pchan_is = GSM_PCHAN_NONE; - return 1; + /* on reactivation, the channel is already activated */ + if (reactivation) { + rc = rsl_tx_chan_act_ack(lchan); + if (rc < 0) + LOGP(DRSL, LOGL_ERROR, "%s Cannot send act ack: %d\n", + gsm_ts_and_pchan_name(ts), rc); + return 0; } - return pcu_tx_info_ind(); + /* actually activate the channel in the BTS */ + rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr); + if (rc < 0) + return rsl_tx_chan_act_acknack(lchan, -rc); + + return 0; } /* 8.4.14 RF CHANnel RELease is received */ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) { - int rc; - if (lchan->state == LCHAN_S_NONE) { LOGP(DRSL, LOGL_ERROR, "%s ss=%d state=%s Rx RSL RF Channel Release, but is already inactive;" @@ -1845,38 +2272,7 @@ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan, uint8_t chan_nr) * not necessarily reflecting the current lchan state. */ return tx_rf_rel_ack(lchan, chan_nr); } - - if (lchan->abis_ip.rtp_socket) { - rsl_tx_ipac_dlcx_ind(lchan, RSL_ERR_NORMAL_UNSPEC); - osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO, - "Closing RTP socket on Channel Release "); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); - } - - /* release handover state */ - handover_reset(lchan); - - lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - - /* Dynamic channel in PDCH mode is released via PCU */ - if (lchan->ts->pchan == GSM_PCHAN_OSMO_DYN - && lchan->ts->dyn.pchan_is == GSM_PCHAN_PDCH) { - rc = dyn_ts_pdch_release(lchan); - if (rc == 1) { - /* If the PCU is not connected, continue to rel ack right away. */ - lchan->rel_act_kind = LCHAN_REL_ACT_PCU; - return rsl_tx_rf_rel_ack(lchan); - } - /* Waiting for PDCH release */ - return rc; - } - - l1sap_chan_rel(lchan->ts->trx, chan_nr); - - lapdm_channel_exit(&lchan->lapdm_ch); - + gsm_lchan_release(lchan, LCHAN_REL_ACT_RSL); return 0; } @@ -1910,7 +2306,7 @@ static int tx_ciph_mod_compl_hack(struct gsm_lchan *lchan, uint8_t link_id, } } - rsl_rll_push_l3(fake_msg, RSL_MT_DATA_IND, gsm_lchan2chan_nr(lchan), + rsl_rll_push_l3(fake_msg, RSL_MT_DATA_IND, gsm_lchan2chan_nr_rsl(lchan), link_id, 1); fake_msg->lchan = lchan; @@ -1955,7 +2351,8 @@ static int rsl_rx_encr_cmd(struct msgb *msg) uint8_t link_id; if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { - return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT, &dch->chan_nr, NULL, msg); + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(msg->trx, RSL_ERR_PROTO, &dch->chan_nr, NULL, msg); } if (!TLVP_PRESENT(&tp, RSL_IE_ENCR_INFO) || @@ -2024,7 +2421,7 @@ static int _rsl_tx_mode_modif_nack(struct gsm_bts_trx *trx, uint8_t chan_nr, uin struct msgb *msg; if (lchan) - LOGP(DRSL, LOGL_NOTICE, "%s: ", gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, ""); else LOGP(DRSL, LOGL_NOTICE, "0x%02x: ", chan_nr); LOGPC(DRSL, LOGL_NOTICE, "Tx MODE MODIFY NACK (cause = 0x%02x)\n", cause); @@ -2045,7 +2442,7 @@ static int _rsl_tx_mode_modif_nack(struct gsm_bts_trx *trx, uint8_t chan_nr, uin } static int rsl_tx_mode_modif_nack(struct gsm_lchan *lchan, uint8_t cause) { - return _rsl_tx_mode_modif_nack(lchan->ts->trx, gsm_lchan2chan_nr(lchan), cause, lchan); + return _rsl_tx_mode_modif_nack(lchan->ts->trx, gsm_lchan2chan_nr_rsl(lchan), cause, lchan); } @@ -2053,7 +2450,7 @@ static int rsl_tx_mode_modif_nack(struct gsm_lchan *lchan, uint8_t cause) static int rsl_tx_mode_modif_ack(struct gsm_lchan *lchan) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Tx MODE MODIF ACK\n"); @@ -2076,7 +2473,10 @@ static int rsl_rx_mode_modif(struct msgb *msg) uint8_t cause; int rc; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_mode_modif_nack(lchan, RSL_ERR_PROTO); + } /* 9.3.6 Channel Mode */ if (rsl_handle_chan_mod_ie(lchan, &tp, &cause) != 0) @@ -2102,23 +2502,26 @@ static int rsl_rx_mode_modif(struct msgb *msg) /* 9.3.45 Main channel reference */ /* 9.3.52 MultiRate Configuration */ - if (TLVP_PRESENT(&tp, RSL_IE_MR_CONFIG)) { - rc = amr_parse_mr_conf(&lchan->tch.amr_mr, - TLVP_VAL(&tp, RSL_IE_MR_CONFIG), - TLVP_LEN(&tp, RSL_IE_MR_CONFIG)); - if (rc < 0) { - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Error parsing MultiRate conf IE\n"); - rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT, &dch->chan_nr, NULL, msg); - return rsl_tx_mode_modif_nack(lchan, RSL_ERR_IE_CONTENT);; - } + rc = parse_multirate_config(lchan, &tp); + if (rc < 0) + return rsl_tx_mode_modif_nack(lchan, -rc); - amr_log_mr_conf(DRTP, LOGL_DEBUG, gsm_lchan_name(lchan), &lchan->tch.amr_mr); - lchan->tch.last_cmr = AMR_CMR_NONE; - } /* 9.3.53 MultiRate Control */ /* 9.3.54 Supported Codec Types */ - parse_repeated_acch_capability(lchan, &tp); + rc = parse_repeated_acch_capability(lchan, &tp); + if (rc < 0) + return rsl_tx_mode_modif_nack(lchan, -rc); + rc = parse_temporary_overpower_acch_capability(lchan, &tp); + if (rc < 0) + return rsl_tx_mode_modif_nack(lchan, -rc); + + /* Immediately disable ACCH overpower if the value is 0 dB, + * or enable if the RxQual threshold becomes disabled (0). */ + if (lchan->top_acch_cap.overpower_db == 0) + lchan->top_acch_active = false; + else if (lchan->top_acch_cap.rxqual == 0) + lchan->top_acch_active = true; l1sap_chan_modify(lchan->ts->trx, dch->chan_nr); @@ -2139,7 +2542,10 @@ static int rsl_rx_ms_pwr_ctrl(struct msgb *msg) uint8_t pwr; int max_pwr, curr_pwr; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(msg->trx, RSL_ERR_PROTO, &dch->chan_nr, NULL, msg); + } /* 9.3.13 MS Power (M) */ if (!TLVP_PRES_LEN(&tp, RSL_IE_MS_POWER, 1)) @@ -2202,7 +2608,10 @@ static int rsl_rx_bs_pwr_ctrl(struct msgb *msg) struct tlv_parsed tp; uint8_t old, new; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(trx, RSL_ERR_PROTO, &dch->chan_nr, NULL, msg); + } /* 9.3.4 BS Power (M) */ if (!TLVP_PRES_LEN(&tp, RSL_IE_BS_POWER, 1)) @@ -2275,7 +2684,10 @@ static int rsl_rx_sacch_inf_mod(struct msgb *msg) struct tlv_parsed tp; uint8_t rsl_si, osmo_si; - rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_error_report(msg->trx, RSL_ERR_PROTO, &dch->chan_nr, NULL, msg); + } if (TLVP_PRESENT(&tp, RSL_IE_STARTNG_TIME)) { LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "Starting time not supported\n"); @@ -2331,7 +2743,7 @@ int rsl_tx_cbch_load_indication(struct gsm_bts *bts, bool ext_cbch, bool overflo return -ENOMEM; /* 9.3.1 Channel Number */ - rsl_cch_push_hdr(msg, RSL_MT_CBCH_LOAD_IND, gsm_lchan2chan_nr(lchan)); + rsl_cch_push_hdr(msg, RSL_MT_CBCH_LOAD_IND, gsm_lchan2chan_nr_rsl(lchan)); /* 9.3.43 CBCH Load Information */ load_info = ((overflow & 1) << 7) | (amount & 0x0F); @@ -2383,7 +2795,9 @@ int rsl_tx_ipac_dlcx_ind(struct gsm_lchan *lchan, uint8_t cause) { struct msgb *nmsg; - LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "Sending RTP delete indication: cause = %s\n", + LOGPLCHAN(lchan, DRSL, + (cause == RSL_ERR_NORMAL_UNSPEC) ? LOGL_INFO : LOGL_NOTICE, + "Sending RTP delete indication: cause = %s\n", rsl_err_name(cause)); nmsg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr)); @@ -2393,7 +2807,7 @@ int rsl_tx_ipac_dlcx_ind(struct gsm_lchan *lchan, uint8_t cause) msgb_tv16_put(nmsg, RSL_IE_IPAC_CONN_ID, htons(lchan->abis_ip.conn_id)); rsl_add_rtp_stats(lchan, nmsg); msgb_tlv_put(nmsg, RSL_IE_CAUSE, 1, &cause); - rsl_ipa_push_hdr(nmsg, RSL_MT_IPAC_DLCX_IND, gsm_lchan2chan_nr(lchan)); + rsl_ipa_push_hdr(nmsg, RSL_MT_IPAC_DLCX_IND, gsm_lchan2chan_nr_rsl(lchan)); nmsg->trx = lchan->ts->trx; @@ -2405,7 +2819,7 @@ static int rsl_tx_ipac_XXcx_ack(struct gsm_lchan *lchan, int inc_pt2, uint8_t orig_msgt) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); const char *name; struct in_addr ia; @@ -2443,6 +2857,11 @@ static int rsl_tx_ipac_XXcx_ack(struct gsm_lchan *lchan, int inc_pt2, lchan->abis_ip.rtp_payload2); } + /* Osmocom Extension: Osmux CID */ + if (lchan->abis_ip.osmux.use) + msgb_tlv_put(msg, RSL_IE_OSMO_OSMUX_CID, 1, + &lchan->abis_ip.osmux.local_cid); + /* push the header in front */ rsl_ipa_push_hdr(msg, orig_msgt + 1, chan_nr); msg->trx = lchan->ts->trx; @@ -2453,7 +2872,7 @@ static int rsl_tx_ipac_XXcx_ack(struct gsm_lchan *lchan, int inc_pt2, static int rsl_tx_ipac_dlcx_ack(struct gsm_lchan *lchan, int inc_conn_id) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); LOGPLCHAN(lchan, DRSL, LOGL_INFO, "RSL Tx IPAC_DLCX_ACK\n"); @@ -2476,7 +2895,7 @@ static int rsl_tx_ipac_dlcx_nack(struct gsm_lchan *lchan, int inc_conn_id, uint8_t cause) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); LOGPLCHAN(lchan, DRSL, LOGL_INFO, "RSL Tx IPAC_DLCX_NACK\n"); @@ -2497,15 +2916,15 @@ static int rsl_tx_ipac_dlcx_nack(struct gsm_lchan *lchan, int inc_conn_id, } -/* transmit an CRCX NACK for the lchan */ +/* Send an xxCX NACK for the given xxCX message type and lchan */ static int tx_ipac_XXcx_nack(struct gsm_lchan *lchan, uint8_t cause, int inc_ipport, uint8_t orig_msgtype) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); + uint8_t msg_type = orig_msgtype + 2; - /* FIXME: allocate new msgb and copy old over */ - LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "RSL Tx IPAC_BIND_NACK\n"); + LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "RSL Tx %s\n", rsl_ipac_msg_name(msg_type)); msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr)); if (!msg) @@ -2525,7 +2944,7 @@ static int tx_ipac_XXcx_nack(struct gsm_lchan *lchan, uint8_t cause, msgb_tlv_put(msg, RSL_IE_CAUSE, 1, &cause); /* push the header in front */ - rsl_ipa_push_hdr(msg, orig_msgtype + 2, chan_nr); + rsl_ipa_push_hdr(msg, msg_type, chan_nr); msg->trx = lchan->ts->trx; return abis_bts_rsl_sendmsg(msg); @@ -2533,7 +2952,7 @@ static int tx_ipac_XXcx_nack(struct gsm_lchan *lchan, uint8_t cause, static char *get_rsl_local_ip(struct gsm_bts_trx *trx) { - struct e1inp_ts *ts = trx->rsl_link->ts; + struct e1inp_ts *ts = trx->bb_transc.rsl.link->ts; struct sockaddr_storage ss; socklen_t sa_len = sizeof(ss); static char hostbuf[256]; @@ -2553,54 +2972,20 @@ static char *get_rsl_local_ip(struct gsm_bts_trx *trx) return hostbuf; } -static int bind_rtp(struct gsm_bts *bts, struct osmo_rtp_socket *rs, const char *ip) -{ - int rc; - unsigned int i; - unsigned int tries; - - tries = (bts->rtp_port_range_end - bts->rtp_port_range_start) / 2; - for (i = 0; i < tries; i++) { - - if (bts->rtp_port_range_next >= bts->rtp_port_range_end) - bts->rtp_port_range_next = bts->rtp_port_range_start; - - rc = osmo_rtp_socket_bind(rs, ip, bts->rtp_port_range_next); - - bts->rtp_port_range_next += 2; - - if (rc != 0) - continue; - - if (bts->rtp_ip_dscp != -1) { - if (osmo_rtp_socket_set_dscp(rs, bts->rtp_ip_dscp)) - LOGP(DRSL, LOGL_ERROR, "failed to set DSCP=%i: %s\n", - bts->rtp_ip_dscp, strerror(errno)); - } - if (bts->rtp_priority != -1) { - if (osmo_rtp_socket_set_priority(rs, bts->rtp_priority)) - LOGP(DRSL, LOGL_ERROR, "failed to set socket priority %d: %s\n", - bts->rtp_priority, strerror(errno)); - } - return 0; - } - - return -1; -} - static int rsl_rx_ipac_XXcx(struct msgb *msg) { struct abis_rsl_dchan_hdr *dch = msgb_l2(msg); struct tlv_parsed tp; struct gsm_lchan *lchan = msg->lchan; struct gsm_bts *bts = lchan->ts->trx->bts; - const uint8_t *payload_type, *speech_mode, *payload_type2; + const uint8_t *payload_type, *speech_mode, *payload_type2, *osmux_cid, *csd_fmt; uint32_t connect_ip = 0; uint16_t connect_port = 0; - int rc, inc_ip_port = 0, port; + int rc, inc_ip_port = 0; char *name; struct in_addr ia; - struct in_addr addr; + enum rsl_ipac_rtp_csd_format_d csd_fmt_d; + enum rsl_ipac_rtp_csd_format_ir csd_fmt_ir; if (dch->c.msg_type == RSL_MT_IPAC_CRCX) name = "CRCX"; @@ -2612,13 +2997,14 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) return tx_ipac_XXcx_nack(lchan, 0x52, 0, dch->c.msg_type); - rc = rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); - if (rc < 0) - return tx_ipac_XXcx_nack(lchan, RSL_ERR_MAND_IE_ERROR, - 0, dch->c.msg_type); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_PROTO, 0, dch->c.msg_type); + } LOGPLCHAN(lchan, DRSL, LOGL_DEBUG, "IPAC_%s: ", name); if (TLVP_PRES_LEN(&tp, RSL_IE_IPAC_REMOTE_IP, 4)) { + struct in_addr addr; connect_ip = tlvp_val32_unal(&tp, RSL_IE_IPAC_REMOTE_IP); addr.s_addr = connect_ip; LOGPC(DRSL, LOGL_DEBUG, "connect_ip=%s ", inet_ntoa(addr)); @@ -2640,6 +3026,12 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) LOGPC(DRSL, LOGL_DEBUG, "\n"); payload_type2 = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_PAYLOAD2); + if (payload_type2) + LOGPC(DRSL, LOGL_DEBUG, "payload_type2=%u ", *payload_type2); + + osmux_cid = TLVP_VAL(&tp, RSL_IE_OSMO_OSMUX_CID); + if (osmux_cid) + LOGPC(DRSL, LOGL_DEBUG, "osmux_cid=%u ", *osmux_cid); if (dch->c.msg_type == RSL_MT_IPAC_CRCX && connect_ip && connect_port) inc_ip_port = 1; @@ -2651,116 +3043,107 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg) inc_ip_port, dch->c.msg_type); } - if (dch->c.msg_type == RSL_MT_IPAC_CRCX) { - char cname[256+4]; - char *ipstr = NULL; - if (lchan->abis_ip.rtp_socket) { - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC CRCX, " - "but we already have socket!\n"); - return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, - inc_ip_port, dch->c.msg_type); + if ((csd_fmt = TLVP_VAL(&tp, RSL_IE_IPAC_RTP_CSD_FMT))) { + csd_fmt_d = *csd_fmt & 0xf; + csd_fmt_ir = *csd_fmt >> 4; + LOGPC(DRSL, LOGL_DEBUG, "csd_fmt_d=%d csd_fmt_ir=%d ", csd_fmt_d, csd_fmt_ir); + if (csd_fmt_d != RSL_IPAC_RTP_CSD_TRAU_BTS) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC %s, csd_fmt_d=%d is not supported\n", + name, csd_fmt_d); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_SERV_OPT_UNIMPL, inc_ip_port, dch->c.msg_type); } - /* FIXME: select default value depending on speech_mode */ - //if (!payload_type) - lchan->tch.last_fn = LCHAN_FN_DUMMY; - lchan->abis_ip.rtp_socket = osmo_rtp_socket_create(lchan->ts->trx, - OSMO_RTP_F_POLL); - if (!lchan->abis_ip.rtp_socket) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n"); - oml_tx_failure_event_rep(&lchan->ts->trx->mo, - NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, - "%s IPAC Failed to create RTP/RTCP sockets", - gsm_lchan_name(lchan)); + } + + if (!osmux_cid) { /* Regular RTP */ + if (bts->osmux.use == OSMUX_USAGE_ONLY) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC XXcx without Osmux CID" + "goes against configured Osmux policy 'only'\n"); return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } - rc = osmo_rtp_socket_set_param(lchan->abis_ip.rtp_socket, - bts->rtp_jitter_adaptive ? - OSMO_RTP_P_JIT_ADAP : - OSMO_RTP_P_JITBUF, - bts->rtp_jitter_buf_ms); - if (rc < 0) - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, - "IPAC Failed to set RTP socket parameters: %s\n", strerror(-rc)); - else - LOGPLCHAN(lchan, DRTP, LOGL_INFO, "IPAC set RTP socket parameters: %d\n", rc); - lchan->abis_ip.rtp_socket->priv = lchan; - lchan->abis_ip.rtp_socket->rx_cb = &l1sap_rtp_rx_cb; - - if (connect_ip && connect_port) { - /* if CRCX specifies a remote IP, we can bind() - * here to 0.0.0.0 and wait for the connect() - * below, after which the kernel will have - * selected the local IP address. */ - ipstr = "0.0.0.0"; - } else { - /* if CRCX does not specify a remote IP, we will - * not do any connect() below, and thus the - * local socket will remain bound to 0.0.0.0 - - * which however we cannot legitimately report - * back to the BSC in the CRCX_ACK */ - ipstr = get_rsl_local_ip(lchan->ts->trx); + + if (dch->c.msg_type == RSL_MT_IPAC_CRCX) { /* CRCX */ + char *ipstr = NULL; + if (connect_ip && connect_port) { + /* if CRCX specifies a remote IP, we can bind() + * here to 0.0.0.0 and wait for the connect() + * below, after which the kernel will have + * selected the local IP address. */ + ipstr = "0.0.0.0"; + } else { + /* if CRCX does not specify a remote IP, we will + * not do any connect() below, and thus the + * local socket will remain bound to 0.0.0.0 - + * which however we cannot legitimately report + * back to the BSC in the CRCX_ACK */ + ipstr = get_rsl_local_ip(lchan->ts->trx); + } + rc = lchan_rtp_socket_create(lchan, ipstr); + if (rc < 0) + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, + inc_ip_port, dch->c.msg_type); + } else { /* MDCX */ + if (!lchan->abis_ip.rtp_socket) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC MDCX, " + "but we have no RTP socket!\n"); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, + inc_ip_port, dch->c.msg_type); + } } - rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, ipstr); + + /* Special rule: If connect_ip == 0.0.0.0, use RSL IP + * address */ + if (connect_ip == 0) { + struct e1inp_sign_link *sign_link = + lchan->ts->trx->bb_transc.rsl.link; + + ia.s_addr = htonl(get_signlink_remote_ip(sign_link)); + } else + ia.s_addr = connect_ip; + rc = lchan_rtp_socket_connect(lchan, &ia, connect_port); if (rc < 0) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n"); - oml_tx_failure_event_rep(&lchan->ts->trx->mo, - NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT, - "%s IPAC Failed to bind RTP/RTCP sockets", - gsm_lchan_name(lchan)); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + lchan_rtp_socket_free(lchan); return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } - /* Ensure RTCP SDES contains some useful information */ - snprintf(cname, sizeof(cname), "bts@%s", ipstr); - osmo_rtp_set_source_desc(lchan->abis_ip.rtp_socket, cname, - gsm_lchan_name(lchan), NULL, NULL, - gsm_trx_unit_id(lchan->ts->trx), - "OsmoBTS-" PACKAGE_VERSION, NULL); - /* FIXME: multiplex connection, BSC proxy */ - } else { - /* MDCX */ - if (!lchan->abis_ip.rtp_socket) { - LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC MDCX, " - "but we have no RTP socket!\n"); + + } else { /* Osmux */ + if (bts->osmux.use == OSMUX_USAGE_OFF) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC XXcx with Osmux CID" + "goes against configured Osmux policy 'off'\n"); return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, inc_ip_port, dch->c.msg_type); } - } - - /* Special rule: If connect_ip == 0.0.0.0, use RSL IP - * address */ - if (connect_ip == 0) { - struct e1inp_sign_link *sign_link = - lchan->ts->trx->rsl_link; + if (dch->c.msg_type == RSL_MT_IPAC_CRCX) { /* CRCX */ + rc = lchan_osmux_init(lchan, payload_type ? *payload_type : 0); + if (rc < 0) + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, + inc_ip_port, dch->c.msg_type); + } else { /* MDCX */ + if (!lchan->abis_ip.osmux.use) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "Rx RSL IPAC MDCX with Osmux CID, " + "CRCX was configured as RTP!\n"); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, + inc_ip_port, dch->c.msg_type); + } + } - ia.s_addr = htonl(get_signlink_remote_ip(sign_link)); - } else - ia.s_addr = connect_ip; - rc = osmo_rtp_socket_connect(lchan->abis_ip.rtp_socket, - inet_ntoa(ia), connect_port); - if (rc < 0) { - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "Failed to connect RTP/RTCP sockets\n"); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); - return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, - inc_ip_port, dch->c.msg_type); + if (connect_ip != 0) + lchan->abis_ip.connect_ip = connect_ip; + if (connect_port != 0) + lchan->abis_ip.connect_port = connect_port; + lchan->abis_ip.osmux.remote_cid = *osmux_cid; + if (lchan->abis_ip.connect_ip && lchan->abis_ip.connect_port && + !lchan_osmux_connected(lchan)) { + rc = lchan_osmux_connect(lchan); + if (rc < 0) { + lchan_osmux_release(lchan); + return tx_ipac_XXcx_nack(lchan, RSL_ERR_RES_UNAVAIL, + inc_ip_port, dch->c.msg_type); + } + } } - /* save IP address and port number */ - lchan->abis_ip.connect_ip = ntohl(ia.s_addr); - lchan->abis_ip.connect_port = connect_port; - - rc = osmo_rtp_get_bound_ip_port(lchan->abis_ip.rtp_socket, - &lchan->abis_ip.bound_ip, - &port); - if (rc < 0) - LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC cannot obtain locally bound IP/port: %d\n", rc); - lchan->abis_ip.bound_port = port; /* Everything has succeeded, we can store new values in lchan */ if (payload_type) { @@ -2790,9 +3173,10 @@ static int rsl_rx_ipac_dlcx(struct msgb *msg) struct gsm_lchan *lchan = msg->lchan; int rc, inc_conn_id = 0; - rc = rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)); - if (rc < 0) - return rsl_tx_ipac_dlcx_nack(lchan, 0, RSL_ERR_MAND_IE_ERROR); + if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "%s(): rsl_tlv_parse() failed\n", __func__); + return rsl_tx_ipac_dlcx_nack(lchan, 0, RSL_ERR_PROTO); + } if (TLVP_PRESENT(&tp, RSL_IE_IPAC_CONN_ID)) inc_conn_id = 1; @@ -2801,9 +3185,7 @@ static int rsl_rx_ipac_dlcx(struct msgb *msg) if (lchan->abis_ip.rtp_socket) { osmo_rtp_socket_log_stats(lchan->abis_ip.rtp_socket, DRTP, LOGL_INFO, "Closing RTP socket on DLCX "); - osmo_rtp_socket_free(lchan->abis_ip.rtp_socket); - lchan->abis_ip.rtp_socket = NULL; - msgb_queue_flush(&lchan->dl_tch_queue); + lchan_rtp_socket_free(lchan); } return rc; } @@ -2817,7 +3199,7 @@ static int rsl_rx_ipac_dlcx(struct msgb *msg) static int rsl_tx_dyn_pdch_ack(struct gsm_lchan *lchan, bool pdch_act) { struct gsm_time *gtime = get_time(lchan->ts->trx->bts); - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); struct msgb *msg; uint8_t ie[2]; @@ -2846,7 +3228,7 @@ static int rsl_tx_dyn_pdch_nack(struct gsm_lchan *lchan, bool pdch_act, uint8_t cause) { struct msgb *msg; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); LOGPLCHAN(lchan, DRSL, LOGL_NOTICE, "Tx PDCH %s NACK (cause = 0x%02x)\n", pdch_act ? "ACT" : "DEACT", cause); @@ -2955,7 +3337,6 @@ static void rsl_rx_dyn_pdch(struct msgb *msg, bool pdch_act) if (pdch_act) { /* Clear TCH state. Only first lchan matters for PDCH */ clear_lchan_for_pdch_activ(ts->lchan); - /* First, disconnect the TCH channel, to connect PDTCH later */ rc = bts_model_ts_disconnect(ts); } else { @@ -2984,14 +3365,12 @@ static void ipacc_dyn_pdch_ts_disconnected(struct gsm_bts_trx_ts *ts) enum gsm_phys_chan_config as_pchan; if (ts->flags & TS_F_PDCH_DEACT_PENDING) { - LOGP(DRSL, LOGL_DEBUG, - "%s PDCH DEACT operation: channel disconnected, will reconnect as TCH\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, + "PDCH DEACT operation: channel disconnected, will reconnect as TCH\n"); as_pchan = GSM_PCHAN_TCH_F; } else if (ts->flags & TS_F_PDCH_ACT_PENDING) { - LOGP(DRSL, LOGL_DEBUG, - "%s PDCH ACT operation: channel disconnected, will reconnect as PDTCH\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, + "PDCH ACT operation: channel disconnected, will reconnect as PDTCH\n"); as_pchan = GSM_PCHAN_PDCH; } else /* No reconnect pending. */ @@ -3052,39 +3431,31 @@ void cb_ts_disconnected(struct gsm_bts_trx_ts *ts) static void ipacc_dyn_pdch_ts_connected(struct gsm_bts_trx_ts *ts, int rc) { if (rc) { - LOGP(DRSL, LOGL_NOTICE, "%s PDCH ACT IPA operation failed (%d) in bts model\n", - gsm_lchan_name(ts->lchan), rc); + LOGPLCHAN(ts->lchan, DRSL, LOGL_NOTICE, "PDCH ACT IPA operation failed (%d) in bts model\n", rc); ipacc_dyn_pdch_complete(ts, rc); return; } if (ts->flags & TS_F_PDCH_DEACT_PENDING) { - if (ts->lchan[0].type != GSM_LCHAN_TCH_F) - LOGP(DRSL, LOGL_ERROR, "%s PDCH DEACT error:" - " timeslot connected, so expecting" - " lchan type TCH/F, but is %s\n", - gsm_lchan_name(ts->lchan), - gsm_lchant_name(ts->lchan[0].type)); + if (ts->lchan[0].type != GSM_LCHAN_TCH_F) { + LOGPLCHAN(ts->lchan, DRSL, LOGL_ERROR, "PDCH DEACT error: timeslot connected, so " + "expecting lchan type TCH/F, but is %s\n", gsm_lchant_name(ts->lchan[0].type)); + } - LOGP(DRSL, LOGL_DEBUG, "%s PDCH DEACT operation:" - " timeslot connected as TCH/F\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "PDCH DEACT operation: timeslot connected as TCH/F\n"); /* During PDCH DEACT, we're done right after the TCH/F came * back up. */ ipacc_dyn_pdch_complete(ts, 0); } else if (ts->flags & TS_F_PDCH_ACT_PENDING) { - if (ts->lchan[0].type != GSM_LCHAN_PDTCH) - LOGP(DRSL, LOGL_ERROR, "%s PDCH ACT error:" - " timeslot connected, so expecting" - " lchan type PDTCH, but is %s\n", - gsm_lchan_name(ts->lchan), + if (ts->lchan[0].type != GSM_LCHAN_PDTCH) { + LOGPLCHAN(ts->lchan, DRSL, LOGL_ERROR, "PDCH ACT error: timeslot connected, " + "so expecting lchan type PDTCH, but is %s\n", gsm_lchant_name(ts->lchan[0].type)); + } - LOGP(DRSL, LOGL_DEBUG, "%s PDCH ACT operation:" - " timeslot connected as PDTCH\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "PDCH ACT operation: timeslot connected as PDTCH\n"); /* The PDTCH is connected, now tell the PCU about it. Except * when the PCU is not connected (yet), then there's nothing @@ -3107,30 +3478,31 @@ static void ipacc_dyn_pdch_ts_connected(struct gsm_bts_trx_ts *ts, int rc) static void osmo_dyn_ts_connected(struct gsm_bts_trx_ts *ts, int rc) { - struct msgb *msg = ts->dyn.pending_chan_activ; - ts->dyn.pending_chan_activ = NULL; + unsigned int ln; if (rc) { - LOGP(DRSL, LOGL_NOTICE, "%s PDCH ACT OSMO operation failed (%d) in bts model\n", - gsm_lchan_name(ts->lchan), rc); + LOGPLCHAN(ts->lchan, DRSL, LOGL_NOTICE, "PDCH ACT OSMO operation failed (%d) in bts model\n", rc); ipacc_dyn_pdch_complete(ts, rc); return; } - if (!msg) { - LOGP(DRSL, LOGL_ERROR, - "%s TS re-connected, but no chan activ msg pending\n", - gsm_ts_and_pchan_name(ts)); - return; - } - ts->dyn.pchan_is = ts->dyn.pchan_want; DEBUGP(DRSL, "%s Connected\n", gsm_ts_and_pchan_name(ts)); - /* continue where we left off before re-connecting the TS. */ - rc = rsl_rx_chan_activ(msg); - if (rc != 1) - msgb_free(msg); + /* Handle postponed RSL CHANnel ACTIVation messages (if any) */ + for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { + struct gsm_lchan *lchan = &ts->lchan[ln]; + + if (lchan->pending_chan_activ == NULL) + continue; + + struct msgb *msg = lchan->pending_chan_activ; + lchan->pending_chan_activ = NULL; + + /* Continue where we left off before re-connecting the TS */ + if (rsl_rx_chan_activ(msg) != 1) + msgb_free(msg); + } } void cb_ts_connected(struct gsm_bts_trx_ts *ts, int rc) @@ -3154,10 +3526,10 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc) pdch_act = ts->flags & TS_F_PDCH_ACT_PENDING; - if ((ts->flags & TS_F_PDCH_PENDING_MASK) == TS_F_PDCH_PENDING_MASK) - LOGP(DRSL, LOGL_ERROR, - "%s Internal Error: both PDCH ACT and PDCH DEACT pending\n", - gsm_lchan_name(ts->lchan)); + if ((ts->flags & TS_F_PDCH_PENDING_MASK) == TS_F_PDCH_PENDING_MASK) { + LOGPLCHAN(ts->lchan, DRSL, LOGL_ERROR, + "Internal Error: both PDCH ACT and PDCH DEACT pending\n"); + } ts->flags &= ~TS_F_PDCH_PENDING_MASK; @@ -3173,9 +3545,8 @@ void ipacc_dyn_pdch_complete(struct gsm_bts_trx_ts *ts, int rc) ts->flags |= TS_F_PDCH_ACTIVE; else ts->flags &= ~TS_F_PDCH_ACTIVE; - DEBUGP(DRSL, "%s %s switched to %s mode (ts->flags == %x)\n", - gsm_lchan_name(ts->lchan), gsm_pchan_name(ts->pchan), - pdch_act? "PDCH" : "TCH/F", ts->flags); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "%s switched to %s mode (ts->flags == %x)\n", + gsm_pchan_name(ts->pchan), pdch_act ? "PDCH" : "TCH/F", ts->flags); rc = rsl_tx_dyn_pdch_ack(ts->lchan, pdch_act); if (rc) @@ -3277,8 +3648,11 @@ static int rsl_rx_rll(struct gsm_bts_trx *trx, struct msgb *msg) return -1; } - DEBUGP(DRLL, "%s Rx RLL %s Abis -> LAPDm\n", gsm_lchan_name(lchan), - rsl_msg_name(rh->c.msg_type)); + /* VGCS Uplink is released by MSC using REL-REQ. */ + if (rh->c.msg_type == RSL_MT_REL_REQ) + vgcs_talker_reset(lchan, true); + + LOGPLCHAN(lchan, DRLL, LOGL_DEBUG, "Rx RLL %s Abis -> LAPDm\n", rsl_msg_name(rh->c.msg_type)); /* make copy of RLL header, as the message will be free'd in case of erroneous return */ rh2 = *rh; @@ -3373,15 +3747,15 @@ static int handle_gprs_susp_req(struct msgb *msg) int rc; if (!gh || msgb_l3len(msg) < sizeof(*gh)+sizeof(*gsr)) { - LOGP(DRSL, LOGL_NOTICE, "%s Short GPRS SUSPEND REQ received, ignoring\n", gsm_lchan_name(msg->lchan)); + LOGPLCHAN(msg->lchan, DRSL, LOGL_NOTICE, "Short GPRS SUSPEND REQ received, ignoring\n"); + msgb_free(msg); return -EINVAL; } gsr = (struct gsm48_gprs_susp_req *) gh->data; tlli = osmo_ntohl(gsr->tlli); - LOGP(DRSL, LOGL_INFO, "%s Fwd GPRS SUSPEND REQ for TLLI=0x%08x to PCU\n", - gsm_lchan_name(msg->lchan), tlli); + LOGPLCHAN(msg->lchan, DRSL, LOGL_INFO, "Fwd GPRS SUSPEND REQ for TLLI=0x%08x to PCU\n", tlli); rc = pcu_tx_susp_req(msg->lchan, tlli, gsr->ra_id, gsr->cause); msgb_free(msg); @@ -3389,16 +3763,6 @@ static int handle_gprs_susp_req(struct msgb *msg) return rc; } -static inline uint8_t ms_to2rsl(const struct gsm_lchan *lchan, const struct lapdm_entity *le) -{ - return (lchan->ms_t_offs >= 0) ? lchan->ms_t_offs : (lchan->p_offs - le->ta); -} - -static inline bool ms_to_valid(const struct gsm_lchan *lchan) -{ - return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0); -} - struct osmo_bts_supp_meas_info { int16_t toa256_mean; int16_t toa256_min; @@ -3406,12 +3770,12 @@ struct osmo_bts_supp_meas_info { uint16_t toa256_std_dev; } __attribute__((packed)); -/* Compose and send 8.4.8 MEASUREMENT RESult via RSL */ -int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le) +/* Compose and send 8.4.8 MEASUREMENT RESult via RSL. (timing_offset=-1 -> not present) */ +int rsl_tx_meas_res(struct gsm_lchan *lchan, const uint8_t *l3, unsigned int l3_len, int timing_offset) { struct msgb *msg; uint8_t meas_res[16]; - uint8_t chan_nr = gsm_lchan2chan_nr(lchan); + uint8_t chan_nr = gsm_lchan2chan_nr_rsl(lchan); int res_valid = lchan->meas.flags & LC_UL_M_F_RES_VALID; struct gsm_bts *bts = lchan->ts->trx->bts; @@ -3426,20 +3790,19 @@ int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const stru return -ENOMEM; LOGPLCHAN(lchan, DRSL, LOGL_DEBUG, - "Send Meas RES: NUM:%u, RXLEV_FULL:%u, RXLEV_SUB:%u, RXQUAL_FULL:%u, RXQUAL_SUB:%u, MS_PWR:%u, UL_TA:%u, L3_LEN:%d, TimingOff:%u\n", + "Send Meas RES: NUM:%u, RXLEV_FULL:%u, RXLEV_SUB:%u, RXQUAL_FULL:%u, RXQUAL_SUB:%u, MS_PWR:%u, UL_TA:%u, L3_LEN:%u, TimingOff:%u\n", lchan->meas.res_nr, lchan->meas.ul_res.full.rx_lev, lchan->meas.ul_res.sub.rx_lev, lchan->meas.ul_res.full.rx_qual, lchan->meas.ul_res.sub.rx_qual, lchan->meas.l1_info.ms_pwr, - lchan->meas.l1_info.ta, l3_len, ms_to2rsl(lchan, le) - MEAS_MAX_TIMING_ADVANCE); + lchan->meas.l1_info.ta, l3_len, timing_offset - MEAS_MAX_TIMING_ADVANCE); - msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, lchan->meas.res_nr++); + msgb_tv_put(msg, RSL_IE_MEAS_RES_NR, lchan->meas.res_nr); size_t ie_len = gsm0858_rsl_ul_meas_enc(&lchan->meas.ul_res, lchan->tch.dtx.dl_active, meas_res); - lchan->tch.dtx.dl_active = false; if (ie_len >= 3) { if (bts->supp_meas_toa256 && lchan->meas.flags & LC_UL_M_F_OSMO_EXT_VALID) { struct osmo_bts_supp_meas_info *smi; @@ -3457,24 +3820,18 @@ int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const stru smi->toa256_min = htons(ta256 + lchan->meas.ext.toa256_min); smi->toa256_max = htons(ta256 + lchan->meas.ext.toa256_max); smi->toa256_std_dev = htons(lchan->meas.ext.toa256_std_dev); - lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID; } msgb_tlv_put(msg, RSL_IE_UPLINK_MEAS, ie_len, meas_res); - lchan->meas.flags &= ~LC_UL_M_F_RES_VALID; } msgb_tv_put(msg, RSL_IE_BS_POWER, lchan->bs_power_ctrl.current / 2); if (lchan->meas.flags & LC_UL_M_F_L1_VALID) { msgb_tv_fixed_put(msg, RSL_IE_L1_INFO, sizeof(lchan->meas.l1_info), (uint8_t*)&lchan->meas.l1_info); - lchan->meas.flags &= ~LC_UL_M_F_L1_VALID; } - if (l3 && l3_len > 0) + if (l3 && l3_len > 0) { msgb_tl16v_put(msg, RSL_IE_L3_INFO, l3_len, l3); - if (ms_to_valid(lchan)) { - if (l3 && l3_len > 0) - msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, ms_to2rsl(lchan, le)); - lchan->ms_t_offs = -1; - lchan->p_offs = -1; + if (timing_offset != -1) + msgb_tv_put(msg, RSL_IE_MS_TIMING_OFFSET, timing_offset); } rsl_dch_push_hdr(msg, RSL_MT_MEAS_RES, chan_nr); @@ -3502,22 +3859,42 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx) msg->trx = lchan->ts->trx; msg->lchan = lchan; - /* check if this is a measurement report from SACCH which needs special - * processing before forwarding */ - if (rslms_is_meas_rep(msg)) { - int rc; + /* If DL estabishment on main signaling link and SAPI 0 with L3 info is expected. */ + if (lchan->l3_info_estab && rh->msg_type == RSL_MT_EST_IND) { + struct abis_rsl_rll_hdr *rllh = msgb_l2(msg); + if ((rllh->link_id & 0xc7) == 0) { + /* Reject initial establishment without L3 info. */ + if (msgb_l2len(msg) == sizeof(struct abis_rsl_rll_hdr)) { + LOGPLCHAN(lchan, DRSL, LOGL_ERROR, "RLL EST IND without contention resolution.\n"); + /* Release normally, re-use the msgb. */ + rh->msg_type = RSL_MT_REL_REQ; + msgb_tv_put(msg, RSL_IE_RELEASE_MODE, RSL_REL_NORMAL); + return rsl_rx_rll(lchan->ts->trx, msg); + } + /* Re-estabishment without contention resoltuion is allowed. */ + lchan->l3_info_estab = false; + } + } - LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Handing RLL msg %s from LAPDm to MEAS REP\n", + /* If this is a Measurement Report, then we simply ignore it, + * because it has already been processed in l1sap_ph_data_ind(). */ + if (rslms_is_meas_rep(msg)) { + msgb_free(msg); + return 0; + } else if (rslms_is_gprs_susp_req(msg)) { + return handle_gprs_susp_req(msg); + } else { + LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Fwd RLL msg %s from LAPDm to A-bis\n", rsl_msg_name(rh->msg_type)); /* REL_IND handling */ - if (rh->msg_type == RSL_MT_REL_IND && - (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)) { + if (rh->msg_type == RSL_MT_REL_IND && lchan_is_tch(lchan)) { + vgcs_talker_reset(lchan, true); LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Scheduling %s to L3 in next associated TCH-RTS.ind\n", rsl_msg_name(rh->msg_type)); - if(lchan->pending_rel_ind_msg) { + if (lchan->pending_rel_ind_msg) { LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Dropping pending release indication message\n"); msgb_free(lchan->pending_rel_ind_msg); @@ -3527,16 +3904,6 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx) return 0; } - repeated_dl_facch_active_decision(lchan, msgb_l3(msg), msgb_l3len(msg)); - rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le); - msgb_free(msg); - return rc; - } else if (rslms_is_gprs_susp_req(msg)) { - return handle_gprs_susp_req(msg); - } else { - LOGPLCHAN(lchan, DRSL, LOGL_INFO, "Fwd RLL msg %s from LAPDm to A-bis\n", - rsl_msg_name(rh->msg_type)); - return abis_bts_rsl_sendmsg(msg); } } @@ -3583,8 +3950,10 @@ static int rsl_rx_cchan(struct gsm_bts_trx *trx, struct msgb *msg) case RSL_MT_SMS_BC_CMD: ret = rsl_rx_sms_bcast_cmd(trx, msg); break; - case RSL_MT_SMS_BC_REQ: case RSL_MT_NOT_CMD: + ret = rsl_rx_notification_cmd(trx, msg); + break; + case RSL_MT_SMS_BC_REQ: LOGPLCHAN(msg->lchan, DRSL, LOGL_NOTICE, "unimplemented RSL cchan msg_type %s\n", rsl_msg_name(cch->c.msg_type)); rsl_tx_error_report(trx, RSL_ERR_MSG_TYPE, &cch->chan_nr, NULL, msg); @@ -3767,14 +4136,6 @@ static int rsl_rx_ipaccess(struct gsm_bts_trx *trx, struct msgb *msg) return ret; } -int lchan_deactivate(struct gsm_lchan *lchan) -{ - OSMO_ASSERT(lchan); - - lchan->ciph_state = 0; - return bts_model_lchan_deactivate(lchan); -} - int down_rsl(struct gsm_bts_trx *trx, struct msgb *msg) { struct abis_rsl_common_hdr *rslh; diff --git a/src/common/rtp_input_preen.c b/src/common/rtp_input_preen.c new file mode 100644 index 00000000..5729229f --- /dev/null +++ b/src/common/rtp_input_preen.c @@ -0,0 +1,151 @@ +/* + * This module implements a helper function for the RTP input path: + * validates incoming RTP payloads, makes the accept-or-drop decision, + * and for some codecs signals additional required actions such as + * dropping one header octet. + * + * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2023 - however, + * Mother Mychaela's contributions are NOT subject to copyright. + * No rights reserved, all rights relinquished. + * + * 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 <stdbool.h> +#include <stdint.h> + +#include <osmocom/core/logging.h> +#include <osmocom/core/utils.h> + +#include <osmocom/codec/codec.h> + +#include <osmo-bts/lchan.h> +#include <osmo-bts/logging.h> +#include <osmo-bts/rtp_input_preen.h> + +static bool amr_is_octet_aligned(const uint8_t *rtp_pl, unsigned rtp_pl_len) +{ + /* + * Logic: If 1st bit padding is not zero, packet is either: + * - bandwidth-efficient AMR payload. + * - malformed packet. + * However, Bandwidth-efficient AMR 4,75 frame last in payload(F=0, FT=0) + * with 4th,5ht,6th AMR payload to 0 matches padding==0. + * Furthermore, both AMR 4,75 bw-efficient and octet alignment are 14 bytes long (AMR 4,75 encodes 95b): + * bw-efficient: 95b, + 4b hdr + 6b ToC = 105b, + padding = 112b = 14B. + * octet-aligned: 1B hdr + 1B ToC + 95b = 111b, + padding = 112b = 14B. + * We cannot use other fields to match since they are inside the AMR + * payload bits which are unknown. + * As a result, this function may return false positive (true) for some AMR + * 4,75 AMR frames, but given the length, CMR and FT read is the same as a + * consequence, the damage in here is harmless other than being unable to + * decode the audio at the other side. + */ + #define AMR_PADDING1(rtp_pl) (rtp_pl[0] & 0x0f) + #define AMR_PADDING2(rtp_pl) (rtp_pl[1] & 0x03) + + if (rtp_pl_len < 2 || AMR_PADDING1(rtp_pl) || AMR_PADDING2(rtp_pl)) + return false; + + return true; +} + +static enum pl_input_decision +input_preen_fr(const uint8_t *rtp_pl, unsigned rtp_pl_len) +{ + if (rtp_pl_len != GSM_FR_BYTES) + return PL_DECISION_DROP; + if ((rtp_pl[0] & 0xF0) != 0xD0) + return PL_DECISION_DROP; + return PL_DECISION_ACCEPT; +} + +static enum pl_input_decision +input_preen_efr(const uint8_t *rtp_pl, unsigned rtp_pl_len) +{ + if (rtp_pl_len != GSM_EFR_BYTES) + return PL_DECISION_DROP; + if ((rtp_pl[0] & 0xF0) != 0xC0) + return PL_DECISION_DROP; + return PL_DECISION_ACCEPT; +} + +static enum pl_input_decision +input_preen_hr(const uint8_t *rtp_pl, unsigned rtp_pl_len, + bool *rfc5993_sid_flag) +{ + switch (rtp_pl_len) { + case GSM_HR_BYTES: + /* RTP input matches our internal format - we are good */ + return PL_DECISION_ACCEPT; + case GSM_HR_BYTES_RTP_RFC5993: + /* Validate ToC octet: for payload of this length to be valid, + * the F bit must be 0 and the FT field must be either 0 (good + * speech) or 2 (good SID). */ + switch (rtp_pl[0] & 0xF0) { + case 0x00: + break; + case 0x20: + *rfc5993_sid_flag = true; + break; + default: + /* invalid payload */ + return PL_DECISION_DROP; + } + /* Strip ToC octet, leaving only "pure" TS 101 318 payload. */ + return PL_DECISION_STRIP_HDR_OCTET; + default: + /* invalid payload */ + return PL_DECISION_DROP; + } +} + +enum pl_input_decision +rtp_payload_input_preen(struct gsm_lchan *lchan, const uint8_t *rtp_pl, + unsigned rtp_pl_len, bool *rfc5993_sid_flag) +{ + /* If rtp continuous-streaming is enabled, we shall emit RTP packets + * with zero-length payloads as BFI markers. In a TrFO scenario such + * RTP packets sent by call leg A will be received by call leg B, + * hence we need to handle them gracefully. For the purposes of a BTS + * that runs on its own TDMA timing and does not need timing ticks from + * an incoming RTP stream, the correct action upon receiving such + * timing-tick-only RTP packets should be the same as when receiving + * no RTP packet at all. The simplest way to produce that behavior + * is to treat zero-length RTP payloads as invalid. */ + if (rtp_pl_len == 0) + return PL_DECISION_DROP; + + switch (lchan->tch_mode) { + case GSM48_CMODE_SPEECH_V1: + if (lchan->type == GSM_LCHAN_TCH_F) + return input_preen_fr(rtp_pl, rtp_pl_len); + else + return input_preen_hr(rtp_pl, rtp_pl_len, rfc5993_sid_flag); + case GSM48_CMODE_SPEECH_EFR: + return input_preen_efr(rtp_pl, rtp_pl_len); + case GSM48_CMODE_SPEECH_AMR: + /* Avoid forwarding bw-efficient AMR to lower layers, + * most bts models don't support it. */ + if (!amr_is_octet_aligned(rtp_pl, rtp_pl_len)) { + LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, + "RTP->L1: Dropping unexpected AMR encoding (bw-efficient?) %s\n", + osmo_hexdump(rtp_pl, rtp_pl_len)); + return PL_DECISION_DROP; + } + return PL_DECISION_ACCEPT; + default: + return PL_DECISION_ACCEPT; + } +} diff --git a/src/common/scheduler.c b/src/common/scheduler.c index 6e1e4fb1..a449d167 100644 --- a/src/common/scheduler.c +++ b/src/common/scheduler.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -35,6 +35,7 @@ #include <osmocom/core/stats.h> #include <osmocom/gsm/protocol/gsm_08_58.h> +#include <osmocom/gsm/gsm0502.h> #include <osmocom/gsm/a5.h> #include <osmo-bts/gsm_data.h> @@ -150,7 +151,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { .desc = "Frequency correction channel", /* Tx only, frequency correction bursts */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .dl_fn = tx_fcch_fn, }, [TRXC_SCH] = { @@ -158,7 +158,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { .desc = "Synchronization channel", /* Tx only, synchronization bursts */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .dl_fn = tx_sch_fn, }, [TRXC_BCCH] = { @@ -169,7 +168,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { /* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4), * regular interleaving (3GPP TS 05.02, clause 7, table 3): * a L2 frame is interleaved over 4 consecutive bursts. */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .rts_fn = rts_data_fn, .dl_fn = tx_data_fn, }, @@ -179,7 +177,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { .chan_nr = RSL_CHAN_RACH, /* Rx only, RACH convolutional coding (3GPP TS 05.03, section 4.6). */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .ul_fn = rx_rach_fn, }, [TRXC_CCCH] = { @@ -190,7 +187,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { /* Tx only, xCCH convolutional coding (3GPP TS 05.03, section 4.4), * regular interleaving (3GPP TS 05.02, clause 7, table 3): * a L2 frame is interleaved over 4 consecutive bursts. */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .rts_fn = rts_data_fn, .dl_fn = tx_data_fn, }, @@ -221,13 +217,14 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { /* Rx and Tx, multiple convolutional coding types (3GPP TS 05.03, * chapter 3), block diagonal interleaving (3GPP TS 05.02, clause 7): * - * - a traffic frame is interleaved over 6 consecutive bursts + * - a traffic frame is interleaved over 4 consecutive bursts * using the even numbered bits of the first 2 bursts, - * all bits of the middle two 2 bursts, * and odd numbered bits of the last 2 bursts; * - a FACCH/H frame 'steals' (replaces) two traffic frames, - * interleaving is done over 4 consecutive bursts, - * the same as given for a TCH/FS. */ + * interleaving is done over 6 consecutive bursts, + * using the even numbered bits of the first 2 bursts, + * all bits of the middle two 2 bursts, + * and odd numbered bits of the last 2 bursts. */ .rts_fn = rts_tchh_fn, .dl_fn = tx_tchh_fn, .ul_fn = rx_tchh_fn, @@ -546,9 +543,7 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { .chan_nr = RSL_CHAN_OSMO_PDCH, /* Rx and Tx, multiple coding schemes: CS-2..4 and MCS-1..9 (3GPP TS - * 05.03, chapter 5), regular interleaving as specified for xCCH. - * NOTE: the burst buffer is three times bigger because the - * payload of EDGE bursts is three times longer. */ + * 05.03, chapter 5), regular interleaving as specified for xCCH. */ .rts_fn = rts_data_fn, .dl_fn = tx_pdtch_fn, .ul_fn = rx_pdtch_fn, @@ -574,7 +569,6 @@ const struct trx_chan_desc trx_chan_desc[_TRX_CHAN_MAX] = { .chan_nr = RSL_CHAN_OSMO_CBCH4, /* Tx only, same as for TRXC_BCCH (xCCH), see above. */ - .flags = TRX_CHAN_FLAG_AUTO_ACTIVE, .rts_fn = rts_data_fn, .dl_fn = tx_data_fn, }, @@ -653,35 +647,39 @@ void trx_sched_init(struct gsm_bts_trx *trx) } } +static void trx_sched_clean_ts(struct gsm_bts_trx_ts *ts) +{ + struct l1sched_ts *l1ts = ts->priv; + unsigned int i; + + msgb_queue_free(&l1ts->dl_prims); + rate_ctr_group_free(l1ts->ctrs); + l1ts->ctrs = NULL; + + /* clear lchan channel states */ + for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) + lchan_set_state(&ts->lchan[i], LCHAN_S_NONE); + + talloc_free(l1ts); + ts->priv = NULL; +} + void trx_sched_clean(struct gsm_bts_trx *trx) { - unsigned int tn, i; + unsigned int tn; LOGPTRX(trx, DL1C, LOGL_DEBUG, "Clean scheduler structures\n"); for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { struct gsm_bts_trx_ts *ts = &trx->ts[tn]; - struct l1sched_ts *l1ts = ts->priv; - - msgb_queue_flush(&l1ts->dl_prims); - rate_ctr_group_free(l1ts->ctrs); - l1ts->ctrs = NULL; - for (i = 0; i < _TRX_CHAN_MAX; i++) { - struct l1sched_chan_state *chan_state; - chan_state = &l1ts->chan_state[i]; - if (chan_state->dl_bursts) { - talloc_free(chan_state->dl_bursts); - chan_state->dl_bursts = NULL; - } - if (chan_state->ul_bursts) { - talloc_free(chan_state->ul_bursts); - chan_state->ul_bursts = NULL; - } - } - /* clear lchan channel states */ - for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) - lchan_set_state(&ts->lchan[i], LCHAN_S_NONE); + + /* Clean primary and shadow timeslots */ + trx_sched_clean_ts(ts); + trx_sched_clean_ts(ts->vamos.peer); } + + /* Free previously allocated shadow timeslots */ + gsm_bts_trx_free_shadow_ts(trx); } struct msgb *_sched_dequeue_prim(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br) @@ -752,10 +750,10 @@ free_msg: } int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn, - enum trx_chan_type chan, uint8_t *l2, - uint8_t l2_len, float rssi, + enum trx_chan_type chan, + const uint8_t *data, size_t data_len, + uint16_t ber10k, float rssi, int16_t ta_offs_256bits, int16_t link_qual_cb, - uint16_t ber10k, enum osmo_ph_pres_info_type presence_info) { struct msgb *msg; @@ -767,7 +765,7 @@ int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn, chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK; /* compose primitive */ - msg = l1sap_msgb_alloc(l2_len); + msg = l1sap_msgb_alloc(data_len); l1sap = msgb_l1sap_prim(msg); osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_PH_DATA, PRIM_OP_INDICATION, msg); @@ -779,12 +777,9 @@ int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn, l1sap->u.data.ta_offs_256bits = ta_offs_256bits; l1sap->u.data.lqual_cb = link_qual_cb; l1sap->u.data.pdch_presence_info = presence_info; - msg->l2h = msgb_put(msg, l2_len); - if (l2_len) - memcpy(msg->l2h, l2, l2_len); - - if (L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id)) - l1ts->chan_state[chan].lost_frames = 0; + msg->l2h = msgb_put(msg, data_len); + if (data_len) + memcpy(msg->l2h, data, data_len); /* forward primitive */ l1sap_up(l1ts->ts->trx, l1sap); @@ -793,8 +788,10 @@ int _sched_compose_ph_data_ind(struct l1sched_ts *l1ts, uint32_t fn, } int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn, - enum trx_chan_type chan, uint8_t *tch, uint8_t tch_len, - int16_t ta_offs_256bits, uint16_t ber10k, float rssi, + enum trx_chan_type chan, + const uint8_t *data, size_t data_len, + uint16_t ber10k, float rssi, + int16_t ta_offs_256bits, int16_t link_qual_cb, uint8_t is_sub) { struct msgb *msg; @@ -807,7 +804,7 @@ int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn, chan_nr |= RSL_CHAN_OSMO_VAMOS_MASK; /* compose primitive */ - msg = l1sap_msgb_alloc(tch_len); + msg = l1sap_msgb_alloc(data_len); l1sap = msgb_l1sap_prim(msg); osmo_prim_init(&l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_INDICATION, msg); @@ -816,17 +813,15 @@ int _sched_compose_tch_ind(struct l1sched_ts *l1ts, uint32_t fn, l1sap->u.tch.rssi = (int8_t) (rssi); l1sap->u.tch.ber10k = ber10k; l1sap->u.tch.ta_offs_256bits = ta_offs_256bits; + l1sap->u.tch.lqual_cb = link_qual_cb; l1sap->u.tch.is_sub = is_sub & 1; - msg->l2h = msgb_put(msg, tch_len); - if (tch_len) - memcpy(msg->l2h, tch, tch_len); - - if (l1ts->chan_state[chan].lost_frames) - l1ts->chan_state[chan].lost_frames--; + msg->l2h = msgb_put(msg, data_len); + if (data_len) + memcpy(msg->l2h, data, data_len); - LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.data.fn, "%s Rx -> RTP: %s\n", - gsm_lchan_name(lchan), osmo_hexdump(msgb_l2(msg), msgb_l2len(msg))); + LOGL1S(DL1P, LOGL_DEBUG, l1ts, chan, l1sap->u.tch.fn, "%s Rx -> RTP: %s\n", + gsm_lchan_name(lchan), msgb_hexdump_l2(msg)); /* forward primitive */ l1sap_up(l1ts->ts->trx, l1sap); @@ -848,11 +843,8 @@ int trx_sched_ph_data_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap "PH-DATA.req: chan_nr=0x%02x link_id=0x%02x\n", l1sap->u.data.chan_nr, l1sap->u.data.link_id); - OSMO_ASSERT(l1sap->oph.operation == PRIM_OP_REQUEST); - OSMO_ASSERT(l1sap->oph.msg); - /* ignore empty frame */ - if (!msgb_l2len(l1sap->oph.msg)) { + if (!l1sap->oph.msg->l2h || msgb_l2len(l1sap->oph.msg) == 0) { msgb_free(l1sap->oph.msg); return 0; } @@ -874,9 +866,6 @@ int trx_sched_tch_req(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) LOGL1S(DL1P, LOGL_DEBUG, l1ts, -1, l1sap->u.tch.fn, "TCH.req: chan_nr=0x%02x\n", l1sap->u.tch.chan_nr); - OSMO_ASSERT(l1sap->oph.operation == PRIM_OP_REQUEST); - OSMO_ASSERT(l1sap->oph.msg); - /* ignore empty frame */ if (!msgb_l2len(l1sap->oph.msg)) { msgb_free(l1sap->oph.msg); @@ -996,12 +985,21 @@ static int rts_tchf_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_ return rts_tch_common(l1ts, br, true); } +/* FACCH/H channel mapping for Downlink (see 3GPP TS 45.002, table 1). + * This mapping is valid for both FACCH/H(0) and FACCH/H(1). */ +const uint8_t sched_tchh_dl_facch_map[26] = { + [4] = 1, /* FACCH/H(0): B0(4,6,8,10,13,15) */ + [5] = 1, /* FACCH/H(1): B0(5,7,9,11,14,16) */ + [13] = 1, /* FACCH/H(0): B1(13,15,17,19,21,23) */ + [14] = 1, /* FACCH/H(1): B1(14,16,18,20,22,24) */ + [21] = 1, /* FACCH/H(0): B2(21,23,0,2,4,6) */ + [22] = 1, /* FACCH/H(1): B2(22,24,1,3,5,7) */ +}; /* RTS for half rate traffic frame */ static int rts_tchh_fn(const struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br) { - /* the FN 4/5, 13/14, 21/22 defines that FACCH may be included. */ - return rts_tch_common(l1ts, br, ((br->fn % 26) >> 2) & 1); + return rts_tch_common(l1ts, br, sched_tchh_dl_facch_map[br->fn % 26]); } /* set multiframe scheduler to given pchan */ @@ -1010,8 +1008,8 @@ int trx_sched_set_pchan(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config pch struct l1sched_ts *l1ts = ts->priv; int i = find_sched_mframe_idx(pchan, ts->nr); if (i < 0) { - LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe\n", - gsm_ts_name(ts)); + LOGP(DL1C, LOGL_NOTICE, "%s Failed to configure multiframe (pchan=0x%02x)\n", + gsm_ts_name(ts), pchan); return -ENOTSUP; } l1ts->mf_index = i; @@ -1059,6 +1057,51 @@ static void trx_sched_queue_filter(struct llist_head *q, uint8_t chan_nr, uint8_ } } +static void _trx_sched_set_lchan(struct gsm_lchan *lchan, + enum trx_chan_type chan, + bool active) +{ + struct l1sched_ts *l1ts = lchan->ts->priv; + struct l1sched_chan_state *chan_state; + + OSMO_ASSERT(l1ts != NULL); + chan_state = &l1ts->chan_state[chan]; + + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s %s\n", + (active) ? "Activating" : "Deactivating", + trx_chan_desc[chan].name); + + if (active) { + /* Clean up everything */ + memset(chan_state, 0, sizeof(*chan_state)); + + /* Bind to generic 'struct gsm_lchan' */ + chan_state->lchan = lchan; + + /* Allocate memory for Rx/Tx burst buffers. Use the maximim size + * of 24 * (2 * 58) bytes, which is sufficient to store up to 24 GMSK + * modulated bursts for CSD or up to 8 8PSK modulated bursts for EGPRS. */ + const size_t buf_size = 24 * GSM_NBITS_NB_GMSK_PAYLOAD; + if (trx_chan_desc[chan].dl_fn != NULL) + chan_state->dl_bursts = talloc_zero_size(l1ts, buf_size); + if (trx_chan_desc[chan].ul_fn != NULL) + chan_state->ul_bursts = talloc_zero_size(l1ts, buf_size); + } else { + chan_state->ho_rach_detect = 0; + + /* Remove pending Tx prims belonging to this lchan */ + trx_sched_queue_filter(&l1ts->dl_prims, + trx_chan_desc[chan].chan_nr, + trx_chan_desc[chan].link_id); + + /* Release memory used by Rx/Tx burst buffers */ + TALLOC_FREE(chan_state->dl_bursts); + TALLOC_FREE(chan_state->ul_bursts); + } + + chan_state->active = active; +} + /* setting all logical channels given attributes to active/inactive */ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_id, bool active) { @@ -1066,7 +1109,12 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i uint8_t tn = L1SAP_CHAN2TS(chan_nr); uint8_t ss = l1sap_chan2ss(chan_nr); bool found = false; - int i; + + if (!l1ts) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s lchan with uninitialized scheduler structure\n", + (active) ? "Activating" : "Deactivating"); + return -EINVAL; + } /* VAMOS: convert Osmocom specific channel number to a generic one, * otherwise we won't match anything in trx_chan_desc[]. */ @@ -1074,51 +1122,74 @@ int trx_sched_set_lchan(struct gsm_lchan *lchan, uint8_t chan_nr, uint8_t link_i chan_nr &= ~RSL_CHAN_OSMO_VAMOS_MASK; /* look for all matching chan_nr/link_id */ - for (i = 0; i < _TRX_CHAN_MAX; i++) { - struct l1sched_chan_state *chan_state = &l1ts->chan_state[i]; - - if (trx_chan_desc[i].chan_nr != (chan_nr & RSL_CHAN_NR_MASK)) + for (enum trx_chan_type chan = 0; chan < _TRX_CHAN_MAX; chan++) { + if (trx_chan_desc[chan].chan_nr != (chan_nr & RSL_CHAN_NR_MASK)) continue; - if (trx_chan_desc[i].link_id != link_id) + if (trx_chan_desc[chan].link_id != link_id) continue; - if (chan_state->active == active) + if (l1ts->chan_state[chan].active == active) continue; found = true; + _trx_sched_set_lchan(lchan, chan, active); + } - LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "%s %s\n", - (active) ? "Activating" : "Deactivating", - trx_chan_desc[i].name); - /* free burst memory, to cleanly start with burst 0 */ - if (chan_state->dl_bursts) { - talloc_free(chan_state->dl_bursts); - chan_state->dl_bursts = NULL; - } - if (chan_state->ul_bursts) { - talloc_free(chan_state->ul_bursts); - chan_state->ul_bursts = NULL; - } + /* disable handover detection (on deactivation) */ + if (!active) + _sched_act_rach_det(lchan->ts->trx, tn, ss, 0); - if (active) { - /* Clean up everything */ - memset(chan_state, 0, sizeof(*chan_state)); + return found ? 0 : -EINVAL; +} - /* Bind to generic 'struct gsm_lchan' */ - chan_state->lchan = lchan; - } else { - chan_state->ho_rach_detect = 0; +int trx_sched_set_ul_access(struct gsm_lchan *lchan, uint8_t chan_nr, bool active) +{ + struct l1sched_ts *l1ts = lchan->ts->priv; + uint8_t tn = L1SAP_CHAN2TS(chan_nr); + uint8_t ss = l1sap_chan2ss(chan_nr); + int i; - /* Remove pending Tx prims belonging to this lchan */ - trx_sched_queue_filter(&l1ts->dl_prims, chan_nr, link_id); - } + if (!l1ts) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "%s UL access on lchan with uninitialized scheduler structure.\n", + (active) ? "Activating" : "Deactivating"); + return -EINVAL; + } + + /* look for all matching chan_nr */ + for (i = 0; i < _TRX_CHAN_MAX; i++) { + if (trx_chan_desc[i].chan_nr == (chan_nr & RSL_CHAN_NR_MASK)) { + struct l1sched_chan_state *l1cs = &l1ts->chan_state[i]; - chan_state->active = active; + l1cs->ho_rach_detect = active; + } } - /* disable handover detection (on deactivation) */ - if (!active) - _sched_act_rach_det(lchan->ts->trx, tn, ss, 0); + _sched_act_rach_det(lchan->ts->trx, tn, ss, active); - return found ? 0 : -EINVAL; + return 0; +} + +int trx_sched_set_bcch_ccch(struct gsm_lchan *lchan, bool active) +{ + struct l1sched_ts *l1ts = lchan->ts->priv; + static const enum trx_chan_type chans[] = { + TRXC_FCCH, + TRXC_SCH, + TRXC_BCCH, + TRXC_RACH, + TRXC_CCCH, + }; + + if (!l1ts) + return -EINVAL; + + for (unsigned int i = 0; i < ARRAY_SIZE(chans); i++) { + enum trx_chan_type chan = chans[i]; + + if (l1ts->chan_state[chan].active == active) + continue; + _trx_sched_set_lchan(lchan, chan, active); + } + + return 0; } /* setting all logical channels given attributes to active/inactive */ @@ -1147,7 +1218,7 @@ int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_c && trx_chan_desc[i].link_id == 0x00) { struct l1sched_chan_state *chan_state = &l1ts->chan_state[i]; - LOGP(DL1C, LOGL_NOTICE, + LOGP(DL1C, LOGL_INFO, "%s Set mode for %s (rsl_cmode=%u, tch_mode=%u, handover=%u)\n", gsm_ts_name(ts), trx_chan_desc[i].name, rsl_cmode, tch_mode, handover); @@ -1166,8 +1237,8 @@ int trx_sched_set_mode(struct gsm_bts_trx_ts *ts, uint8_t chan_nr, uint8_t rsl_c chan_state->dl_ft = initial_id; chan_state->ul_cmr = initial_id; chan_state->dl_cmr = initial_id; - chan_state->ber_sum = 0; - chan_state->ber_num = 0; + chan_state->lqual_cb_sum = 0; + chan_state->lqual_cb_num = 0; } rc = 0; } @@ -1214,7 +1285,7 @@ int trx_sched_set_cipher(struct gsm_lchan *lchan, uint8_t chan_nr, bool downlink struct l1sched_ts *l1ts = lchan->ts->priv; struct l1sched_chan_state *l1cs = &l1ts->chan_state[i]; - LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "Set A5/%d %s for %s\n", + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "Set A5/%d %s for %s\n", algo, (downlink) ? "downlink" : "uplink", trx_chan_desc[i].name); @@ -1264,7 +1335,7 @@ int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn) return 0; /* check if channel is active */ - if (!TRX_CHAN_IS_ACTIVE(&l1ts->chan_state[chan], chan)) + if (!l1ts->chan_state[chan].active) return -EINVAL; /* There is no burst, just for logging */ @@ -1278,6 +1349,26 @@ int _sched_rts(const struct l1sched_ts *l1ts, uint32_t fn) return func(l1ts, &dbr); } +static void trx_sched_apply_att(const struct gsm_lchan *lchan, + struct trx_dl_burst_req *br) +{ + const struct trx_chan_desc *desc = &trx_chan_desc[br->chan]; + + /* Current BS power reduction value in dB */ + br->att = lchan->bs_power_ctrl.current; + + /* Temporary Overpower for SACCH/FACCH bursts */ + if (!lchan->top_acch_active) + return; + if ((lchan->top_acch_cap.sacch_enable && desc->link_id == LID_SACCH) || + (lchan->top_acch_cap.facch_enable && br->flags & TRX_BR_F_FACCH)) { + if (br->att > lchan->top_acch_cap.overpower_db) + br->att -= lchan->top_acch_cap.overpower_db; + else + br->att = 0; + } +} + /* process downlink burst */ void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { @@ -1301,7 +1392,7 @@ void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) l1cs = &l1ts->chan_state[br->chan]; /* check if channel is active */ - if (!TRX_CHAN_IS_ACTIVE(l1cs, br->chan)) + if (!l1cs->active) return; /* Training Sequence Code and Set */ @@ -1317,9 +1408,7 @@ void _sched_dl_burst(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) /* BS Power reduction (in dB) per logical channel */ if (l1cs->lchan != NULL) - br->att = l1cs->lchan->bs_power_ctrl.current; - else /* Ensure no attenuation in the absence of lchan (e.g. on PDCH) */ - br->att = 0; + trx_sched_apply_att(l1cs->lchan, br); /* encrypt */ if (br->burst_len && l1cs->dl_encr_algo) { @@ -1492,7 +1581,7 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi) func = trx_chan_desc[bi->chan].ul_fn; /* check if channel is active */ - if (!TRX_CHAN_IS_ACTIVE(l1cs, bi->chan)) { + if (!l1cs->active) { /* handle noise measurements on dedicated and idle channels */ if (TRX_CHAN_IS_DEDIC(bi->chan) || bi->chan == TRXC_IDLE) trx_sched_noise_meas(l1cs, bi); @@ -1512,16 +1601,9 @@ int trx_sched_ul_burst(struct l1sched_ts *l1ts, struct trx_ul_burst_ind *bi) /* handle NOPE indications */ if (bi->flags & TRX_BI_F_NOPE_IND) { - switch (bi->chan) { - case TRXC_PTCCH: - case TRXC_RACH: - /* For some logical channel types NOPE.ind is valueless. */ - return 0; - default: - /* NOTE: Uplink burst handler must check bi->burst_len before - * accessing bi->burst to avoid uninitialized memory access. */ - return func(l1ts, bi); - } + /* NOTE: Uplink burst handler must check bi->burst_len before + * accessing bi->burst to avoid uninitialized memory access. */ + return func(l1ts, bi); } /* decrypt */ diff --git a/src/common/scheduler_mframe.c b/src/common/scheduler_mframe.c index f6476ece..60b63531 100644 --- a/src/common/scheduler_mframe.c +++ b/src/common/scheduler_mframe.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -1000,7 +1000,7 @@ int find_sched_mframe_idx(enum gsm_phys_chan_config pchan, uint8_t tn) } /* Determine if given frame number contains SACCH (true) or other (false) burst */ -bool trx_sched_is_sacch_fn(struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink) +bool trx_sched_is_sacch_fn(const struct gsm_bts_trx_ts *ts, uint32_t fn, bool uplink) { int i; const struct trx_sched_multiframe *sched; diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 5c5af253..48b1a19e 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -164,20 +164,24 @@ uint8_t num_agch(const struct gsm_bts_trx *trx, const char * arg) return 1; } -/* obtain the next to-be transmitted dowlink SACCH frame (L2 hdr + L3); returns pointer to lchan->si buffer */ -uint8_t *lchan_sacch_get(struct gsm_lchan *lchan) +/* Returns position of the NCH accroding to SI1 rest octets. See Table 10.5.2.32.1 of TS 44.018. + * Returns < 0, if not present. */ +int pos_nch(const struct gsm_bts_trx *trx, const char *arg) { - uint32_t tmp, i; - - for (i = 0; i < _MAX_SYSINFO_TYPE; i++) { - tmp = (lchan->si.last + 1 + i) % _MAX_SYSINFO_TYPE; - if (!(lchan->si.valid & (1 << tmp))) - continue; - lchan->si.last = tmp; - return GSM_LCHAN_SI(lchan, tmp); + const struct gsm_bts *b = trx->bts; + const struct gsm48_system_information_type_1 *si1; + + if (GSM_BTS_HAS_SI(b, SYSINFO_TYPE_1)) { + si1 = GSM_BTS_SI(b, SYSINFO_TYPE_1); + if (si1->rest_octets[0] & 0x80) { + /* H <NCH Position : bit (5)> */ + return (si1->rest_octets[0] >> 2) & 0x1f; + } + return -ENOTSUP; } - LOGPLCHAN(lchan, DL1P, LOGL_NOTICE, "SACCH no SI available\n"); - return NULL; + LOGP(DL1P, LOGL_NOTICE, "%s: Unable to determine actual NCH Position " + "value as SI1 is not available yet.\n", arg); + return -EINVAL; } /* re-generate SI3 restoctets with GPRS indicator depending on the PCU socket connection state */ diff --git a/src/common/ta_control.c b/src/common/ta_control.c index ccb60e2b..6fe409a2 100644 --- a/src/common/ta_control.c +++ b/src/common/ta_control.c @@ -1,6 +1,7 @@ /* Loop control for Timing Advance */ /* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> + * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -12,39 +13,90 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ +/* Related specs: 3GPP TS 45.010 sections 5.5, 5.6 */ + #include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_trx.h> #include <osmo-bts/logging.h> -/* 90% of one bit duration in 1/256 symbols: 256*0.9 */ -#define TOA256_9OPERCENT 230 +/* 3GPP TS 45.010 sec 5.6.3 Delay assessment error: + * 75% of one bit duration in 1/256 symbols: 256*0.75 */ +#define TOA256_THRESH 192 /* rqd_ta value range */ #define TA_MIN 0 #define TA_MAX 63 -void lchan_ms_ta_ctrl(struct gsm_lchan *lchan) +/* TODO: make configurable over osmo-bts VTY? Pass it BSC->BTS? */ +#define TA_MAX_INC_STEP 2 +#define TA_MAX_DEC_STEP 2 + + +/*! compute the new "Ordered Timing Advance" communicated to the MS and store it in lchan. + * \param lchan logical channel for which to compute (and in which to store) new power value. + * \param[in] ms_tx_ta The TA used by the MS and reported in L1SACCH, see struct gsm_sacch_l1_hdr field "ta". + * \param[in] toa256 Time of Arrival (in 1/256th bits) computed at Rx side + */ +void lchan_ms_ta_ctrl(struct gsm_lchan *lchan, uint8_t ms_tx_ta, int16_t toa256) { - int16_t toa256 = lchan->meas.ms_toa256; - - if (toa256 < -TOA256_9OPERCENT && lchan->rqd_ta > TA_MIN) { - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, - "TOA is too early (%d), now lowering TA from %d to %d\n", - toa256, lchan->rqd_ta, lchan->rqd_ta - 1); - lchan->rqd_ta--; - } else if (toa256 > TOA256_9OPERCENT && lchan->rqd_ta < TA_MAX) { - LOGPLCHAN(lchan, DLOOP, LOGL_INFO, - "TOA is too late (%d), now raising TA from %d to %d\n", - toa256, lchan->rqd_ta, lchan->rqd_ta + 1); - lchan->rqd_ta++; - } else + int16_t new_ta; + /* Shall we skip current block based on configured interval? */ + + /* TA control interval: how many blocks do we skip? */ + if (lchan->ta_ctrl.skip_block_num-- > 0) + return; + + /* Reset the number of SACCH blocks to be skipped: + * ctrl_interval=0 => 0 blocks to skip, + * ctrl_interval=1 => 1 blocks to skip, + * ctrl_interval=2 => 3 blocks to skip, + * so basically ctrl_interval * 2 - 1. */ + lchan->ta_ctrl.skip_block_num = lchan->ts->trx->ta_ctrl_interval * 2 - 1; + + int16_t delta_ta = toa256/256; + if (toa256 >= 0) { + if ((toa256 - (256 * delta_ta)) > TOA256_THRESH) + delta_ta++; + if (delta_ta > TA_MAX_INC_STEP) + delta_ta = TA_MAX_INC_STEP; + } else { + if ((toa256 - (256 * delta_ta)) < -TOA256_THRESH) + delta_ta--; + if (delta_ta < -TA_MAX_DEC_STEP) + delta_ta = -TA_MAX_DEC_STEP; + } + + new_ta = ms_tx_ta + delta_ta; + + /* Make sure new_ta is never negative: */ + if (new_ta < TA_MIN) + new_ta = TA_MIN; + + /* Don't ask for out of range TA: */ + if (new_ta > TA_MAX) + new_ta = TA_MAX; + + if (lchan->ta_ctrl.current == (uint8_t)new_ta) { LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, - "TOA is correct (%d), keeping current TA of %d\n", - toa256, lchan->rqd_ta); + "Keeping current TA at %u: TOA was %d\n", + lchan->ta_ctrl.current, toa256); + return; + } + + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, + "%s TA %u => %u: TOA was too %s (%d)\n", + (uint8_t)new_ta > lchan->ta_ctrl.current ? "Raising" : "Lowering", + lchan->ta_ctrl.current, (uint8_t)new_ta, + (uint8_t)new_ta > lchan->ta_ctrl.current ? "late" : "early", + toa256); + + /* store the resulting new TA in the lchan */ + lchan->ta_ctrl.current = (uint8_t)new_ta; } diff --git a/src/common/tx_power.c b/src/common/tx_power.c index 348aba5c..83cdb629 100644 --- a/src/common/tx_power.c +++ b/src/common/tx_power.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -239,8 +239,7 @@ static void power_ramp_do_step(struct gsm_bts_trx *trx, int first) osmo_timer_schedule(&tpp->ramp.step_timer, tpp->ramp.step_interval_sec, 0); } - -int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, ramp_compl_cb_t ramp_compl_cb) +int _power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, ramp_compl_cb_t ramp_compl_cb, bool skip_ramping) { struct trx_power_params *tpp = &trx->power_params; @@ -259,13 +258,18 @@ int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, } /* Cancel any pending request */ - osmo_timer_del(&tpp->ramp.step_timer); + power_ramp_abort(trx); /* set the new target */ tpp->p_total_tgt_mdBm = p_total_tgt_mdBm; tpp->ramp.compl_cb = ramp_compl_cb; - if (we_are_ramping_up(trx)) { + if (skip_ramping) { + /* Jump straight to the target power */ + tpp->p_total_cur_mdBm = p_total_tgt_mdBm; + tpp->ramp.attenuation_mdB = 0; + power_ramp_timer_cb(trx); + } else if (we_are_ramping_up(trx)) { if (tpp->p_total_tgt_mdBm <= tpp->ramp.max_initial_pout_mdBm) { LOGPTRX(trx, DL1C, LOGL_INFO, "target_power (%d mdBm) is below or equal to 'power ramp max-initial' power (%d mdBm)\n", @@ -297,6 +301,12 @@ int power_ramp_start(struct gsm_bts_trx *trx, int p_total_tgt_mdBm, int bypass, return 0; } +/* Cancel any pending request */ +void power_ramp_abort(struct gsm_bts_trx *trx) +{ + osmo_timer_del(&trx->power_params.ramp.step_timer); +} + /* determine the initial transceiver output power at start-up time */ int power_ramp_initial_power_mdBm(const struct gsm_bts_trx *trx) { diff --git a/src/common/vty.c b/src/common/vty.c index a7d1e845..c0008a85 100644 --- a/src/common/vty.c +++ b/src/common/vty.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -22,6 +22,7 @@ #include "btsconfig.h" #include <inttypes.h> +#include <limits.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -37,17 +38,20 @@ #include <osmocom/vty/logging.h> #include <osmocom/vty/misc.h> #include <osmocom/vty/ports.h> +#include <osmocom/vty/tdef_vty.h> #include <osmocom/core/gsmtap.h> #include <osmocom/core/utils.h> #include <osmocom/core/sockaddr_str.h> #include <osmocom/trau/osmo_ortp.h> - +#include <osmocom/core/fsm.h> +#include <osmocom/codec/codec.h> #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/phy_link.h> #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/rsl.h> #include <osmo-bts/oml.h> #include <osmo-bts/signal.h> @@ -56,6 +60,7 @@ #include <osmo-bts/measurement.h> #include <osmo-bts/vty.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/osmux.h> #define VTY_STR "Configure the VTY\n" @@ -66,6 +71,9 @@ #define BTS_TRX_STR BTS_NR_STR TRX_NR_STR #define BTS_TRX_TS_STR BTS_TRX_STR TS_NR_STR #define BTS_TRX_TS_LCHAN_STR BTS_TRX_TS_STR LCHAN_NR_STR +/* INT32_MAX, because osmo_wqueue_init takes int as an argument + * and INT_MAX can't be stringified as a decimal */ +#define BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX 2147483647 #define X(x) (1 << x) @@ -132,21 +140,9 @@ int bts_vty_go_parent(struct vty *vty) return vty->node; } -int bts_vty_is_config_node(struct vty *vty, int node) -{ - switch (node) { - case TRX_NODE: - case BTS_NODE: - case PHY_NODE: - case PHY_INST_NODE: - return 1; - default: - return 0; - } -} - static const char osmobts_copyright[] = - "Copyright (C) 2010, 2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" + "Copyright (C) 2010-2011 by Harald Welte, Andreas Eversberg and On-Waves\r\n" + "Copyright (C) 2011-2022 by sysmocom - s.f.m.c. GmbH\r\n" "License AGPLv3+: GNU AGPL version 3 or later <http://gnu.org/licenses/agpl-3.0.html>\r\n" "This is free software: you are free to change and redistribute it.\r\n" "There is NO WARRANTY, to the extent permitted by law.\r\n"; @@ -156,7 +152,6 @@ struct vty_app_info bts_vty_info = { .version = PACKAGE_VERSION, .copyright = osmobts_copyright, .go_parent_cb = bts_vty_go_parent, - .is_config_node = bts_vty_is_config_node, .usr_attr_desc = { [BTS_VTY_ATTR_NEW_LCHAN] = \ "This command applies for newly created lchans", @@ -169,13 +164,6 @@ struct vty_app_info bts_vty_info = { }, }; -extern struct gsm_network bts_gsmnet; - -struct gsm_network *gsmnet_from_vty(struct vty *v) -{ - return &bts_gsmnet; -} - static struct cmd_node bts_node = { BTS_NODE, "%s(bts)# ", @@ -188,6 +176,12 @@ static struct cmd_node trx_node = { 1, }; +static struct cmd_node osmux_node = { + OSMUX_NODE, + "%s(osmux)# ", + 1, +}; + gDEFUN(cfg_bts_auto_band, cfg_bts_auto_band_cmd, "auto-band", "Automatically select band for ARFCN based on configured band\n") @@ -208,6 +202,90 @@ gDEFUN(cfg_bts_no_auto_band, cfg_bts_no_auto_band_cmd, return CMD_SUCCESS; } +DEFUN_ATTR(cfg_bts_osmux, cfg_bts_osmux_cmd, + "osmux", + "Configure Osmux\n", + CMD_ATTR_IMMEDIATE) +{ + vty->node = OSMUX_NODE; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_bts_osmux_use, cfg_bts_osmux_use_cmd, + "use (off|on|only)", + "Configure Osmux usage\n" + "Never use Osmux\n" + "Use Osmux if requested by BSC (default)\n" + "Always use Osmux, reject non-Osmux BSC requests\n", + CMD_ATTR_IMMEDIATE) +{ + struct gsm_bts *bts = vty->index; + if (strcmp(argv[0], "off") == 0) + bts->osmux.use = OSMUX_USAGE_OFF; + else if (strcmp(argv[0], "on") == 0) + bts->osmux.use = OSMUX_USAGE_ON; + else if (strcmp(argv[0], "only") == 0) + bts->osmux.use = OSMUX_USAGE_ONLY; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_ip, + cfg_bts_osmux_ip_cmd, + "local-ip " VTY_IPV46_CMD, + IP_STR + "IPv4 Address to bind to\n" + "IPv6 Address to bind to\n") +{ + struct gsm_bts *bts = vty->index; + osmo_talloc_replace_string(bts, &bts->osmux.local_addr, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_port, + cfg_bts_osmux_port_cmd, + "local-port <1-65535>", + "Osmux port\n" "UDP port\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.local_port = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_batch_factor, + cfg_bts_osmux_batch_factor_cmd, + "batch-factor <1-8>", + "Batching factor\n" "Number of messages in the batch\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.batch_factor = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_batch_size, + cfg_bts_osmux_batch_size_cmd, + "batch-size <1-65535>", + "Batch size\n" "Batch size in bytes\n") +{ + struct gsm_bts *bts = vty->index; + bts->osmux.batch_size = atoi(argv[0]); + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_osmux_dummy_padding, + cfg_bts_osmux_dummy_padding_cmd, + "dummy-padding (on|off)", + "Dummy padding\n" + "Enable dummy padding\n" + "Disable dummy padding (default)\n") +{ + struct gsm_bts *bts = vty->index; + if (strcmp(argv[0], "on") == 0) + bts->osmux.dummy_padding = true; + else if (strcmp(argv[0], "off") == 0) + bts->osmux.dummy_padding = false; + return CMD_SUCCESS; +} + DEFUN_ATTR(cfg_bts_trx, cfg_bts_trx_cmd, "trx <0-254>", "Select a TRX to configure\n" "TRX number\n", @@ -277,11 +355,35 @@ static void config_write_dpc_params(struct vty *vty, const char *prefix, } } +static void config_write_osmux(struct vty *vty, const char *prefix, const struct gsm_bts *bts) +{ + vty_out(vty, "%sosmux%s", prefix, VTY_NEWLINE); + vty_out(vty, "%s use ", prefix); + switch (bts->osmux.use) { + case OSMUX_USAGE_ON: + vty_out(vty, "on%s", VTY_NEWLINE); + break; + case OSMUX_USAGE_ONLY: + vty_out(vty, "only%s", VTY_NEWLINE); + break; + case OSMUX_USAGE_OFF: + default: + vty_out(vty, "off%s", VTY_NEWLINE); + break; + } + vty_out(vty, "%s local-ip %s%s", prefix, bts->osmux.local_addr, VTY_NEWLINE); + vty_out(vty, "%s local-port %u%s", prefix, bts->osmux.local_port, VTY_NEWLINE); + vty_out(vty, "%s batch-factor %d%s", prefix, bts->osmux.batch_factor, VTY_NEWLINE); + vty_out(vty, "%s batch-size %u%s", prefix, bts->osmux.batch_size, VTY_NEWLINE); + vty_out(vty, "%s dummy-padding %s%s", prefix, bts->osmux.dummy_padding ? "on" : "off", VTY_NEWLINE); +} + static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) { const struct gsm_bts_trx *trx; const char *sapi_buf; int i; + struct bsc_oml_host *bsc_oml_host; vty_out(vty, "bts %u%s", bts->nr, VTY_NEWLINE); if (bts->description) @@ -291,7 +393,8 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " auto-band%s", VTY_NEWLINE); vty_out(vty, " ipa unit-id %u %u%s", bts->ip_access.site_id, bts->ip_access.bts_id, VTY_NEWLINE); - vty_out(vty, " oml remote-ip %s%s", bts->bsc_oml_host, VTY_NEWLINE); + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) + vty_out(vty, " oml remote-ip %s%s", bsc_oml_host->addr, VTY_NEWLINE); vty_out(vty, " rtp jitter-buffer %u", bts->rtp_jitter_buf_ms); if (bts->rtp_jitter_adaptive) vty_out(vty, " adaptive"); @@ -299,9 +402,15 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " rtp port-range %u %u%s", bts->rtp_port_range_start, bts->rtp_port_range_end, VTY_NEWLINE); if (bts->rtp_ip_dscp != -1) - vty_out(vty, " rtp ip-dscp %i%s", bts->rtp_ip_dscp, VTY_NEWLINE); + vty_out(vty, " rtp ip-dscp %d%s", bts->rtp_ip_dscp, VTY_NEWLINE); if (bts->rtp_priority != -1) - vty_out(vty, " rtp socket-priority %i%s", bts->rtp_priority, VTY_NEWLINE); + vty_out(vty, " rtp socket-priority %d%s", bts->rtp_priority, VTY_NEWLINE); + if (bts->rtp_nogaps_mode) + vty_out(vty, " rtp continuous-streaming%s", VTY_NEWLINE); + vty_out(vty, " %srtp internal-uplink-ecu%s", + bts->use_ul_ecu ? "" : "no ", VTY_NEWLINE); + vty_out(vty, " rtp hr-format %s%s", + bts->emit_hr_rfc5993 ? "rfc5993" : "ts101318", VTY_NEWLINE); vty_out(vty, " paging queue-size %u%s", paging_get_queue_max(bts->paging_state), VTY_NEWLINE); vty_out(vty, " paging lifetime %u%s", paging_get_lifetime(bts->paging_state), @@ -321,6 +430,10 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " gsmtap-remote-host %s%s", bts->gsmtap.remote_host, VTY_NEWLINE); + if (bts->gsmtap.local_host != NULL) + vty_out(vty, " gsmtap-local-host %s%s", + bts->gsmtap.local_host, + VTY_NEWLINE); for (i = 0; i < sizeof(uint32_t) * 8; i++) { if (bts->gsmtap.sapi_mask & ((uint32_t) 1 << i)) { sapi_buf = get_value_string_or_null(gsmtap_sapi_names, i); @@ -334,6 +447,12 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) sapi_buf = osmo_str_tolower(get_value_string(gsmtap_sapi_names, GSMTAP_CHANNEL_ACCH)); vty_out(vty, " gsmtap-sapi %s%s", sapi_buf, VTY_NEWLINE); } + if (bts->gsmtap.rlp) { + if (bts->gsmtap.rlp_skip_null) + vty_out(vty, " gsmtap-rlp skip-null%s", VTY_NEWLINE); + else + vty_out(vty, " gsmtap-rlp%s", VTY_NEWLINE); + } vty_out(vty, " min-qual-rach %d%s", bts->min_qual_rach, VTY_NEWLINE); vty_out(vty, " min-qual-norm %d%s", bts->min_qual_norm, @@ -342,12 +461,16 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) VTY_NEWLINE); if (strcmp(bts->pcu.sock_path, PCU_SOCK_DEFAULT)) vty_out(vty, " pcu-socket %s%s", bts->pcu.sock_path, VTY_NEWLINE); + if (bts->pcu.sock_wqueue_len_max != BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX) + vty_out(vty, " pcu-socket-wqueue-length %u%s", bts->pcu.sock_wqueue_len_max, VTY_NEWLINE); if (bts->supp_meas_toa256) vty_out(vty, " supp-meas-info toa256%s", VTY_NEWLINE); vty_out(vty, " smscb queue-max-length %d%s", bts->smscb_queue_max_len, VTY_NEWLINE); vty_out(vty, " smscb queue-target-length %d%s", bts->smscb_queue_tgt_len, VTY_NEWLINE); vty_out(vty, " smscb queue-hysteresis %d%s", bts->smscb_queue_hyst, VTY_NEWLINE); + config_write_osmux(vty, " ", bts); + bts_model_config_write_bts(vty, bts); llist_for_each_entry(trx, &bts->trx_list, list) { @@ -355,7 +478,7 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) const struct phy_instance *pinst = trx_phy_instance(trx); vty_out(vty, " trx %u%s", trx->nr, VTY_NEWLINE); - if (trx->power_params.user_gain_mdB) + if (tpp->user_gain_mdB) vty_out(vty, " user-gain %u mdB%s", tpp->user_gain_mdB, VTY_NEWLINE); vty_out(vty, " power-ramp max-initial %d mdBm%s", @@ -367,6 +490,8 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " ms-power-control %s%s", trx->ms_pwr_ctl_soft ? "osmo" : "dsp", VTY_NEWLINE); + vty_out(vty, " ta-control interval %u%s", + trx->ta_ctrl_interval, VTY_NEWLINE); vty_out(vty, " phy %u instance %u%s", pinst->phy_link->num, pinst->num, VTY_NEWLINE); @@ -376,12 +501,12 @@ static void config_write_bts_single(struct vty *vty, const struct gsm_bts *bts) static int config_write_bts(struct vty *vty) { - struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts; - llist_for_each_entry(bts, &net->bts_list, list) + llist_for_each_entry(bts, &g_bts_sm->bts_list, list) config_write_bts_single(vty, bts); + osmo_tdef_vty_groups_write(vty, ""); return CMD_SUCCESS; } @@ -437,16 +562,15 @@ DEFUN_ATTR(cfg_bts, "BTS Number\n", CMD_ATTR_IMMEDIATE) { - struct gsm_network *gsmnet = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); struct gsm_bts *bts; - if (bts_nr >= gsmnet->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% Unknown BTS number %u (num %u)%s", - bts_nr, gsmnet->num_bts, VTY_NEWLINE); + bts_nr, g_bts_sm->num_bts, VTY_NEWLINE); return CMD_WARNING; } else - bts = gsm_bts_num(gsmnet, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); vty->index = bts; vty->index_sub = &bts->description; @@ -507,11 +631,51 @@ DEFUN(cfg_bts_oml_ip, "OML Parameters\n" "OML IP Address\n" "OML IP Address\n") { struct gsm_bts *bts = vty->index; + struct bsc_oml_host *bsc_oml_host; + + /* stop when the address is already in the list */ + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) { + if (strcmp(argv[0], bsc_oml_host->addr) == 0) { + vty_out(vty, "%% duplicate BSC (A-Bis/OML) ip address configured ('%s')%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + } + + bsc_oml_host = talloc_zero(bts, struct bsc_oml_host); + OSMO_ASSERT(bsc_oml_host); + bsc_oml_host->addr = talloc_strdup(bsc_oml_host, argv[0]); + OSMO_ASSERT(bsc_oml_host->addr); + llist_add_tail(&bsc_oml_host->list, &bts->bsc_oml_hosts); + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_oml_ip, + cfg_bts_no_oml_ip_cmd, + "no oml remote-ip A.B.C.D", + NO_STR "OML Parameters\n" "OML IP Address\n" "OML IP Address\n") +{ + struct gsm_bts *bts = vty->index; + struct bsc_oml_host *bsc_oml_host; + struct bsc_oml_host *bsc_oml_host_del = NULL; - if (bts->bsc_oml_host) - talloc_free(bts->bsc_oml_host); + llist_for_each_entry(bsc_oml_host, &bts->bsc_oml_hosts, list) { + if (strcmp(argv[0], bsc_oml_host->addr) == 0) + bsc_oml_host_del = bsc_oml_host; + } - bts->bsc_oml_host = talloc_strdup(bts, argv[0]); + if (bsc_oml_host_del) { + if (bts->abis_link_fi) { + osmo_fsm_inst_dispatch(bts->abis_link_fi, ABIS_LINK_EV_VTY_RM_ADDR, bsc_oml_host_del); + llist_del(&bsc_oml_host_del->list); + talloc_free(bsc_oml_host_del); + } + } else { + vty_out(vty, "%% no such BSC (A-Bis/OML) ip address configured ('%s')%s", + argv[0], VTY_NEWLINE); + return CMD_WARNING; + } return CMD_SUCCESS; } @@ -612,6 +776,62 @@ DEFUN_USRATTR(cfg_bts_rtp_priority, return CMD_SUCCESS; } +DEFUN(cfg_bts_rtp_cont_stream, + cfg_bts_rtp_cont_stream_cmd, + "rtp continuous-streaming", + RTP_STR "Always emit an RTP packet every 20 ms\n") +{ + struct gsm_bts *bts = vty->index; + + bts->rtp_nogaps_mode = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_rtp_cont_stream, + cfg_bts_no_rtp_cont_stream_cmd, + "no rtp continuous-streaming", + NO_STR RTP_STR "Always emit an RTP packet every 20 ms\n") +{ + struct gsm_bts *bts = vty->index; + + bts->rtp_nogaps_mode = false; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_rtp_int_ul_ecu, + cfg_bts_rtp_int_ul_ecu_cmd, + "rtp internal-uplink-ecu", + RTP_STR "Apply a BTS-internal ECU to the uplink traffic frame stream\n") +{ + struct gsm_bts *bts = vty->index; + + bts->use_ul_ecu = true; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_rtp_int_ul_ecu, + cfg_bts_no_rtp_int_ul_ecu_cmd, + "no rtp internal-uplink-ecu", + NO_STR RTP_STR "Apply a BTS-internal ECU to the uplink traffic frame stream\n") +{ + struct gsm_bts *bts = vty->index; + + bts->use_ul_ecu = false; + return CMD_SUCCESS; +} + +DEFUN_ATTR(cfg_bts_rtp_hr_format, + cfg_bts_rtp_hr_format_cmd, + "rtp hr-format (rfc5993|ts101318)", + RTP_STR "HRv1 codec output format\n" "RFC 5993\n" "TS 101 318\n", + CMD_ATTR_IMMEDIATE) +{ + struct gsm_bts *bts = vty->index; + + bts->emit_hr_rfc5993 = !strcmp(argv[0], "rfc5993"); + return CMD_SUCCESS; +} + #define PAG_STR "Paging related parameters\n" DEFUN_ATTR(cfg_bts_paging_queue_size, @@ -800,7 +1020,7 @@ DEFUN_ATTR(cfg_bts_max_ber_rach, cfg_bts_max_ber_rach_cmd, return CMD_SUCCESS; } -DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd, +DEFUN(cfg_bts_pcu_sock_path, cfg_bts_pcu_sock_path_cmd, "pcu-socket PATH", "Configure the PCU socket file/path name\n" "UNIX socket path\n") @@ -813,6 +1033,16 @@ DEFUN(cfg_bts_pcu_sock, cfg_bts_pcu_sock_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_pcu_sock_ql, cfg_bts_pcu_sock_ql_cmd, + "pcu-socket-wqueue-length <1-" OSMO_STRINGIFY_VAL(BTS_CFG_PCU_SOCK_WQUEUE_LEN_MAX_MAX) ">", + "Configure the PCU socket queue length\n" + "Queue length\n") +{ + struct gsm_bts *bts = vty->index; + bts->pcu.sock_wqueue_len_max = atoi(argv[0]); + return CMD_SUCCESS; +} + DEFUN_ATTR(cfg_bts_supp_meas_toa256, cfg_bts_supp_meas_toa256_cmd, "supp-meas-info toa256", "Configure the RSL Supplementary Measurement Info\n" @@ -965,6 +1195,19 @@ DEFUN(cfg_trx_ms_power_control, cfg_trx_ms_power_control_cmd, return CMD_SUCCESS; } +DEFUN(cfg_ta_ctrl_interval, cfg_ta_ctrl_interval_cmd, + "ta-control interval <0-31>", + "Timing Advance Control Parameters\n" + "Set TA control loop interval\n" + "As in P_CON_INTERVAL, in units of 2 SACCH periods (0.96 seconds) (default=0, every SACCH block)\n") +{ + struct gsm_bts_trx *trx = vty->index; + + trx->ta_ctrl_interval = atoi(argv[0]); + + return CMD_SUCCESS; +} + DEFUN(cfg_trx_phy, cfg_trx_phy_cmd, "phy <0-255> instance <0-255>", "Configure PHY Link+Instance for this TRX\n" @@ -1030,10 +1273,10 @@ static void bts_dump_vty_features(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " BTS model specific (internal) flags:%s", VTY_NEWLINE); - for (i = 0, no_features = true; i < sizeof(bts->flags) * 8; i++) { - if (bts_internal_flag_get(bts, (1 << i))) { + for (i = 0, no_features = true; i < _BTS_INTERNAL_FLAG_NUM; i++) { + if (bts_internal_flag_get(bts, i)) { vty_out(vty, " %03u ", i); - vty_out(vty, "%-40s%s", get_value_string(bts_impl_flag_desc, (1 << i)), VTY_NEWLINE); + vty_out(vty, "%-40s%s", get_value_string(bts_impl_flag_desc, i), VTY_NEWLINE); no_features = false; } } @@ -1072,7 +1315,7 @@ static void bts_dump_vty(struct vty *vty, const struct gsm_bts *bts) vty_out(vty, " NM State: "); net_dump_nmstate(vty, &bts->mo.nm_state); vty_out(vty, " Site Mgr NM State: "); - net_dump_nmstate(vty, &bts->site_mgr.mo.nm_state); + net_dump_nmstate(vty, &g_bts_sm->mo.nm_state); if (strnlen(bts->pcu_version, MAX_VERSION_LENGTH)) vty_out(vty, " PCU version %s connected%s", bts->pcu_version, VTY_NEWLINE); @@ -1131,23 +1374,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", SHOW_STR "Display information about a BTS\n" BTS_NR_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr; if (argc != 0) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + bts_dump_vty(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } /* print all BTS's */ - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) - bts_dump_vty(vty, gsm_bts_num(net, bts_nr)); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) + bts_dump_vty(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } @@ -1155,21 +1397,22 @@ DEFUN(show_bts, show_bts_cmd, "show bts [<0-255>]", static void gprs_dump_vty(struct vty *vty, const struct gsm_bts *bts) { unsigned int i; + const struct gsm_gprs_nse *nse = &bts->site_mgr->gprs.nse; /* GPRS parameters received from the BSC */ vty_out(vty, "BTS %u, RAC %u, NSEI %u, BVCI %u%s", bts->nr, bts->gprs.rac, - bts->gprs.nse.nsei, + nse->nsei, bts->gprs.cell.bvci, VTY_NEWLINE); vty_out(vty, " Cell NM state: "); net_dump_nmstate(vty, &bts->gprs.cell.mo.nm_state); vty_out(vty, " NSE NM state: "); - net_dump_nmstate(vty, &bts->gprs.nse.mo.nm_state); + net_dump_nmstate(vty, &nse->mo.nm_state); - for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { - const struct gsm_bts_gprs_nsvc *nsvc = &bts->gprs.nsvc[i]; + for (i = 0; i < ARRAY_SIZE(nse->nsvc); i++) { + const struct gsm_gprs_nsvc *nsvc = &nse->nsvc[i]; vty_out(vty, " NSVC%u (NSVCI %u) NM state: ", i, nsvc->nsvci); net_dump_nmstate(vty, &nsvc->mo.nm_state); @@ -1204,10 +1447,9 @@ DEFUN(show_bts_gprs, show_bts_gprs_cmd, SHOW_STR "Display information about a BTS\n" BTS_NR_STR "GPRS/EGPRS configuration\n") { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts; - bts = gsm_bts_num(net, atoi(argv[0])); + bts = gsm_bts_num(g_bts_sm, atoi(argv[0])); if (bts == NULL) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); @@ -1223,16 +1465,15 @@ DEFUN(test_send_failure_event_report, test_send_failure_event_report_cmd, "test "Various testing commands\n" "Send a test OML failure event report to the BSC\n" BTS_NR_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); const struct gsm_bts *bts; - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); oml_tx_failure_event_rep(&bts->mo, NM_SEVER_MINOR, OSMO_EVT_WARN_SW_WARN, "test message sent from VTY"); return CMD_SUCCESS; @@ -1244,9 +1485,8 @@ DEFUN_HIDDEN(radio_link_timeout, radio_link_timeout_cmd, "bts <0-0> radio-link-t "Use infinite timeout (DANGEROUS: only use during testing!)\n" "Number of lost SACCH blocks\n") { - const struct gsm_network *net = gsmnet_from_vty(vty); int bts_nr = atoi(argv[0]); - struct gsm_bts *bts = gsm_bts_num(net, bts_nr); + struct gsm_bts *bts = gsm_bts_num(g_bts_sm, bts_nr); if (!bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); @@ -1270,17 +1510,16 @@ DEFUN_HIDDEN(radio_link_timeout, radio_link_timeout_cmd, "bts <0-0> radio-link-t DEFUN(bts_c0_power_red, bts_c0_power_red_cmd, - "bts <0-255> c0-power-red <0-6>", + "bts <0-0> c0-power-red <0-6>", "BTS Specific Commands\n" BTS_NR_STR "BCCH carrier power reduction operation\n" "Power reduction value (in dB, even numbers only)\n") { - struct gsm_network *net = gsmnet_from_vty(vty); const int bts_nr = atoi(argv[0]); const int red = atoi(argv[1]); struct gsm_bts *bts; - bts = gsm_bts_num(net, atoi(argv[0])); + bts = gsm_bts_num(g_bts_sm, atoi(argv[0])); if (bts == NULL) { vty_out(vty, "%% No such BTS (%d)%s", bts_nr, VTY_NEWLINE); return CMD_WARNING; @@ -1347,7 +1586,7 @@ static void dump_dpc_meas_params(struct vty *vty, const unsigned int indent, } static void dump_dpc_params(struct vty *vty, const unsigned int indent, - const struct gsm_power_ctrl_params *cp) + const struct gsm_power_ctrl_params *cp, bool uplink) { cfg_out(vty, "Power control interval: %u ms (every %u SACCH block(s))%s", cp->ctrl_interval ? cp->ctrl_interval * 2 * 480 : 480, @@ -1364,6 +1603,26 @@ static void dump_dpc_params(struct vty *vty, const unsigned int indent, cfg_out(vty, "RxQual measurement processing:%s", VTY_NEWLINE); dump_dpc_meas_params(vty, indent + 2, &cp->rxqual_meas, "RXQUAL", 3); + + if (uplink) { + cfg_out(vty, "C/I measurement processing (FR/EFR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_fr_meas, "CI_FR", 0); + + cfg_out(vty, "C/I measurement processing (HR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_hr_meas, "CI_HR", 0); + + cfg_out(vty, "C/I measurement processing (AMR-FR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_amr_fr_meas, "CI_AMR_FR", 0); + + cfg_out(vty, "C/I measurement processing (AMR-HR):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_amr_hr_meas, "CI_AMR_HR", 0); + + cfg_out(vty, "C/I measurement processing (SDCCH):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_sdcch_meas, "CI_SDCCH", 0); + + cfg_out(vty, "C/I measurement processing (GPRS):%s", VTY_NEWLINE); + dump_dpc_meas_params(vty, indent + 2, &cp->ci_gprs_meas, "CI_GPRS", 0); + } } static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx) @@ -1381,20 +1640,20 @@ static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx) trx->bs_dpc_params == &trx->bts->bs_dpc_params ? "fall-back" : "from BSC", VTY_NEWLINE); - dump_dpc_params(vty, 4, trx->bs_dpc_params); + dump_dpc_params(vty, 4, trx->bs_dpc_params, false); vty_out(vty, " MS Power control parameters (%s):%s", trx->ms_dpc_params == &trx->bts->ms_dpc_params ? "fall-back" : "from BSC", VTY_NEWLINE); - dump_dpc_params(vty, 4, trx->ms_dpc_params); + dump_dpc_params(vty, 4, trx->ms_dpc_params, true); vty_out(vty, " NM State: "); net_dump_nmstate(vty, &trx->mo.nm_state); - vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE); + vty_out(vty, " RSL State: %s%s", trx->bb_transc.rsl.link ? "connected" : "disconnected", VTY_NEWLINE); vty_out(vty, " Baseband Transceiver NM State: "); net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state); - vty_out(vty, " IPA stream ID: 0x%02x%s", trx->rsl_tei, VTY_NEWLINE); + vty_out(vty, " IPA stream ID: 0x%02x%s", trx->bb_transc.rsl.tei, VTY_NEWLINE); } static inline void print_all_trx(struct vty *vty, const struct gsm_bts *bts) @@ -1410,19 +1669,18 @@ DEFUN(show_trx, SHOW_STR "Display information about a TRX\n" BTS_TRX_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; int bts_nr, trx_nr; if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -1440,8 +1698,8 @@ DEFUN(show_trx, return CMD_SUCCESS; } - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) - print_all_trx(vty, gsm_bts_num(net, bts_nr)); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) + print_all_trx(vty, gsm_bts_num(g_bts_sm, bts_nr)); return CMD_SUCCESS; } @@ -1466,7 +1724,6 @@ DEFUN(show_ts, SHOW_STR "Display information about a TS\n" BTS_TRX_TS_STR) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; const struct gsm_bts_trx *trx = NULL; const struct gsm_bts_trx_ts *ts = NULL; @@ -1475,12 +1732,12 @@ DEFUN(show_ts, if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS '%s'%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); } if (argc >= 2) { trx_nr = atoi(argv[1]); @@ -1521,8 +1778,8 @@ DEFUN(show_ts, } } else { /* Iterate over all BTS, TRX in each BTS, TS in each TRX */ - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = gsm_bts_num(net, bts_nr); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) { + bts = gsm_bts_num(g_bts_sm, bts_nr); for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) { trx = gsm_bts_trx_num(bts, trx_nr); for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) { @@ -1594,7 +1851,7 @@ static void lchan_bs_power_ctrl_state_dump(struct vty *vty, unsigned int indent, return; cfg_out(vty, "Power Control parameters:%s", VTY_NEWLINE); - dump_dpc_params(vty, indent + 2, st->dpc_params); + dump_dpc_params(vty, indent + 2, st->dpc_params, false); } static void lchan_ms_power_ctrl_state_dump(struct vty *vty, unsigned int indent, @@ -1610,17 +1867,17 @@ static void lchan_ms_power_ctrl_state_dump(struct vty *vty, unsigned int indent, int current_dbm = ms_pwr_dbm(trx->bts->band, st->current); int max_dbm = ms_pwr_dbm(trx->bts->band, st->max); - cfg_out(vty, "Current power level: %u, -%d dBm", + cfg_out(vty, "Current power level: %u, %d dBm", st->current, current_dbm); if (st->dpc_params != NULL) - vty_out(vty, " (max %u, -%d dBm)", st->max, max_dbm); + vty_out(vty, " (max %u, %d dBm)", st->max, max_dbm); vty_out(vty, "%s", VTY_NEWLINE); if (st->dpc_params == NULL) return; cfg_out(vty, "Power Control parameters:%s", VTY_NEWLINE); - dump_dpc_params(vty, indent + 2, st->dpc_params); + dump_dpc_params(vty, indent + 2, st->dpc_params, true); } static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, @@ -1628,23 +1885,23 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, { cfg_out(vty, "ACCH repetition:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.rxqual) + if (lchan->rep_acch_cap.rxqual) cfg_out(vty, "Enable RXQUAL threshold: %u%s", - lchan->repeated_acch_capability.rxqual, VTY_NEWLINE); + lchan->rep_acch_cap.rxqual, VTY_NEWLINE); else cfg_out(vty, "Enable RXQUAL threshold: (none, alway on)%s", VTY_NEWLINE); cfg_out(vty, "DL-FACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.dl_facch_all) + if (lchan->rep_acch_cap.dl_facch_all) cfg_out(vty, "retramsit all LAPDM block types%s", VTY_NEWLINE); - else if (lchan->repeated_acch_capability.dl_facch_cmd) + else if (lchan->rep_acch_cap.dl_facch_cmd) cfg_out(vty, "retramsit only LAPDM command blocks%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_dl_facch_active) + if (lchan->rep_acch.dl_facch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1653,12 +1910,12 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, cfg_out(vty, "DL-SACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.ul_sacch) + if (lchan->rep_acch_cap.ul_sacch) cfg_out(vty, "retramsit all SACCH blocks for SAPI=0%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_dl_sacch_active) + if (lchan->rep_acch.dl_sacch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1667,12 +1924,12 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, cfg_out(vty, "UL-SACCH:%s", VTY_NEWLINE); indent += 2; - if (lchan->repeated_acch_capability.dl_sacch) + if (lchan->rep_acch_cap.dl_sacch) cfg_out(vty, "retramsit all SACCH blocks for SAPI=0%s", VTY_NEWLINE); else cfg_out(vty, "no retransmission (disabled)%s", VTY_NEWLINE); - if (lchan->repeated_ul_sacch_active) + if (lchan->rep_acch.ul_sacch_active) cfg_out(vty, "retransmission currently active%s", VTY_NEWLINE); else cfg_out(vty, "retransmission currently inactive%s", @@ -1680,6 +1937,34 @@ static void lchan_acch_rep_state_dump(struct vty *vty, unsigned int indent, indent -= 2; } +static void lchan_acch_top_state_dump(struct vty *vty, unsigned int indent, + const struct gsm_lchan *lchan) +{ + if (lchan->top_acch_cap.overpower_db == 0) + return; + + cfg_out(vty, "Temporary ACCH overpower:%s", VTY_NEWLINE); + indent += 2; + + cfg_out(vty, "Overpower value: %u dB%s", + lchan->top_acch_cap.overpower_db, VTY_NEWLINE); + + cfg_out(vty, "SACCH overpower: %sabled%s", + lchan->top_acch_cap.sacch_enable ? "en" : "dis", + VTY_NEWLINE); + cfg_out(vty, "FACCH overpower: %sabled%s", + lchan->top_acch_cap.facch_enable ? "en" : "dis", + VTY_NEWLINE); + + if (lchan->top_acch_cap.rxqual == 0) { + cfg_out(vty, "RxQual threshold: disabled " + "(overpower is always on)%s", VTY_NEWLINE); + } else { + cfg_out(vty, "RxQual threshold: %u%s", + lchan->top_acch_cap.rxqual, VTY_NEWLINE); + } +} + static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) { struct in_addr ia; @@ -1712,20 +1997,39 @@ static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) vty_out(vty, " Channel Mode / Codec: %s%s", gsm48_chan_mode_name(lchan->tch_mode), VTY_NEWLINE); + if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) { + const struct amr_multirate_conf *amr_mrc = &lchan->tch.amr_mr; + const struct gsm48_multi_rate_conf *mr_conf = + (const struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie; + vty_out(vty, " AMR Multi-Rate Configuration: ICMI=%u, Start Mode=%u gsm48=%02x%02x%s", + mr_conf->icmi, mr_conf->smod, amr_mrc->gsm48_ie[0], amr_mrc->gsm48_ie[1], VTY_NEWLINE); + for (uint8_t i = 0; i < amr_mrc->num_modes; i++) { + const struct amr_mode *amode = &amr_mrc->mode[i]; + vty_out(vty, " AMR Mode %u (%s), threshold=%u, hysteresis=%u%s", + amode->mode, osmo_amr_type_name(amode->mode), + amode->threshold, amode->hysteresis, VTY_NEWLINE); + } + } if (lchan->abis_ip.bound_ip) { ia.s_addr = htonl(lchan->abis_ip.bound_ip); - vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s", + vty_out(vty, " Bound IP: %s Port %u CONN_ID=%u", inet_ntoa(ia), lchan->abis_ip.bound_port, - lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id, - VTY_NEWLINE); + lchan->abis_ip.conn_id); + if (lchan->abis_ip.osmux.use) + vty_out(vty, " Osmux_CID=%u%s", lchan->abis_ip.osmux.local_cid, VTY_NEWLINE); + else + vty_out(vty, " RTP_TYPE2=%u%s", lchan->abis_ip.rtp_payload2, VTY_NEWLINE); } if (lchan->abis_ip.connect_ip) { ia.s_addr = htonl(lchan->abis_ip.connect_ip); - vty_out(vty, " Conn. IP: %s Port %u RTP_TYPE=%u SPEECH_MODE=0x%02u%s", + vty_out(vty, " Conn. IP: %s Port %u SPEECH_MODE=0x%02x", inet_ntoa(ia), lchan->abis_ip.connect_port, - lchan->abis_ip.rtp_payload, lchan->abis_ip.speech_mode, - VTY_NEWLINE); + lchan->abis_ip.speech_mode); + if (lchan->abis_ip.osmux.use) + vty_out(vty, " Osmux_CID=%u%s", lchan->abis_ip.osmux.remote_cid, VTY_NEWLINE); + else + vty_out(vty, " RTP_TYPE=%u%s", lchan->abis_ip.rtp_payload, VTY_NEWLINE); } #define LAPDM_ESTABLISHED(link, sapi_idx) \ (link).datalink[sapi_idx].dl.state == LAPD_STATE_MF_EST @@ -1751,10 +2055,21 @@ static void lchan_dump_full_vty(struct vty *vty, const struct gsm_lchan *lchan) vty_out(vty, " RTP/PDCH Loopback Enabled%s", VTY_NEWLINE); vty_out(vty, " Radio Link Failure Counter 'S': %d%s", lchan->s, VTY_NEWLINE); + /* Interference levels */ + if (lchan->meas.interf_meas_avg_dbm != 0) { + vty_out(vty, " Interference: %d dBm (band %d)%s", + lchan->meas.interf_meas_avg_dbm, + lchan->meas.interf_band, + VTY_NEWLINE); + } + /* BS/MS Power Control state and parameters */ lchan_bs_power_ctrl_state_dump(vty, 2, lchan); lchan_ms_power_ctrl_state_dump(vty, 2, lchan); + + /* ACCH repetition / overpower state */ lchan_acch_rep_state_dump(vty, 2, lchan); + lchan_acch_top_state_dump(vty, 2, lchan); } static void lchan_dump_short_vty(struct vty *vty, const struct gsm_lchan *lchan) @@ -1827,7 +2142,6 @@ static int dump_lchan_bts(const struct gsm_bts *bts, struct vty *vty, static int lchan_summary(struct vty *vty, int argc, const char **argv, void (*dump_cb)(struct vty *, const struct gsm_lchan *)) { - const struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_bts *bts = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ const struct gsm_bts_trx *trx = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ const struct gsm_bts_trx_ts *ts = NULL; /* initialize to avoid uninitialized false warnings on some gcc versions (11.1.0) */ @@ -1837,12 +2151,12 @@ static int lchan_summary(struct vty *vty, int argc, const char **argv, if (argc >= 1) { /* use the BTS number that the user has specified */ bts_nr = atoi(argv[0]); - if (bts_nr >= net->num_bts) { + if (bts_nr >= g_bts_sm->num_bts) { vty_out(vty, "%% can't find BTS %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); if (argc == 1) return dump_lchan_bts(bts, vty, dump_cb); @@ -1883,8 +2197,8 @@ static int lchan_summary(struct vty *vty, int argc, const char **argv, return CMD_SUCCESS; } - for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) { - bts = gsm_bts_num(net, bts_nr); + for (bts_nr = 0; bts_nr < g_bts_sm->num_bts; bts_nr++) { + bts = gsm_bts_num(g_bts_sm, bts_nr); dump_lchan_bts(bts, vty, dump_cb); } @@ -1910,8 +2224,7 @@ DEFUN(show_lchan_summary, return lchan_summary(vty, argc, argv, lchan_dump_short_vty); } -static struct gsm_lchan *resolve_lchan(const struct gsm_network *net, - const char **argv, int idx) +static struct gsm_lchan *resolve_lchan(const char **argv, int idx) { int bts_nr = atoi(argv[idx+0]); int trx_nr = atoi(argv[idx+1]); @@ -1922,7 +2235,7 @@ static struct gsm_lchan *resolve_lchan(const struct gsm_network *net, struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; - bts = gsm_bts_num(net, bts_nr); + bts = gsm_bts_num(g_bts_sm, bts_nr); if (!bts) return NULL; @@ -1975,6 +2288,22 @@ DEFUN(cfg_bts_gsmtap_remote_host, return CMD_SUCCESS; } +DEFUN(cfg_bts_gsmtap_local_host, + cfg_bts_gsmtap_local_host_cmd, + "gsmtap-local-host HOSTNAME", + "Enable local bind for GSMTAP Um logging (see also 'gsmtap-sapi')\n" + "Local IP address or hostname\n") +{ + struct gsm_bts *bts = vty->index; + + osmo_talloc_replace_string(bts, &bts->gsmtap.local_host, argv[0]); + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + DEFUN(cfg_bts_no_gsmtap_remote_host, cfg_bts_no_gsmtap_remote_host_cmd, "no gsmtap-remote-host", @@ -1992,6 +2321,24 @@ DEFUN(cfg_bts_no_gsmtap_remote_host, return CMD_SUCCESS; } +DEFUN(cfg_bts_no_gsmtap_local_host, + cfg_bts_no_gsmtap_local_host_cmd, + "no gsmtap-local-host", + NO_STR "Disable local bind for GSMTAP Um logging\n") +{ + struct gsm_bts *bts = vty->index; + + if (bts->gsmtap.local_host != NULL) + talloc_free(bts->gsmtap.local_host); + + bts->gsmtap.local_host = NULL; + + if (vty->type != VTY_FILE) + vty_out(vty, "%% This command requires restart%s", VTY_NEWLINE); + + return CMD_SUCCESS; +} + DEFUN(cfg_bts_gsmtap_sapi_all, cfg_bts_gsmtap_sapi_all_cmd, "gsmtap-sapi (enable-all|disable-all)", "Enable/disable sending of UL/DL messages over GSMTAP\n" @@ -2028,7 +2375,7 @@ DEFUN(cfg_bts_gsmtap_sapi, cfg_bts_gsmtap_sapi_cmd, return CMD_SUCCESS; } -DEFUN(cfg_trx_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, +DEFUN(cfg_bts_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, "HIDDEN", "HIDDEN") { struct gsm_bts *bts = vty->index; @@ -2045,6 +2392,29 @@ DEFUN(cfg_trx_no_gsmtap_sapi, cfg_bts_no_gsmtap_sapi_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_gsmtap_rlp, cfg_bts_gsmtap_rlp_cmd, + "gsmtap-rlp [skip-null]", + "Enable generation of GSMTAP frames for RLP (non-transparent CSD)\n" + "Skip the generation of GSMTAP for RLP NULL frames\n") +{ + struct gsm_bts *bts = vty->index; + bts->gsmtap.rlp = true; + if (argc >= 1 && !strcmp(argv[0], "skip-null")) + bts->gsmtap.rlp_skip_null = true; + else + bts->gsmtap.rlp_skip_null = false; + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_no_gsmtap_rlp, cfg_bts_no_gsmtap_rlp_cmd, + "no gsmtap-rlp", + NO_STR "Disable generation of GSMTAP frames for RLP (non-transparent CSD)\n") +{ + struct gsm_bts *bts = vty->index; + bts->gsmtap.rlp = false; + return CMD_SUCCESS; +} + static struct cmd_node phy_node = { PHY_NODE, "%s(phy)# ", @@ -2153,11 +2523,10 @@ DEFUN(bts_t_t_l_jitter_buf, BTS_T_T_L_STR "RTP settings\n" "Jitter buffer\n" "Size of jitter buffer in (ms)\n") { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; int jitbuf_ms = atoi(argv[4]), rc; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2186,10 +2555,9 @@ DEFUN_ATTR(bts_t_t_l_loopback, BTS_T_T_L_STR "Set loopback\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2205,10 +2573,9 @@ DEFUN_ATTR(no_bts_t_t_l_loopback, NO_STR BTS_T_T_L_STR "Set loopback\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2231,13 +2598,12 @@ DEFUN_ATTR(bts_t_t_l_power_ctrl_mode, "Enable the power control loop\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); const struct gsm_power_ctrl_params *params; struct lchan_power_ctrl_state *state; const char **args = argv + 4; struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2268,12 +2634,11 @@ DEFUN_ATTR(bts_t_t_l_power_ctrl_current_max, "BS power reduction (in dB) or MS power level\n", CMD_ATTR_HIDDEN) { - struct gsm_network *net = gsmnet_from_vty(vty); struct lchan_power_ctrl_state *state; const char **args = argv + 4; struct gsm_lchan *lchan; - lchan = resolve_lchan(net, argv, 0); + lchan = resolve_lchan(argv, 0); if (!lchan) { vty_out(vty, "%% Could not resolve logical channel%s", VTY_NEWLINE); return CMD_WARNING; @@ -2376,13 +2741,22 @@ int bts_vty_init(void *ctx) install_node(&bts_node, config_write_bts); install_element(CONFIG_NODE, &cfg_bts_cmd); install_element(CONFIG_NODE, &cfg_vty_telnet_port_cmd); + + osmo_tdef_vty_groups_init(CONFIG_NODE, bts_tdef_groups); + install_element(BTS_NODE, &cfg_bts_unit_id_cmd); install_element(BTS_NODE, &cfg_bts_oml_ip_cmd); + install_element(BTS_NODE, &cfg_bts_no_oml_ip_cmd); install_element(BTS_NODE, &cfg_bts_rtp_bind_ip_cmd); install_element(BTS_NODE, &cfg_bts_rtp_jitbuf_cmd); install_element(BTS_NODE, &cfg_bts_rtp_port_range_cmd); install_element(BTS_NODE, &cfg_bts_rtp_ip_dscp_cmd); install_element(BTS_NODE, &cfg_bts_rtp_priority_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_cont_stream_cmd); + install_element(BTS_NODE, &cfg_bts_no_rtp_cont_stream_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_int_ul_ecu_cmd); + install_element(BTS_NODE, &cfg_bts_no_rtp_int_ul_ecu_cmd); + install_element(BTS_NODE, &cfg_bts_rtp_hr_format_cmd); install_element(BTS_NODE, &cfg_bts_band_cmd); install_element(BTS_NODE, &cfg_description_cmd); install_element(BTS_NODE, &cfg_no_description_cmd); @@ -2397,7 +2771,8 @@ int bts_vty_init(void *ctx) install_element(BTS_NODE, &cfg_bts_min_qual_rach_cmd); install_element(BTS_NODE, &cfg_bts_min_qual_norm_cmd); install_element(BTS_NODE, &cfg_bts_max_ber_rach_cmd); - install_element(BTS_NODE, &cfg_bts_pcu_sock_cmd); + install_element(BTS_NODE, &cfg_bts_pcu_sock_path_cmd); + install_element(BTS_NODE, &cfg_bts_pcu_sock_ql_cmd); install_element(BTS_NODE, &cfg_bts_supp_meas_toa256_cmd); install_element(BTS_NODE, &cfg_bts_no_supp_meas_toa256_cmd); install_element(BTS_NODE, &cfg_bts_smscb_max_qlen_cmd); @@ -2406,9 +2781,24 @@ int bts_vty_init(void *ctx) install_element(BTS_NODE, &cfg_bts_gsmtap_remote_host_cmd); install_element(BTS_NODE, &cfg_bts_no_gsmtap_remote_host_cmd); + install_element(BTS_NODE, &cfg_bts_gsmtap_local_host_cmd); + install_element(BTS_NODE, &cfg_bts_no_gsmtap_local_host_cmd); install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_all_cmd); install_element(BTS_NODE, &cfg_bts_gsmtap_sapi_cmd); install_element(BTS_NODE, &cfg_bts_no_gsmtap_sapi_cmd); + install_element(BTS_NODE, &cfg_bts_gsmtap_rlp_cmd); + install_element(BTS_NODE, &cfg_bts_no_gsmtap_rlp_cmd); + + /* Osmux Node */ + install_element(BTS_NODE, &cfg_bts_osmux_cmd); + install_node(&osmux_node, config_write_dummy); + + install_element(OSMUX_NODE, &cfg_bts_osmux_use_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_ip_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_port_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_batch_factor_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_batch_size_cmd); + install_element(OSMUX_NODE, &cfg_bts_osmux_dummy_padding_cmd); /* add and link to TRX config node */ install_element(BTS_NODE, &cfg_bts_trx_cmd); @@ -2419,6 +2809,7 @@ int bts_vty_init(void *ctx) install_element(TRX_NODE, &cfg_trx_pr_step_size_cmd); install_element(TRX_NODE, &cfg_trx_pr_step_interval_cmd); install_element(TRX_NODE, &cfg_trx_ms_power_control_cmd); + install_element(TRX_NODE, &cfg_ta_ctrl_interval_cmd); install_element(TRX_NODE, &cfg_trx_phy_cmd); install_element(ENABLE_NODE, &bts_t_t_l_jitter_buf_cmd); diff --git a/src/osmo-bts-lc15/Makefile.am b/src/osmo-bts-lc15/Makefile.am index bb68efaf..58284e95 100644 --- a/src/osmo-bts-lc15/Makefile.am +++ b/src/osmo-bts-lc15/Makefile.am @@ -1,38 +1,102 @@ AUTOMAKE_OPTIONS = subdir-objects AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(LITECELL15_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(LIBSYSTEMD_CFLAGS) -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBGPS_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ + $(NULL) + +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) AM_CFLAGS += -DENABLE_LC15BTS -EXTRA_DIST = misc/lc15bts_mgr.h misc/lc15bts_misc.h misc/lc15bts_par.h misc/lc15bts_led.h \ - misc/lc15bts_temp.h misc/lc15bts_power.h misc/lc15bts_clock.h \ - misc/lc15bts_bid.h misc/lc15bts_nl.h misc/lc15bts_bts.h misc/lc15bts_swd.h \ - hw_misc.h l1_if.h l1_transp.h lc15bts.h utils.h +EXTRA_DIST = \ + misc/lc15bts_mgr.h \ + misc/lc15bts_misc.h \ + misc/lc15bts_par.h \ + misc/lc15bts_led.h \ + misc/lc15bts_temp.h \ + misc/lc15bts_power.h \ + misc/lc15bts_clock.h \ + misc/lc15bts_bid.h \ + misc/lc15bts_nl.h \ + misc/lc15bts_bts.h \ + misc/lc15bts_swd.h \ + hw_misc.h \ + l1_if.h \ + l1_transp.h \ + lc15bts.h \ + utils.h \ + $(NULL) bin_PROGRAMS = osmo-bts-lc15 lc15bts-mgr lc15bts-util -COMMON_SOURCES = main.c lc15bts.c l1_if.c oml.c lc15bts_vty.c tch.c hw_misc.c calib_file.c \ - utils.c misc/lc15bts_par.c misc/lc15bts_bid.c +COMMON_SOURCES = \ + main.c \ + lc15bts.c \ + l1_if.c \ + oml.c \ + lc15bts_vty.c \ + tch.c \ + hw_misc.c \ + calib_file.c \ + utils.c \ + misc/lc15bts_par.c \ + misc/lc15bts_bid.c \ + $(NULL) osmo_bts_lc15_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c -osmo_bts_lc15_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) +osmo_bts_lc15_LDADD = \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(NULL) lc15bts_mgr_SOURCES = \ - misc/lc15bts_mgr.c misc/lc15bts_misc.c \ - misc/lc15bts_par.c misc/lc15bts_nl.c \ - misc/lc15bts_temp.c misc/lc15bts_power.c \ - misc/lc15bts_clock.c misc/lc15bts_bid.c \ + misc/lc15bts_mgr.c \ + misc/lc15bts_misc.c \ + misc/lc15bts_par.c \ + misc/lc15bts_nl.c \ + misc/lc15bts_temp.c \ + misc/lc15bts_power.c \ + misc/lc15bts_clock.c \ + misc/lc15bts_bid.c \ misc/lc15bts_mgr_vty.c \ misc/lc15bts_mgr_nl.c \ misc/lc15bts_mgr_temp.c \ misc/lc15bts_mgr_calib.c \ misc/lc15bts_led.c \ misc/lc15bts_bts.c \ - misc/lc15bts_swd.c + misc/lc15bts_swd.c \ + $(NULL) -lc15bts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBSYSTEMD_LIBS) $(COMMON_LDADD) +lc15bts_mgr_LDADD = \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(LIBGPS_LIBS) \ + $(LIBSYSTEMD_LIBS) \ + $(NULL) -lc15bts_util_SOURCES = misc/lc15bts_util.c misc/lc15bts_par.c +lc15bts_util_SOURCES = \ + misc/lc15bts_util.c \ + misc/lc15bts_par.c \ + $(NULL) lc15bts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-lc15/calib_file.c b/src/osmo-bts-lc15/calib_file.c index 2641552f..543be90f 100644 --- a/src/osmo-bts-lc15/calib_file.c +++ b/src/osmo-bts-lc15/calib_file.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/hw_misc.c b/src/osmo-bts-lc15/hw_misc.c index 9f070bba..97ed3b75 100644 --- a/src/osmo-bts-lc15/hw_misc.c +++ b/src/osmo-bts-lc15/hw_misc.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/l1_if.c b/src/osmo-bts-lc15/l1_if.c index 02c8646e..4ef90949 100644 --- a/src/osmo-bts-lc15/l1_if.c +++ b/src/osmo-bts-lc15/l1_if.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -347,7 +347,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, abort(); } - len = msgb_l2len(msg); + len = (msg->l2h) ? msgb_l2len(msg) : 0; chan_nr = l1sap->u.data.chan_nr; link_id = l1sap->u.data.link_id; @@ -395,9 +395,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, else sapi = GsmL1_Sapi_Agch; } else { - LOGPFN(DL1C, LOGL_NOTICE, u32Fn, "unknown prim %d op %d " - "chan_nr %d link_id %d\n", l1sap->oph.primitive, - l1sap->oph.operation, chan_nr, link_id); + LOGPLCFN(lchan, u32Fn, DL1C, LOGL_NOTICE, "unknown prim %d op %d chan_nr %d link_id %d\n", + l1sap->oph.primitive, l1sap->oph.operation, chan_nr, link_id); msgb_free(l1msg); return -EINVAL; } @@ -458,9 +457,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, msgb_l2len(msg)); } - LOGPFN(DL1P, LOGL_DEBUG, u32Fn, "PH-DATA.req(%s)\n", - osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, - l1p->u.phDataReq.msgUnitParam.u8Size)); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_DEBUG, "PH-DATA.req(%s)\n", + osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, l1p->u.phDataReq.msgUnitParam.u8Size)); } else { /* empty frame */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); @@ -470,7 +468,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) { - LOGPFN(DL1P, LOGL_ERROR, u32Fn, "MQ_L1_WRITE queue full. Dropping msg.\n"); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); msgb_free(l1msg); } else dtx_int_signal(lchan); @@ -508,7 +506,6 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, /* create new message and fill data */ if (msg) { - msgb_pull(msg, sizeof(*l1sap)); /* create new message */ nmsg = l1p_msgb_alloc(); if (!nmsg) @@ -517,7 +514,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn, use_cache, + msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache, l1sap->u.tch.marker); if (rc < 0) { /* no data encoded for L1: smth will be generated below */ @@ -553,7 +550,12 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } /* send message to DSP's queue */ - osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg) < 0) { + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); + msgb_free(nmsg); + return -ENOBUFS; + } + if (dtx_is_first_p1(lchan)) dtx_dispatch(lchan, E_FIRST); else @@ -1245,7 +1247,6 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, Litecell15_Prim_t *sysp = msgb_sysprim(resp); GsmL1_Status_t status; int on = 0; - unsigned int i; if (sysp->id == Litecell15_PrimId_ActivateRfCnf) on = 1; @@ -1276,8 +1277,8 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, } else { if (bts_lc15->led_ctrl_mode == LC15_LED_CONTROL_BTS) bts_update_status(BTS_STATUS_RF_ACTIVE, 0); - osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL); - osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL); + osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL); } msgb_free(resp); @@ -1425,6 +1426,30 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, LOGP(DL1C, LOGL_FATAL, "BTS band %s not supported by hw\n", gsm_band_name(trx->bts->band)); + /* Frequency bands indicated to the BSC */ + switch (fl1h->hw_info.band_support) { + case GSM_BAND_450: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_450; + break; + case GSM_BAND_480: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_480; + break; + case GSM_BAND_850: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_850; + break; + case GSM_BAND_900: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PGSM; + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_EGSM? */ + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_RGSM? */ + break; + case GSM_BAND_1800: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_DCS; + break; + case GSM_BAND_1900: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PCS; + break; + } + /* Request the activation */ l1if_activate_rf(fl1h, 1); diff --git a/src/osmo-bts-lc15/l1_transp_hw.c b/src/osmo-bts-lc15/l1_transp_hw.c index 36b77fed..63b596b2 100644 --- a/src/osmo-bts-lc15/l1_transp_hw.c +++ b/src/osmo-bts-lc15/l1_transp_hw.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/lc15bts.c b/src/osmo-bts-lc15/lc15bts.c index 0ba89a11..40077902 100644 --- a/src/osmo-bts-lc15/lc15bts.c +++ b/src/osmo-bts-lc15/lc15bts.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/lc15bts_vty.c b/src/osmo-bts-lc15/lc15bts_vty.c index be6a4f8b..5efbfcc5 100644 --- a/src/osmo-bts-lc15/lc15bts_vty.c +++ b/src/osmo-bts-lc15/lc15bts_vty.c @@ -140,7 +140,7 @@ DEFUN(cfg_phy_no_dsp_trace_f, cfg_phy_no_dsp_trace_f_cmd, /* runtime */ DEFUN(show_dsp_trace_f, show_dsp_trace_f_cmd, - "show trx <0-0> dsp-trace-flags", + "show dsp-trace-flags trx <0-0>", SHOW_TRX_STR "Display the current setting of the DSP trace flags") { int trx_nr = atoi(argv[0]); diff --git a/src/osmo-bts-lc15/main.c b/src/osmo-bts-lc15/main.c index 3e119f66..23601299 100644 --- a/src/osmo-bts-lc15/main.c +++ b/src/osmo-bts-lc15/main.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -89,6 +89,8 @@ int bts_model_init(struct gsm_bts *bts) bts->model_priv = bts_lc15; bts->variant = BTS_OSMO_LITECELL15; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS + | NM_IPAC_MASK_GPRS_CODING_MCS; /* specific default values for LC15 platform */ bts_lc15->led_ctrl_mode = LC15_BTS_LED_CTRL_MODE_DEFAULT; @@ -100,24 +102,43 @@ int bts_model_init(struct gsm_bts *bts) exit(23); } - osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); + osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); - osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER); + /* The default HR codec output format in the absence of saved + * vty config needs to match what was implemented previously, + * for the sake of existing deployments, i.e., to avoid + * a surprise functional change upon software update. */ + bts->emit_hr_rfc5993 = false; + return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = 0x00; /* updated in info_compl_cb() */ + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH + | NM_IPAC_F_CHANT_SDCCH8_CBCH + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH; + trx->nominal_power = 40; trx->power_params.trx_p_max_out_mdBm = to_mdB(trx->bts->c0->nominal_power); return 0; diff --git a/src/osmo-bts-lc15/misc/lc15bts_bid.c b/src/osmo-bts-lc15/misc/lc15bts_bid.c index 9284b62e..9267e06f 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_bid.c +++ b/src/osmo-bts-lc15/misc/lc15bts_bid.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_bts.c b/src/osmo-bts-lc15/misc/lc15bts_bts.c index 0343e930..560320a0 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_bts.c +++ b/src/osmo-bts-lc15/misc/lc15bts_bts.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_clock.c b/src/osmo-bts-lc15/misc/lc15bts_clock.c index 71701496..23f8f021 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_clock.c +++ b/src/osmo-bts-lc15/misc/lc15bts_clock.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_led.c b/src/osmo-bts-lc15/misc/lc15bts_led.c index a93d3fb0..88b12207 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_led.c +++ b/src/osmo-bts-lc15/misc/lc15bts_led.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_mgr.c b/src/osmo-bts-lc15/misc/lc15bts_mgr.c index b258d0cb..fb4f5c40 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_mgr.c +++ b/src/osmo-bts-lc15/misc/lc15bts_mgr.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -319,7 +319,7 @@ int main(int argc, char **argv) exit(1); } - rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); diff --git a/src/osmo-bts-lc15/misc/lc15bts_mgr_calib.c b/src/osmo-bts-lc15/misc/lc15bts_mgr_calib.c index badb5455..f25955f8 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_mgr_calib.c +++ b/src/osmo-bts-lc15/misc/lc15bts_mgr_calib.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_mgr_nl.c b/src/osmo-bts-lc15/misc/lc15bts_mgr_nl.c index 3a617dd7..b34becf1 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_mgr_nl.c +++ b/src/osmo-bts-lc15/misc/lc15bts_mgr_nl.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_mgr_temp.c b/src/osmo-bts-lc15/misc/lc15bts_mgr_temp.c index 9665e1db..abffce3b 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_mgr_temp.c +++ b/src/osmo-bts-lc15/misc/lc15bts_mgr_temp.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_mgr_vty.c b/src/osmo-bts-lc15/misc/lc15bts_mgr_vty.c index 424ff18f..65c1fe72 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_mgr_vty.c +++ b/src/osmo-bts-lc15/misc/lc15bts_mgr_vty.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -89,39 +89,10 @@ static int go_to_parent(struct vty *vty) return vty->node; } -static int is_config_node(struct vty *vty, int node) -{ - switch (node) { - case MGR_NODE: - case ACT_NORM_NODE: - case ACT_WARN_NODE: - case ACT_CRIT_NODE: - case LIMIT_SUPPLY_TEMP_NODE: - case LIMIT_SOC_NODE: - case LIMIT_FPGA_NODE: - case LIMIT_RMSDET_NODE: - case LIMIT_OCXO_NODE: - case LIMIT_TX0_TEMP_NODE: - case LIMIT_TX1_TEMP_NODE: - case LIMIT_PA0_TEMP_NODE: - case LIMIT_PA1_TEMP_NODE: - case LIMIT_SUPPLY_VOLT_NODE: - case LIMIT_TX0_VSWR_NODE: - case LIMIT_TX1_VSWR_NODE: - case LIMIT_SUPPLY_PWR_NODE: - case LIMIT_PA0_PWR_NODE: - case LIMIT_PA1_PWR_NODE: - return 1; - default: - return 0; - } -} - static struct vty_app_info vty_info = { .name = "lc15bts-mgr", .version = PACKAGE_VERSION, .go_parent_cb = go_to_parent, - .is_config_node = is_config_node, .copyright = copyright, }; diff --git a/src/osmo-bts-lc15/misc/lc15bts_misc.c b/src/osmo-bts-lc15/misc/lc15bts_misc.c index 467b9d0a..bd801099 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_misc.c +++ b/src/osmo-bts-lc15/misc/lc15bts_misc.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_nl.c b/src/osmo-bts-lc15/misc/lc15bts_nl.c index 39f64aae..d1d1bd13 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_nl.c +++ b/src/osmo-bts-lc15/misc/lc15bts_nl.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_nl.h b/src/osmo-bts-lc15/misc/lc15bts_nl.h index 340cf117..b5a15403 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_nl.h +++ b/src/osmo-bts-lc15/misc/lc15bts_nl.h @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_par.c b/src/osmo-bts-lc15/misc/lc15bts_par.c index af9d030f..e93c45b6 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_par.c +++ b/src/osmo-bts-lc15/misc/lc15bts_par.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_power.c b/src/osmo-bts-lc15/misc/lc15bts_power.c index 1a37d8e6..c28232b7 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_power.c +++ b/src/osmo-bts-lc15/misc/lc15bts_power.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_swd.c b/src/osmo-bts-lc15/misc/lc15bts_swd.c index eac64d66..f0af6bca 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_swd.c +++ b/src/osmo-bts-lc15/misc/lc15bts_swd.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_temp.c b/src/osmo-bts-lc15/misc/lc15bts_temp.c index 45602dcc..f69b9bb7 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_temp.c +++ b/src/osmo-bts-lc15/misc/lc15bts_temp.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/misc/lc15bts_util.c b/src/osmo-bts-lc15/misc/lc15bts_util.c index 430ce0f7..a5ab6027 100644 --- a/src/osmo-bts-lc15/misc/lc15bts_util.c +++ b/src/osmo-bts-lc15/misc/lc15bts_util.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-lc15/oml.c b/src/osmo-bts-lc15/oml.c index b4945be0..6f312e80 100644 --- a/src/osmo-bts-lc15/oml.c +++ b/src/osmo-bts-lc15/oml.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -49,6 +49,8 @@ #include "lc15bts.h" #include "utils.h" +static void dump_lch_par(int logl, GsmL1_LogChParam_t *lch_par, GsmL1_Sapi_t sapi); + static int mph_info_chan_confirm(struct gsm_lchan *lchan, enum osmo_mph_info_type type, uint8_t cause) { @@ -569,8 +571,7 @@ GsmL1_Sapi_t lchan_to_GsmL1_Sapi_t(const struct gsm_lchan *lchan) case GSM_LCHAN_TCH_H: return GsmL1_Sapi_TchH; default: - LOGP(DL1C, LOGL_NOTICE, "%s cannot determine L1 SAPI\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "cannot determine L1 SAPI\n"); break; } return GsmL1_Sapi_Idle; @@ -781,12 +782,8 @@ static void sapi_queue_dispatch(struct gsm_lchan *lchan, int status) talloc_free(cmd); if (end || llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_DEBUG, - "%s End of SAPI cmd queue encountered.%s\n", - gsm_lchan_name(lchan), - llist_empty(&lchan->sapi_cmds) - ? " Queue is now empty." - : " More pending."); + LOGPLCHAN(lchan, DL1C, LOGL_DEBUG, "End of SAPI cmd queue encountered.%s\n", + llist_empty(&lchan->sapi_cmds) ? " Queue is now empty." : " More pending."); return; } @@ -826,9 +823,8 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.conf (%s ", - gsm_lchan_name(lchan), - get_value_string(lc15bts_l1sapi_names, ic->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.conf (%s ", + get_value_string(lc15bts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(lc15bts_dir_names, ic->dir)); @@ -849,19 +845,15 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, lchan->sapis_ul[ic->sapi] = status; if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_ACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -942,8 +934,7 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) (struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie; int j; - LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n", - gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s tch_mode=0x%02x\n", __func__, lchan->tch_mode); switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: @@ -971,7 +962,9 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) case GSM48_CMODE_SPEECH_AMR: lch_par->tch.tchPlType = GsmL1_TchPlType_Amr; set_payload_format(lch_par); - lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; /* FIXME? */ + /* At call set-up, after every successful handover and after a channel mode modify, the + * default phase (odd) shall be used in downlink direction. */ + lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; lch_par->tch.amrInitCodecMode = amr_get_initial_mode(lchan); /* initialize to clean state */ @@ -1094,9 +1087,9 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) break; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.req (hL2=0x%08x, %s ", - gsm_lchan_name(lchan), (uint32_t)act_req->hLayer2, - get_value_string(lc15bts_l1sapi_names, act_req->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.req (hL2=0x%08x, %s ", + (uint32_t)act_req->hLayer2, get_value_string(lc15bts_l1sapi_names, act_req->sapi)); + dump_lch_par(LOGL_INFO, lch_par, act_req->sapi); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(lc15bts_dir_names, act_req->dir)); @@ -1120,9 +1113,7 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) /* FIXME: Error handling */ if (status != GsmL1_Status_Success) { - LOGP(DL1C, LOGL_ERROR, - "%s act failed mark broken due status: %d\n", - gsm_lchan_name(lchan), status); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "act failed mark broken due status: %d\n", status); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, RSL_ERR_PROCESSOR_OVERLOAD); @@ -1169,13 +1160,11 @@ int lchan_activate(struct gsm_lchan *lchan) lchan_set_state(lchan, LCHAN_S_ACT_REQ); if (!llist_empty(&lchan->sapi_cmds)) - LOGP(DL1C, LOGL_ERROR, - "%s Trying to activate lchan, but commands in queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Trying to activate lchan, but commands in queue\n"); /* For handover, always start the main channel immediately. lchan->want_dl_sacch_active indicates whether dl * SACCH should be activated. Also, for HO, start the RACH SAPI. */ - if (lchan->ho.active == HANDOVER_ENABLED) + if (lchan->ho.active == HANDOVER_ENABLED || rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink); for (i = 0; i < s4l->num_sapis; i++) { @@ -1197,10 +1186,6 @@ int lchan_activate(struct gsm_lchan *lchan) enqueue_sapi_act_cmd(lchan, sapi, dir); } - -#warning "FIXME: Should this be in sapi_activate_cb?" - lchan_init_lapdm(lchan); - return 0; } @@ -1336,9 +1321,8 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ", - gsm_lchan_name(lchan), - get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.conf (%s) ", + get_value_string(lc15bts_l1cfgt_names, cc->cfgParamId)); switch (cc->cfgParamId) { case GsmL1_ConfigParamId_SetLogChParams: @@ -1370,9 +1354,7 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, break; } if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got ciphering conf with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got ciphering conf with empty queue\n"); goto err; } @@ -1423,10 +1405,8 @@ static int mph_send_config_logchpar(struct gsm_lchan *lchan, struct sapi_cmd *cm /* FIXME: update encryption */ - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.req (%s) ", - gsm_lchan_name(lchan), - get_value_string(lc15bts_l1sapi_names, - conf_req->cfgParams.setLogChParams.sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.req (%s) ", + get_value_string(lc15bts_l1sapi_names, conf_req->cfgParams.setLogChParams.sapi)); LOGPC(DL1C, LOGL_INFO, "cfgParams Tn=%u, subCh=%u, dir=0x%x ", conf_req->cfgParams.setLogChParams.u8Tn, conf_req->cfgParams.setLogChParams.subCh, @@ -1536,11 +1516,9 @@ static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *c return -EINVAL; cfgr->cfgParams.setCipheringParams.cipherId = rsl2l1_ciph[lchan->encr.alg_id]; - LOGP(DL1C, LOGL_NOTICE, "%s SET_CIPHERING (ALG=%u %s)\n", - gsm_lchan_name(lchan), + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "SET_CIPHERING (ALG=%u %s)\n", cfgr->cfgParams.setCipheringParams.cipherId, - get_value_string(lc15bts_dir_names, - cfgr->cfgParams.setCipheringParams.dir)); + get_value_string(lc15bts_dir_names, cfgr->cfgParams.setCipheringParams.dir)); memcpy(cfgr->cfgParams.setCipheringParams.u8Kc, lchan->encr.key, lchan->encr.key_len); @@ -1618,9 +1596,8 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.conf (%s ", - gsm_lchan_name(lchan), - get_value_string(lc15bts_l1sapi_names, ic->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.conf (%s ", + get_value_string(lc15bts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(lc15bts_dir_names, ic->dir)); @@ -1642,19 +1619,15 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got de-activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got de-activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_DEACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -1679,9 +1652,8 @@ static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd deact_req->sapi = cmd->sapi; deact_req->hLayer3 = (HANDLE)l1if_lchan_to_hLayer(lchan); - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.req (%s ", - gsm_lchan_name(lchan), - get_value_string(lc15bts_l1sapi_names, deact_req->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.req (%s ", + get_value_string(lc15bts_l1sapi_names, deact_req->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(lc15bts_dir_names, deact_req->dir)); @@ -1693,8 +1665,7 @@ static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status) { /* FIXME: Error handling. There is no NACK... */ if (status != GsmL1_Status_Success && lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s is now broken. Stopping the release.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "is now broken. Stopping the release.\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); @@ -1779,8 +1750,7 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) /* nothing was queued */ if (res == 0) { - LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "all SAPIs already released?\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); } @@ -1831,16 +1801,22 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { - if (kind == NM_OC_RADIO_CARRIER) { - struct gsm_bts_trx *trx = obj; - struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(trx); - /* convert max TA to max cell size in qbits */ - uint8_t cell_size = bts->max_ta << 2; + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx; + struct lc15l1_hdl *fl1h; + + switch (foh->msg_type) { + case NM_MT_SET_RADIO_ATTR: + trx = obj; + fl1h = trx_lc15l1_hdl(trx); #if LITECELL15_API_VERSION >= LITECELL15_API(2,1,7) + { + /* convert max TA to max cell size in qbits */ + uint8_t cell_size = bts->max_ta << 2; /* We do not need to check for L1 handle * because the max cell size parameter can receive before MphInit */ if (fl1h->phy_inst->u.lc15.max_cell_size != cell_size) { @@ -1849,6 +1825,7 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, /* update current max cell size */ fl1h->phy_inst->u.lc15.max_cell_size = cell_size; } + } #endif /* Did we go through MphInit yet? If yes fire and forget */ @@ -1870,9 +1847,10 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, } #endif } + break; } - /* FIXME: we actually need to send a ACK or NACK for the OML message */ - return oml_fom_ack_nack(msg, 0); + + return 0; } /* callback from OML */ @@ -1886,35 +1864,21 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); + case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: + case NM_OC_GPRS_CELL: + case NM_OC_GPRS_NSVC: + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: trx = (struct gsm_bts_trx *) obj; rc = trx_init(trx); break; - case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: ts = (struct gsm_bts_trx_ts*) obj; rc = ts_opstart(ts); break; - case NM_OC_GPRS_NSE: - case NM_OC_GPRS_CELL: - case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); - rc = oml_mo_opstart_ack(mo); - if (mo->obj_class == NM_OC_BTS) { - oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nse.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.cell.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK); - } - break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); } @@ -1984,14 +1948,10 @@ int l1if_rsl_chan_act(struct gsm_lchan *lchan) */ int l1if_rsl_chan_mod(struct gsm_lchan *lchan) { - const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; - unsigned int i; - if (lchan->ho.active == HANDOVER_NONE) return -1; - LOGP(DHO, LOGL_ERROR, "%s modifying channel for handover\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DHO, LOGL_ERROR, "modifying channel for handover\n"); /* Give up listening to RACH bursts */ release_sapi_ul_rach(lchan); @@ -2007,8 +1967,7 @@ int l1if_rsl_chan_rel(struct gsm_lchan *lchan) { /* A duplicate RF Release Request, ignore it */ if (lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s already in release request state.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "already in release request state.\n"); return 0; } @@ -2044,8 +2003,7 @@ static int ts_disconnect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - LOGP(DL1C, LOGL_DEBUG, "%s Rx mphDisconnectCnf\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "Rx mphDisconnectCnf\n"); cb_ts_disconnected(ts); @@ -2060,7 +2018,7 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) struct lc15l1_hdl *fl1h = trx_lc15l1_hdl(ts->trx); GsmL1_MphDisconnectReq_t *cr; - DEBUGP(DRSL, "%s TS disconnect\n", gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "TS disconnect\n"); cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDisconnectReq, fl1h, l1p_handle_for_ts(ts)); cr->u8Tn = ts->nr; @@ -2076,8 +2034,7 @@ static int ts_connect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - DEBUGP(DL1C, "%s %s Rx mphConnectCnf flags=%s%s%s\n", - gsm_lchan_name(ts->lchan), + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "%s Rx mphConnectCnf flags=%s%s%s\n", gsm_pchan_name(ts->pchan), ts->flags & TS_F_PDCH_ACTIVE ? "ACTIVE " : "", ts->flags & TS_F_PDCH_ACT_PENDING ? "ACT_PENDING " : "", diff --git a/src/osmo-bts-lc15/tch.c b/src/osmo-bts-lc15/tch.c index 526b2ddf..afd5b53f 100644 --- a/src/osmo-bts-lc15/tch.c +++ b/src/osmo-bts-lc15/tch.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -68,7 +68,7 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur = msgb_put(msg, GSM_FR_BYTES); memcpy(cur, l1_payload, GSM_FR_BYTES); - lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan); + lchan_set_marker(osmo_fr_is_any_sid(l1_payload), lchan); return msg; } @@ -101,12 +101,8 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, /* new L1 can deliver bits like we need them */ cur = msgb_put(msg, GSM_EFR_BYTES); memcpy(cur, l1_payload, GSM_EFR_BYTES); - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - osmo_amr_rtp_dec(l1_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - lchan_set_marker(ft == AMR_GSM_EFR_SID, lchan); + + lchan_set_marker(osmo_efr_is_any_sid(l1_payload), lchan); return msg; } @@ -259,7 +255,10 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); - /* FIXME: detect and save EFR SID */ + if (rc && lchan->ts->trx->bts->dtxd) + is_sid = osmo_efr_check_sid(rtp_pl, rtp_pl_len); + if (is_sid) + dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, -1); break; case GSM48_CMODE_SPEECH_AMR: if (use_cache) { @@ -360,7 +359,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) { GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg); GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; - uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 }; + uint8_t *payload, payload_type, payload_len; struct msgb *rmsg = NULL; struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; @@ -368,7 +367,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); /* Push empty payload to upper layers */ rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, @@ -399,6 +398,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) if (lchan->type != GSM_LCHAN_TCH_H && lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received ONSET from L1 " "(%d bytes)\n", + payload_len); /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP frame */ @@ -407,33 +408,32 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) case GsmL1_TchPlType_Amr_SidFirstP1: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P1 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstP2: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P2 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_INH from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidUpdateInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_UPDATE_INH from L1 " + "(%d bytes)\n", payload_len); break; default: - LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "%s Rx Payload Type %s is unsupported\n", - gsm_lchan_name(lchan), - get_value_string(lc15bts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n", + gsm_lchan_name(lchan), get_value_string(lc15bts_tch_pl_names, payload_type)); break; } @@ -449,14 +449,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) rmsg = l1_to_rtppayload_efr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Amr: - rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); - break; case GsmL1_TchPlType_Amr_SidFirstP1: - memcpy(sid_first, payload, payload_len); - int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); - if (len < 0) - return 0; - rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); + rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; } @@ -468,8 +462,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return 0; err_payload_match: - LOGPFN(DL1P, LOGL_ERROR, data_ind->u32Fn, "%s Rx Payload Type %s incompatible with lchan\n", - gsm_lchan_name(lchan), get_value_string(lc15bts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_ERROR, "%s Rx Payload Type %s incompatible with lchan\n", + gsm_lchan_name(lchan), get_value_string(lc15bts_tch_pl_names, payload_type)); return -EINVAL; } diff --git a/src/osmo-bts-lc15/utils.c b/src/osmo-bts-lc15/utils.c index 8d980ba8..b1906d12 100644 --- a/src/osmo-bts-lc15/utils.c +++ b/src/osmo-bts-lc15/utils.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/Makefile.am b/src/osmo-bts-oc2g/Makefile.am index 7b18e88f..29374efd 100644 --- a/src/osmo-bts-oc2g/Makefile.am +++ b/src/osmo-bts-oc2g/Makefile.am @@ -1,38 +1,104 @@ -AUTOMAKE_OPTIONS = subdir-objects +AUTOMAKE_OPTIONS = subdir-objects AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(OC2G_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) $(ORTP_CFLAGS) $(LIBSYSTEMD_CFLAGS) -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) $(ORTP_LIBS) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBGPS_CFLAGS) \ + $(LIBSYSTEMD_CFLAGS) \ + $(ORTP_CFLAGS) \ + $(NULL) + +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(ORTP_LIBS) \ + $(NULL) AM_CFLAGS += -DENABLE_OC2GBTS -EXTRA_DIST = misc/oc2gbts_mgr.h misc/oc2gbts_misc.h misc/oc2gbts_par.h misc/oc2gbts_led.h \ - misc/oc2gbts_temp.h misc/oc2gbts_power.h misc/oc2gbts_clock.h \ - misc/oc2gbts_bid.h misc/oc2gbts_bts.h misc/oc2gbts_nl.h misc/oc2gbts_swd.h \ - hw_misc.h l1_if.h l1_transp.h oc2gbts.h utils.h +EXTRA_DIST = \ + misc/oc2gbts_mgr.h \ + misc/oc2gbts_misc.h \ + misc/oc2gbts_par.h \ + misc/oc2gbts_led.h \ + misc/oc2gbts_temp.h \ + misc/oc2gbts_power.h \ + misc/oc2gbts_clock.h \ + misc/oc2gbts_bid.h \ + misc/oc2gbts_bts.h \ + misc/oc2gbts_nl.h \ + misc/oc2gbts_swd.h \ + hw_misc.h \ + l1_if.h \ + l1_transp.h \ + oc2gbts.h \ + utils.h \ + $(NULL) bin_PROGRAMS = osmo-bts-oc2g oc2gbts-mgr oc2gbts-util -COMMON_SOURCES = main.c oc2gbts.c l1_if.c oml.c oc2gbts_vty.c tch.c hw_misc.c calib_file.c \ - utils.c misc/oc2gbts_par.c misc/oc2gbts_bid.c +COMMON_SOURCES = \ + main.c \ + oc2gbts.c \ + l1_if.c \ + oml.c \ + oc2gbts_vty.c \ + tch.c \ + hw_misc.c \ + calib_file.c \ + utils.c \ + misc/oc2gbts_par.c \ + misc/oc2gbts_bid.c \ + $(NULL) osmo_bts_oc2g_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c -osmo_bts_oc2g_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) +osmo_bts_oc2g_LDADD = \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(NULL) oc2gbts_mgr_SOURCES = \ - misc/oc2gbts_mgr.c misc/oc2gbts_misc.c \ - misc/oc2gbts_par.c misc/oc2gbts_nl.c \ - misc/oc2gbts_temp.c misc/oc2gbts_power.c \ - misc/oc2gbts_clock.c misc/oc2gbts_bid.c \ + misc/oc2gbts_mgr.c \ + misc/oc2gbts_misc.c \ + misc/oc2gbts_par.c \ + misc/oc2gbts_nl.c \ + misc/oc2gbts_temp.c \ + misc/oc2gbts_power.c \ + misc/oc2gbts_clock.c \ + misc/oc2gbts_bid.c \ misc/oc2gbts_mgr_vty.c \ misc/oc2gbts_mgr_nl.c \ misc/oc2gbts_mgr_temp.c \ misc/oc2gbts_mgr_calib.c \ misc/oc2gbts_led.c \ misc/oc2gbts_bts.c \ - misc/oc2gbts_swd.c + misc/oc2gbts_swd.c \ + $(NULL) -oc2gbts_mgr_LDADD = $(top_builddir)/src/common/libbts.a $(LIBGPS_LIBS) $(LIBOSMOCORE_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCTRL_LIBS) $(LIBSYSTEMD_LIBS) $(COMMON_LDADD) +oc2gbts_mgr_LDADD = \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(LIBGPS_LIBS) \ + $(LIBSYSTEMD_LIBS) \ + $(NULL) -oc2gbts_util_SOURCES = misc/oc2gbts_util.c misc/oc2gbts_par.c +oc2gbts_util_SOURCES = \ + misc/oc2gbts_util.c \ + misc/oc2gbts_par.c \ + $(NULL) oc2gbts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-oc2g/calib_file.c b/src/osmo-bts-oc2g/calib_file.c index 22122ab3..df15ee99 100644 --- a/src/osmo-bts-oc2g/calib_file.c +++ b/src/osmo-bts-oc2g/calib_file.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/hw_misc.c b/src/osmo-bts-oc2g/hw_misc.c index 31daf078..d886effd 100644 --- a/src/osmo-bts-oc2g/hw_misc.c +++ b/src/osmo-bts-oc2g/hw_misc.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/l1_if.c b/src/osmo-bts-oc2g/l1_if.c index 2cefc3b0..d43f31b7 100644 --- a/src/osmo-bts-oc2g/l1_if.c +++ b/src/osmo-bts-oc2g/l1_if.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -392,7 +392,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, abort(); } - len = msgb_l2len(msg); + len = (msg->l2h) ? msgb_l2len(msg) : 0; chan_nr = l1sap->u.data.chan_nr; link_id = l1sap->u.data.link_id; @@ -440,9 +440,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, else sapi = GsmL1_Sapi_Agch; } else { - LOGPFN(DL1C, LOGL_NOTICE, u32Fn, "unknown prim %d op %d " - "chan_nr %d link_id %d\n", l1sap->oph.primitive, - l1sap->oph.operation, chan_nr, link_id); + LOGPLCFN(lchan, u32Fn, DL1C, LOGL_NOTICE, "unknown prim %d op %d " "chan_nr %d link_id %d\n", + l1sap->oph.primitive, l1sap->oph.operation, chan_nr, link_id); msgb_free(l1msg); return -EINVAL; } @@ -503,9 +502,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, msgb_l2len(msg)); } - LOGPFN(DL1P, LOGL_DEBUG, u32Fn, "PH-DATA.req(%s)\n", - osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, - l1p->u.phDataReq.msgUnitParam.u8Size)); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_DEBUG, "PH-DATA.req(%s)\n", + osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, l1p->u.phDataReq.msgUnitParam.u8Size)); } else { GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); if (lchan->rsl_cmode == RSL_CMOD_SPD_SIGN) @@ -523,7 +521,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) { - LOGPFN(DL1P, LOGL_ERROR, u32Fn, "MQ_L1_WRITE queue full. Dropping msg.\n"); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); msgb_free(l1msg); } else dtx_int_signal(lchan); @@ -561,7 +559,6 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, /* create new message and fill data */ if (msg) { - msgb_pull(msg, sizeof(*l1sap)); /* create new message */ nmsg = l1p_msgb_alloc(); if (!nmsg) @@ -570,7 +567,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn, use_cache, + msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache, l1sap->u.tch.marker); if (rc < 0) { /* no data encoded for L1: smth will be generated below */ @@ -606,7 +603,11 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, empty_req_from_l1sap(l1p, fl1, u8Tn, u32Fn, sapi, subCh, u8BlockNbr); } /* send message to DSP's queue */ - osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg); + if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg) < 0) { + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); + msgb_free(nmsg); + return -ENOBUFS; + } if (dtx_is_first_p1(lchan)) dtx_dispatch(lchan, E_FIRST); else @@ -1474,6 +1475,30 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, LOGP(DL1C, LOGL_FATAL, "BTS band %s not supported by hw\n", gsm_band_name(trx->bts->band)); + /* Frequency bands indicated to the BSC */ + switch (fl1h->hw_info.band_support) { + case GSM_BAND_450: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_450; + break; + case GSM_BAND_480: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_480; + break; + case GSM_BAND_850: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_850; + break; + case GSM_BAND_900: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PGSM; + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_EGSM? */ + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_RGSM? */ + break; + case GSM_BAND_1800: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_DCS; + break; + case GSM_BAND_1900: + trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PCS; + break; + } + /* Request the activation */ l1if_activate_rf(fl1h, 1); diff --git a/src/osmo-bts-oc2g/l1_transp_hw.c b/src/osmo-bts-oc2g/l1_transp_hw.c index 3738b237..5ffd6568 100644 --- a/src/osmo-bts-oc2g/l1_transp_hw.c +++ b/src/osmo-bts-oc2g/l1_transp_hw.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/main.c b/src/osmo-bts-oc2g/main.c index 9a4bbfe6..75ad3149 100644 --- a/src/osmo-bts-oc2g/main.c +++ b/src/osmo-bts-oc2g/main.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -88,6 +88,8 @@ int bts_model_init(struct gsm_bts *bts) bts->model_priv = bts_oc2g; bts->variant = BTS_OSMO_OC2G; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS + | NM_IPAC_MASK_GPRS_CODING_MCS; /* specific default values for OC2G platform */ /* TODO(oramadan) MERGE @@ -101,24 +103,43 @@ int bts_model_init(struct gsm_bts *bts) exit(23); } - osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); + osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); - osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER); + /* The default HR codec output format in the absence of saved + * vty config needs to match what was implemented previously, + * for the sake of existing deployments, i.e., to avoid + * a surprise functional change upon software update. */ + bts->emit_hr_rfc5993 = false; + return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = 0x00; /* updated in info_compl_cb() */ + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH + | NM_IPAC_F_CHANT_SDCCH8_CBCH + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH; + trx->nominal_power = 25; trx->power_params.trx_p_max_out_mdBm = to_mdB(trx->bts->c0->nominal_power); return 0; diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_bid.c b/src/osmo-bts-oc2g/misc/oc2gbts_bid.c index c2cd483d..0589e3f0 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_bid.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_bid.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_bts.c b/src/osmo-bts-oc2g/misc/oc2gbts_bts.c index b3dae76e..3e5db829 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_bts.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_bts.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_clock.c b/src/osmo-bts-oc2g/misc/oc2gbts_clock.c index 5263e3ec..10b97a31 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_clock.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_clock.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_led.c b/src/osmo-bts-oc2g/misc/oc2gbts_led.c index 40d4b722..c2c807b6 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_led.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_led.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_mgr.c b/src/osmo-bts-oc2g/misc/oc2gbts_mgr.c index 9469259c..843fbb38 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_mgr.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_mgr.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -306,7 +306,7 @@ int main(int argc, char **argv) exit(1); } - rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_calib.c b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_calib.c index f66761af..cf904aea 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_calib.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_calib.c @@ -17,7 +17,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -171,7 +171,12 @@ static void mgr_gps_checkfix(struct oc2gbts_mgr_instance *mgr) return; } +#if GPSD_API_MAJOR_VERSION >= 9 + mgr->gps.gps_fix_now = data->fix.time.tv_sec; +#else mgr->gps.gps_fix_now = (time_t) data->fix.time; +#endif + LOGP(DCALIB, LOGL_INFO, "Got a GPS fix, satellites used: %d, timestamp: %ld\n", data->satellites_used, mgr->gps.gps_fix_now); osmo_timer_del(&mgr->gps.fix_timeout); diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_nl.c b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_nl.c index db67caf2..1091f622 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_nl.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_nl.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_temp.c b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_temp.c index f9efd9cd..9a92a075 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_temp.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_temp.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_vty.c b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_vty.c index 9693eab6..10dda21f 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_mgr_vty.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_mgr_vty.c @@ -1,5 +1,5 @@ /* Copyright (C) 2015 by Yves Godin <support@nuranwireless.com> - * + * * Based on sysmoBTS: * sysmobts_mgr_vty.c * (C) 2014 by oc2gcom - s.f.m.c. GmbH @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -86,35 +86,10 @@ static int go_to_parent(struct vty *vty) return vty->node; } -static int is_config_node(struct vty *vty, int node) -{ - switch (node) { - case MGR_NODE: - case ACT_NORM_NODE: - case ACT_WARN_NODE: - case ACT_CRIT_NODE: - case LIMIT_SUPPLY_TEMP_NODE: - case LIMIT_SOC_NODE: - case LIMIT_FPGA_NODE: - case LIMIT_RMSDET_NODE: - case LIMIT_OCXO_NODE: - case LIMIT_TX_TEMP_NODE: - case LIMIT_PA_TEMP_NODE: - case LIMIT_SUPPLY_VOLT_NODE: - case LIMIT_VSWR_NODE: - case LIMIT_SUPPLY_PWR_NODE: - case LIMIT_PA_PWR_NODE: - return 1; - default: - return 0; - } -} - static struct vty_app_info vty_info = { .name = "oc2gbts-mgr", .version = PACKAGE_VERSION, .go_parent_cb = go_to_parent, - .is_config_node = is_config_node, .copyright = copyright, }; @@ -649,7 +624,7 @@ DEFUN(show_thresh, show_thresh_cmd, "show thresholds", DEFUN(calibrate_clock, calibrate_clock_cmd, "calibrate clock", - "Calibration commands\n" + "Calibration commands\n" "Calibrate clock against GPS PPS\n") { if (oc2gbts_mgr_calib_run(s_mgr) < 0) { diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_misc.c b/src/osmo-bts-oc2g/misc/oc2gbts_misc.c index 0d31f0b1..c3b91ec1 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_misc.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_misc.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_nl.c b/src/osmo-bts-oc2g/misc/oc2gbts_nl.c index 39f64aae..d1d1bd13 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_nl.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_nl.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_nl.h b/src/osmo-bts-oc2g/misc/oc2gbts_nl.h index 340cf117..b5a15403 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_nl.h +++ b/src/osmo-bts-oc2g/misc/oc2gbts_nl.h @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_par.c b/src/osmo-bts-oc2g/misc/oc2gbts_par.c index 7dc77c90..fef350f2 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_par.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_par.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_power.c b/src/osmo-bts-oc2g/misc/oc2gbts_power.c index 4e2fc95a..46b8fc03 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_power.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_power.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_swd.c b/src/osmo-bts-oc2g/misc/oc2gbts_swd.c index 1ccef5b9..6358d4e2 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_swd.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_swd.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_temp.c b/src/osmo-bts-oc2g/misc/oc2gbts_temp.c index 8425dda3..d7afa4e6 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_temp.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_temp.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/misc/oc2gbts_util.c b/src/osmo-bts-oc2g/misc/oc2gbts_util.c index b71f0383..0919da93 100644 --- a/src/osmo-bts-oc2g/misc/oc2gbts_util.c +++ b/src/osmo-bts-oc2g/misc/oc2gbts_util.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/oc2gbts.c b/src/osmo-bts-oc2g/oc2gbts.c index 012d705c..5860a566 100644 --- a/src/osmo-bts-oc2g/oc2gbts.c +++ b/src/osmo-bts-oc2g/oc2gbts.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-oc2g/oc2gbts_vty.c b/src/osmo-bts-oc2g/oc2gbts_vty.c index d69225ac..051528ab 100644 --- a/src/osmo-bts-oc2g/oc2gbts_vty.c +++ b/src/osmo-bts-oc2g/oc2gbts_vty.c @@ -47,6 +47,7 @@ #include <osmo-bts/signal.h> #include <osmo-bts/oml.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/phy_link.h> @@ -133,7 +134,7 @@ DEFUN(cfg_phy_no_dsp_trace_f, cfg_phy_no_dsp_trace_f_cmd, /* runtime */ DEFUN(show_dsp_trace_f, show_dsp_trace_f_cmd, - "show trx <0-0> dsp-trace-flags", + "show dsp-trace-flags trx <0-0>", SHOW_TRX_STR "Display the current setting of the DSP trace flags") { int trx_nr = atoi(argv[0]); @@ -412,7 +413,6 @@ DEFUN(cfg_phy_c0_idle_red_pwr, cfg_phy_c0_idle_red_pwr_cmd, DEFUN(trigger_ho_cause, trigger_ho_cause_cmd, "HIDDEN", TRX_STR) { - struct gsm_network *net = gsmnet_from_vty(vty); struct gsm_bts *bts; struct gsm_bts_trx *trx; struct gsm_bts_trx_ts *ts; @@ -422,7 +422,7 @@ DEFUN(trigger_ho_cause, trigger_ho_cause_cmd, "HIDDEN", TRX_STR) /* uint8_t old_ho_cause; */ /* get BTS pointer */ - bts = gsm_bts_num(net, 0); + bts = gsm_bts_num(g_bts_sm, 0); if (!bts) { vty_out(vty, "Can not get BTS node %s", VTY_NEWLINE); return CMD_WARNING; diff --git a/src/osmo-bts-oc2g/oml.c b/src/osmo-bts-oc2g/oml.c index 9791ab8b..4b434e83 100644 --- a/src/osmo-bts-oc2g/oml.c +++ b/src/osmo-bts-oc2g/oml.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -49,6 +49,8 @@ #include "oc2gbts.h" #include "utils.h" +static void dump_lch_par(int logl, GsmL1_LogChParam_t *lch_par, GsmL1_Sapi_t sapi); + static int mph_info_chan_confirm(struct gsm_lchan *lchan, enum osmo_mph_info_type type, uint8_t cause) { @@ -584,8 +586,7 @@ GsmL1_Sapi_t lchan_to_GsmL1_Sapi_t(const struct gsm_lchan *lchan) case GSM_LCHAN_TCH_H: return GsmL1_Sapi_TchH; default: - LOGP(DL1C, LOGL_NOTICE, "%s cannot determine L1 SAPI\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "cannot determine L1 SAPI\n"); break; } return GsmL1_Sapi_Idle; @@ -796,12 +797,8 @@ static void sapi_queue_dispatch(struct gsm_lchan *lchan, int status) talloc_free(cmd); if (end || llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_DEBUG, - "%s End of SAPI cmd queue encountered.%s\n", - gsm_lchan_name(lchan), - llist_empty(&lchan->sapi_cmds) - ? " Queue is now empty." - : " More pending."); + LOGPLCHAN(lchan, DL1C, LOGL_DEBUG, "End of SAPI cmd queue encountered.%s\n", + llist_empty(&lchan->sapi_cmds) ? " Queue is now empty." : " More pending."); return; } @@ -841,9 +838,8 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.conf (%s ", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_l1sapi_names, ic->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.conf (%s ", + get_value_string(oc2gbts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(oc2gbts_dir_names, ic->dir)); @@ -864,19 +860,15 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, lchan->sapis_ul[ic->sapi] = status; if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_ACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -957,8 +949,7 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) (struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie; int j; - LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n", - gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "%s tch_mode=0x%02x\n", __func__, lchan->tch_mode); switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: @@ -986,7 +977,9 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) case GSM48_CMODE_SPEECH_AMR: lch_par->tch.tchPlType = GsmL1_TchPlType_Amr; set_payload_format(lch_par); - lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; /* FIXME? */ + /* At call set-up, after every successful handover and after a channel mode modify, the + * default phase (odd) shall be used in downlink direction. */ + lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; lch_par->tch.amrInitCodecMode = amr_get_initial_mode(lchan); /* initialize to clean state */ @@ -1109,9 +1102,9 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) break; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.req (hL2=0x%08x, %s ", - gsm_lchan_name(lchan), (uint32_t)act_req->hLayer2, - get_value_string(oc2gbts_l1sapi_names, act_req->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.req (hL2=0x%08x, %s ", + (uint32_t)act_req->hLayer2, get_value_string(oc2gbts_l1sapi_names, act_req->sapi)); + dump_lch_par(LOGL_INFO, lch_par, act_req->sapi); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(oc2gbts_dir_names, act_req->dir)); @@ -1135,9 +1128,7 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) /* FIXME: Error handling */ if (status != GsmL1_Status_Success) { - LOGP(DL1C, LOGL_ERROR, - "%s act failed mark broken due status: %d\n", - gsm_lchan_name(lchan), status); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "act failed mark broken due status: %d\n", status); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, RSL_ERR_PROCESSOR_OVERLOAD); @@ -1184,13 +1175,11 @@ int lchan_activate(struct gsm_lchan *lchan) lchan_set_state(lchan, LCHAN_S_ACT_REQ); if (!llist_empty(&lchan->sapi_cmds)) - LOGP(DL1C, LOGL_ERROR, - "%s Trying to activate lchan, but commands in queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Trying to activate lchan, but commands in queue\n"); /* For handover, always start the main channel immediately. lchan->want_dl_sacch_active indicates whether dl * SACCH should be activated. Also, for HO, start the RACH SAPI. */ - if (lchan->ho.active == HANDOVER_ENABLED) + if (lchan->ho.active == HANDOVER_ENABLED || rsl_chan_rt_is_asci(lchan->rsl_chan_rt)) enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink); for (i = 0; i < s4l->num_sapis; i++) { @@ -1212,10 +1201,6 @@ int lchan_activate(struct gsm_lchan *lchan) enqueue_sapi_act_cmd(lchan, sapi, dir); } - -#warning "FIXME: Should this be in sapi_activate_cb?" - lchan_init_lapdm(lchan); - return 0; } @@ -1347,9 +1332,8 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_l1cfgt_names, cc->cfgParamId)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.conf (%s) ", + get_value_string(oc2gbts_l1cfgt_names, cc->cfgParamId)); switch (cc->cfgParamId) { case GsmL1_ConfigParamId_SetLogChParams: @@ -1381,9 +1365,7 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, break; } if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got ciphering conf with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got ciphering conf with empty queue\n"); goto err; } @@ -1434,10 +1416,8 @@ static int mph_send_config_logchpar(struct gsm_lchan *lchan, struct sapi_cmd *cm /* FIXME: update encryption */ - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.req (%s) ", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_l1sapi_names, - conf_req->cfgParams.setLogChParams.sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.req (%s) ", + get_value_string(oc2gbts_l1sapi_names, conf_req->cfgParams.setLogChParams.sapi)); LOGPC(DL1C, LOGL_INFO, "cfgParams Tn=%u, subCh=%u, dir=0x%x ", conf_req->cfgParams.setLogChParams.u8Tn, conf_req->cfgParams.setLogChParams.subCh, @@ -1545,11 +1525,9 @@ static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *c return -EINVAL; cfgr->cfgParams.setCipheringParams.cipherId = rsl2l1_ciph[lchan->encr.alg_id]; - LOGP(DL1C, LOGL_NOTICE, "%s SET_CIPHERING (ALG=%u %s)\n", - gsm_lchan_name(lchan), - cfgr->cfgParams.setCipheringParams.cipherId, - get_value_string(oc2gbts_dir_names, - cfgr->cfgParams.setCipheringParams.dir)); + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "SET_CIPHERING (ALG=%u %s)\n", + cfgr->cfgParams.setCipheringParams.cipherId, + get_value_string(oc2gbts_dir_names, cfgr->cfgParams.setCipheringParams.dir)); memcpy(cfgr->cfgParams.setCipheringParams.u8Kc, lchan->encr.key, lchan->encr.key_len); @@ -1627,9 +1605,8 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.conf (%s ", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_l1sapi_names, ic->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.conf (%s ", + get_value_string(oc2gbts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(oc2gbts_dir_names, ic->dir)); @@ -1651,19 +1628,15 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got de-activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got de-activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_DEACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -1688,9 +1661,8 @@ static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd deact_req->sapi = cmd->sapi; deact_req->hLayer3 = (HANDLE)l1if_lchan_to_hLayer(lchan); - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.req (%s ", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_l1sapi_names, deact_req->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.req (%s ", + get_value_string(oc2gbts_l1sapi_names, deact_req->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(oc2gbts_dir_names, deact_req->dir)); @@ -1702,8 +1674,7 @@ static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status) { /* FIXME: Error handling. There is no NACK... */ if (status != GsmL1_Status_Success && lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s is now broken. Stopping the release.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "is now broken. Stopping the release.\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); @@ -1788,8 +1759,7 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) /* nothing was queued */ if (res == 0) { - LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "all SAPIs already released?\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); } @@ -1840,14 +1810,20 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) -{ - if (kind == NM_OC_RADIO_CARRIER) { - struct gsm_bts_trx *trx = obj; - struct oc2gl1_hdl *fl1h = trx_oc2gl1_hdl(trx); +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) +{ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx; + struct oc2gl1_hdl *fl1h; + uint8_t cell_size; + + switch (foh->msg_type) { + case NM_MT_SET_RADIO_ATTR: + trx = obj; + fl1h = trx_oc2gl1_hdl(trx); /* convert max TA to max cell size in qbits */ - uint8_t cell_size = bts->max_ta << 2; + cell_size = bts->max_ta << 2; /* We do not need to check for L1 handle * because the max cell size parameter can receive before MphInit */ @@ -1876,11 +1852,10 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, l1if_set_txpower_c0_idle_pwr_red(fl1h, fl1h->phy_inst->u.oc2g.tx_c0_idle_pwr_red); } } - + break; } - /* FIXME: we actually need to send a ACK or NACK for the OML message */ - return oml_fom_ack_nack(msg, 0); + return 0; } /* callback from OML */ @@ -1894,32 +1869,20 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); - oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nse.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.cell.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK); + case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: + case NM_OC_GPRS_CELL: + case NM_OC_GPRS_NSVC: + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: trx = (struct gsm_bts_trx *) obj; rc = trx_init(trx); break; - case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: ts = (struct gsm_bts_trx_ts*) obj; - rc = ts_opstart(obj); - break; - case NM_OC_GPRS_NSE: - case NM_OC_GPRS_CELL: - case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); - rc = oml_mo_opstart_ack(mo); + rc = ts_opstart(ts); break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); @@ -1990,14 +1953,10 @@ int l1if_rsl_chan_act(struct gsm_lchan *lchan) */ int l1if_rsl_chan_mod(struct gsm_lchan *lchan) { - const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; - unsigned int i; - if (lchan->ho.active == HANDOVER_NONE) return -1; - LOGP(DHO, LOGL_ERROR, "%s modifying channel for handover\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DHO, LOGL_ERROR, "modifying channel for handover\n"); /* Give up listening to RACH bursts */ release_sapi_ul_rach(lchan); @@ -2013,8 +1972,7 @@ int l1if_rsl_chan_rel(struct gsm_lchan *lchan) { /* A duplicate RF Release Request, ignore it */ if (lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s already in release request state.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "already in release request state.\n"); return 0; } @@ -2050,8 +2008,7 @@ static int ts_disconnect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - LOGP(DL1C, LOGL_DEBUG, "%s Rx mphDisconnectCnf\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "Rx mphDisconnectCnf\n"); cb_ts_disconnected(ts); @@ -2066,7 +2023,7 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) struct oc2gl1_hdl *fl1h = trx_oc2gl1_hdl(ts->trx); GsmL1_MphDisconnectReq_t *cr; - DEBUGP(DRSL, "%s TS disconnect\n", gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "TS disconnect\n"); cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDisconnectReq, fl1h, l1p_handle_for_ts(ts)); cr->u8Tn = ts->nr; @@ -2082,12 +2039,11 @@ static int ts_connect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - DEBUGP(DL1C, "%s %s Rx mphConnectCnf flags=%s%s%s\n", - gsm_lchan_name(ts->lchan), - gsm_pchan_name(ts->pchan), - ts->flags & TS_F_PDCH_ACTIVE ? "ACTIVE " : "", - ts->flags & TS_F_PDCH_ACT_PENDING ? "ACT_PENDING " : "", - ts->flags & TS_F_PDCH_DEACT_PENDING ? "DEACT_PENDING " : ""); + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "%s Rx mphConnectCnf flags=%s%s%s\n", + gsm_pchan_name(ts->pchan), + ts->flags & TS_F_PDCH_ACTIVE ? "ACTIVE " : "", + ts->flags & TS_F_PDCH_ACT_PENDING ? "ACT_PENDING " : "", + ts->flags & TS_F_PDCH_DEACT_PENDING ? "DEACT_PENDING " : ""); cb_ts_connected(ts, 0); diff --git a/src/osmo-bts-oc2g/tch.c b/src/osmo-bts-oc2g/tch.c index 09ee1e7c..4ea1eb61 100644 --- a/src/osmo-bts-oc2g/tch.c +++ b/src/osmo-bts-oc2g/tch.c @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -68,7 +68,7 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur = msgb_put(msg, GSM_FR_BYTES); memcpy(cur, l1_payload, GSM_FR_BYTES); - lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan); + lchan_set_marker(osmo_fr_is_any_sid(l1_payload), lchan); return msg; } @@ -101,12 +101,8 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, /* new L1 can deliver bits like we need them */ cur = msgb_put(msg, GSM_EFR_BYTES); memcpy(cur, l1_payload, GSM_EFR_BYTES); - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - osmo_amr_rtp_dec(l1_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - lchan_set_marker(ft == AMR_GSM_EFR_SID, lchan); + + lchan_set_marker(osmo_efr_is_any_sid(l1_payload), lchan); return msg; } @@ -259,7 +255,10 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); - /* FIXME: detect and save EFR SID */ + if (rc && lchan->ts->trx->bts->dtxd) + is_sid = osmo_efr_check_sid(rtp_pl, rtp_pl_len); + if (is_sid) + dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, -1); break; case GSM48_CMODE_SPEECH_AMR: if (use_cache) { @@ -360,7 +359,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) { GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg); GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; - uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 }; + uint8_t *payload, payload_type, payload_len; struct msgb *rmsg = NULL; struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; @@ -368,7 +367,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); /* Push empty payload to upper layers */ rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, @@ -403,6 +402,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) if (lchan->type != GSM_LCHAN_TCH_H && lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received ONSET from L1 " "(%d bytes)\n", + payload_len); /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP frame */ @@ -412,43 +413,40 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) case GsmL1_TchPlType_Amr_SidFirstP1: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P1 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstP2: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P2 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->tch.dtx.is_speech_resume = true; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_INH from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidUpdateInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->tch.dtx.is_speech_resume = true; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_UPDATE_INH from L1 " + "(%d bytes)\n", payload_len); break; default: - LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "%s Rx Payload Type %s is unsupported\n", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n", + gsm_lchan_name(lchan), get_value_string(oc2gbts_tch_pl_names, payload_type)); break; } - LOGP(DL1P, LOGL_DEBUG, "%s %s lchan->rtp_tx_marker = %s, len=%u\n", - gsm_lchan_name(lchan), - get_value_string(oc2gbts_tch_pl_names, payload_type), - lchan->rtp_tx_marker ? "true" : "false", - payload_len); + LOGPLCHAN(lchan, DL1P, LOGL_DEBUG, "%s lchan->rtp_tx_marker = %s, len=%u\n", + get_value_string(oc2gbts_tch_pl_names, payload_type), + lchan->rtp_tx_marker ? "true" : "false", payload_len); switch (payload_type) { case GsmL1_TchPlType_Fr: @@ -461,14 +459,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) rmsg = l1_to_rtppayload_efr(payload, payload_len, lchan); break; case GsmL1_TchPlType_Amr: - rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); - break; case GsmL1_TchPlType_Amr_SidFirstP1: - memcpy(sid_first, payload, payload_len); - int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); - if (len < 0) - return 0; - rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); + rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; } @@ -480,8 +472,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return 0; err_payload_match: - LOGPFN(DL1P, LOGL_ERROR, data_ind->u32Fn, "%s Rx Payload Type %s incompatible with lchan\n", - gsm_lchan_name(lchan), get_value_string(oc2gbts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_ERROR, "%s Rx Payload Type %s incompatible with lchan\n", + gsm_lchan_name(lchan), get_value_string(oc2gbts_tch_pl_names, payload_type)); return -EINVAL; } diff --git a/src/osmo-bts-oc2g/utils.c b/src/osmo-bts-oc2g/utils.c index cb65f45a..f98e88af 100644 --- a/src/osmo-bts-oc2g/utils.c +++ b/src/osmo-bts-oc2g/utils.c @@ -16,7 +16,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-octphy/Makefile.am b/src/osmo-bts-octphy/Makefile.am index 43d9cd7d..fb3f6691 100644 --- a/src/osmo-bts-octphy/Makefile.am +++ b/src/osmo-bts-octphy/Makefile.am @@ -1,12 +1,42 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(OCTSDR2G_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) + +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) + +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) EXTRA_DIST = l1_if.h l1_oml.h l1_utils.h octphy_hw_api.h octpkt.h bin_PROGRAMS = osmo-bts-octphy -COMMON_SOURCES = main.c l1_if.c l1_oml.c l1_utils.c l1_tch.c octphy_hw_api.c octphy_vty.c octpkt.c +COMMON_SOURCES = \ + main.c \ + l1_if.c \ + l1_oml.c \ + l1_utils.c \ + l1_tch.c \ + octphy_hw_api.c \ + octphy_vty.c \ + octpkt.c \ + $(NULL) osmo_bts_octphy_SOURCES = $(COMMON_SOURCES) osmo_bts_octphy_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c index 294a65ec..074a1a7f 100644 --- a/src/osmo-bts-octphy/l1_if.c +++ b/src/osmo-bts-octphy/l1_if.c @@ -479,7 +479,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, abort(); } - len = msgb_l2len(msg); + len = (msg->l2h) ? msgb_l2len(msg) : 0; chan_nr = l1sap->u.data.chan_nr; link_id = l1sap->u.data.link_id; @@ -589,11 +589,10 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, if (msg) { nmsg = l1p_msgb_alloc(); if (!nmsg) { - LOGPFN(DL1C, LOGL_FATAL, u32Fn, "L1SAP PH-TCH.req msg alloc failed\n"); + LOGPLCFN(lchan, u32Fn, DL1C, LOGL_FATAL, "L1SAP PH-TCH.req msg alloc failed\n"); return -ENOMEM; } - msgb_pull(msg, sizeof(*l1sap)); tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *data_req = (tOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD *) msgb_put(nmsg, sizeof(*data_req)); @@ -615,7 +614,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, &data_req->Data.ulPayloadType, data_req->Data.abyDataContent, &data_req->Data.ulDataLength, - msg->data, msg->len); + msgb_l2(msg), msgb_l2len(msg)); mOCTVC1_GSM_MSG_TRX_REQUEST_LOGICAL_CHANNEL_DATA_CMD_SWAP(data_req); } else { @@ -769,15 +768,17 @@ int bts_model_init(struct gsm_bts *bts) bts->variant = BTS_OSMO_OCTPHY; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS; /* FIXME: what is the nominal transmit power of the PHY/board? */ bts->c0->nominal_power = 15; - osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); - osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); + /* order alphabetically */ #if defined(cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_FCCH_SCH_BCCH_CCCH_SDCCH4_CBCH_SACCHC4) && defined(cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_SDCCH8_CBCH_SACCHC8) osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); #endif + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); @@ -786,6 +787,29 @@ int bts_model_init(struct gsm_bts *bts) int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = NM_IPAC_F_FREQ_BAND_PGSM + | NM_IPAC_F_FREQ_BAND_EGSM + | NM_IPAC_F_FREQ_BAND_RGSM + | NM_IPAC_F_FREQ_BAND_DCS + | NM_IPAC_F_FREQ_BAND_PCS + | NM_IPAC_F_FREQ_BAND_850 + | NM_IPAC_F_FREQ_BAND_480 + | NM_IPAC_F_FREQ_BAND_450; + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON +#if defined(cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_FCCH_SCH_BCCH_CCCH_SDCCH4_CBCH_SACCHC4) + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH +#endif +#if defined(cOCTVC1_GSM_LOGICAL_CHANNEL_COMBINATION_ENUM_SDCCH8_CBCH_SACCHC8) + | NM_IPAC_F_CHANT_SDCCH8_CBCH +#endif + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_F_CHANM_SPEECH_FS + | NM_IPAC_F_CHANM_SPEECH_HS; + return 0; } @@ -1302,7 +1326,11 @@ static int retransmit_wlc_upto(struct octphy_hdl *fl1h, uint32_t trans_id) wlc->num_retrans++; msg = msgb_copy(wlc->cmd_msg, "PHY CMD Retrans"); msg_set_retrans_flag(msg); - osmo_wqueue_enqueue(&fl1h->phy_wq, msg); + if (osmo_wqueue_enqueue(&fl1h->phy_wq, msg) < 0) { + LOGP(DL1C, LOGL_ERROR, "Queue full on wlc retransmit\n"); + msgb_free(msg); + return 0; + } osmo_timer_schedule(&wlc->timer, CMD_TIMEOUT, 0); count++; LOGP(DL1C, LOGL_INFO, "Re-transmitting %s " diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index 5b48b2e6..bb519a04 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -259,7 +259,7 @@ static int lchan2lch_par(struct gsm_lchan *lchan, int j; LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n", - gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode); + gsm_lchan_name(lchan), __func__, lchan->tch_mode); switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: @@ -459,7 +459,7 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) lac->LchId.bySAPI = cmd->sapi; lac->LchId.byDirection = cmd->dir; - lac->Config.byTimingAdvance = lchan->rqd_ta; + lac->Config.byTimingAdvance = lchan->ta_ctrl.current; lac->Config.byBSIC = lchan->ts->trx->bts->bsic; if ((rc = lchan2lch_par(lchan, &lac->Config)) != 0) { talloc_free(msg); @@ -1107,9 +1107,6 @@ int lchan_activate(struct gsm_lchan *lchan) } enqueue_sapi_act_cmd(lchan, sapi, dir); } - - lchan_init_lapdm(lchan); - return 0; } @@ -1176,7 +1173,7 @@ static int app_info_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *air = (tOCTVC1_MAIN_MSG_APPLICATION_INFO_RSP *) resp->l2h; - snprintf(ver_hdr, sizeof(ver_hdr), "%02i.%02i.%02i-B%i", + snprintf(ver_hdr, sizeof(ver_hdr), "%02d.%02d.%02d-B%d", cOCTVC1_MAIN_VERSION_MAJOR, cOCTVC1_MAIN_VERSION_MINOR, cOCTVC1_MAIN_VERSION_MAINTENANCE, cOCTVC1_MAIN_VERSION_BUILD); @@ -1518,8 +1515,7 @@ static int ts_connect_as(struct gsm_bts_trx_ts *ts, struct phy_instance *pinst = trx_phy_instance(ts->trx); struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc = - (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *) oc; + tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD *oc; oc = (tOCTVC1_GSM_MSG_TRX_ACTIVATE_PHYSICAL_CHANNEL_CMD*) msgb_put(msg, sizeof(*oc)); @@ -1745,52 +1741,47 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { - if (kind == NM_OC_RADIO_CARRIER) { - struct gsm_bts_trx *trx = obj; - /*struct octphy_hdl *fl1h = trx_octphy_hdl(trx); */ + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx; + switch (foh->msg_type) { + case NM_MT_SET_RADIO_ATTR: + trx = obj; power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL); + break; } - return oml_fom_ack_nack(msg, 0); + + return 0; } /* callback from OML */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { - struct gsm_bts_bb_trx *bb_transc; struct gsm_bts_trx* trx; struct gsm_bts_trx_ts *ts; int rc; switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); + case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: + case NM_OC_GPRS_CELL: + case NM_OC_GPRS_NSVC: + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: trx = (struct gsm_bts_trx*) obj; rc = trx_init(trx); break; - case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: ts = (struct gsm_bts_trx_ts*) obj; rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL); break; - case NM_OC_GPRS_NSE: - case NM_OC_GPRS_CELL: - case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); - rc = oml_mo_opstart_ack(mo); - break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); } @@ -1808,8 +1799,7 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) struct phy_instance *pinst = trx_phy_instance(ts->trx); struct octphy_hdl *fl1h = pinst->phy_link->u.octphy.hdl; struct msgb *msg = l1p_msgb_alloc(); - tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc = - (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *) oc; + tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *oc; oc = (tOCTVC1_GSM_MSG_TRX_DEACTIVATE_PHYSICAL_CHANNEL_CMD *) msgb_put(msg, sizeof(*oc)); diff --git a/src/osmo-bts-octphy/l1_tch.c b/src/osmo-bts-octphy/l1_tch.c index bffa1e95..4b542d11 100644 --- a/src/osmo-bts-octphy/l1_tch.c +++ b/src/osmo-bts-octphy/l1_tch.c @@ -146,7 +146,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; if (data_ind->Data.ulDataLength < 1) { - LOGPFN(DL1P, LOGL_DEBUG, fn, "chan_nr %d Rx Payload size 0\n", chan_nr); + LOGPLCFN(lchan, fn, DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); /* Push empty payload to upper layers */ rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); return add_l1sap_header(trx, rmsg, lchan, chan_nr, @@ -173,13 +173,13 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, goto err_payload_match; break; default: - LOGPFN(DL1P, LOGL_NOTICE, fn, "%s Rx Payload Type %d is unsupported\n", - gsm_lchan_name(lchan), payload_type); + LOGPLCFN(lchan, fn, DL1P, LOGL_NOTICE, "%s Rx Payload Type %d is unsupported\n", + gsm_lchan_name(lchan), payload_type); break; } - LOGPFN(DL1P, LOGL_DEBUG, fn, "%s Rx codec frame (%u): %s\n", gsm_lchan_name(lchan), - payload_len, osmo_hexdump(payload, payload_len)); + LOGPLCFN(lchan, fn, DL1P, LOGL_DEBUG, "%s Rx codec frame (%u): %s\n", gsm_lchan_name(lchan), payload_len, + osmo_hexdump(payload, payload_len)); switch (payload_type) { case cOCTVC1_GSM_PAYLOAD_TYPE_ENUM_FULL_RATE: @@ -201,7 +201,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, rmsg = l1_to_rtppayload_amr(payload, payload_len, &lchan->tch.amr_mr); #else - LOGPFN(DL1P, LOGL_ERROR, fn, "OctPHY only supports FR!\n"); + LOGPLCFN(lchan, fn, DL1P, LOGL_ERROR, "OctPHY only supports FR!\n"); return -1; #endif break; @@ -215,8 +215,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, return 0; err_payload_match: - LOGPFN(DL1P, LOGL_ERROR, fn, "%s Rx Payload Type %d incompatible with lchan\n", - gsm_lchan_name(lchan), payload_type); + LOGPLCFN(lchan, fn, DL1P, LOGL_ERROR, "%s Rx Payload Type %d incompatible with lchan\n", + gsm_lchan_name(lchan), payload_type); return -EINVAL; } @@ -241,8 +241,7 @@ void l1if_tch_encode(struct gsm_lchan *lchan, uint32_t *payload_type, uint8_t *l1_payload; int rc = -1; - DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan), - osmo_hexdump(rtp_pl, rtp_pl_len)); + LOGPLCHAN(lchan, DRTP, LOGL_DEBUG, "RTP IN: %s\n", osmo_hexdump(rtp_pl, rtp_pl_len)); l1_payload = &data[0]; @@ -271,13 +270,11 @@ void l1if_tch_encode(struct gsm_lchan *lchan, uint32_t *payload_type, } if (rc < 0) { - LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "unable to parse RTP payload\n"); return; } *len = rc; - DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan), - osmo_hexdump(data, *len)); + LOGPLCHAN(lchan, DRTP, LOGL_DEBUG, "RTP->L1: %s\n", osmo_hexdump(data, *len)); } diff --git a/src/osmo-bts-octphy/octphy_hw_api.c b/src/osmo-bts-octphy/octphy_hw_api.c index 6da038b1..271ed04f 100644 --- a/src/osmo-bts-octphy/octphy_hw_api.c +++ b/src/osmo-bts-octphy/octphy_hw_api.c @@ -119,7 +119,7 @@ static int rf_port_stats_compl_cb(struct octphy_hdl *fl1, struct msgb *resp, LOGP(DL1C, LOGL_INFO, "RF-PORT-STATS.resp Idx=%u RadioStandard=%s, " "Rx(Bytes=%u, Overflow=%u, AvgBps=%u, Period=%uus, Freq=%u) " - "Tx(Bytes=%i, Underflow=%u, AvgBps=%u, Period=%uus, Freq=%u)\n", + "Tx(Bytes=%d, Underflow=%u, AvgBps=%u, Period=%uus, Freq=%u)\n", psr->ulPortIndex, get_value_string(radio_std_vals, psr->ulRadioStandard), psr->RxStats.ulRxByteCnt, psr->RxStats.ulRxOverflowCnt, diff --git a/src/osmo-bts-omldummy/Makefile.am b/src/osmo-bts-omldummy/Makefile.am index 5a4ce7c5..f7a05047 100644 --- a/src/osmo-bts-omldummy/Makefile.am +++ b/src/osmo-bts-omldummy/Makefile.am @@ -1,6 +1,28 @@ -AM_CFLAGS = -Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) +AM_CFLAGS = \ + -Wall -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBGPS_CFLAGS) \ + $(NULL) + AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Iinclude -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) -ldl + +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + -ldl \ + $(NULL) bin_PROGRAMS = osmo-bts-omldummy diff --git a/src/osmo-bts-omldummy/bts_model.c b/src/osmo-bts-omldummy/bts_model.c index 46558a1c..0690d9db 100644 --- a/src/osmo-bts-omldummy/bts_model.c +++ b/src/osmo-bts-omldummy/bts_model.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -93,58 +93,45 @@ static uint8_t vbts_set_ts(struct gsm_bts_trx_ts *ts) return 0; } -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { struct abis_om_fom_hdr *foh = msgb_l3(msg); - int cause = 0; + int rc; switch (foh->msg_type) { case NM_MT_SET_BTS_ATTR: - cause = vbts_set_bts(obj); + rc = vbts_set_bts(obj); break; case NM_MT_SET_RADIO_ATTR: - cause = vbts_set_trx(obj); + rc = vbts_set_trx(obj); break; case NM_MT_SET_CHAN_ATTR: - cause = vbts_set_ts(obj); + rc = vbts_set_ts(obj); + break; + default: + rc = 0; break; } - return oml_fom_ack_nack(msg, cause); + + return rc; } /* MO: TS 12.21 Managed Object */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { int rc; - struct gsm_bts_bb_trx *bb_transc; - struct gsm_bts_trx* trx; - struct gsm_bts_trx_ts* ts; switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; - case NM_OC_RADIO_CARRIER: - trx = (struct gsm_bts_trx*) obj; - rc = osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; + case NM_OC_RADIO_CARRIER: case NM_OC_CHANNEL: - ts = (struct gsm_bts_trx_ts *) obj; - rc = osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - rc = oml_mo_opstart_ack(mo); + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); @@ -185,9 +172,12 @@ uint32_t trx_get_hlayer1(const struct gsm_bts_trx *trx) int bts_model_init(struct gsm_bts *bts) { bts->variant = BTS_OSMO_OMLDUMMY; + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_BCCH_POWER_RED); osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING); - osmo_bts_set_feature(bts->features, BTS_FEAT_BCCH_POWER_RED); + osmo_bts_set_feature(bts->features, BTS_FEAT_VBS); + osmo_bts_set_feature(bts->features, BTS_FEAT_VGCS); return 0; } diff --git a/src/osmo-bts-omldummy/main.c b/src/osmo-bts-omldummy/main.c index a36e0db5..167d43a2 100644 --- a/src/osmo-bts-omldummy/main.c +++ b/src/osmo-bts-omldummy/main.c @@ -10,6 +10,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/oml.h> static void print_usage(const char *prog_name) @@ -107,7 +108,7 @@ int main(int argc, char **argv) { struct gsm_bts *bts; struct gsm_bts_trx *trx; - struct e1inp_line *line; + struct bsc_oml_host *bsc_oml_host; int i; parse_cmdline(argc, argv); @@ -117,9 +118,14 @@ int main(int argc, char **argv) osmo_init_logging2(tall_bts_ctx, &bts_log_info); - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) + exit(1); + + bts = gsm_bts_alloc(g_bts_sm, 0); if (!bts) exit(1); + bts->ip_access.site_id = cmdline.site_id; bts->ip_access.bts_id = 0; @@ -144,9 +150,13 @@ int main(int argc, char **argv) //btsb = bts_role_bts(bts); abis_init(bts); - line = abis_open(bts, cmdline.dst_host, "OMLdummy"); - if (!line) - exit(2); + bsc_oml_host = talloc_zero(bts, struct bsc_oml_host); + OSMO_ASSERT(bsc_oml_host); + bsc_oml_host->addr = talloc_strdup(bsc_oml_host, cmdline.dst_host); + OSMO_ASSERT(bsc_oml_host->addr); + llist_add_tail(&bsc_oml_host->list, &bts->bsc_oml_hosts); + if (abis_open(bts, "OMLdummy") != 0) + exit(1); while (1) { osmo_select_main(0); diff --git a/src/osmo-bts-sysmo/Makefile.am b/src/osmo-bts-sysmo/Makefile.am index 1faf1221..12dea3b4 100644 --- a/src/osmo-bts-sysmo/Makefile.am +++ b/src/osmo-bts-sysmo/Makefile.am @@ -1,16 +1,62 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include $(SYSMOBTS_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBGPS_CFLAGS) \ + $(NULL) -EXTRA_DIST = misc/sysmobts_mgr.h misc/sysmobts_misc.h misc/sysmobts_par.h \ - misc/sysmobts_eeprom.h misc/sysmobts_nl.h femtobts.h hw_misc.h \ +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +EXTRA_DIST = \ + misc/sysmobts_mgr.h \ + misc/sysmobts_misc.h \ + misc/sysmobts_par.h \ + misc/sysmobts_eeprom.h \ + misc/sysmobts_nl.h \ misc/sysmobts-layer1.h \ - l1_fwd.h l1_if.h l1_transp.h eeprom.h utils.h + femtobts.h \ + hw_misc.h \ + l1_fwd.h \ + l1_if.h \ + l1_transp.h \ + eeprom.h \ + utils.h \ + $(NULL) bin_PROGRAMS = osmo-bts-sysmo osmo-bts-sysmo-remote l1fwd-proxy sysmobts-mgr sysmobts-util -COMMON_SOURCES = main.c femtobts.c l1_if.c oml.c sysmobts_vty.c tch.c hw_misc.c calib_file.c \ - eeprom.c calib_fixup.c utils.c misc/sysmobts_par.c sysmobts_ctrl.c +COMMON_SOURCES = \ + main.c \ + femtobts.c \ + l1_if.c \ + oml.c \ + sysmobts_vty.c \ + tch.c \ + hw_misc.c \ + calib_file.c \ + eeprom.c \ + calib_fixup.c \ + utils.c \ + misc/sysmobts_par.c \ + sysmobts_ctrl.c \ + $(NULL) + osmo_bts_sysmo_SOURCES = $(COMMON_SOURCES) l1_transp_hw.c osmo_bts_sysmo_LDADD = $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) @@ -37,7 +83,15 @@ sysmobts_mgr_SOURCES = \ misc/sysmobts_mgr_temp.c \ misc/sysmobts_mgr_calib.c \ eeprom.c -sysmobts_mgr_LDADD = $(LIBGPS_LIBS) $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) +sysmobts_mgr_LDADD = \ + $(LIBGPS_LIBS) \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(NULL) -sysmobts_util_SOURCES = misc/sysmobts_util.c misc/sysmobts_par.c eeprom.c +sysmobts_util_SOURCES = \ + misc/sysmobts_util.c \ + misc/sysmobts_par.c \ + eeprom.c \ + $(NULL) sysmobts_util_LDADD = $(LIBOSMOCORE_LIBS) diff --git a/src/osmo-bts-sysmo/calib_file.c b/src/osmo-bts-sysmo/calib_file.c index 2f723dd0..bb6cabfd 100644 --- a/src/osmo-bts-sysmo/calib_file.c +++ b/src/osmo-bts-sysmo/calib_file.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/femtobts.c b/src/osmo-bts-sysmo/femtobts.c index 480fe06b..7b02adc5 100644 --- a/src/osmo-bts-sysmo/femtobts.c +++ b/src/osmo-bts-sysmo/femtobts.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/hw_misc.c b/src/osmo-bts-sysmo/hw_misc.c index 6aa3b83f..21d8dfdf 100644 --- a/src/osmo-bts-sysmo/hw_misc.c +++ b/src/osmo-bts-sysmo/hw_misc.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/l1_fwd_main.c b/src/osmo-bts-sysmo/l1_fwd_main.c index db35ec3b..76c45e17 100644 --- a/src/osmo-bts-sysmo/l1_fwd_main.c +++ b/src/osmo-bts-sysmo/l1_fwd_main.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 5c998243..9ca1c323 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -344,7 +344,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, abort(); } - len = msgb_l2len(msg); + len = (msg->l2h) ? msgb_l2len(msg) : 0; chan_nr = l1sap->u.data.chan_nr; link_id = l1sap->u.data.link_id; @@ -392,9 +392,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, else sapi = GsmL1_Sapi_Agch; } else { - LOGPFN(DL1C, LOGL_NOTICE, u32Fn, "unknown prim %d op %d " - "chan_nr %d link_id %d\n", l1sap->oph.primitive, - l1sap->oph.operation, chan_nr, link_id); + LOGPLCFN(lchan, u32Fn, DL1C, LOGL_NOTICE, "unknown prim %d op %d " "chan_nr %d link_id %d\n", + l1sap->oph.primitive, l1sap->oph.operation, chan_nr, link_id); msgb_free(l1msg); return -EINVAL; } @@ -455,9 +454,8 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer, msg->l2h, msgb_l2len(msg)); } - LOGPFN(DL1P, LOGL_DEBUG, u32Fn, "PH-DATA.req(%s)\n", - osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, - l1p->u.phDataReq.msgUnitParam.u8Size)); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_DEBUG, "PH-DATA.req(%s)\n", + osmo_hexdump(l1p->u.phDataReq.msgUnitParam.u8Buffer, l1p->u.phDataReq.msgUnitParam.u8Size)); } else { /* empty frame */ GsmL1_Prim_t *l1p = msgb_l1prim(l1msg); @@ -467,7 +465,7 @@ static int ph_data_req(struct gsm_bts_trx *trx, struct msgb *msg, /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], l1msg) != 0) { - LOGPFN(DL1P, LOGL_ERROR, u32Fn, "MQ_L1_WRITE queue full. Dropping msg.\n"); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); msgb_free(l1msg); } else dtx_int_signal(lchan); @@ -505,7 +503,6 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, /* create new message and fill data */ if (msg) { - msgb_pull(msg, sizeof(*l1sap)); /* create new message */ nmsg = l1p_msgb_alloc(); if (!nmsg) @@ -514,7 +511,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, rc = l1if_tch_encode(lchan, l1p->u.phDataReq.msgUnitParam.u8Buffer, &l1p->u.phDataReq.msgUnitParam.u8Size, - msg->data, msg->len, u32Fn, use_cache, + msgb_l2(msg), msgb_l2len(msg), u32Fn, use_cache, l1sap->u.tch.marker); if (rc < 0) { /* no data encoded for L1: smth will be generated below */ @@ -551,7 +548,7 @@ static int ph_tch_req(struct gsm_bts_trx *trx, struct msgb *msg, } /* send message to DSP's queue */ if (osmo_wqueue_enqueue(&fl1->write_q[MQ_L1_WRITE], nmsg) != 0) { - LOGPFN(DL1P, LOGL_ERROR, u32Fn, "MQ_L1_WRITE queue full. Dropping msg.\n"); + LOGPLCFN(lchan, u32Fn, DL1P, LOGL_ERROR, "MQ_L1_WRITE queue full. Dropping msg.\n"); msgb_free(nmsg); return -ENOBUFS; } @@ -607,6 +604,15 @@ static int mph_info_req(struct gsm_bts_trx *trx, struct msgb *msg, else l1if_rsl_chan_rel(lchan); break; + case PRIM_INFO_ACT_UL_ACC: + case PRIM_INFO_DEACT_UL_ACC: + chan_nr = l1sap->u.info.u.ulacc_req.chan_nr; + lchan = get_lchan_by_chan_nr(trx, chan_nr); + if (l1sap->u.info.type == PRIM_INFO_ACT_UL_ACC) + l1if_set_ul_acc(lchan, true); + else + l1if_set_ul_acc(lchan, false); + break; default: LOGP(DL1C, LOGL_NOTICE, "unknown MPH-INFO.req %d\n", l1sap->u.info.type); @@ -981,6 +987,25 @@ static int handle_ph_data_ind(struct femtol1_hdl *fl1, GsmL1_PhDataInd_t *data_i return rc; } + /* If we got FACCH, the RTP clock needs to account for it, + * and if we have rtp continuous-streaming enabled, + * an actual BFI packet will be emitted. + * + * Only the case of TCH/F is currently handled; the task of + * supporting TCH/H is left as a FIXME for other/later + * developers. The difficulty with supporting FACCH/H is that + * only one GsmL1_Sapi_FacchH message will be received, + * covering 40 ms of time, but two RTP "tick" output calls + * will need to be made, with appropriately adjusted frame + * numbers. As a further consideration for rtp continuous-streaming + * mode, having the two RTP BFI packets sent directly back to back, + * as opposed to proper 20 ms timing, may be so undesirable + * that some deployments may rather disable TCH/H (use only TCH/F) + * than deal with the extra pain, or use TCH/H only on SDR-based + * BTS with osmo-bts-trx where correct timing is easily achieved. */ + if (data_ind->sapi == GsmL1_Sapi_FacchF) + l1if_tch_rx_facch(trx, chan_nr, l1p_msg); + /* fill L1SAP header */ sap_msg = l1sap_msgb_alloc(data_ind->msgUnitParam.u8Size); l1sap = msgb_l1sap_prim(sap_msg); @@ -1212,6 +1237,121 @@ int l1if_handle_sysprim(struct femtol1_hdl *fl1h, struct msgb *msg) return l1if_handle_ind(fl1h, msg); } +static void mute_handle_ts(struct gsm_bts_trx_ts *ts, int is_muted) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) { + struct gsm_lchan *lchan = &ts->lchan[i]; + + if (!is_muted) + continue; + + if (lchan->state != LCHAN_S_ACTIVE) + continue; + + /* skip channels that might be active for another reason */ + if (lchan->type == GSM_LCHAN_CCCH) + continue; + if (lchan->type == GSM_LCHAN_PDTCH) + continue; + + if (lchan->s <= 0) + continue; + + lchan->s = 0; + rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL); + } +} + +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3, 6, 0) +static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, + void *data) +{ + struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + SuperFemto_Prim_t *sysp = msgb_sysprim(resp); + GsmL1_Status_t status; + + status = sysp->u.muteRfCnf.status; + + if (status != GsmL1_Status_Success) { + LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n", + get_value_string(femtobts_l1status_names, status)); + if (trx->mo.fi->state != NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED) + oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0); + } else { + int i; + + LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", + get_value_string(femtobts_l1status_names, status)); + bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); + if (trx->mo.fi->state != NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED) + oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); + + osmo_static_assert( + ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute), + ts_array_size); + + for (i = 0; i < ARRAY_SIZE(fl1h->last_rf_mute); ++i) + mute_handle_ts(&trx->ts[i], fl1h->last_rf_mute[i]); + } + + msgb_free(resp); + + return 0; +} +#endif + +/* mute/unmute RF time slots */ +int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8], l1if_compl_cb *cb) +{ + + LOGP(DL1C, LOGL_INFO, "Tx RF-MUTE.req (%d, %d, %d, %d, %d, %d, %d, %d)\n", + mute[0], mute[1], mute[2], mute[3], + mute[4], mute[5], mute[6], mute[7] + ); + +#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(3, 6, 0) + const uint8_t unmuted[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + struct gsm_bts_trx *trx = hdl->phy_inst->trx; + int i; + LOGP(DL1C, LOGL_ERROR, "RF-MUTE.req not supported by SuperFemto\n"); + /* always acknowledge an un-MUTE (which is a no-op if MUTE is not supported */ + if (!memcmp(mute, unmuted, ARRAY_SIZE(unmuted))) { + bts_update_status(BTS_STATUS_RF_MUTE, mute[0]); + oml_mo_rf_lock_chg(&trx->mo, mute, 1); + for (i = 0; i < ARRAY_SIZE(unmuted); ++i) + mute_handle_ts(&trx->ts[i], mute[i]); + return 0; + } + return -ENOTSUP; +#else + struct msgb *msg = sysp_msgb_alloc(); + SuperFemto_Prim_t *sysp = msgb_sysprim(msg); + sysp->id = SuperFemto_PrimId_MuteRfReq; + memcpy(sysp->u.muteRfReq.u8Mute, mute, sizeof(sysp->u.muteRfReq.u8Mute)); + /* save for later use */ + memcpy(hdl->last_rf_mute, mute, sizeof(hdl->last_rf_mute)); + + return l1if_req_compl(hdl, msg, cb ? cb : mute_rf_compl_cb, NULL); +#endif /* < 3.6.0 */ +} + +static int activate_rf_mute_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) +{ +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3, 6, 0) + mute_rf_compl_cb(trx, resp, data); +#endif + + /* signal availability */ + osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL); + + return 0; +} + +int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb); + static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) { @@ -1236,12 +1376,14 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n", get_value_string(femtobts_l1status_names, status)); bts_shutdown(trx->bts, "RF-ACT failure"); - } else + } else { bts_update_status(BTS_STATUS_RF_ACTIVE, 1); - - /* signal availability */ - osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL); - osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL); +#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3, 6, 0) + trx_rf_lock(trx, 1, activate_rf_mute_compl_cb); +#else + activate_rf_mute_compl_cb(trx, resp, NULL); +#endif + } } else { bts_update_status(BTS_STATUS_RF_ACTIVE, 0); osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL); @@ -1339,104 +1481,6 @@ int l1if_activate_rf(struct femtol1_hdl *hdl, int on) return l1if_req_compl(hdl, msg, activate_rf_compl_cb, NULL); } -static void mute_handle_ts(struct gsm_bts_trx_ts *ts, int is_muted) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ts->lchan); i++) { - struct gsm_lchan *lchan = &ts->lchan[i]; - - if (!is_muted) - continue; - - if (lchan->state != LCHAN_S_ACTIVE) - continue; - - /* skip channels that might be active for another reason */ - if (lchan->type == GSM_LCHAN_CCCH) - continue; - if (lchan->type == GSM_LCHAN_PDTCH) - continue; - - if (lchan->s <= 0) - continue; - - lchan->s = 0; - rsl_tx_conn_fail(lchan, RSL_ERR_RADIO_LINK_FAIL); - } -} - -#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0) -static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, - void *data) -{ - struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); - SuperFemto_Prim_t *sysp = msgb_sysprim(resp); - GsmL1_Status_t status; - - status = sysp->u.muteRfCnf.status; - - if (status != GsmL1_Status_Success) { - LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n", - get_value_string(femtobts_l1status_names, status)); - oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0); - } else { - int i; - - LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n", - get_value_string(femtobts_l1status_names, status)); - bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]); - oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1); - - osmo_static_assert( - ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute), - ts_array_size); - - for (i = 0; i < ARRAY_SIZE(fl1h->last_rf_mute); ++i) - mute_handle_ts(&trx->ts[i], fl1h->last_rf_mute[i]); - } - - msgb_free(resp); - - return 0; -} -#endif - -/* mute/unmute RF time slots */ -int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8], l1if_compl_cb *cb) -{ - - LOGP(DL1C, LOGL_INFO, "Tx RF-MUTE.req (%d, %d, %d, %d, %d, %d, %d, %d)\n", - mute[0], mute[1], mute[2], mute[3], - mute[4], mute[5], mute[6], mute[7] - ); - -#if SUPERFEMTO_API_VERSION < SUPERFEMTO_API(3,6,0) - const uint8_t unmuted[8] = { 0,0,0,0,0,0,0,0 }; - struct gsm_bts_trx *trx = hdl->phy_inst->trx; - int i; - LOGP(DL1C, LOGL_ERROR, "RF-MUTE.req not supported by SuperFemto\n"); - /* always acknowledge an un-MUTE (which is a no-op if MUTE is not supported */ - if (!memcmp(mute, unmuted, ARRAY_SIZE(unmuted))) { - bts_update_status(BTS_STATUS_RF_MUTE, mute[0]); - oml_mo_rf_lock_chg(&trx->mo, mute, 1); - for (i = 0; i < ARRAY_SIZE(unmuted); ++i) - mute_handle_ts(&trx->ts[i], mute[i]); - return 0; - } - return -ENOTSUP; -#else - struct msgb *msg = sysp_msgb_alloc(); - SuperFemto_Prim_t *sysp = msgb_sysprim(msg); - sysp->id = SuperFemto_PrimId_MuteRfReq; - memcpy(sysp->u.muteRfReq.u8Mute, mute, sizeof(sysp->u.muteRfReq.u8Mute)); - /* save for later use */ - memcpy(hdl->last_rf_mute, mute, sizeof(hdl->last_rf_mute)); - - return l1if_req_compl(hdl, msg, cb ? cb : mute_rf_compl_cb, NULL); -#endif /* < 3.6.0 */ -} - /* call-back on arrival of DSP+FPGA version + band capability */ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, void *data) @@ -1458,10 +1502,12 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, fl1h->hw_info.ver_minor = sic->boardVersion.option; #endif - LOGP(DL1C, LOGL_INFO, "DSP v%u.%u.%u, FPGA v%u.%u.%u\nn", - sic->dspVersion.major, sic->dspVersion.minor, - sic->dspVersion.build, sic->fpgaVersion.major, - sic->fpgaVersion.minor, sic->fpgaVersion.build); + snprintf(trx->pinst->version, sizeof(trx->pinst->version), "%u.%u dsp %u.%u.%u fpga %u.%u.%u", + fl1h->hw_info.ver_major, fl1h->hw_info.ver_minor, + fl1h->hw_info.dsp_version[0], fl1h->hw_info.dsp_version[1], fl1h->hw_info.dsp_version[2], + fl1h->hw_info.fpga_version[0], fl1h->hw_info.fpga_version[1], fl1h->hw_info.fpga_version[2]); + + LOGP(DL1C, LOGL_INFO, "%s\n", trx->pinst->version); #ifdef HW_SYSMOBTS_V1 if (sic->rfBand.gsm850) @@ -1497,6 +1543,8 @@ static int info_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp, msgb_free(resp); + phy_link_state_set(trx->pinst->phy_link, PHY_LINK_CONNECTED); + /* FIXME: clock related */ return 0; } @@ -1898,12 +1946,28 @@ int bts_model_phy_link_open(struct phy_link *plink) hdl = pinst->u.sysmobts.hdl; osmo_strlcpy(bts->sub_model, sysmobts_model(hdl->hw_info.model_nr, hdl->hw_info.trx_nr), sizeof(bts->sub_model)); - snprintf(pinst->version, sizeof(pinst->version), "%u.%u dsp %u.%u.%u fpga %u.%u.%u", - hdl->hw_info.ver_major, hdl->hw_info.ver_minor, - hdl->hw_info.dsp_version[0], hdl->hw_info.dsp_version[1], hdl->hw_info.dsp_version[2], - hdl->hw_info.fpga_version[0], hdl->hw_info.fpga_version[1], hdl->hw_info.fpga_version[2]); - phy_link_state_set(plink, PHY_LINK_CONNECTED); + /* Frequency bands indicated to the BSC */ + for (unsigned int i = 0; i < sizeof(hdl->hw_info.band_support) * 8; i++) { + if (~hdl->hw_info.band_support & (1 << i)) + continue; + switch (1 << i) { + case GSM_BAND_850: + pinst->trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_850; + break; + case GSM_BAND_900: + pinst->trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PGSM; + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_EGSM? */ + /* XXX: does GSM_BAND_900 include NM_IPAC_F_FREQ_BAND_RGSM? */ + break; + case GSM_BAND_1800: + pinst->trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_DCS; + break; + case GSM_BAND_1900: + pinst->trx->support.freq_bands |= NM_IPAC_F_FREQ_BAND_PCS; + break; + } + } return 0; } diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h index 8691eef8..c81b6bd4 100644 --- a/src/osmo-bts-sysmo/l1_if.h +++ b/src/osmo-bts-sysmo/l1_if.h @@ -129,6 +129,8 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool use_cache, bool marker); int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg); +int l1if_tch_rx_facch(struct gsm_bts_trx *trx, uint8_t chan_nr, + struct msgb *l1p_msg); int l1if_tch_fill(struct gsm_lchan *lchan, uint8_t *l1_buffer); struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn); @@ -143,6 +145,7 @@ int l1if_rsl_chan_rel(struct gsm_lchan *lchan); int l1if_rsl_chan_mod(struct gsm_lchan *lchan); int l1if_rsl_deact_sacch(struct gsm_lchan *lchan); int l1if_rsl_mode_modify(struct gsm_lchan *lchan); +int l1if_set_ul_acc(struct gsm_lchan *lchan, bool active); /* calibration loading */ int calib_load(struct femtol1_hdl *fl1h); diff --git a/src/osmo-bts-sysmo/l1_transp_fwd.c b/src/osmo-bts-sysmo/l1_transp_fwd.c index ef272eb1..ac510eda 100644 --- a/src/osmo-bts-sysmo/l1_transp_fwd.c +++ b/src/osmo-bts-sysmo/l1_transp_fwd.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/l1_transp_hw.c b/src/osmo-bts-sysmo/l1_transp_hw.c index 7df74eb5..cfbc77c9 100644 --- a/src/osmo-bts-sysmo/l1_transp_hw.c +++ b/src/osmo-bts-sysmo/l1_transp_hw.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index 2bf10687..20b425da 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -60,32 +60,54 @@ int bts_model_init(struct gsm_bts *bts) bts->variant = BTS_OSMO_SYSMO; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS + | NM_IPAC_MASK_GPRS_CODING_MCS; if (stat(SYSMOBTS_RF_LOCK_PATH, &st) == 0) { LOGP(DL1C, LOGL_NOTICE, "Not starting BTS due to RF_LOCK file present\n"); exit(23); } + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); - osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); - osmo_bts_set_feature(bts->features, BTS_FEAT_AGCH_PCH_PROP); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); + osmo_bts_set_feature(bts->features, BTS_FEAT_VBS); + osmo_bts_set_feature(bts->features, BTS_FEAT_VGCS); - bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB); + bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MS_PWR_CTRL_DSP); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_NM_RCHANNEL_DEPENDS_RCARRIER); + /* The default HR codec output format in the absence of saved + * vty config needs to match what was implemented previously, + * for the sake of existing deployments, i.e., to avoid + * a surprise functional change upon software update. */ + bts->emit_hr_rfc5993 = false; + return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = 0x00; /* updated in bts_model_phy_link_open() */ + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH + | NM_IPAC_F_CHANT_SDCCH8_CBCH + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH; + return 0; } diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c index 60779910..79bbf77e 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -288,7 +288,7 @@ int main(int argc, char **argv) exit(1); } - rc = telnet_init(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); + rc = telnet_init_default(tall_mgr_ctx, NULL, OSMO_VTY_PORT_BTSMGR); if (rc < 0) { fprintf(stderr, "Error initializing telnet\n"); exit(1); diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c index 12961e3f..45b024e1 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_2050.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c index 6ea28763..ac35f392 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_calib.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -541,8 +541,8 @@ int sysmobts_mgr_calib_init(struct sysmobts_mgr_instance *mgr) return 0; } - mgr->calib.bts_conn = ipa_client_conn_create(tall_mgr_ctx, NULL, 0, - "localhost", 4238, + mgr->calib.bts_conn = ipa_client_conn_create2(tall_mgr_ctx, NULL, 0, + NULL, 0, "localhost", 4238, bts_updown_cb, bts_read_cb, NULL, mgr); if (!mgr->calib.bts_conn) { diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c index 48a03124..fead4f27 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_nl.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c index 1be56ac2..eea68793 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_temp.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -233,7 +233,7 @@ static void sysmobts_mgr_temp_handle(struct sysmobts_mgr_instance *manager, rep->variable = "oml-alert"; rep->value = oml_alert; LOGP(DTEMP, LOGL_ERROR, "OML alert sent: %d\n", - ctrl_cmd_send(&ctrl->write_queue, rep)); + ctrl_cmd_send2(ctrl, rep)); talloc_free(rep); } diff --git a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c index fb3987bf..33cf0dcb 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_mgr_vty.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -69,28 +69,10 @@ static int go_to_parent(struct vty *vty) return vty->node; } -static int is_config_node(struct vty *vty, int node) -{ - switch (node) { - case MGR_NODE: - case ACT_NORM_NODE: - case ACT_WARN_NODE: - case ACT_CRIT_NODE: - case LIMIT_RF_NODE: - case LIMIT_DIGITAL_NODE: - case LIMIT_BOARD_NODE: - case LIMIT_PA_NODE: - return 1; - default: - return 0; - } -} - static struct vty_app_info vty_info = { .name = "sysmobts-mgr", .version = PACKAGE_VERSION, .go_parent_cb = go_to_parent, - .is_config_node = is_config_node, .copyright = copyright, }; diff --git a/src/osmo-bts-sysmo/misc/sysmobts_misc.c b/src/osmo-bts-sysmo/misc/sysmobts_misc.c index ae59d787..b391ce66 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_misc.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_misc.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_nl.c b/src/osmo-bts-sysmo/misc/sysmobts_nl.c index 67aa6636..5a937dcb 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_nl.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_nl.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_nl.h b/src/osmo-bts-sysmo/misc/sysmobts_nl.h index 84f4d9cc..5dda4679 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_nl.h +++ b/src/osmo-bts-sysmo/misc/sysmobts_nl.h @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_par.c b/src/osmo-bts-sysmo/misc/sysmobts_par.c index f1fe8f2d..0e8685f3 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_par.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_par.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/misc/sysmobts_util.c b/src/osmo-bts-sysmo/misc/sysmobts_util.c index c9930d8f..bd751431 100644 --- a/src/osmo-bts-sysmo/misc/sysmobts_util.c +++ b/src/osmo-bts-sysmo/misc/sysmobts_util.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 93ecf902..b4f6752d 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -46,6 +46,8 @@ #include "femtobts.h" #include "utils.h" +static void dump_lch_par(int logl, GsmL1_LogChParam_t *lch_par, GsmL1_Sapi_t sapi); + static int mph_info_chan_confirm(struct gsm_lchan *lchan, enum osmo_mph_info_type type, uint8_t cause) { @@ -96,7 +98,7 @@ static const enum GsmL1_LogChComb_t pchan_to_logChComb[_GSM_PCHAN_MAX] = { */ }; -static int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb); +int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb); static void *prim_init(GsmL1_Prim_t *prim, GsmL1_PrimId_t id, struct femtol1_hdl *gl1, HANDLE hLayer3) @@ -339,6 +341,8 @@ static int trx_mute_on_init_cb(struct gsm_bts_trx *trx, struct msgb *resp, bts_shutdown(trx->bts, "RF-MUTE failure"); } + bts_update_status(BTS_STATUS_RF_MUTE, 1); + msgb_free(resp); return 0; @@ -479,7 +483,7 @@ void bts_model_trx_close(struct gsm_bts_trx *trx) bts_model_trx_close_cb(trx, rc); } -static int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb) +int trx_rf_lock(struct gsm_bts_trx *trx, int locked, l1if_compl_cb *cb) { struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); uint8_t mute[8]; @@ -534,10 +538,9 @@ static int ts_connect_as(struct gsm_bts_trx_ts *ts, cr->u8Tn = ts->nr; cr->logChComb = pchan_to_logChComb[pchan]; - DEBUGP(DL1C, "%s pchan=%s ts_connect_as(%s) logChComb=%s\n", - gsm_lchan_name(ts->lchan), gsm_pchan_name(ts->pchan), - gsm_pchan_name(pchan), get_value_string(femtobts_chcomb_names, - cr->logChComb)); + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "pchan=%s ts_connect_as(%s) logChComb=%s\n", + gsm_pchan_name(ts->pchan), gsm_pchan_name(pchan), + get_value_string(femtobts_chcomb_names, cr->logChComb)); return l1if_gsm_req_compl(fl1h, msg, cb, NULL); } @@ -570,8 +573,7 @@ GsmL1_Sapi_t lchan_to_GsmL1_Sapi_t(const struct gsm_lchan *lchan) case GSM_LCHAN_TCH_H: return GsmL1_Sapi_TchH; default: - LOGP(DL1C, LOGL_NOTICE, "%s cannot determine L1 SAPI\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "cannot determine L1 SAPI\n"); break; } return GsmL1_Sapi_Idle; @@ -783,12 +785,8 @@ static void sapi_queue_dispatch(struct gsm_lchan *lchan, int status) talloc_free(cmd); if (end || llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_DEBUG, - "%s End of SAPI cmd queue encountered.%s\n", - gsm_lchan_name(lchan), - llist_empty(&lchan->sapi_cmds) - ? " Queue is now empty." - : " More pending."); + LOGPLCHAN(lchan, DL1C, LOGL_DEBUG, "End of SAPI cmd queue encountered.%s\n", + llist_empty(&lchan->sapi_cmds) ? " Queue is now empty." : " More pending."); return; } @@ -828,8 +826,7 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.conf (%s ", - gsm_lchan_name(lchan), + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.conf (%s ", get_value_string(femtobts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(femtobts_dir_names, ic->dir)); @@ -851,19 +848,15 @@ static int lchan_act_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, lchan->sapis_ul[ic->sapi] = status; if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_ACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -950,8 +943,7 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) (struct gsm48_multi_rate_conf *) amr_mrc->gsm48_ie; int j; - LOGP(DL1C, LOGL_INFO, "%s: %s tch_mode=0x%02x\n", - gsm_lchan_name(lchan), __FUNCTION__, lchan->tch_mode); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, ": %s tch_mode=0x%02x\n", __func__, lchan->tch_mode); switch (lchan->tch_mode) { case GSM48_CMODE_SIGN: @@ -979,7 +971,9 @@ static int lchan2lch_par(GsmL1_LogChParam_t *lch_par, struct gsm_lchan *lchan) case GSM48_CMODE_SPEECH_AMR: lch_par->tch.tchPlType = GsmL1_TchPlType_Amr; set_payload_format(lch_par); - lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; /* FIXME? */ + /* At call set-up, after every successful handover and after a channel mode modify, the + * default phase (odd) shall be used in downlink direction. */ + lch_par->tch.amrCmiPhase = GsmL1_AmrCmiPhase_Odd; lch_par->tch.amrInitCodecMode = amr_get_initial_mode(lchan); /* initialize to clean state */ @@ -1102,9 +1096,9 @@ static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd) break; } - LOGP(DL1C, LOGL_INFO, "%s MPH-ACTIVATE.req (hL2=0x%08x, %s ", - gsm_lchan_name(lchan), act_req->hLayer2, - get_value_string(femtobts_l1sapi_names, act_req->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-ACTIVATE.req (hL2=0x%08x, %s ", act_req->hLayer2, + get_value_string(femtobts_l1sapi_names, act_req->sapi)); + dump_lch_par(LOGL_INFO, lch_par, act_req->sapi); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(femtobts_dir_names, act_req->dir)); @@ -1128,9 +1122,7 @@ static int sapi_activate_cb(struct gsm_lchan *lchan, int status) /* FIXME: Error handling */ if (status != GsmL1_Status_Success) { - LOGP(DL1C, LOGL_ERROR, - "%s act failed mark broken due status: %d\n", - gsm_lchan_name(lchan), status); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "act failed mark broken due status: %d\n", status); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_ACTIVATE, RSL_ERR_PROCESSOR_OVERLOAD); @@ -1177,12 +1169,10 @@ int lchan_activate(struct gsm_lchan *lchan) lchan_set_state(lchan, LCHAN_S_ACT_REQ); if (!llist_empty(&lchan->sapi_cmds)) - LOGP(DL1C, LOGL_ERROR, - "%s Trying to activate lchan, but commands in queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Trying to activate lchan, but commands in queue\n"); /* For handover, always start the main channel immediately. lchan->want_dl_sacch_active indicates whether dl - * SACCH should be activated. Also, for HO, start the RACH SAPI. */ + * SACCH should be activated. */ if (lchan->ho.active == HANDOVER_ENABLED) enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink); @@ -1204,10 +1194,6 @@ int lchan_activate(struct gsm_lchan *lchan) continue; enqueue_sapi_act_cmd(lchan, sapi, dir); } - -#warning "FIXME: Should this be in sapi_activate_cb?" - lchan_init_lapdm(lchan); - return 0; } @@ -1293,9 +1279,8 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.conf (%s) ", - gsm_lchan_name(lchan), - get_value_string(femtobts_l1cfgt_names, cc->cfgParamId)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.conf (%s) ", + get_value_string(femtobts_l1cfgt_names, cc->cfgParamId)); switch (cc->cfgParamId) { case GsmL1_ConfigParamId_SetLogChParams: @@ -1327,9 +1312,7 @@ static int chmod_modif_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, break; } if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got ciphering conf with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got ciphering conf with empty queue\n"); goto err; } @@ -1380,10 +1363,8 @@ static int mph_send_config_logchpar(struct gsm_lchan *lchan, struct sapi_cmd *cm /* FIXME: update encryption */ - LOGP(DL1C, LOGL_INFO, "%s MPH-CONFIG.req (%s) ", - gsm_lchan_name(lchan), - get_value_string(femtobts_l1sapi_names, - conf_req->cfgParams.setLogChParams.sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-CONFIG.req (%s) ", + get_value_string(femtobts_l1sapi_names, conf_req->cfgParams.setLogChParams.sapi)); LOGPC(DL1C, LOGL_INFO, "cfgParams Tn=%u, subCh=%u, dir=0x%x ", conf_req->cfgParams.setLogChParams.u8Tn, conf_req->cfgParams.setLogChParams.subCh, @@ -1450,11 +1431,9 @@ static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *c return -EINVAL; cfgr->cfgParams.setCipheringParams.cipherId = rsl2l1_ciph[lchan->encr.alg_id]; - LOGP(DL1C, LOGL_NOTICE, "%s SET_CIPHERING (ALG=%u %s)\n", - gsm_lchan_name(lchan), - cfgr->cfgParams.setCipheringParams.cipherId, - get_value_string(femtobts_dir_names, - cfgr->cfgParams.setCipheringParams.dir)); + LOGPLCHAN(lchan, DL1C, LOGL_NOTICE, "SET_CIPHERING (ALG=%u %s)\n", + cfgr->cfgParams.setCipheringParams.cipherId, + get_value_string(femtobts_dir_names, cfgr->cfgParams.setCipheringParams.dir)); memcpy(cfgr->cfgParams.setCipheringParams.u8Kc, lchan->encr.key, lchan->encr.key_len); @@ -1491,6 +1470,16 @@ int l1if_set_ciphering(struct femtol1_hdl *fl1h, return 0; } +int l1if_set_ul_acc(struct gsm_lchan *lchan, bool active) +{ + if (active) + enqueue_sapi_act_cmd(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink); + else + check_sapi_release(lchan, GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink); + + return 0; +} + int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan) { if (lchan->state != LCHAN_S_ACTIVE) @@ -1532,9 +1521,8 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, goto err; } - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.conf (%s ", - gsm_lchan_name(lchan), - get_value_string(femtobts_l1sapi_names, ic->sapi)); + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.conf (%s ", + get_value_string(femtobts_l1sapi_names, ic->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(femtobts_dir_names, ic->dir)); @@ -1556,19 +1544,15 @@ static int lchan_deact_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, if (llist_empty(&lchan->sapi_cmds)) { - LOGP(DL1C, LOGL_ERROR, - "%s Got de-activation confirmation with empty queue\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Got de-activation confirmation with empty queue\n"); goto err; } cmd = llist_entry(lchan->sapi_cmds.next, struct sapi_cmd, entry); if (cmd->sapi != ic->sapi || cmd->dir != ic->dir || cmd->type != SAPI_CMD_DEACTIVATE) { - LOGP(DL1C, LOGL_ERROR, - "%s Confirmation mismatch (%d, %d) (%d, %d)\n", - gsm_lchan_name(lchan), cmd->sapi, cmd->dir, - ic->sapi, ic->dir); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Confirmation mismatch (%d, %d) (%d, %d)\n", + cmd->sapi, cmd->dir, ic->sapi, ic->dir); goto err; } @@ -1593,8 +1577,7 @@ static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd deact_req->sapi = cmd->sapi; deact_req->hLayer3 = l1if_lchan_to_hLayer(lchan); - LOGP(DL1C, LOGL_INFO, "%s MPH-DEACTIVATE.req (%s ", - gsm_lchan_name(lchan), + LOGPLCHAN(lchan, DL1C, LOGL_INFO, "MPH-DEACTIVATE.req (%s ", get_value_string(femtobts_l1sapi_names, deact_req->sapi)); LOGPC(DL1C, LOGL_INFO, "%s)\n", get_value_string(femtobts_dir_names, deact_req->dir)); @@ -1607,8 +1590,7 @@ static int sapi_deactivate_cb(struct gsm_lchan *lchan, int status) { /* FIXME: Error handling. There is no NACK... */ if (status != GsmL1_Status_Success && lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s is now broken. Stopping the release.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "is now broken. Stopping the release.\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); sapi_clear_queue(&lchan->sapi_cmds); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); @@ -1693,8 +1675,7 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) /* nothing was queued */ if (res == 0) { - LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "all SAPIs already released?\n"); lchan_set_state(lchan, LCHAN_S_BROKEN); mph_info_chan_confirm(lchan, PRIM_INFO_DEACTIVATE, 0); } @@ -1745,60 +1726,52 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { - if (kind == NM_OC_RADIO_CARRIER) { - struct gsm_bts_trx *trx = obj; - struct femtol1_hdl *fl1h = trx_femtol1_hdl(trx); + struct abis_om_fom_hdr *foh = msgb_l3(msg); + struct gsm_bts_trx *trx; + struct femtol1_hdl *fl1h; + + switch (foh->msg_type) { + case NM_MT_SET_RADIO_ATTR: + trx = obj; + fl1h = trx_femtol1_hdl(trx); /* Did we go through MphInit yet? If yes fire and forget */ if (fl1h->hLayer1) power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL); + break; } - /* FIXME: we actually need to send a ACK or NACK for the OML message */ - return oml_fom_ack_nack(msg, 0); + return 0; } /* callback from OML */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { - struct gsm_bts_bb_trx *bb_transc; struct gsm_bts_trx* trx; struct gsm_bts_trx_ts *ts; int rc; switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); - oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nse.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.cell.mo, -1, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK); + case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: + case NM_OC_GPRS_CELL: + case NM_OC_GPRS_NSVC: + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: trx = (struct gsm_bts_trx *) obj; rc = trx_init(trx); break; - case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: ts = (struct gsm_bts_trx_ts*) obj; rc = ts_opstart(ts); break; - case NM_OC_GPRS_NSE: - case NM_OC_GPRS_CELL: - case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); - rc = oml_mo_opstart_ack(mo); - break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); } @@ -1871,8 +1844,7 @@ int l1if_rsl_chan_mod(struct gsm_lchan *lchan) if (lchan->ho.active == HANDOVER_NONE) return -1; - LOGP(DHO, LOGL_ERROR, "%s modifying channel for handover\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DHO, LOGL_ERROR, "modifying channel for handover\n"); /* Give up listening to RACH bursts */ release_sapi_ul_rach(lchan); @@ -1897,8 +1869,7 @@ int l1if_rsl_chan_rel(struct gsm_lchan *lchan) { /* A duplicate RF Release Request, ignore it */ if (lchan->state == LCHAN_S_REL_REQ) { - LOGP(DL1C, LOGL_ERROR, "%s already in release request state.\n", - gsm_lchan_name(lchan)); + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "already in release request state.\n"); return 0; } @@ -1934,8 +1905,7 @@ static int ts_disconnect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - LOGP(DL1C, LOGL_DEBUG, "%s Rx mphDisconnectCnf\n", - gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "Rx mphDisconnectCnf\n"); cb_ts_disconnected(ts); @@ -1948,7 +1918,7 @@ int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) struct femtol1_hdl *fl1h = trx_femtol1_hdl(ts->trx); GsmL1_MphDisconnectReq_t *cr; - DEBUGP(DRSL, "%s TS disconnect\n", gsm_lchan_name(ts->lchan)); + LOGPLCHAN(ts->lchan, DRSL, LOGL_DEBUG, "TS disconnect\n"); cr = prim_init(msgb_l1prim(msg), GsmL1_PrimId_MphDisconnectReq, fl1h, l1p_handle_for_ts(ts)); cr->u8Tn = ts->nr; @@ -1964,8 +1934,7 @@ static int ts_connect_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg, struct gsm_bts_trx_ts *ts = &trx->ts[cnf->u8Tn]; OSMO_ASSERT(cnf->u8Tn < TRX_NR_TS); - DEBUGP(DL1C, "%s %s Rx mphConnectCnf flags=%s%s%s\n", - gsm_lchan_name(ts->lchan), + LOGPLCHAN(ts->lchan, DL1C, LOGL_DEBUG, "%s Rx mphConnectCnf flags=%s%s%s\n", gsm_pchan_name(ts->pchan), ts->flags & TS_F_PDCH_ACTIVE ? "ACTIVE " : "", ts->flags & TS_F_PDCH_ACT_PENDING ? "ACT_PENDING " : "", diff --git a/src/osmo-bts-sysmo/sysmobts_ctrl.c b/src/osmo-bts-sysmo/sysmobts_ctrl.c index c6dac58c..6beeaf62 100644 --- a/src/osmo-bts-sysmo/sysmobts_ctrl.c +++ b/src/osmo-bts-sysmo/sysmobts_ctrl.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-sysmo/sysmobts_vty.c b/src/osmo-bts-sysmo/sysmobts_vty.c index a8e7401f..2e853356 100644 --- a/src/osmo-bts-sysmo/sysmobts_vty.c +++ b/src/osmo-bts-sysmo/sysmobts_vty.c @@ -226,7 +226,7 @@ DEFUN(show_phy_clksrc, show_trx_clksrc_cmd, } DEFUN(show_dsp_trace_f, show_dsp_trace_f_cmd, - "show trx <0-0> dsp-trace-flags", + "show dsp-trace-flags trx <0-0>", SHOW_TRX_STR "Display the current setting of the DSP trace flags") { int trx_nr = atoi(argv[0]); diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c index eb719f1d..2cf784e6 100644 --- a/src/osmo-bts-sysmo/tch.c +++ b/src/osmo-bts-sysmo/tch.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -77,7 +77,7 @@ static struct msgb *l1_to_rtppayload_fr(uint8_t *l1_payload, uint8_t payload_len cur[0] |= 0xD0; #endif /* USE_L1_RTP_MODE */ - lchan_set_marker(osmo_fr_check_sid(l1_payload, payload_len), lchan); + lchan_set_marker(osmo_fr_is_any_sid(l1_payload), lchan); return msg; } @@ -131,12 +131,8 @@ static struct msgb *l1_to_rtppayload_efr(uint8_t *l1_payload, cur[0] |= 0xC0; #endif /* USE_L1_RTP_MODE */ - enum osmo_amr_type ft; - enum osmo_amr_quality bfi; - uint8_t cmr; - int8_t sti, cmi; - osmo_amr_rtp_dec(l1_payload, payload_len, &cmr, &cmi, &ft, &bfi, &sti); - lchan_set_marker(ft == AMR_GSM_EFR_SID, lchan); + + lchan_set_marker(osmo_efr_is_any_sid(l1_payload), lchan); return msg; } @@ -298,7 +294,7 @@ static struct msgb *l1_to_rtppayload_amr(uint8_t *l1_payload, uint8_t payload_le LOGP(DL1P, LOGL_NOTICE, "L1->RTP: overriding CMR IDX %u\n", cmr_idx); cmr = AMR_CMR_NONE; } else { - cmr = amr_mrc->bts_mode[cmr_idx].mode; + cmr = amr_mrc->mode[cmr_idx].mode; lchan->tch.last_cmr = cmr; } @@ -403,7 +399,10 @@ int l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len, *payload_type = GsmL1_TchPlType_Efr; rc = rtppayload_to_l1_efr(l1_payload, rtp_pl, rtp_pl_len); - /* FIXME: detect and save EFR SID */ + if (rc && lchan->ts->trx->bts->dtxd) + is_sid = osmo_efr_check_sid(rtp_pl, rtp_pl_len); + if (is_sid) + dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, -1); break; #endif case GSM48_CMODE_SPEECH_AMR: @@ -505,7 +504,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) { GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg); GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; - uint8_t *payload, payload_type, payload_len, sid_first[9] = { 0 }; + uint8_t *payload, payload_type, payload_len; struct msgb *rmsg = NULL; struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; @@ -513,7 +512,7 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return -EAGAIN; if (data_ind->msgUnitParam.u8Size < 1) { - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "chan_nr %d Rx Payload size 0\n", chan_nr); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "chan_nr %d Rx Payload size 0\n", chan_nr); /* Push empty payload to upper layers */ rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, @@ -549,6 +548,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) if (lchan->type != GSM_LCHAN_TCH_H && lchan->type != GSM_LCHAN_TCH_F) goto err_payload_match; + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received ONSET from L1 " "(%d bytes)\n", + payload_len); /* according to 3GPP TS 26.093 ONSET frames precede the first speech frame of a speech burst - set the marker for next RTP frame */ @@ -557,33 +558,32 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) case GsmL1_TchPlType_Amr_SidFirstP1: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P1 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P1 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstP2: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_P2 from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_P2 from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidFirstInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_FIRST_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_FIRST_INH from L1 " + "(%d bytes)\n", payload_len); break; case GsmL1_TchPlType_Amr_SidUpdateInH: if (lchan->type != GSM_LCHAN_TCH_H) goto err_payload_match; lchan->rtp_tx_marker = true; - LOGPFN(DL1P, LOGL_DEBUG, data_ind->u32Fn, "DTX: received SID_UPDATE_INH from L1 " - "(%d bytes)\n", payload_len); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "DTX: received SID_UPDATE_INH from L1 " + "(%d bytes)\n", payload_len); break; default: - LOGPFN(DL1P, LOGL_NOTICE, data_ind->u32Fn, "%s Rx Payload Type %s is unsupported\n", - gsm_lchan_name(lchan), - get_value_string(femtobts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_NOTICE, "%s Rx Payload Type %s is unsupported\n", + gsm_lchan_name(lchan), get_value_string(femtobts_tch_pl_names, payload_type)); break; } @@ -601,14 +601,8 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) break; #endif case GsmL1_TchPlType_Amr: - rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); - break; case GsmL1_TchPlType_Amr_SidFirstP1: - memcpy(sid_first, payload, payload_len); - int len = osmo_amr_rtp_enc(sid_first, 0, AMR_SID, AMR_GOOD); - if (len < 0) - return 0; - rmsg = l1_to_rtppayload_amr(sid_first, len, lchan); + rmsg = l1_to_rtppayload_amr(payload, payload_len, lchan); break; /* FIXME: what about GsmL1_TchPlType_Amr_SidBad? not well documented. */ } @@ -624,12 +618,34 @@ int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg) return 0; err_payload_match: - LOGPFN(DL1P, LOGL_ERROR, data_ind->u32Fn, "%s Rx Payload Type %s incompatible with lchan\n", - gsm_lchan_name(lchan), - get_value_string(femtobts_tch_pl_names, payload_type)); + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_ERROR, "%s Rx Payload Type %s incompatible with lchan\n", + gsm_lchan_name(lchan), get_value_string(femtobts_tch_pl_names, payload_type)); return -EINVAL; } +/*! \brief provide an RTP empty payload "tick" to upper layers upon FACCH */ +int l1if_tch_rx_facch(struct gsm_bts_trx *trx, uint8_t chan_nr, + struct msgb *l1p_msg) +{ + GsmL1_Prim_t *l1p = msgb_l1prim(l1p_msg); + GsmL1_PhDataInd_t *data_ind = &l1p->u.phDataInd; + struct msgb *rmsg = NULL; + struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)].lchan[l1sap_chan2ss(chan_nr)]; + + if (is_recv_only(lchan->abis_ip.speech_mode)) + return -EAGAIN; + + LOGPLCFN(lchan, data_ind->u32Fn, DL1P, LOGL_DEBUG, "chan_nr %d Rx FACCH\n", chan_nr); + /* Push empty payload to upper layers */ + rmsg = msgb_alloc_headroom(256, 128, "L1P-to-RTP"); + return add_l1sap_header(trx, rmsg, lchan, chan_nr, data_ind->u32Fn, + data_ind->measParam.fBer * 10000, + data_ind->measParam.fLinkQuality * 10, + 0, /* suppress RSSI like in osmo-bts-trx */ + data_ind->measParam.i16BurstTiming * 64, + 0); +} + struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn) { struct msgb *msg; diff --git a/src/osmo-bts-sysmo/utils.c b/src/osmo-bts-sysmo/utils.c index 0e3ef273..735ebe0e 100644 --- a/src/osmo-bts-sysmo/utils.c +++ b/src/osmo-bts-sysmo/utils.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-trx/Makefile.am b/src/osmo-bts-trx/Makefile.am index 54d1af9e..63c00fec 100644 --- a/src/osmo-bts-trx/Makefile.am +++ b/src/osmo-bts-trx/Makefile.am @@ -1,6 +1,7 @@ AM_CPPFLAGS = \ $(all_includes) \ -I$(top_srcdir)/include \ + -I$(top_builddir)/include \ $(NULL) AM_CFLAGS = \ @@ -10,9 +11,10 @@ AM_CFLAGS = \ $(LIBOSMOCODEC_CFLAGS) \ $(LIBOSMOCODING_CFLAGS) \ $(LIBOSMOVTY_CFLAGS) \ - $(LIBOSMOTRAU_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) \ $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ $(NULL) LDADD = \ @@ -21,9 +23,10 @@ LDADD = \ $(LIBOSMOCODEC_LIBS) \ $(LIBOSMOCODING_LIBS) \ $(LIBOSMOVTY_LIBS) \ - $(LIBOSMOTRAU_LIBS) \ - $(LIBOSMOABIS_LIBS) \ $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ -ldl \ $(NULL) @@ -31,7 +34,7 @@ noinst_HEADERS = \ sched_utils.h \ trx_if.h \ l1_if.h \ - loops.h \ + amr_loop.h \ trx_provision_fsm.h \ $(NULL) @@ -50,7 +53,8 @@ osmo_bts_trx_SOURCES = \ sched_lchan_tchh.c \ trx_provision_fsm.c \ trx_vty.c \ - loops.c \ + amr_loop.c \ + probes.d \ $(NULL) osmo_bts_trx_LDADD = \ @@ -58,3 +62,14 @@ osmo_bts_trx_LDADD = \ $(top_builddir)/src/common/libbts.a \ $(LDADD) \ $(NULL) + +if ENABLE_SYSTEMTAP +probes.h: probes.d + $(DTRACE) -C -h -s $< -o $@ + +probes.lo: probes.d + $(LIBTOOL) --mode=compile $(AM_V_lt) --tag=CC env CFLAGS="$(CFLAGS)" $(DTRACE) -C -G -s $< -o $@ + +BUILT_SOURCES = probes.h probes.lo +osmo_bts_trx_LDADD += probes.lo +endif diff --git a/src/osmo-bts-trx/amr_loop.c b/src/osmo-bts-trx/amr_loop.c new file mode 100644 index 00000000..cf75a8fc --- /dev/null +++ b/src/osmo-bts-trx/amr_loop.c @@ -0,0 +1,107 @@ +/* AMR link adaptation loop (see 3GPP TS 45.009, section 3) */ + +/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> + * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <inttypes.h> + +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/logging.h> +#include <osmocom/gsm/gsm_utils.h> + +#include "amr_loop.h" + +void trx_loop_amr_input(struct l1sched_chan_state *chan_state, + const struct l1sched_meas_set *meas_set) +{ + const struct gsm_lchan *lchan = chan_state->lchan; + const struct amr_multirate_conf *cfg = &lchan->tch.amr_mr; + const uint8_t mi = chan_state->ul_ft; /* mode index 0..3 */ + int lqual_cb = meas_set->ci_cb; /* cB (centibel) */ + + /* count per-block C/I samples for further averaging */ + if (lchan->type == GSM_LCHAN_TCH_H) { + chan_state->lqual_cb_num += 2; + chan_state->lqual_cb_sum += (lqual_cb + lqual_cb); + } else { + chan_state->lqual_cb_num++; + chan_state->lqual_cb_sum += lqual_cb; + } + + /* wait for MS to use the requested codec */ + if (mi != chan_state->dl_cmr) + return; + + /* count frames */ + if (chan_state->lqual_cb_num < 48) + return; + + /* calculate average (reuse lqual_cb variable) */ + lqual_cb = chan_state->lqual_cb_sum / chan_state->lqual_cb_num; + + LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "AMR link quality (C/I) is %d cB, " + "codec mode[%u]=%u\n", lqual_cb, mi, cfg->mode[mi].mode); + + /* reset the link quality measurements */ + chan_state->lqual_cb_num = 0; + chan_state->lqual_cb_sum = 0; + + /* If the current codec mode can be degraded */ + if (mi > 0) { + /* The threshold/hysteresis is in 0.5 dB steps, convert to cB: + * 1dB is 10cB, so 0.5dB is 5cB - this is why we multiply by 5. */ + const int thresh_lower_cb = cfg->mode[mi - 1].threshold * 5; + + /* Degrade if the link quality is below THR_MX_Dn(i - 1) */ + if (lqual_cb < thresh_lower_cb) { + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Degrading AMR codec mode: " + "[%u]=%u -> [%u]=%u due to link quality %d cB < THR_MX_Dn=%d cB\n", + mi, cfg->mode[mi].mode, mi - 1, cfg->mode[mi - 1].mode, + lqual_cb, thresh_lower_cb); + chan_state->dl_cmr--; + return; + } + } + + /* If the current codec mode can be upgraded */ + if (mi < chan_state->codecs - 1) { + /* The threshold/hysteresis is in 0.5 dB steps, convert to cB: + * 1dB is 10cB, so 0.5dB is 5cB - this is why we multiply by 5. */ + const int thresh_upper_cb = cfg->mode[mi].threshold * 5 \ + + cfg->mode[mi].hysteresis * 5; + + /* Upgrade if the link quality is above THR_MX_Up(i) */ + if (lqual_cb > thresh_upper_cb) { + LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "Upgrading AMR codec mode: " + "[%u]=%u -> [%u]=%u due to link quality %d cB > THR_MX_Up=%d cB\n", + mi, cfg->mode[mi].mode, mi + 1, cfg->mode[mi + 1].mode, + lqual_cb, thresh_upper_cb); + chan_state->dl_cmr++; + return; + } + } + + LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Keeping the current AMR codec " + "mode[%u]=%u\n", mi, cfg->mode[mi].mode); +} diff --git a/src/osmo-bts-trx/loops.h b/src/osmo-bts-trx/amr_loop.h index 4aa05c4c..efff76cf 100644 --- a/src/osmo-bts-trx/loops.h +++ b/src/osmo-bts-trx/amr_loop.h @@ -1,5 +1,4 @@ -#ifndef _TRX_LOOPS_H -#define _TRX_LOOPS_H +#pragma once #include <osmo-bts/scheduler.h> @@ -12,8 +11,6 @@ */ void trx_loop_amr_input(struct l1sched_chan_state *chan_state, - int n_errors, int n_bits_total); + const struct l1sched_meas_set *meas_set); void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop); - -#endif /* _TRX_LOOPS_H */ diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c index 754e9d7a..54f5bd24 100644 --- a/src/osmo-bts-trx/l1_if.c +++ b/src/osmo-bts-trx/l1_if.c @@ -45,6 +45,7 @@ #include <osmo-bts/scheduler.h> #include <osmo-bts/pcu_if.h> #include <osmo-bts/nm_common_fsm.h> +#include <osmo-bts/handover.h> #include "l1_if.h" #include "trx_if.h" @@ -87,38 +88,23 @@ struct trx_l1h *trx_l1h_alloc(void *tall_ctx, struct phy_instance *pinst) return l1h; } -static void check_transceiver_availability_trx(struct trx_l1h *l1h, int avail) +int bts_model_lchan_deactivate(struct gsm_lchan *lchan) { - struct phy_instance *pinst = l1h->phy_inst; - struct gsm_bts_trx *trx = pinst->trx; + int rc; + /* set lchan inactive */ + lchan_set_state(lchan, LCHAN_S_NONE); - /* HACK, we should change state when we receive first clock from - * transceiver */ - if (avail) { - /* signal availability */ - if (!pinst->u.osmotrx.sw_act_reported) { - osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL); - osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL); - pinst->u.osmotrx.sw_act_reported = true; - } - } else { - osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL); - osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL); - } -} + /* Disable it on the scheduler: */ + rc = trx_sched_set_lchan(lchan, gsm_lchan2chan_nr(lchan), LID_DEDIC, false); -int bts_model_lchan_deactivate(struct gsm_lchan *lchan) -{ + /* Reactivate CCCH due to SI3 update in RSL */ if (lchan->rel_act_kind == LCHAN_REL_ACT_REACT) { lchan->rel_act_kind = LCHAN_REL_ACT_RSL; - /* FIXME: perform whatever is needed (if any) to set proper PCH/AGCH allocation according to - 3GPP TS 44.018 Table 10.5.2.11.1 using num_agch(lchan->ts->trx, "TRX L1"); function */ - return 0; + trx_sched_set_lchan(lchan, gsm_lchan2chan_nr(lchan), LID_DEDIC, true); + lchan_set_state(lchan, LCHAN_S_ACTIVE); + return rc; } - /* set lchan inactive */ - lchan_set_state(lchan, LCHAN_S_NONE); - - return trx_sched_set_lchan(lchan, gsm_lchan2chan_nr(lchan), LID_DEDIC, false); + return rc; } int bts_model_lchan_deactivate_sacch(struct gsm_lchan *lchan) @@ -185,10 +171,6 @@ static int trx_init(struct gsm_bts_trx *trx) if (rc != 0) return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK, (void*)(intptr_t)NM_NACK_CANT_PERFORM); - - if (trx == trx->bts->c0) - lchan_init_lapdm(&trx->ts[0].lchan[CCCH_LCHAN]); - /* Send OPSTART ack */ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL); } @@ -211,13 +193,15 @@ void bts_model_trx_close(struct gsm_bts_trx *trx) osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CLOSE, NULL); /* Set to Operational State: Disabled */ - check_transceiver_availability_trx(l1h, 0); + osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL); } -/* on RSL failure, deactivate transceiver */ void bts_model_abis_close(struct gsm_bts *bts) { - bts_shutdown(bts, "Abis close"); + /* Go into shutdown state deactivating transceivers until Abis link + * becomes up again */ + bts_shutdown_ext(bts, "Abis close", false, true); } int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan) @@ -228,17 +212,21 @@ int bts_model_adjst_ms_pwr(struct gsm_lchan *lchan) } /* set bts attributes */ -static uint8_t trx_set_bts(struct gsm_bts *bts, struct tlv_parsed *new_attr) +static uint8_t trx_set_bts(struct gsm_bts *bts) { - struct gsm_bts_trx *trx; + struct phy_instance *pinst = trx_phy_instance(bts->c0); + struct trx_l1h *l1h = pinst->u.osmotrx.hdl; uint8_t bsic = bts->bsic; + struct gsm_bts_trx *trx; + + /* ARFCN for C0 is assigned during Set BTS Attr, see oml.c */ + osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ARFCN, (void *)(intptr_t)pinst->trx->arfcn); llist_for_each_entry(trx, &bts->trx_list, list) { - struct phy_instance *pinst = trx_phy_instance(trx); - struct phy_link *plink = pinst->phy_link; - struct trx_l1h *l1h = pinst->u.osmotrx.hdl; + pinst = trx_phy_instance(trx); + l1h = pinst->u.osmotrx.hdl; + osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_BSIC, (void*)(intptr_t)bsic); - check_transceiver_availability_trx(l1h, phy_link_state_get(plink) != PHY_LINK_SHUTDOWN); } return 0; @@ -252,7 +240,9 @@ static uint8_t trx_set_trx(struct gsm_bts_trx *trx) struct phy_link *plink = pinst->phy_link; uint16_t arfcn = trx->arfcn; - osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ARFCN, (void*)(intptr_t)arfcn); + /* ARFCN for C0 is assigned during Set BTS Attr, see oml.c */ + if (trx != trx->bts->c0) + osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ARFCN, (void *)(intptr_t)arfcn); /* Begin to ramp up the power if power reduction is set by OML and TRX is already running. Otherwise skip, power ramping will be started @@ -286,18 +276,33 @@ static uint8_t trx_set_ts_as_pchan(struct gsm_bts_trx_ts *ts, if (rc) return NM_NACK_RES_NOTAVAIL; - /* activate lchan for CCCH */ - if (pchan == GSM_PCHAN_CCCH || pchan == GSM_PCHAN_CCCH_SDCCH4 || - pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) { + /* activate lchans for [CBCH/]BCCH/CCCH */ + switch (pchan) { + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: + /* using RSL_CHAN_OSMO_CBCH4 is correct here, because the scheduler + * does not distinguish between SDCCH/4+CBCH abd SDCCH/8+CBCH. */ + trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN], + RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true); + break; + case GSM_PCHAN_CCCH_SDCCH4_CBCH: + trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN], + RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true); + /* fall-through */ + case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH: + trx_sched_set_bcch_ccch(&ts->lchan[CCCH_LCHAN], true); ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE); + break; + default: + break; } slottype = transceiver_chan_types[pchan]; struct trx_prov_ev_cfg_ts_data data = { .tn = tn, .slottype = slottype }; - if (ts->tsc_set != 0 || ts->tsc != BTS_TSC(ts->trx->bts)) { + if (ts->tsc_set != 0) { /* On TRXC we use 3GPP compliant numbering, so +1 */ data.tsc_set = ts->tsc_set + 1; data.tsc_val = ts->tsc; @@ -342,8 +347,8 @@ static uint8_t trx_set_ts(struct gsm_bts_trx_ts *ts) /* enable ciphering */ static int l1if_set_ciphering(struct gsm_lchan *lchan, uint8_t chan_nr, int downlink) { - /* ciphering already enabled in both directions */ - if (lchan->ciph_state == LCHAN_CIPH_RXTX_CONF) + /* ignore the request when the channel is not active */ + if (lchan->state != LCHAN_S_ACTIVE) return -EINVAL; if (!downlink) { @@ -415,98 +420,98 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) switch (l1sap->u.info.type) { case PRIM_INFO_ACT_CIPH: chan_nr = l1sap->u.info.u.ciph_req.chan_nr; - lchan = get_lchan_by_chan_nr(trx, chan_nr); + break; + case PRIM_INFO_ACT_UL_ACC: + case PRIM_INFO_DEACT_UL_ACC: + chan_nr = l1sap->u.info.u.ulacc_req.chan_nr; + break; + default: + /* u.act_req used by PRIM_INFO_{ACTIVATE,DEACTIVATE,MODIFY} */ + chan_nr = l1sap->u.info.u.act_req.chan_nr; + } + lchan = get_lchan_by_chan_nr(trx, chan_nr); + if (OSMO_UNLIKELY(lchan == NULL)) { + LOGP(DL1C, LOGL_ERROR, + "Rx MPH-INFO.req (type=0x%02x) for non-existent lchan (%s)\n", + l1sap->u.info.type, rsl_chan_nr_str(chan_nr)); + rc = -ENODEV; + break; + } + + switch (l1sap->u.info.type) { + case PRIM_INFO_ACT_CIPH: if (l1sap->u.info.u.ciph_req.uplink) l1if_set_ciphering(lchan, chan_nr, 0); if (l1sap->u.info.u.ciph_req.downlink) l1if_set_ciphering(lchan, chan_nr, 1); break; + case PRIM_INFO_ACT_UL_ACC: + trx_sched_set_ul_access(lchan, chan_nr, true); + break; + case PRIM_INFO_DEACT_UL_ACC: + trx_sched_set_ul_access(lchan, chan_nr, false); + break; case PRIM_INFO_ACTIVATE: - case PRIM_INFO_DEACTIVATE: - case PRIM_INFO_MODIFY: - chan_nr = l1sap->u.info.u.act_req.chan_nr; - lchan = get_lchan_by_chan_nr(trx, chan_nr); - if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) { - if ((chan_nr & 0xE0) == 0x80) { - LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate" - " channel %s\n", rsl_chan_nr_str(chan_nr)); - break; - } - - /* attempt to allocate an Error Concealment Unit instance, if available */ - lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan)); - - /* trx_chan_desc[] in scheduler.c uses the RSL_CHAN_OSMO_PDCH cbits - * (0xc0) to indicate the need for PDTCH and PTCCH SAPI activation. - * However, 0xc0 is a cbits pattern exclusively used for Osmocom style - * dyn TS (a non-standard RSL Chan Activ mod); hence, for IPA style dyn - * TS, the chan_nr will never reflect 0xc0 and we would omit the - * PDTCH,PTTCH SAPIs. To properly de-/activate the PDTCH SAPIs in - * scheduler.c, make sure the 0xc0 cbits are set for de-/activating PDTCH - * lchans, i.e. both Osmocom and IPA style dyn TS. (For Osmocom style dyn - * TS, the chan_nr typically already reflects 0xc0, while it doesn't for - * IPA style.) */ - if (lchan->type == GSM_LCHAN_PDTCH) - chan_nr = RSL_CHAN_OSMO_PDCH | (chan_nr & ~RSL_CHAN_NR_MASK); - - /* activate dedicated channel */ - trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true); - /* activate associated channel */ - trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true); - /* set mode */ - trx_sched_set_mode(lchan->ts, chan_nr, - lchan->rsl_cmode, lchan->tch_mode, - lchan->tch.amr_mr.num_modes, - lchan->tch.amr_mr.bts_mode[0].mode, - lchan->tch.amr_mr.bts_mode[1].mode, - lchan->tch.amr_mr.bts_mode[2].mode, - lchan->tch.amr_mr.bts_mode[3].mode, - amr_get_initial_mode(lchan), - (lchan->ho.active == 1)); - /* init lapdm */ - lchan_init_lapdm(lchan); - /* set lchan active */ - lchan_set_state(lchan, LCHAN_S_ACTIVE); - /* set initial ciphering */ - l1if_set_ciphering(lchan, chan_nr, 0); - l1if_set_ciphering(lchan, chan_nr, 1); - if (lchan->encr.alg_id) - lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; - else - lchan->ciph_state = LCHAN_CIPH_NONE; - - /* confirm */ - mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); - break; - } - if (l1sap->u.info.type == PRIM_INFO_MODIFY) { - /* ECU for possibly new codec */ - if (lchan->ecu_state) - osmo_ecu_destroy(lchan->ecu_state); - lchan->ecu_state = osmo_ecu_init(trx, lchan2ecu_codec(lchan)); - /* change mode */ - trx_sched_set_mode(lchan->ts, chan_nr, - lchan->rsl_cmode, lchan->tch_mode, - lchan->tch.amr_mr.num_modes, - lchan->tch.amr_mr.bts_mode[0].mode, - lchan->tch.amr_mr.bts_mode[1].mode, - lchan->tch.amr_mr.bts_mode[2].mode, - lchan->tch.amr_mr.bts_mode[3].mode, - amr_get_initial_mode(lchan), - 0); + if ((chan_nr & 0xE0) == 0x80) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate" + " channel %s\n", rsl_chan_nr_str(chan_nr)); + rc = -EPERM; break; } - /* here, type == PRIM_INFO_DEACTIVATE */ + + /* activate dedicated channel */ + trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true); + /* activate associated channel */ + trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true); + /* set mode */ + trx_sched_set_mode(lchan->ts, chan_nr, + lchan->rsl_cmode, lchan->tch_mode, + lchan->tch.amr_mr.num_modes, + lchan->tch.amr_mr.mode[0].mode, + lchan->tch.amr_mr.mode[1].mode, + lchan->tch.amr_mr.mode[2].mode, + lchan->tch.amr_mr.mode[3].mode, + amr_get_initial_mode(lchan), + (lchan->ho.active == HANDOVER_ENABLED)); + /* set lchan active */ + lchan_set_state(lchan, LCHAN_S_ACTIVE); + /* set initial ciphering */ + l1if_set_ciphering(lchan, chan_nr, 0); + l1if_set_ciphering(lchan, chan_nr, 1); + if (lchan->encr.alg_id) + lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; + else + lchan->ciph_state = LCHAN_CIPH_NONE; + + /* confirm */ + mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); + break; + case PRIM_INFO_MODIFY: + /* change mode */ + trx_sched_set_mode(lchan->ts, chan_nr, + lchan->rsl_cmode, lchan->tch_mode, + lchan->tch.amr_mr.num_modes, + lchan->tch.amr_mr.mode[0].mode, + lchan->tch.amr_mr.mode[1].mode, + lchan->tch.amr_mr.mode[2].mode, + lchan->tch.amr_mr.mode[3].mode, + amr_get_initial_mode(lchan), + 0); + /* update ciphering params */ + l1if_set_ciphering(lchan, chan_nr, 0); + l1if_set_ciphering(lchan, chan_nr, 1); + if (lchan->encr.alg_id) + lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; + else + lchan->ciph_state = LCHAN_CIPH_NONE; + break; + case PRIM_INFO_DEACTIVATE: if ((chan_nr & 0xE0) == 0x80) { LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate" " channel %s\n", rsl_chan_nr_str(chan_nr)); + rc = -EPERM; break; } - /* clear ECU state (if any) */ - if (lchan->ecu_state) { - osmo_ecu_destroy(lchan->ecu_state); - lchan->ecu_state = NULL; - } /* deactivate associated channel */ bts_model_lchan_deactivate_sacch(lchan); if (!l1sap->u.info.u.act_req.sacch_only) { @@ -551,61 +556,51 @@ int bts_model_check_oml(struct gsm_bts *bts, uint8_t msg_type, } /* callback from OML */ -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { struct abis_om_fom_hdr *foh = msgb_l3(msg); - int cause = 0; + int rc; switch (foh->msg_type) { case NM_MT_SET_BTS_ATTR: - cause = trx_set_bts(obj, new_attr); + rc = trx_set_bts(obj); break; case NM_MT_SET_RADIO_ATTR: - cause = trx_set_trx(obj); + rc = trx_set_trx(obj); break; case NM_MT_SET_CHAN_ATTR: - cause = trx_set_ts(obj); + rc = trx_set_ts(obj); + break; + default: + rc = 0; break; } - return oml_fom_ack_nack(msg, cause); + return rc; } /* callback from OML */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { - struct gsm_bts_bb_trx *bb_transc; struct gsm_bts_trx *trx; - struct gsm_bts_trx_ts *ts; int rc; switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; - case NM_OC_RADIO_CARRIER: - /* activate transceiver */ - trx = (struct gsm_bts_trx *) obj; - rc = trx_init(trx); - break; case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: - ts = (struct gsm_bts_trx_ts *) obj; - rc = osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - rc = oml_mo_opstart_ack(mo); + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); + break; + case NM_OC_RADIO_CARRIER: + /* activate transceiver */ + trx = (struct gsm_bts_trx *) obj; + rc = trx_init(trx); break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); diff --git a/src/osmo-bts-trx/l1_if.h b/src/osmo-bts-trx/l1_if.h index 50369d9d..84fd4b5b 100644 --- a/src/osmo-bts-trx/l1_if.h +++ b/src/osmo-bts-trx/l1_if.h @@ -30,6 +30,7 @@ enum { BTSTRX_CTR_SCHED_DL_MISS_FN, BTSTRX_CTR_SCHED_DL_FH_NO_CARRIER, + BTSTRX_CTR_SCHED_DL_FH_CACHE_MISS, BTSTRX_CTR_SCHED_UL_FH_NO_CARRIER, }; @@ -119,6 +120,10 @@ struct trx_l1h { struct llist_head trx_ctrl_list; /* Latest RSPed cmd, used to catch duplicate RSPs from sent retransmissions */ struct trx_ctrl_msg *last_acked; + /* Whether the code path is in the middle of handling a received message. */ + bool in_trx_ctrl_read_cb; + /* Whether the l1h->trx_ctrl_list was flushed by the callback handling a received message */ + bool flushed_while_in_trx_ctrl_read_cb; //struct gsm_bts_trx *trx; struct phy_instance *phy_inst; diff --git a/src/osmo-bts-trx/loops.c b/src/osmo-bts-trx/loops.c deleted file mode 100644 index 4c70e8d1..00000000 --- a/src/osmo-bts-trx/loops.c +++ /dev/null @@ -1,120 +0,0 @@ -/* Loop control for OsmoBTS-TRX */ - -/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> - * - * All Rights Reserved - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -#include <stdint.h> -#include <unistd.h> -#include <stdlib.h> -#include <errno.h> -#include <inttypes.h> - -#include <osmo-bts/gsm_data.h> -#include <osmo-bts/logging.h> -#include <osmo-bts/l1sap.h> -#include <osmocom/core/bits.h> -#include <osmocom/gsm/gsm_utils.h> - -#include "trx_if.h" -#include "l1_if.h" -#include "loops.h" - -void trx_loop_amr_input(struct l1sched_chan_state *chan_state, - int n_errors, int n_bits_total) -{ - struct gsm_lchan *lchan = chan_state->lchan; - float ber; - - /* calculate BER (Bit Error Ratio) */ - if (n_bits_total == 0) - ber = 1.0; /* 100% BER */ - else - ber = (float) n_errors / (float) n_bits_total; - - /* check if loop is enabled */ - if (!chan_state->amr_loop) - return; - - /* wait for MS to use the requested codec */ - if (chan_state->ul_ft != chan_state->dl_cmr) - return; - - /* count bit errors */ - if (lchan->type == GSM_LCHAN_TCH_H) { - chan_state->ber_num += 2; - chan_state->ber_sum += (ber + ber); - } else { - chan_state->ber_num++; - chan_state->ber_sum += ber; - } - - /* count frames */ - if (chan_state->ber_num < 48) - return; - - /* calculate average (reuse ber variable) */ - ber = chan_state->ber_sum / chan_state->ber_num; - - /* reset bit errors */ - chan_state->ber_num = 0; - chan_state->ber_sum = 0; - - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Current bit error rate (BER) %.6f " - "codec id %d\n", ber, chan_state->ul_ft); - - /* degrade */ - if (chan_state->dl_cmr > 0) { - /* degrade, if ber is above threshold FIXME: C/I */ - if (ber > - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr-1].threshold) { - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Degrading due to BER %.6f " - "from codec id %d to %d\n", ber, chan_state->dl_cmr, - chan_state->dl_cmr - 1); - chan_state->dl_cmr--; - } - } else if (chan_state->dl_cmr < chan_state->codecs - 1) { - /* degrade, if ber is above threshold FIXME: C/I*/ - if (ber < - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].threshold - - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].hysteresis) { - LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Upgrading due to BER %.6f " - "from codec id %d to %d\n", ber, chan_state->dl_cmr, - chan_state->dl_cmr + 1); - chan_state->dl_cmr++; - } - } -} - -void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop) -{ - if (chan_state->amr_loop && !loop) { - chan_state->amr_loop = 0; - return; - } - - if (!chan_state->amr_loop && loop) { - chan_state->amr_loop = 1; - - /* reset bit errors */ - chan_state->ber_num = 0; - chan_state->ber_sum = 0; - - return; - } -} diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c index 9720b035..9809e6c4 100644 --- a/src/osmo-bts-trx/main.c +++ b/src/osmo-bts-trx/main.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -70,6 +70,10 @@ static const struct rate_ctr_desc btstrx_ctr_desc[] = { "trx_sched:dl_fh_no_carrier", "Frequency hopping: no carrier found for a Downlink burst (check hopping parameters)" }, + [BTSTRX_CTR_SCHED_DL_FH_CACHE_MISS] = { + "trx_sched:dl_fh_cache_miss", + "Frequency hopping: no Downlink carrier found in cache (lookup performed)" + }, [BTSTRX_CTR_SCHED_UL_FH_NO_CARRIER] = { "trx_sched:ul_fh_no_carrier", "Frequency hopping: no carrier found for an Uplink burst (check hopping parameters)" @@ -128,34 +132,73 @@ int bts_model_init(struct gsm_bts *bts) bts->model_priv = bts_trx; bts->variant = BTS_OSMO_TRX; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3) | CIPHER_A5(4); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS + | NM_IPAC_MASK_GPRS_CODING_MCS; /* The nominal value for each TRX is later overwritten through VTY cmd * 'nominal-tx-power' if present, otherwise through TRXC cmd NOMTXPOWER. */ bts->c0->nominal_power = 23; - osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP); + osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_TEMP_OVP); + osmo_bts_set_feature(bts->features, BTS_FEAT_BCCH_POWER_RED); + osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING); + osmo_bts_set_feature(bts->features, BTS_FEAT_MULTI_TSC); osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR); - osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); - osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING); - osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP); - osmo_bts_set_feature(bts->features, BTS_FEAT_MULTI_TSC); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_VAMOS); - osmo_bts_set_feature(bts->features, BTS_FEAT_BCCH_POWER_RED); + osmo_bts_set_feature(bts->features, BTS_FEAT_VGCS); + osmo_bts_set_feature(bts->features, BTS_FEAT_VBS); bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB); + bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_INTERF_MEAS); + + /* The default HR codec output format in the absence of saved + * vty config needs to match what was implemented previously, + * for the sake of existing deployments, i.e., to avoid + * a surprise functional change upon software update. */ + bts->emit_hr_rfc5993 = true; + + /* For the same reason as the above, rtp internal-uplink-ecu + * needs to be enabled by default on osmo-bts-trx model only. */ + bts->use_ul_ecu = true; return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = NM_IPAC_F_FREQ_BAND_PGSM + | NM_IPAC_F_FREQ_BAND_EGSM + | NM_IPAC_F_FREQ_BAND_RGSM + | NM_IPAC_F_FREQ_BAND_DCS + | NM_IPAC_F_FREQ_BAND_PCS + | NM_IPAC_F_FREQ_BAND_850 + | NM_IPAC_F_FREQ_BAND_480 + | NM_IPAC_F_FREQ_BAND_450; + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH + | NM_IPAC_F_CHANT_SDCCH8_CBCH + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH + | NM_IPAC_MASK_CHANM_CSD_NT + | NM_IPAC_MASK_CHANM_CSD_T; + /* TODO: NM_IPAC_F_CHANM_CSD_T_14k4 (see OS#6167) */ + trx->support.chan_modes &= ~NM_IPAC_F_CHANM_CSD_T_14k4; + /* The nominal value for each TRX is later overwritten through VTY cmd * 'nominal-tx-power' if present, otherwise through TRXC cmd NOMTXPOWER. */ diff --git a/src/osmo-bts-trx/probes.d b/src/osmo-bts-trx/probes.d new file mode 100644 index 00000000..2f905bd1 --- /dev/null +++ b/src/osmo-bts-trx/probes.d @@ -0,0 +1,7 @@ +provider osmo_bts_trx { + probe ul_data_start(int, int, int); /* trx_nr, ts_nr, fn */ + probe ul_data_done(int, int, int); /* trx_nr, ts_nr, fn */ + + probe dl_rts_start(int, int, int); /* trx_nr, ts_nr, fn */ + probe dl_rts_done(int, int, int); /* trx_nr, ts_nr, fn */ +}; diff --git a/src/osmo-bts-trx/sched_lchan_fcch_sch.c b/src/osmo-bts-trx/sched_lchan_fcch_sch.c index 993cb63b..5722b288 100644 --- a/src/osmo-bts-trx/sched_lchan_fcch_sch.c +++ b/src/osmo-bts-trx/sched_lchan_fcch_sch.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-trx/sched_lchan_pdtch.c b/src/osmo-bts-trx/sched_lchan_pdtch.c index 335ba6fe..466a4144 100644 --- a/src/osmo-bts-trx/sched_lchan_pdtch.c +++ b/src/osmo-bts-trx/sched_lchan_pdtch.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -42,9 +42,9 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) { struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; - sbit_t *burst, **bursts_p = &chan_state->ul_bursts; + sbit_t *burst, *bursts_p = chan_state->ul_bursts; uint32_t first_fn; - uint8_t *mask = &chan_state->ul_mask; + uint32_t *mask = &chan_state->ul_mask; struct l1sched_meas_set meas_avg; uint8_t l2[EGPRS_0503_MAX_BYTES]; int n_errors = 0; @@ -56,17 +56,13 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received PDTCH bid=%u\n", bi->bid); - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, - GSM0503_EGPRS_BURSTS_NBITS); - if (!*bursts_p) - return -ENOMEM; - } + /* An MS may be polled to send an ACK in form of four Access Bursts */ + if (bi->flags & TRX_BI_F_ACCESS_BURST) + return rx_rach_fn(l1ts, bi); /* clear burst */ if (bi->bid == 0) { - memset(*bursts_p, 0, GSM0503_EGPRS_BURSTS_NBITS); + memset(bursts_p, 0, GSM0503_EGPRS_BURSTS_NBITS); *mask = 0x0; } @@ -79,21 +75,19 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) /* copy burst to buffer of 4 bursts */ switch (bi->burst_len) { case EGPRS_BURST_LEN: - burst = *bursts_p + bi->bid * 348; + burst = bursts_p + bi->bid * 348; memcpy(burst, bi->burst + 9, 174); memcpy(burst + 174, bi->burst + 261, 174); n_bursts_bits = GSM0503_EGPRS_BURSTS_NBITS; break; case GSM_BURST_LEN: - burst = *bursts_p + bi->bid * 116; + burst = bursts_p + bi->bid * 116; memcpy(burst, bi->burst + 3, 58); memcpy(burst + 58, bi->burst + 87, 58); n_bursts_bits = GSM0503_GPRS_BURSTS_NBITS; break; case 0: /* NOPE.ind, assume GPRS? */ - burst = *bursts_p + bi->bid * 116; - memset(burst, 0, 116); n_bursts_bits = GSM0503_GPRS_BURSTS_NBITS; } @@ -102,7 +96,7 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) return 0; /* average measurements of the last 4 bursts */ - trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_QUAD); + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_S4N4); /* check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { @@ -117,19 +111,19 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) * then we incur decoding overhead of 31 bits on the Type 3 EGPRS * header, which is tolerable. */ - rc = gsm0503_pdtch_egprs_decode(l2, *bursts_p, n_bursts_bits, + rc = gsm0503_pdtch_egprs_decode(l2, bursts_p, n_bursts_bits, NULL, &n_errors, &n_bits_total); if ((bi->burst_len == GSM_BURST_LEN) && (rc < 0)) { - rc = gsm0503_pdtch_decode(l2, *bursts_p, NULL, + rc = gsm0503_pdtch_decode(l2, bursts_p, NULL, &n_errors, &n_bits_total); } if (rc > 0) { presence_info = PRES_INFO_BOTH; } else { - LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received bad PDTCH (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, + BAD_DATA_MSG_FMT "\n", BAD_DATA_MSG_ARGS); rc = 0; presence_info = PRES_INFO_INVALID; } @@ -137,10 +131,12 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) ber10k = compute_ber10k(n_bits_total, n_errors); first_fn = GSM_TDMA_FN_SUB(bi->fn, 3); - return _sched_compose_ph_data_ind(l1ts, - first_fn, bi->chan, l2, rc, - meas_avg.rssi, meas_avg.toa256, - meas_avg.ci_cb, ber10k, + return _sched_compose_ph_data_ind(l1ts, first_fn, bi->chan, + &l2[0], rc, + ber10k, + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, presence_info); } @@ -148,55 +144,46 @@ int rx_pdtch_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { struct msgb *msg = NULL; /* make GCC happy */ - ubit_t *burst, **bursts_p = &l1ts->chan_state[br->chan].dl_bursts; - enum trx_mod_type *mod = &l1ts->chan_state[br->chan].dl_mod_type; + struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; + ubit_t *burst, *bursts_p = chan_state->dl_bursts; + enum trx_mod_type *mod = &chan_state->dl_mod_type; + uint8_t *mask = &chan_state->dl_mask; int rc = 0; /* send burst, if we already got a frame */ if (br->bid > 0) { - if (!*bursts_p) - return 0; + if ((*mask & 0x01) != 0x01) + return -ENOMSG; goto send_burst; } + *mask = *mask << 4; + /* get mac block from queue */ msg = _sched_dequeue_prim(l1ts, br); - if (msg) - goto got_msg; - - LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No prim for transmit.\n"); - -no_msg: - /* free burst memory */ - if (*bursts_p) { - talloc_free(*bursts_p); - *bursts_p = NULL; + if (!msg) { + /* It's totally fine to get no block here, since PCU may submit + * empty blocks when there's no MS listening. The scheduler will + * take care of filling C0 with dummy bursts to keep expected + * power transmit levels + */ + return -ENODEV; } - return -ENODEV; -got_msg: /* BURST BYPASS */ - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, - GSM0503_EGPRS_BURSTS_NBITS); - if (!*bursts_p) - return -ENOMEM; - } - /* encode bursts */ - rc = gsm0503_pdtch_egprs_encode(*bursts_p, msg->l2h, msg->tail - msg->l2h); + rc = gsm0503_pdtch_egprs_encode(bursts_p, msg->l2h, msgb_l2len(msg)); if (rc < 0) - rc = gsm0503_pdtch_encode(*bursts_p, msg->l2h, msg->tail - msg->l2h); + rc = gsm0503_pdtch_encode(bursts_p, msg->l2h, msgb_l2len(msg)); /* check validity of message */ if (rc < 0) { LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim invalid length, please FIX! " - "(len=%ld)\n", (long)(msg->tail - msg->l2h)); + "(len=%u)\n", msgb_l2len(msg)); /* free message */ msgb_free(msg); - goto no_msg; + return -EINVAL; } else if (rc == GSM0503_EGPRS_BURSTS_NBITS) { *mod = TRX_MOD_T_8PSK; } else { @@ -209,7 +196,7 @@ got_msg: send_burst: /* compose burst */ if (*mod == TRX_MOD_T_8PSK) { - burst = *bursts_p + br->bid * 348; + burst = bursts_p + br->bid * 348; memset(br->burst, 1, 9); memcpy(br->burst + 9, burst, 174); memcpy(br->burst + 183, TRX_8PSK_NB_TSC(br), 78); @@ -218,7 +205,7 @@ send_burst: br->burst_len = EGPRS_BURST_LEN; } else { - burst = *bursts_p + br->bid * 116; + burst = bursts_p + br->bid * 116; memcpy(br->burst + 3, burst, 58); memcpy(br->burst + 61, TRX_GMSK_NB_TSC(br), 26); memcpy(br->burst + 87, burst + 58, 58); @@ -226,6 +213,8 @@ send_burst: br->burst_len = GSM_BURST_LEN; } + *mask |= (1 << br->bid); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid); return 0; diff --git a/src/osmo-bts-trx/sched_lchan_rach.c b/src/osmo-bts-trx/sched_lchan_rach.c index c3abf321..c92dfe24 100644 --- a/src/osmo-bts-trx/sched_lchan_rach.c +++ b/src/osmo-bts-trx/sched_lchan_rach.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -112,6 +112,10 @@ int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) uint8_t ra; int rc; + /* Ignore NOPE indications, they're of no use here */ + if (bi->flags & TRX_BI_F_NOPE_IND) + return 0; + /* TSC (Training Sequence Code) is an optional parameter of the UL burst * indication. We need this information in order to decide whether an * Access Burst is 11-bit encoded or not (see OS#1854). If this information @@ -133,7 +137,7 @@ int rx_rach_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received%s RACH (%s): rssi=%d toa256=%d", - (bi->chan != TRXC_RACH) ? " handover" : "", + TRX_CHAN_IS_DEDIC(bi->chan) ? " handover" : "", get_value_string(rach_synch_seq_names, synch_seq), bi->rssi, bi->toa256); if (bi->flags & TRX_BI_F_CI_CB) diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index 689925fb..5a3e80ac 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -1,7 +1,7 @@ /* * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> * (C) 2015-2017 by Harald Welte <laforge@gnumonks.org> - * Contributions by sysmocom - s.f.m.c. GmbH + * (C) 2020-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -30,11 +30,12 @@ #include <osmocom/gsm/gsm0502.h> #include <osmocom/codec/codec.h> -#include <osmocom/codec/ecu.h> #include <osmocom/coding/gsm0503_coding.h> #include <osmocom/coding/gsm0503_amr_dtx.h> +#include <osmocom/netif/amr.h> + #include <osmo-bts/bts.h> #include <osmo-bts/l1sap.h> #include <osmo-bts/logging.h> @@ -43,28 +44,80 @@ #include <osmo-bts/msg_utils.h> #include <sched_utils.h> -#include <loops.h> +#include <amr_loop.h> + +/* 3GPP TS 45.009, table 3.2.1.3-{1,3}: AMR on Uplink TCH/F. + * + * +---+---+---+---+---+---+---+---+ + * | a | b | c | d | e | f | g | h | Burst 'a' received first + * +---+---+---+---+---+---+---+---+ + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Speech/FACCH frame (bursts 'a' .. 'h') + * + * TDMA frame number of burst 'h' is always used as the table index. */ +static const uint8_t sched_tchf_ul_amr_cmi_map[26] = { + [7] = 1, /* TCH/F: a=0 / h=7 */ + [16] = 1, /* TCH/F: a=8 / h=16 */ + [24] = 1, /* TCH/F: a=17 / h=24 */ +}; + +/* TDMA frame number of burst 'a' should be used as the table index. */ +static const uint8_t sched_tchf_dl_amr_cmi_map[26] = { + [4] = 1, /* TCH/F: a=4 */ + [13] = 1, /* TCH/F: a=13 */ + [21] = 1, /* TCH/F: a=21 */ +}; + +extern const uint8_t sched_tchh_dl_amr_cmi_map[26]; + +static int decode_fr_facch(struct l1sched_ts *l1ts, + const struct trx_ul_burst_ind *bi) +{ + struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; + const sbit_t *bursts_p = chan_state->ul_bursts; + struct l1sched_meas_set meas_avg; + uint8_t data[GSM_MACBLOCK_LEN]; + int n_errors, n_bits_total; + int rc; + + rc = gsm0503_tch_fr_facch_decode(&data[0], BUFTAIL8(bursts_p), + &n_errors, &n_bits_total); + if (rc != GSM_MACBLOCK_LEN) + return rc; + + /* average measurements of the last 8 bursts, obtain TDMA Fn of the first burst */ + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_S8N8); + + _sched_compose_ph_data_ind(l1ts, meas_avg.fn, bi->chan, + &data[0], GSM_MACBLOCK_LEN, + compute_ber10k(n_bits_total, n_errors), + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, + PRES_INFO_UNKNOWN); + return GSM_MACBLOCK_LEN; +} -/*! \brief a single TCH/F burst was received by the PHY, process it */ +/* Process a single Uplink TCH/F burst received by the PHY. + * This function is visualized in file 'doc/trx_sched_tch.txt'. */ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) { struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; struct gsm_lchan *lchan = chan_state->lchan; - sbit_t *burst, **bursts_p = &chan_state->ul_bursts; - uint8_t *mask = &chan_state->ul_mask; + sbit_t *burst, *bursts_p = chan_state->ul_bursts; + uint32_t *mask = &chan_state->ul_mask; uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; - uint8_t tch_data[128]; /* just to be safe */ - enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_OCTO; + uint8_t tch_data[290]; /* large enough to hold 290 unpacked bits for CSD */ + enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_S8N8; struct l1sched_meas_set meas_avg; int rc, amr = 0; int n_errors = 0; int n_bits_total = 0; - bool bfi_flag = false; unsigned int fn_begin; uint16_t ber10k; uint8_t is_sub = 0; uint8_t ft; + bool amr_is_cmr; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -73,17 +126,11 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received TCH/F, bid=%u\n", bi->bid); - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 928); - if (!*bursts_p) - return -ENOMEM; - } - - /* clear burst */ + /* shift the buffer by 4 bursts leftwards */ if (bi->bid == 0) { - memset(*bursts_p + 464, 0, 464); - *mask = 0x0; + memmove(BUFPOS(bursts_p, 0), BUFPOS(bursts_p, 4), 20 * BPLEN); + memset(BUFPOS(bursts_p, 20), 0, 4 * BPLEN); + *mask = *mask << 4; } /* update mask */ @@ -92,43 +139,48 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) /* store measurements */ trx_sched_meas_push(chan_state, bi); - /* copy burst to end of buffer of 8 bursts */ - burst = *bursts_p + bi->bid * 116 + 464; + /* copy burst to end of buffer of 24 bursts */ + burst = BUFPOS(bursts_p, 20 + bi->bid); if (bi->burst_len > 0) { memcpy(burst, bi->burst + 3, 58); memcpy(burst + 58, bi->burst + 87, 58); - } else - memset(burst, 0, 116); + } /* wait until complete set of bursts */ if (bi->bid != 3) return 0; - /* check for complete set of bursts */ - if ((*mask & 0xf) != 0xf) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, - "Received incomplete frame (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); + /* fill up the burst buffer so that we have 8 bursts in there */ + if (OSMO_UNLIKELY((*mask & 0xff) != 0xff)) { + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, + "UL burst buffer is not filled up: mask=0x%02x != 0xff\n", + *mask); + return 0; /* TODO: send BFI */ } - *mask = 0x0; - /* decode - * also shift buffer by 4 bursts for interleaving */ - switch ((rsl_cmode != RSL_CMOD_SPD_SPEECH) ? GSM48_CMODE_SPEECH_V1 - : tch_mode) { + /* TCH/F: speech and signalling frames are interleaved over 8 bursts, while + * CSD frames are interleaved over 22 bursts. Unless we're in CSD mode, + * decode only the last 8 bursts to avoid introducing additional delays. */ + switch (tch_mode) { + case GSM48_CMODE_SIGN: case GSM48_CMODE_SPEECH_V1: /* FR */ - rc = gsm0503_tch_fr_decode(tch_data, *bursts_p, 1, 0, &n_errors, &n_bits_total); - if (rc >= 0) - lchan_set_marker(osmo_fr_check_sid(tch_data, rc), lchan); /* DTXu */ + rc = gsm0503_tch_fr_decode(tch_data, BUFTAIL8(bursts_p), + 1, 0, &n_errors, &n_bits_total); + if (rc == GSM_FR_BYTES) /* only for valid *speech* frames */ + lchan_set_marker(osmo_fr_is_any_sid(tch_data), lchan); /* DTXu */ break; case GSM48_CMODE_SPEECH_EFR: /* EFR */ - rc = gsm0503_tch_fr_decode(tch_data, *bursts_p, 1, 1, &n_errors, &n_bits_total); + rc = gsm0503_tch_fr_decode(tch_data, BUFTAIL8(bursts_p), + 1, 1, &n_errors, &n_bits_total); + if (rc == GSM_EFR_BYTES) /* only for valid *speech* frames */ + lchan_set_marker(osmo_efr_is_any_sid(tch_data), lchan); /* DTXu */ break; case GSM48_CMODE_SPEECH_AMR: /* AMR */ /* the first FN 0,8,17 defines that CMI is included in frame, * the first FN 4,13,21 defines that CMR is included in frame. * NOTE: A frame ends 7 FN after start. */ + amr_is_cmr = !sched_tchf_ul_amr_cmi_map[bi->fn % 26]; /* The AFS_ONSET frame itself does not result into an RTP frame * since it only contains a recognition pattern that marks the @@ -138,21 +190,24 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) if (chan_state->amr_last_dtx == AFS_ONSET) lchan_set_marker(false, lchan); - /* we store tch_data + 2 header bytes, the amr variable set to - * 2 will allow us to skip the first 2 bytes in case we did - * receive an FACCH frame instead of a voice frame (we do not - * know this before we actually decode the frame) */ - amr = 2; - rc = gsm0503_tch_afs_decode_dtx(tch_data + amr, *bursts_p, - (((bi->fn + 26 - 7) % 26) >> 2) & 1, chan_state->codec, - chan_state->codecs, &chan_state->ul_ft, + /* Store AMR payload in tch-data with an offset of 2 bytes, so + * that we can easily prepend/fill the RTP AMR header (struct + * amr_hdr) with osmo_amr_rtp_enc() later on. The amr variable + * is used far below to account for the decoded offset in case + * we receive an FACCH frame instead of a voice frame (we + * do not know this before we actually decode the frame) */ + amr = sizeof(struct amr_hdr); + rc = gsm0503_tch_afs_decode_dtx(tch_data + amr, BUFTAIL8(bursts_p), + amr_is_cmr, chan_state->codec, chan_state->codecs, &chan_state->ul_ft, &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx); /* Tag all frames that are not regular AMR voice frames as * SUB-Frames */ if (chan_state->amr_last_dtx != AMR_OTHER) { - LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received AMR SID frame: %s\n", - gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx)); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, + "Received AMR DTX frame (rc=%d, BER %d/%d): %s\n", + rc, n_errors, n_bits_total, + gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx)); is_sub = 1; } @@ -173,20 +228,18 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) switch (chan_state->amr_last_dtx) { case AFS_SID_FIRST: case AFS_SID_UPDATE_CN: - meas_avg_mode = SCHED_MEAS_AVG_M8_FIRST_QUAD; + meas_avg_mode = SCHED_MEAS_AVG_M_S8N4; break; case AFS_SID_UPDATE: case AFS_ONSET: - meas_avg_mode = SCHED_MEAS_AVG_M_QUAD; + meas_avg_mode = SCHED_MEAS_AVG_M_S4N4; break; } - if (rc) - trx_loop_amr_input(chan_state, n_errors, n_bits_total); /* only good speech frames get rtp header */ if (rc != GSM_MACBLOCK_LEN && rc >= 4) { if (chan_state->amr_last_dtx == AMR_OTHER) { - ft = chan_state->codec[chan_state->ul_cmr]; + ft = chan_state->codec[chan_state->ul_ft]; } else { /* SID frames will always get Frame Type Index 8 (AMR_SID) */ ft = AMR_SID; @@ -197,44 +250,70 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) } break; + /* CSD (TCH/F9.6): 12.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_12k0: + /* FACCH/F does not steal TCH/F9.6 frames, but only disturbs some bits */ + decode_fr_facch(l1ts, bi); + rc = gsm0503_tch_fr96_decode(&tch_data[0], BUFPOS(bursts_p, 0), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S24N22; + break; + /* CSD (TCH/F4.8): 6.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_6k0: + /* FACCH/F does not steal TCH/F4.8 frames, but only disturbs some bits */ + decode_fr_facch(l1ts, bi); + rc = gsm0503_tch_fr48_decode(&tch_data[0], BUFPOS(bursts_p, 0), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S24N22; + break; + /* CSD (TCH/F2.4): 3.6 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_3k6: + /* TCH/F2.4 employs the same interleaving as TCH/FS (8 bursts), + * so FACCH/F *does* steal TCH/F2.4 frames completely. */ + if (decode_fr_facch(l1ts, bi) == GSM_MACBLOCK_LEN) + return 0; /* TODO: emit BFI */ + rc = gsm0503_tch_fr24_decode(&tch_data[0], BUFTAIL8(bursts_p), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S8N8; + break; + /* CSD (TCH/F14.4): 14.5 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_14k5: + /* FACCH/F does not steal TCH/F14.4 frames, but only disturbs some bits */ + decode_fr_facch(l1ts, bi); + rc = gsm0503_tch_fr144_decode(&tch_data[0], BUFPOS(bursts_p, 0), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S24N22; + break; default: LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, "TCH mode %u invalid, please fix!\n", tch_mode); return -EINVAL; } - memcpy(*bursts_p, *bursts_p + 464, 464); + + ber10k = compute_ber10k(n_bits_total, n_errors); /* average measurements of the last N (depends on mode) bursts */ trx_sched_meas_avg(chan_state, &meas_avg, meas_avg_mode); + /* meas_avg.fn now contains TDMA frame number of the first burst */ + fn_begin = meas_avg.fn; + + if (tch_mode == GSM48_CMODE_SPEECH_AMR) + trx_loop_amr_input(chan_state, &meas_avg); /* Check if the frame is bad */ - if (rc < 0) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); - bfi_flag = true; - } else if (rc < 4) { + if (rc < 4) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, - "Received bad data (%u/%u) with invalid codec mode %d\n", - bi->fn % l1ts->mf_period, l1ts->mf_period, rc); - bfi_flag = true; - } - - if (rc != GSM_MACBLOCK_LEN && lchan->ecu_state) - osmo_ecu_frame_in(lchan->ecu_state, bfi_flag, tch_data, rc); - - ber10k = compute_ber10k(n_bits_total, n_errors); - if (bfi_flag) - goto bfi; - - /* FACCH */ - if (rc == GSM_MACBLOCK_LEN) { - fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_F); + BAD_DATA_MSG_FMT "\n", BAD_DATA_MSG_ARGS); + rc = 0; /* this is how we signal BFI to l1sap */ + } else if (rc == GSM_MACBLOCK_LEN) { /* FACCH/F */ _sched_compose_ph_data_ind(l1ts, fn_begin, bi->chan, - tch_data + amr, GSM_MACBLOCK_LEN, - meas_avg.rssi, meas_avg.toa256, - meas_avg.ci_cb, ber10k, - PRES_INFO_UNKNOWN); + &tch_data[amr], GSM_MACBLOCK_LEN, + ber10k, + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, + PRES_INFO_UNKNOWN); /* If we are in SPEECH mode we will generate a fake (BFI) TCH * indication as well. This indication is needed by the higher @@ -244,184 +323,82 @@ int rx_tchf_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) * the fake (BFI) TCH indication we set meas_avg.rssi to zero. * Doing so tells l1sap.c to ignore the measurement result. */ meas_avg.rssi = 0; - -bfi: - if (rsl_cmode == RSL_CMOD_SPD_SPEECH) { - /* indicate bad frame */ - if (lchan->tch.dtx.ul_sid) { - /* DTXu: pause in progress. Push empty payload to upper layers */ - rc = 0; - goto compose_l1sap; - } - - /* If there is an ECU active on this channel, use its output */ - if (lchan->ecu_state) { - rc = osmo_ecu_frame_out(lchan->ecu_state, tch_data); - if (rc >= 0) /* Otherwise we send a BFI */ - goto compose_l1sap; - } - - switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* FR */ - memset(tch_data, 0, GSM_FR_BYTES); - tch_data[0] = 0xd0; - rc = GSM_FR_BYTES; - break; - case GSM48_CMODE_SPEECH_EFR: /* EFR */ - memset(tch_data, 0, GSM_EFR_BYTES); - tch_data[0] = 0xc0; - rc = GSM_EFR_BYTES; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - rc = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->dl_cmr], - chan_state->codec[chan_state->dl_ft], - AMR_BAD); - if (rc < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", rc); - return -EINVAL; - } - memset(tch_data + 2, 0, rc - 2); - break; - default: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "TCH mode %u invalid, please fix!\n", tch_mode); - return -EINVAL; - } - } + rc = 0; } - if (rsl_cmode != RSL_CMOD_SPD_SPEECH) + if (rsl_cmode == RSL_CMOD_SPD_SIGN) return 0; /* TCH or BFI */ -compose_l1sap: - fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F); - return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, tch_data, rc, - /* FIXME: what should we use for BFI here? */ - bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k, - bfi_flag ? bi->rssi : meas_avg.rssi, is_sub); + return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, + &tch_data[0], rc, + ber10k, + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, + is_sub); } /* common section for generation of TCH bursts (TCH/H and TCH/F). * FIXME: this function is over-complicated, refactor / get rid of it. */ -void tx_tch_common(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br, - struct msgb **_msg_tch, struct msgb **_msg_facch) +void tch_dl_dequeue(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br, + struct msgb **msg_tch, struct msgb **msg_facch) { - struct msgb *msg1, *msg2, *msg_tch = NULL, *msg_facch = NULL; + struct msgb *msg1, *msg2; struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; struct osmo_phsap_prim *l1sap; - /* handle loss detection of received TCH frames */ - if (rsl_cmode == RSL_CMOD_SPD_SPEECH - && ++(chan_state->lost_frames) > 5) { - uint8_t tch_data[GSM_FR_BYTES]; - int len; - - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Missing TCH bursts detected, sending BFI\n"); - - /* indicate bad frame */ - switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* FR / HR */ - if (br->chan != TRXC_TCHF) { /* HR */ - tch_data[0] = 0x70; /* F = 0, FT = 111 */ - memset(tch_data + 1, 0, 14); - len = 15; - break; - } - memset(tch_data, 0, GSM_FR_BYTES); - len = GSM_FR_BYTES; - break; - case GSM48_CMODE_SPEECH_EFR: /* EFR */ - if (br->chan != TRXC_TCHF) - goto inval_mode1; - memset(tch_data, 0, GSM_EFR_BYTES); - len = GSM_EFR_BYTES; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - len = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->dl_cmr], - chan_state->codec[chan_state->dl_ft], AMR_BAD); - if (len < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", len); - return; - } - memset(tch_data + 2, 0, len - 2); - break; - default: -inval_mode1: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n"); - len = 0; - } - - if (len) { - /* Note: RSSI/ToA256 is set to 0 to indicate to the higher - * layers that this is a faked tch_ind */ - _sched_compose_tch_ind(l1ts, br->fn, br->chan, - tch_data, len, 0, 10000, 0, 0); - } - } - /* get frame and unlink from queue */ msg1 = _sched_dequeue_prim(l1ts, br); msg2 = _sched_dequeue_prim(l1ts, br); if (msg1) { l1sap = msgb_l1sap_prim(msg1); if (l1sap->oph.primitive == PRIM_TCH) { - msg_tch = msg1; + *msg_tch = msg1; if (msg2) { l1sap = msgb_l1sap_prim(msg2); if (l1sap->oph.primitive == PRIM_TCH) { LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "TCH twice, please FIX!\n"); msgb_free(msg2); } else - msg_facch = msg2; + *msg_facch = msg2; } } else { - msg_facch = msg1; + *msg_facch = msg1; if (msg2) { l1sap = msgb_l1sap_prim(msg2); if (l1sap->oph.primitive != PRIM_TCH) { LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "FACCH twice, please FIX!\n"); msgb_free(msg2); } else - msg_tch = msg2; + *msg_tch = msg2; } } - } else if (msg2) { - l1sap = msgb_l1sap_prim(msg2); - if (l1sap->oph.primitive == PRIM_TCH) - msg_tch = msg2; - else - msg_facch = msg2; } /* check validity of message */ - if (msg_facch && msgb_l2len(msg_facch) != GSM_MACBLOCK_LEN) { + if (*msg_facch != NULL && msgb_l2len(*msg_facch) != GSM_MACBLOCK_LEN) { LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim has odd len=%u != %u\n", - msgb_l2len(msg_facch), GSM_MACBLOCK_LEN); + msgb_l2len(*msg_facch), GSM_MACBLOCK_LEN); /* free message */ - msgb_free(msg_facch); - msg_facch = NULL; + msgb_free(*msg_facch); + *msg_facch = NULL; } /* check validity of message, get AMR ft and cmr */ - if (!msg_facch && msg_tch) { + if (*msg_tch != NULL) { int len; uint8_t cmr_codec; - int cmr, ft, i; + int ft, i; enum osmo_amr_type ft_codec; enum osmo_amr_quality bfi; int8_t sti, cmi; + bool amr_is_cmr; - if (rsl_cmode != RSL_CMOD_SPD_SPEECH) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping speech frame, " + if (OSMO_UNLIKELY(rsl_cmode == RSL_CMOD_SPD_SIGN)) { + LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Dropping a TCH frame, " "because we are not in speech mode\n"); goto free_bad_msg; } @@ -429,7 +406,7 @@ inval_mode1: switch (tch_mode) { case GSM48_CMODE_SPEECH_V1: /* FR / HR */ if (br->chan != TRXC_TCHF) /* HR */ - len = 15; + len = GSM_HR_BYTES; else len = GSM_FR_BYTES; break; @@ -439,31 +416,28 @@ inval_mode1: len = GSM_EFR_BYTES; break; case GSM48_CMODE_SPEECH_AMR: /* AMR */ - len = osmo_amr_rtp_dec(msg_tch->l2h, msgb_l2len(msg_tch), + len = osmo_amr_rtp_dec(msgb_l2((*msg_tch)), msgb_l2len(*msg_tch), &cmr_codec, &cmi, &ft_codec, &bfi, &sti); - cmr = -1; + if (len < 0) { + LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send invalid AMR payload\n"); + goto free_bad_msg; + } ft = -1; for (i = 0; i < chan_state->codecs; i++) { - if (chan_state->codec[i] == cmr_codec) - cmr = i; if (chan_state->codec[i] == ft_codec) ft = i; } - if (cmr >= 0) { /* new request */ - chan_state->dl_cmr = cmr; - /* disable AMR loop */ - trx_loop_amr_set(chan_state, 0); - } else { - /* enable AMR loop */ - trx_loop_amr_set(chan_state, 1); - } if (ft < 0) { LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Codec (FT = %d) of RTP frame not in list\n", ft_codec); goto free_bad_msg; } - if (fn_is_codec_mode_request(br->fn) && chan_state->dl_ft != ft) { + if (br->chan == TRXC_TCHF) + amr_is_cmr = !sched_tchf_dl_amr_cmi_map[br->fn % 26]; + else /* TRXC_TCHH_0 or TRXC_TCHH_1 */ + amr_is_cmr = !sched_tchh_dl_amr_cmi_map[br->fn % 26]; + if (amr_is_cmr && chan_state->dl_ft != ft) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Codec (FT = %d) " " of RTP cannot be changed now, but in next frame\n", ft_codec); goto free_bad_msg; @@ -473,100 +447,230 @@ inval_mode1: LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Transmitting 'bad AMR frame'\n"); goto free_bad_msg; } + /* pull the AMR header, it's not being sent over Um */ + (*msg_tch)->l2h += sizeof(struct amr_hdr); + len -= sizeof(struct amr_hdr); + break; + case GSM48_CMODE_DATA_14k5: /* TCH/F14.4 */ + if (OSMO_UNLIKELY(br->chan != TRXC_TCHF)) + goto inval_mode2; + len = 290; + break; + case GSM48_CMODE_DATA_12k0: /* TCH/F9.6 */ + if (OSMO_UNLIKELY(br->chan != TRXC_TCHF)) + goto inval_mode2; + len = 4 * 60; + break; + case GSM48_CMODE_DATA_6k0: /* TCH/[FH]4.8 */ + if (br->chan == TRXC_TCHF) + len = 2 * 60; + else + len = 4 * 60; + break; + case GSM48_CMODE_DATA_3k6: /* TCH/[FH]2.4 */ + if (br->chan == TRXC_TCHF) + len = 2 * 36; + else + len = 4 * 36; break; default: inval_mode2: LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "TCH mode invalid, please fix!\n"); goto free_bad_msg; } - if (len < 0) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send invalid AMR payload\n"); - goto free_bad_msg; - } - if (msgb_l2len(msg_tch) != len) { + if (msgb_l2len(*msg_tch) != len) { LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot send payload with " "invalid length! (expecting %d, received %d)\n", - len, msgb_l2len(msg_tch)); + len, msgb_l2len(*msg_tch)); free_bad_msg: /* free message */ - msgb_free(msg_tch); - msg_tch = NULL; - goto send_frame; + msgb_free(*msg_tch); + *msg_tch = NULL; } } +} + +struct msgb *tch_dummy_msgb(size_t size, uint8_t pad) +{ + struct msgb *msg; + + msg = msgb_alloc(size, __func__); + OSMO_ASSERT(msg != NULL); -send_frame: - *_msg_tch = msg_tch; - *_msg_facch = msg_facch; + msg->l2h = msgb_put(msg, size); + memset(msg->l2h, pad, size); + + return msg; } /* obtain a to-be-transmitted TCH/F (Full Traffic Channel) burst */ int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { - struct msgb *msg_tch = NULL, *msg_facch = NULL; struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; uint8_t tch_mode = chan_state->tch_mode; - ubit_t *burst, **bursts_p = &chan_state->dl_bursts; + ubit_t *burst, *bursts_p = chan_state->dl_bursts; + uint8_t *mask = &chan_state->dl_mask; + struct msgb *msg_facch = NULL; + struct msgb *msg_tch = NULL; + struct msgb *msg = NULL; /* send burst, if we already got a frame */ if (br->bid > 0) { - if (!*bursts_p) - return 0; + if ((*mask & 0x01) != 0x01) + return -ENOMSG; goto send_burst; } - tx_tch_common(l1ts, br, &msg_tch, &msg_facch); + *mask = *mask << 4; /* BURST BYPASS */ - /* allocate burst memory, if not already, - * otherwise shift buffer by 4 bursts for interleaving */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 928); - if (!*bursts_p) - return -ENOMEM; - } else { - memcpy(*bursts_p, *bursts_p + 464, 464); - memset(*bursts_p + 464, 0, 464); - } + /* shift buffer by 4 bursts for interleaving */ + memmove(BUFPOS(bursts_p, 0), BUFPOS(bursts_p, 4), 20 * BPLEN); + memset(BUFPOS(bursts_p, 20), 0, 4 * BPLEN); + + /* dequeue a TCH and/or a FACCH message to be transmitted */ + tch_dl_dequeue(l1ts, br, &msg_tch, &msg_facch); + if (msg_tch == NULL && msg_facch == NULL) { + int rc; + + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "No TCH or FACCH prim for transmit.\n"); + /* - If the channel mode is TCH/FS or TCH/EFS, transmit a dummy + * speech block with inverted CRC3, designed to induce a BFI + * condition in the MS receiver. + * - If the channel mode is TCH/AFS, transmit a dummy speech + * block with inverted CRC6, designed to induce a BFI + * condition in the MS receiver. + * - If the channel mode is one of the CSD modes, transmit an + * idle frame as described in 3GPP TS 44.021, sections 8.1.6 + * and 10.2.3 (all data, status and E-bits set to binary '1'). + * - In all other channel modes, transmit dummy FACCH + * like we always did before. + */ + switch (tch_mode) { + case GSM48_CMODE_DATA_12k0: + case GSM48_CMODE_DATA_6k0: + case GSM48_CMODE_DATA_3k6: + case GSM48_CMODE_DATA_14k5: + break; /* see below */ + case GSM48_CMODE_SPEECH_V1: + case GSM48_CMODE_SPEECH_EFR: + rc = gsm0503_tch_fr_encode(BUFPOS(bursts_p, 0), NULL, 0, 1); + if (rc == 0) + goto send_burst; + /* fall-through */ + case GSM48_CMODE_SIGN: + default: + if (tch_mode == GSM48_CMODE_SPEECH_AMR) { + /* the first FN 4,13,21 defines that CMI is included in frame, + * the first FN 0,8,17 defines that CMR is included in frame. + */ + rc = gsm0503_tch_afs_encode(BUFPOS(bursts_p, 0), + NULL, 0, + !sched_tchf_dl_amr_cmi_map[br->fn % 26], + chan_state->codec, + chan_state->codecs, + chan_state->dl_ft, + chan_state->dl_cmr); + if (rc == 0) + goto send_burst; + } - /* no message at all */ - if (!msg_tch && !msg_facch) { - LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n"); - goto send_burst; + /* TODO: use randomized padding */ + msg_facch = tch_dummy_msgb(GSM_MACBLOCK_LEN, GSM_MACBLOCK_PADDING); + /* dummy LAPDm func=UI frame */ + msg_facch->l2h[0] = 0x03; + msg_facch->l2h[1] = 0x03; + msg_facch->l2h[2] = 0x01; + break; + } } - /* encode bursts (prioritize FACCH) */ - if (msg_facch) - gsm0503_tch_fr_encode(*bursts_p, msg_facch->l2h, msgb_l2len(msg_facch), - 1); - else if (tch_mode == GSM48_CMODE_SPEECH_AMR) + /* Unlike SACCH, FACCH has no dedicated slots on the multiframe layout. + * It's multiplexed together with TCH (speech or data) frames basically + * by replacing (stealing) their bits, either completely or partly. */ + msg = (msg_facch != NULL) ? msg_facch : msg_tch; + if (msg == msg_facch) + chan_state->dl_facch_bursts = 8; + + /* populate the buffer with bursts */ + switch (tch_mode) { + case GSM48_CMODE_SIGN: + case GSM48_CMODE_SPEECH_V1: + case GSM48_CMODE_SPEECH_EFR: + gsm0503_tch_fr_encode(BUFPOS(bursts_p, 0), msg->l2h, msgb_l2len(msg), 1); + break; + case GSM48_CMODE_SPEECH_AMR: /* the first FN 4,13,21 defines that CMI is included in frame, * the first FN 0,8,17 defines that CMR is included in frame. */ - gsm0503_tch_afs_encode(*bursts_p, msg_tch->l2h + 2, - msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn), - chan_state->codec, chan_state->codecs, - chan_state->dl_ft, - chan_state->dl_cmr); - else - gsm0503_tch_fr_encode(*bursts_p, msg_tch->l2h, msgb_l2len(msg_tch), 1); - - /* free message */ - if (msg_tch) - msgb_free(msg_tch); - if (msg_facch) - msgb_free(msg_facch); + gsm0503_tch_afs_encode(BUFPOS(bursts_p, 0), + msgb_l2(msg), msgb_l2len(msg), + !sched_tchf_dl_amr_cmi_map[br->fn % 26], + chan_state->codec, + chan_state->codecs, + chan_state->dl_ft, + chan_state->dl_cmr); + break; + /* CSD (TCH/F9.6): 12.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_12k0: + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(4 * 60, 0x01); + gsm0503_tch_fr96_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + if (msg_facch != NULL) + gsm0503_tch_fr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + break; + /* CSD (TCH/F4.8): 6.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_6k0: + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(2 * 60, 0x01); + gsm0503_tch_fr48_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + if (msg_facch != NULL) + gsm0503_tch_fr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + break; + /* CSD (TCH/F2.4): 3.6 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_3k6: + /* FACCH/F does steal a TCH/F2.4 frame completely */ + if (msg_facch != NULL) { + gsm0503_tch_fr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + } else { + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(2 * 36, 0x01); + gsm0503_tch_fr24_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + } + break; + /* CSD (TCH/F14.4): 14.5 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_14k5: + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(290, 0x01); + gsm0503_tch_fr144_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + if (msg_facch != NULL) + gsm0503_tch_fr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + break; + default: + OSMO_ASSERT(0); + } + + /* free messages */ + msgb_free(msg_tch); + msgb_free(msg_facch); send_burst: /* compose burst */ - burst = *bursts_p + br->bid * 116; + burst = BUFPOS(bursts_p, br->bid); memcpy(br->burst + 3, burst, 58); memcpy(br->burst + 61, TRX_GMSK_NB_TSC(br), 26); memcpy(br->burst + 87, burst + 58, 58); br->burst_len = GSM_BURST_LEN; + if (chan_state->dl_facch_bursts > 0) { + chan_state->dl_facch_bursts--; + br->flags |= TRX_BR_F_FACCH; + } + + *mask |= (1 << br->bid); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid); return 0; diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index 4f03bd12..66244cb0 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -1,7 +1,7 @@ /* * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> * (C) 2015-2017 by Harald Welte <laforge@gnumonks.org> - * Contributions by sysmocom - s.f.m.c. GmbH + * (C) 2020-2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -30,11 +30,12 @@ #include <osmocom/gsm/gsm0502.h> #include <osmocom/codec/codec.h> -#include <osmocom/codec/ecu.h> #include <osmocom/coding/gsm0503_coding.h> #include <osmocom/coding/gsm0503_amr_dtx.h> +#include <osmocom/netif/amr.h> + #include <osmo-bts/bts.h> #include <osmo-bts/l1sap.h> #include <osmo-bts/logging.h> @@ -43,35 +44,138 @@ #include <osmo-bts/msg_utils.h> #include <sched_utils.h> -#include <loops.h> +#include <amr_loop.h> -/*! \brief a single TCH/H burst was received by the PHY, process it */ +/* 3GPP TS 45.009, table 3.2.1.3-{2,4}: AMR on Uplink TCH/H. + * + * +---+---+---+---+---+---+ + * | a | b | c | d | e | f | Burst 'a' received first + * +---+---+---+---+---+---+ + * ^^^^^^^^^^^^^^^^^^^^^^^ FACCH frame (bursts 'a' .. 'f') + * ^^^^^^^^^^^^^^^ Speech frame (bursts 'a' .. 'd') + * + * TDMA frame number of burst 'f' is always used as the table index. */ +static const uint8_t sched_tchh_ul_amr_cmi_map[26] = { + [10] = 1, /* TCH/H(0): a=0 / d=6 / f=10 */ + [19] = 1, /* TCH/H(0): a=8 / d=15 / f=19 */ + [2] = 1, /* TCH/H(0): a=17 / d=23 / f=2 */ + + [11] = 1, /* TCH/H(1): a=1 / d=7 / f=11 */ + [20] = 1, /* TCH/H(1): a=9 / d=16 / f=20 */ + [3] = 1, /* TCH/H(1): a=18 / d=24 / f=3 */ +}; + +/* TDMA frame number of burst 'a' should be used as the table index. + * This mapping is valid for both FACCH/H(0) and FACCH/H(1). */ +const uint8_t sched_tchh_dl_amr_cmi_map[26] = { + [4] = 1, /* TCH/H(0): a=4 */ + [13] = 1, /* TCH/H(0): a=13 */ + [21] = 1, /* TCH/H(0): a=21 */ + + [5] = 1, /* TCH/H(1): a=5 */ + [14] = 1, /* TCH/H(1): a=14 */ + [22] = 1, /* TCH/H(1): a=22 */ +}; + +/* 3GPP TS 45.002, table 1 in clause 7: Mapping tables. + * TDMA frame number of burst 'f' is always used as the table index. */ +static const uint8_t sched_tchh_ul_facch_map[26] = { + [10] = 1, /* FACCH/H(0): B0(0,2,4,6,8,10) */ + [11] = 1, /* FACCH/H(1): B0(1,3,5,7,9,11) */ + [19] = 1, /* FACCH/H(0): B1(8,10,13,15,17,19) */ + [20] = 1, /* FACCH/H(1): B1(9,11,14,16,18,20) */ + [2] = 1, /* FACCH/H(0): B2(17,19,21,23,0,2) */ + [3] = 1, /* FACCH/H(1): B2(18,20,22,24,1,3) */ +}; + +/* TDMA frame number of burst 'a' is used as the table index. */ +extern const uint8_t sched_tchh_dl_facch_map[26]; + +/* 3GPP TS 45.002, table 2 in clause 7: Mapping tables for TCH/H2.4 and TCH/H4.8. + * + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | + * +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ + * + * TCH/H(0): B0(0,2,4,6,8,10,13,15,17,19,21,23,0,2,4,6,8,10,13,15,17,19) + * TCH/H(1): B0(1,3,5,7,9,11,14,16,18,20,22,24,1,3,5,7,9,11,14,16,18,20) + * TCH/H(0): B1(8,10,13,15,17,19,21,23,0,2,4,6,8,10,13,15,17,19,21,23,0,2) + * TCH/H(1): B1(9,11,14,16,18,20,22,24,1,3,5,7,9,11,14,16,18,20,22,24,1,3) + * TCH/H(0): B2(17,19,21,23,0,2,4,6,8,10,13,15,17,19,21,23,0,2,4,6,8,10) + * TCH/H(1): B2(18,20,22,24,1,3,5,7,9,11,14,16,18,20,22,24,1,3,5,7,9,11) + * + * TDMA frame number of burst 'v' % 26 is the table index. + * This mapping is valid for both TCH/H(0) and TCH/H(1). */ +static const uint8_t sched_tchh_ul_csd_map[26] = { + [19] = 1, /* TCH/H(0): B0(0 ... 19) */ + [20] = 1, /* TCH/H(1): B0(1 ... 20) */ + [2] = 1, /* TCH/H(0): B1(8 ... 2) */ + [3] = 1, /* TCH/H(1): B1(9 ... 3) */ + [10] = 1, /* TCH/H(0): B2(17 ... 10) */ + [11] = 1, /* TCH/H(1): B2(18 ... 11) */ +}; + +/* TDMA frame number of burst 'a' % 26 is the table index. + * This mapping is valid for both TCH/H(0) and TCH/H(1). */ +static const uint8_t sched_tchh_dl_csd_map[26] = { + [0] = 1, /* TCH/H(0): B0(0 ... 19) */ + [1] = 1, /* TCH/H(1): B0(1 ... 20) */ + [8] = 1, /* TCH/H(0): B1(8 ... 2) */ + [9] = 1, /* TCH/H(1): B1(9 ... 3) */ + [17] = 1, /* TCH/H(0): B2(17 ... 10) */ + [18] = 1, /* TCH/H(1): B2(18 ... 11) */ +}; + +static int decode_hr_facch(struct l1sched_ts *l1ts, + const struct trx_ul_burst_ind *bi) +{ + struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; + const sbit_t *bursts_p = chan_state->ul_bursts; + struct l1sched_meas_set meas_avg; + uint8_t data[GSM_MACBLOCK_LEN]; + int n_errors, n_bits_total; + int rc; + + rc = gsm0503_tch_hr_facch_decode(&data[0], BUFTAIL8(bursts_p), + &n_errors, &n_bits_total); + if (rc != GSM_MACBLOCK_LEN) + return rc; + + /* average measurements of the last 6 bursts, obtain TDMA Fn of the first burst */ + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_S6N6); + + _sched_compose_ph_data_ind(l1ts, meas_avg.fn, bi->chan, + &data[0], GSM_MACBLOCK_LEN, + compute_ber10k(n_bits_total, n_errors), + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, + PRES_INFO_UNKNOWN); + return GSM_MACBLOCK_LEN; +} + +/* Process a single Uplink TCH/H burst received by the PHY. + * This function is visualized in file 'doc/trx_sched_tch.txt'. */ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) { struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; struct gsm_lchan *lchan = chan_state->lchan; - sbit_t *burst, **bursts_p = &chan_state->ul_bursts; - uint8_t *mask = &chan_state->ul_mask; + sbit_t *burst, *bursts_p = chan_state->ul_bursts; + uint32_t *mask = &chan_state->ul_mask; uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; - uint8_t tch_data[128]; /* just to be safe */ - int rc, amr = 0; + uint8_t tch_data[240]; /* large enough to hold 240 unpacked bits for CSD */ + int rc = 0; /* initialize to make gcc happy */ + int amr = 0; int n_errors = 0; int n_bits_total = 0; - bool bfi_flag = false; - /* Note on FN-10: If we are at FN 10, we decoded an even aligned - * TCH/FACCH frame, because our burst buffer carries 6 bursts. - * Even FN ending at: 10,11,19,20,2,3 - */ - int fn_is_odd = (((bi->fn + 26 - 10) % 26) >> 2) & 1; - enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_QUAD; + enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_S6N4; struct l1sched_meas_set meas_avg; unsigned int fn_begin; - unsigned int fn_tch_end; - uint16_t ber10k; + uint16_t ber10k = 0; uint8_t is_sub = 0; uint8_t ft; - bool mask_stolen_tch_block = false; + bool fn_is_cmi; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -80,17 +184,11 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received TCH/H, bid=%u\n", bi->bid); - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 696); - if (!*bursts_p) - return -ENOMEM; - } - - /* clear burst */ + /* shift the buffer by 2 bursts leftwards */ if (bi->bid == 0) { - memset(*bursts_p + 464, 0, 232); - *mask = 0x0; + memmove(BUFPOS(bursts_p, 0), BUFPOS(bursts_p, 2), 20 * BPLEN); + memset(BUFPOS(bursts_p, 20), 0, 2 * BPLEN); + *mask = *mask << 2; } /* update mask */ @@ -99,55 +197,52 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) /* store measurements */ trx_sched_meas_push(chan_state, bi); - /* copy burst to end of buffer of 6 bursts */ - burst = *bursts_p + bi->bid * 116 + 464; + /* copy burst to end of buffer of 24 bursts */ + burst = BUFPOS(bursts_p, 20 + bi->bid); if (bi->burst_len > 0) { memcpy(burst, bi->burst + 3, 58); memcpy(burst + 58, bi->burst + 87, 58); - } else - memset(burst, 0, 116); + } /* wait until complete set of bursts */ if (bi->bid != 1) return 0; - /* check for complete set of bursts */ - if ((*mask & 0x3) != 0x3) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, - "Received incomplete frame (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); + /* fill up the burst buffer so that we have 6 bursts in there */ + if (OSMO_UNLIKELY((*mask & 0x3f) != 0x3f)) { + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, + "UL burst buffer is not filled up: mask=0x%02x != 0x3f\n", + *mask); + return 0; /* TODO: send BFI */ } - *mask = 0x0; /* skip decoding of the last 4 bursts of FACCH/H */ if (chan_state->ul_ongoing_facch) { chan_state->ul_ongoing_facch = 0; - memcpy(*bursts_p, *bursts_p + 232, 232); - memcpy(*bursts_p + 232, *bursts_p + 464, 232); /* we have already sent the first BFI when a FACCH/H frame * was decoded (see below), now send the second one. */ - ber10k = 0; - memset(&meas_avg, 0, sizeof(meas_avg)); - /* In order to provide an even stream of measurement reports - * we ask the code below to mask the missing TCH/H block - * measurement report with the FACCH measurement results. */ - mask_stolen_tch_block = true; + trx_sched_meas_avg(chan_state, &meas_avg, meas_avg_mode); + /* meas_avg.fn now contains TDMA frame number of the first burst */ + fn_begin = meas_avg.fn; goto bfi; } - /* decode - * also shift buffer by 4 bursts for interleaving */ - switch ((rsl_cmode != RSL_CMOD_SPD_SPEECH) ? GSM48_CMODE_SPEECH_V1 - : tch_mode) { + /* TCH/H: speech and signalling frames are interleaved over 4 and 6 bursts, + * respectively, while CSD frames are interleaved over 22 bursts. Unless + * we're in CSD mode, decode only the last 6 bursts to avoid introducing + * additional delays. */ + switch (tch_mode) { + case GSM48_CMODE_SIGN: + meas_avg_mode = SCHED_MEAS_AVG_M_S6N6; + /* fall-through */ case GSM48_CMODE_SPEECH_V1: /* HR or signalling */ - /* Note on FN-10: If we are at FN 10, we decoded an even aligned - * TCH/FACCH frame, because our burst buffer carries 6 bursts. - * Even FN ending at: 10,11,19,20,2,3 - */ - rc = gsm0503_tch_hr_decode(tch_data, *bursts_p, - fn_is_odd, &n_errors, &n_bits_total); - if (rc >= 0) /* DTXu */ - lchan_set_marker(osmo_hr_check_sid(tch_data, rc), lchan); + rc = gsm0503_tch_hr_decode2(tch_data, BUFTAIL8(bursts_p), + !sched_tchh_ul_facch_map[bi->fn % 26], + &n_errors, &n_bits_total); + if (rc == GSM_HR_BYTES) { /* only for valid *speech* frames */ + bool is_sid = osmo_hr_check_sid(tch_data, GSM_HR_BYTES); + lchan_set_marker(is_sid, lchan); /* DTXu */ + } break; case GSM48_CMODE_SPEECH_AMR: /* AMR */ /* the first FN 0,8,17 or 1,9,18 defines that CMI is included @@ -164,17 +259,23 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) break; } + fn_is_cmi = sched_tchh_ul_amr_cmi_map[bi->fn % 26]; + /* See comment in function rx_tchf_fn() */ - amr = 2; - rc = gsm0503_tch_ahs_decode_dtx(tch_data + amr, *bursts_p, - fn_is_odd, fn_is_odd, chan_state->codec, - chan_state->codecs, &chan_state->ul_ft, - &chan_state->ul_cmr, &n_errors, &n_bits_total, &chan_state->amr_last_dtx); + amr = sizeof(struct amr_hdr); + rc = gsm0503_tch_ahs_decode_dtx(tch_data + amr, BUFTAIL8(bursts_p), + !sched_tchh_ul_facch_map[bi->fn % 26], + !fn_is_cmi, chan_state->codec, + chan_state->codecs, &chan_state->ul_ft, + &chan_state->ul_cmr, &n_errors, &n_bits_total, + &chan_state->amr_last_dtx); /* Tag all frames that are not regular AMR voice frames as SUB-Frames */ if (chan_state->amr_last_dtx != AMR_OTHER) { - LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received AMR SID frame: %s\n", + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, + "Received AMR DTX frame (rc=%d, BER %d/%d): %s\n", + rc, n_errors, n_bits_total, gsm0503_amr_dtx_frame_name(chan_state->amr_last_dtx)); is_sub = 1; } @@ -197,20 +298,17 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) case AHS_SID_UPDATE_CN: case AHS_SID_FIRST_INH: case AHS_SID_UPDATE_INH: - meas_avg_mode = SCHED_MEAS_AVG_M6_FIRST_TWO; + meas_avg_mode = SCHED_MEAS_AVG_M_S6N2; break; case AHS_ONSET: - meas_avg_mode = SCHED_MEAS_AVG_M6_MIDDLE_TWO; + meas_avg_mode = SCHED_MEAS_AVG_M_S4N2; break; } - if (rc) - trx_loop_amr_input(chan_state, n_errors, n_bits_total); - /* only good speech frames get rtp header */ if (rc != GSM_MACBLOCK_LEN && rc >= 4) { if (chan_state->amr_last_dtx == AMR_OTHER) { - ft = chan_state->codec[chan_state->ul_cmr]; + ft = chan_state->codec[chan_state->ul_ft]; } else { /* SID frames will always get Frame Type Index 8 (AMR_SID) */ ft = AMR_SID; @@ -221,241 +319,261 @@ int rx_tchh_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) } break; + /* CSD (TCH/H4.8): 6.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_6k0: + if (!sched_tchh_ul_csd_map[bi->fn % 26]) + return 0; /* CSD: skip decoding attempt, need 2 more bursts */ + /* FACCH/H does not steal TCH/H4.8 frames, but only disturbs some bits */ + decode_hr_facch(l1ts, bi); + rc = gsm0503_tch_hr48_decode(&tch_data[0], BUFPOS(bursts_p, 0), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S22N22; + break; + /* CSD (TCH/H2.4): 3.6 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_3k6: + if (!sched_tchh_ul_csd_map[bi->fn % 26]) + return 0; /* CSD: skip decoding attempt, need 2 more bursts */ + /* FACCH/H does not steal TCH/H2.4 frames, but only disturbs some bits */ + decode_hr_facch(l1ts, bi); + rc = gsm0503_tch_hr24_decode(&tch_data[0], BUFPOS(bursts_p, 0), + &n_errors, &n_bits_total); + meas_avg_mode = SCHED_MEAS_AVG_M_S22N22; + break; default: LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, "TCH mode %u invalid, please fix!\n", tch_mode); return -EINVAL; } - memcpy(*bursts_p, *bursts_p + 232, 232); - memcpy(*bursts_p + 232, *bursts_p + 464, 232); + ber10k = compute_ber10k(n_bits_total, n_errors); /* average measurements of the last N (depends on mode) bursts */ - if (rc == GSM_MACBLOCK_LEN) - meas_avg_mode = SCHED_MEAS_AVG_M_SIX; trx_sched_meas_avg(chan_state, &meas_avg, meas_avg_mode); + /* meas_avg.fn now contains TDMA frame number of the first burst */ + fn_begin = meas_avg.fn; + + if (tch_mode == GSM48_CMODE_SPEECH_AMR) + trx_loop_amr_input(chan_state, &meas_avg); /* Check if the frame is bad */ - if (rc < 0) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); - bfi_flag = true; - } else if (rc < 4) { + if (rc < 4) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, - "Received bad data (%u/%u) with invalid codec mode %d\n", - bi->fn % l1ts->mf_period, l1ts->mf_period, rc); - bfi_flag = true; - } - - if (rc != GSM_MACBLOCK_LEN && lchan->ecu_state) - osmo_ecu_frame_in(lchan->ecu_state, bfi_flag, tch_data, rc); - - if (bfi_flag) - goto bfi; - - /* FACCH */ - if (rc == GSM_MACBLOCK_LEN) { + BAD_DATA_MSG_FMT "\n", BAD_DATA_MSG_ARGS); + rc = 0; /* this is how we signal BFI to l1sap */ + } else if (rc == GSM_MACBLOCK_LEN) { /* FACCH */ chan_state->ul_ongoing_facch = 1; - uint16_t ber10k = compute_ber10k(n_bits_total, n_errors); - if (lchan->nr == 0) - fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H0); - else - fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H1); + /* In order to provide an even stream of measurement reports in *speech* + * mode, here we intentionally invalidate RSSI for FACCH, so that this + * report gets dropped in process_l1sap_meas_data(). The averaged results + * will be sent with the first (see below) and second (see above) BFIs. */ _sched_compose_ph_data_ind(l1ts, fn_begin, bi->chan, - tch_data + amr, GSM_MACBLOCK_LEN, - meas_avg.rssi, meas_avg.toa256, - meas_avg.ci_cb, ber10k, - PRES_INFO_UNKNOWN); - - /* Keep a copy of the measurement results of the last FACCH - * transmission in order to be able to create a replacement - * measurement result for the one missing TCH block - * measurement */ - memcpy(&chan_state->meas_avg_facch, &meas_avg, sizeof(meas_avg)); - chan_state->ber10k_facch = ber10k; - - /* Invalidate the current measurement result to prevent the - * code below from handing up the current measurement a second - * time. */ - memset(&meas_avg, 0, sizeof(meas_avg)); + &tch_data[amr], GSM_MACBLOCK_LEN, + ber10k, + tch_mode == GSM48_CMODE_SIGN ? meas_avg.rssi : 0, + meas_avg.toa256, + meas_avg.ci_cb, + PRES_INFO_UNKNOWN); + ber10k = 0; bfi: /* A FACCH/H frame replaces two speech frames, so we need to send two BFIs. * One is sent here, another will be sent two bursts later (see above). */ - if (rsl_cmode == RSL_CMOD_SPD_SPEECH) { - /* indicate bad frame */ - if (lchan->tch.dtx.ul_sid) { - /* DTXu: pause in progress. Push empty payload to upper layers */ - rc = 0; - goto compose_l1sap; - } - - /* If there is an ECU active on this channel, use its output */ - if (lchan->ecu_state) { - rc = osmo_ecu_frame_out(lchan->ecu_state, tch_data); - if (rc >= 0) /* Otherwise we send a BFI */ - goto compose_l1sap; - } - - switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* HR */ - tch_data[0] = 0x70; /* F = 0, FT = 111 */ - memset(tch_data + 1, 0, 14); - rc = 15; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - rc = osmo_amr_rtp_enc(tch_data, - chan_state->codec[chan_state->dl_cmr], - chan_state->codec[chan_state->dl_ft], - AMR_BAD); - if (rc < 2) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "Failed to encode AMR_BAD frame (rc=%d), " - "not sending BFI\n", rc); - return -EINVAL; - } - memset(tch_data + 2, 0, rc - 2); - break; - default: - LOGL1SB(DL1P, LOGL_ERROR, l1ts, bi, - "TCH mode %u invalid, please fix!\n", tch_mode); - return -EINVAL; - } - } + rc = 0; } - if (rsl_cmode != RSL_CMOD_SPD_SPEECH) + if (rsl_cmode == RSL_CMOD_SPD_SIGN) return 0; -compose_l1sap: /* TCH or BFI */ - - /* The input to gsm0502_fn_remap() needs to get the frame number we - * got two bursts ago. The reason for this is that the burst shift - * buffer we use for decoding is 6 bursts wide (one SACCH block) but - * TCH/H blocks are only 4 bursts wide. The decoder functions look - * at the beginning of the buffer while we shift into it at the end, - * this means that TCH/H blocks always decode delayed by two frame - * number positions late. To calculatue the ending frame number of - * the TCH/H we need to subtract 4 or 5 frames if there was a SACCH - * in between. (Note: this is TCH/H, 4 frames ==> 2 bursts) */ - if (bi->fn % 13 < 4) - fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 5); - else - fn_tch_end = GSM_TDMA_FN_SUB(bi->fn, 4); - - if (lchan->nr == 0) - fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H0); - else - fn_begin = gsm0502_fn_remap(fn_tch_end, FN_REMAP_TCH_H1); - - /* A FACCH/H transmission takes out two TCH/H voice blocks and the - * related measurement results. The first measurement result is handed - * up directly with the FACCH (see above), the second one needs to be - * compensated by filling the gap with the measurement result we got - * from the FACCH transmission. */ - if (mask_stolen_tch_block) { - memcpy(&meas_avg, &chan_state->meas_avg_facch, sizeof(meas_avg)); - ber10k = chan_state->ber10k_facch; - memset(&chan_state->meas_avg_facch, 0, sizeof(meas_avg)); - chan_state->ber10k_facch = 0; - } - - return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, tch_data, rc, - /* FIXME: what should we use for BFI here? */ - bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k, - bfi_flag ? bi->rssi : meas_avg.rssi, is_sub); + return _sched_compose_tch_ind(l1ts, fn_begin, bi->chan, + &tch_data[0], rc, + ber10k, + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, + is_sub); } /* common section for generation of TCH bursts (TCH/H and TCH/F). * FIXME: this function is over-complicated, refactor / get rid of it. */ -extern void tx_tch_common(struct l1sched_ts *l1ts, - const struct trx_dl_burst_req *br, - struct msgb **_msg_tch, struct msgb **_msg_facch); +extern void tch_dl_dequeue(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br, + struct msgb **msg_tch, struct msgb **msg_facch); + +struct msgb *tch_dummy_msgb(size_t size, uint8_t pad); /* obtain a to-be-transmitted TCH/H (Half Traffic Channel) burst */ int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { - struct msgb *msg_tch = NULL, *msg_facch = NULL; struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; uint8_t tch_mode = chan_state->tch_mode; - ubit_t *burst, **bursts_p = &chan_state->dl_bursts; + ubit_t *burst, *bursts_p = chan_state->dl_bursts; + uint8_t *mask = &chan_state->dl_mask; + struct msgb *msg_facch = NULL; + struct msgb *msg_tch = NULL; + struct msgb *msg = NULL; /* send burst, if we already got a frame */ if (br->bid > 0) { - if (!*bursts_p) - return 0; + if ((*mask & 0x01) != 0x01) + return -ENOMSG; goto send_burst; } - /* get TCH and/or FACCH */ - tx_tch_common(l1ts, br, &msg_tch, &msg_facch); + *mask = *mask << 2; + + /* BURST BYPASS */ + + /* shift buffer by 2 bursts for interleaving */ + memmove(BUFPOS(bursts_p, 0), BUFPOS(bursts_p, 2), 20 * BPLEN); + memset(BUFPOS(bursts_p, 20), 0, 2 * BPLEN); - /* check for FACCH alignment */ - if (msg_facch && ((((br->fn + 4) % 26) >> 2) & 1)) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, - "Cannot transmit FACCH starting on even frames, please fix RTS!\n"); - msgb_free(msg_facch); - msg_facch = NULL; + /* for half-rate CSD we dequeue every 4th burst */ + if (chan_state->rsl_cmode == RSL_CMOD_SPD_DATA) { + if (!sched_tchh_dl_csd_map[br->fn % 26]) + goto send_burst; } - /* BURST BYPASS */ + /* dequeue a TCH and/or a FACCH message to be transmitted */ + tch_dl_dequeue(l1ts, br, &msg_tch, &msg_facch); - /* allocate burst memory, if not already, - * otherwise shift buffer by 2 bursts for interleaving */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 696); - if (!*bursts_p) - return -ENOMEM; - } else { - memcpy(*bursts_p, *bursts_p + 232, 232); - if (chan_state->dl_ongoing_facch) { - memcpy(*bursts_p + 232, *bursts_p + 464, 232); - memset(*bursts_p + 464, 0, 232); - } else { - memset(*bursts_p + 232, 0, 232); - } + /* if we're sending 2 middle bursts of FACCH/H */ + if (chan_state->dl_ongoing_facch) { + /* FACCH/H shall not be scheduled at wrong FNs */ + OSMO_ASSERT(msg_facch == NULL); + msgb_free(msg_tch); /* drop 2nd speech frame */ + chan_state->dl_ongoing_facch = 0; + goto send_burst; } - /* no message at all */ - if (!msg_tch && !msg_facch && !chan_state->dl_ongoing_facch) { + /* no message at all, send a dummy L2 frame on FACCH */ + if (msg_tch == NULL && msg_facch == NULL) { + int rc; + LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No TCH or FACCH prim for transmit.\n"); - goto send_burst; + /* - If the channel mode is TCH/HS, transmit a dummy speech block + * with inverted CRC3, designed to induce a BFI condition in + * the MS receiver. + * - If the channel mode is TCH/AHS, transmit a dummy speech + * block with inverted CRC6, designed to induce a BFI + * condition in the MS receiver. + * - If the channel mode is one of the CSD modes, transmit an + * idle frame as described in 3GPP TS 44.021, sections 8.1.6 + * and 10.2.3 (all data, status and E-bits set to binary '1'). + * - In all other channel modes, transmit dummy FACCH + * like we always did before. + */ + switch (tch_mode) { + case GSM48_CMODE_DATA_6k0: + case GSM48_CMODE_DATA_3k6: + break; /* see below */ + case GSM48_CMODE_SPEECH_V1: + rc = gsm0503_tch_hr_encode(BUFPOS(bursts_p, 0), NULL, 0); + if (rc == 0) + goto send_burst; + /* fall-through */ + case GSM48_CMODE_SIGN: + default: + if (tch_mode == GSM48_CMODE_SPEECH_AMR) { + /* the first FN 4,13,21 or 5,14,22 defines that CMI is included + * in frame, the first FN 0,8,17 or 1,9,18 defines that CMR is + * included in frame. */ + rc = gsm0503_tch_ahs_encode(BUFPOS(bursts_p, 0), + NULL, 0, + !sched_tchh_dl_amr_cmi_map[br->fn % 26], + chan_state->codec, + chan_state->codecs, + chan_state->dl_ft, + chan_state->dl_cmr); + if (rc == 0) + goto send_burst; + } + + /* FACCH/H can only be scheduled at specific TDMA offset */ + if (!sched_tchh_dl_facch_map[br->fn % 26]) { + /* FACCH/H is not allowed, send half-filled bursts with even numbered + * bits contaning 232 encoded bits of the previous L2 frame, and 232 + * odd numbered bits all set to 0. */ + goto send_burst; + } + + /* TODO: use randomized padding */ + msg_facch = tch_dummy_msgb(GSM_MACBLOCK_LEN, GSM_MACBLOCK_PADDING); + /* dummy LAPDm func=UI frame */ + msg_facch->l2h[0] = 0x03; + msg_facch->l2h[1] = 0x03; + msg_facch->l2h[2] = 0x01; + break; + } } - /* encode bursts (prioritize FACCH) */ - if (msg_facch) { - gsm0503_tch_hr_encode(*bursts_p, msg_facch->l2h, msgb_l2len(msg_facch)); - chan_state->dl_ongoing_facch = 1; /* first of two TCH frames */ - } else if (chan_state->dl_ongoing_facch) /* second of two TCH frames */ - chan_state->dl_ongoing_facch = 0; /* we are done with FACCH */ - else if (tch_mode == GSM48_CMODE_SPEECH_AMR) + /* Unlike SACCH, FACCH has no dedicated slots on the multiframe layout. + * It's multiplexed together with TCH (speech or data) frames basically + * by replacing (stealing) their bits, either completely or partly. */ + msg = (msg_facch != NULL) ? msg_facch : msg_tch; + if (msg == msg_facch) { + if (chan_state->rsl_cmode != RSL_CMOD_SPD_DATA) + chan_state->dl_ongoing_facch = 1; + chan_state->dl_facch_bursts = 6; + } + + /* populate the buffer with bursts */ + switch (tch_mode) { + case GSM48_CMODE_SIGN: + case GSM48_CMODE_SPEECH_V1: + gsm0503_tch_hr_encode(BUFPOS(bursts_p, 0), msg->l2h, msgb_l2len(msg)); + break; + case GSM48_CMODE_SPEECH_AMR: /* the first FN 4,13,21 or 5,14,22 defines that CMI is included * in frame, the first FN 0,8,17 or 1,9,18 defines that CMR is * included in frame. */ - gsm0503_tch_ahs_encode(*bursts_p, msg_tch->l2h + 2, - msgb_l2len(msg_tch) - 2, fn_is_codec_mode_request(br->fn), - chan_state->codec, chan_state->codecs, - chan_state->dl_ft, - chan_state->dl_cmr); - else - gsm0503_tch_hr_encode(*bursts_p, msg_tch->l2h, msgb_l2len(msg_tch)); - - /* free message */ - if (msg_tch) - msgb_free(msg_tch); - if (msg_facch) - msgb_free(msg_facch); + gsm0503_tch_ahs_encode(BUFPOS(bursts_p, 0), + msgb_l2(msg), msgb_l2len(msg), + !sched_tchh_dl_amr_cmi_map[br->fn % 26], + chan_state->codec, + chan_state->codecs, + chan_state->dl_ft, + chan_state->dl_cmr); + break; + /* CSD (TCH/H4.8): 6.0 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_6k0: + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(4 * 60, 0x01); + gsm0503_tch_hr48_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + if (msg_facch != NULL) + gsm0503_tch_hr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + break; + /* CSD (TCH/H2.4): 3.6 kbit/s radio interface rate */ + case GSM48_CMODE_DATA_3k6: + if (msg_tch == NULL) + msg_tch = tch_dummy_msgb(4 * 36, 0x01); + gsm0503_tch_hr24_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_tch)); + if (msg_facch != NULL) + gsm0503_tch_hr_facch_encode(BUFPOS(bursts_p, 0), msgb_l2(msg_facch)); + break; + default: + OSMO_ASSERT(0); + } + + /* free messages */ + msgb_free(msg_tch); + msgb_free(msg_facch); send_burst: /* compose burst */ - burst = *bursts_p + br->bid * 116; + burst = BUFPOS(bursts_p, br->bid); memcpy(br->burst + 3, burst, 58); memcpy(br->burst + 61, TRX_GMSK_NB_TSC(br), 26); memcpy(br->burst + 87, burst + 58, 58); br->burst_len = GSM_BURST_LEN; + if (chan_state->dl_facch_bursts > 0) { + chan_state->dl_facch_bursts--; + br->flags |= TRX_BR_F_FACCH; + } + + *mask |= (1 << br->bid); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid); return 0; diff --git a/src/osmo-bts-trx/sched_lchan_xcch.c b/src/osmo-bts-trx/sched_lchan_xcch.c index 4bfc101a..0580d33b 100644 --- a/src/osmo-bts-trx/sched_lchan_xcch.c +++ b/src/osmo-bts-trx/sched_lchan_xcch.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -36,23 +36,19 @@ #include <sched_utils.h> /* Add two arrays of sbits */ -static void add_sbits(sbit_t * current, const sbit_t * previous) +static void add_sbits(sbit_t *current, const sbit_t *previous) { - unsigned int i; - for (i = 0; i < 464; i++) { - *current = (*current) / 2 + (*previous) / 2; - current++; - previous++; - } + for (unsigned int i = 0; i < BPLEN * 4; i++) + current[i] = current[i] / 2 + previous[i] / 2; } /*! \brief a single (SDCCH/SACCH) burst was received by the PHY, process it */ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) { struct l1sched_chan_state *chan_state = &l1ts->chan_state[bi->chan]; - sbit_t *burst, **bursts_p = &chan_state->ul_bursts; + sbit_t *burst, *bursts_p = chan_state->ul_bursts; uint32_t *first_fn = &chan_state->ul_first_fn; - uint8_t *mask = &chan_state->ul_mask; + uint32_t *mask = &chan_state->ul_mask; uint8_t l2[GSM_MACBLOCK_LEN], l2_len; struct l1sched_meas_set meas_avg; int n_errors = 0; @@ -60,7 +56,7 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) uint16_t ber10k; int rc; struct gsm_lchan *lchan = chan_state->lchan; - bool rep_sacch = L1SAP_IS_LINK_SACCH(trx_chan_desc[bi->chan].link_id) && lchan->repeated_ul_sacch_active; + bool rep_sacch = L1SAP_IS_LINK_SACCH(trx_chan_desc[bi->chan].link_id) && lchan->rep_acch.ul_sacch_active; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -69,24 +65,11 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) LOGL1SB(DL1P, LOGL_DEBUG, l1ts, bi, "Received Data, bid=%u\n", bi->bid); - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 464); - if (!*bursts_p) - return -ENOMEM; - } - - /* UL-SACCH requires additional memory to keep a copy of each previous - * burst set. */ - if (L1SAP_IS_LINK_SACCH(trx_chan_desc[bi->chan].link_id) && !chan_state->ul_bursts_prev) { - chan_state->ul_bursts_prev = talloc_zero_size(tall_bts_ctx, 464); - if (!chan_state->ul_bursts_prev) - return -ENOMEM; - } - /* clear burst & store frame number of first burst */ if (bi->bid == 0) { - memset(*bursts_p, 0, 464); + if (rep_sacch) /* Keep a copy to ease decoding in the next repetition pass */ + memcpy(BUFPOS(bursts_p, 4), BUFPOS(bursts_p, 0), BPLEN * 4); + memset(BUFPOS(bursts_p, 0), 0, BPLEN * 4); *mask = 0x0; *first_fn = bi->fn; } @@ -99,19 +82,18 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) /* Copy burst to buffer of 4 bursts. If the burst indication contains * no data, ensure that the buffer does not stay uninitialized */ - burst = *bursts_p + bi->bid * 116; + burst = bursts_p + bi->bid * 116; if (bi->burst_len > 0) { memcpy(burst, bi->burst + 3, 58); memcpy(burst + 58, bi->burst + 87, 58); - } else - memset(burst, 0, 58 * 2); + } /* wait until complete set of bursts */ if (bi->bid != 3) return 0; /* average measurements of the last 4 bursts */ - trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_QUAD); + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_S4N4); /* check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { @@ -127,10 +109,10 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) *mask = 0x0; /* decode */ - rc = gsm0503_xcch_decode(l2, *bursts_p, &n_errors, &n_bits_total); + rc = gsm0503_xcch_decode(l2, BUFPOS(bursts_p, 0), &n_errors, &n_bits_total); if (rc) { - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Received bad data (%u/%u)\n", - bi->fn % l1ts->mf_period, l1ts->mf_period); + LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, + BAD_DATA_MSG_FMT "\n", BAD_DATA_MSG_ARGS); l2_len = 0; /* When SACCH Repetition is active, we may try to decode the @@ -138,8 +120,8 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) * information from the previous SACCH block. See also: * 3GPP TS 44.006, section 11.2 */ if (rep_sacch) { - add_sbits(*bursts_p, chan_state->ul_bursts_prev); - rc = gsm0503_xcch_decode(l2, *bursts_p, &n_errors, &n_bits_total); + add_sbits(BUFPOS(bursts_p, 0), BUFPOS(bursts_p, 4)); + rc = gsm0503_xcch_decode(l2, BUFPOS(bursts_p, 0), &n_errors, &n_bits_total); if (rc) { LOGL1SB(DL1P, LOGL_NOTICE, l1ts, bi, "Combining current SACCH block with previous SACCH block also yields bad data (%u/%u)\n", @@ -156,14 +138,12 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) ber10k = compute_ber10k(n_bits_total, n_errors); - /* Keep a copy to ease decoding in the next repetition pass */ - if (rep_sacch) - memcpy(chan_state->ul_bursts_prev, *bursts_p, 464); - - return _sched_compose_ph_data_ind(l1ts, *first_fn, - bi->chan, l2, l2_len, - meas_avg.rssi, meas_avg.toa256, - meas_avg.ci_cb, ber10k, + return _sched_compose_ph_data_ind(l1ts, *first_fn, bi->chan, + &l2[0], l2_len, + ber10k, + meas_avg.rssi, + meas_avg.toa256, + meas_avg.ci_cb, PRES_INFO_UNKNOWN); } @@ -171,79 +151,54 @@ int rx_data_fn(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi) int tx_data_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) { struct msgb *msg = NULL; /* make GCC happy */ - ubit_t *burst, **bursts_p = &l1ts->chan_state[br->chan].dl_bursts; + struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; + ubit_t *burst, *bursts_p = chan_state->dl_bursts; + uint8_t *mask = &chan_state->dl_mask; /* send burst, if we already got a frame */ if (br->bid > 0) { - if (!*bursts_p) - return 0; + if ((*mask & 0x01) != 0x01) + return -ENOMSG; goto send_burst; } + *mask = *mask << 4; + /* get mac block from queue */ msg = _sched_dequeue_prim(l1ts, br); - if (msg) - goto got_msg; - - LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No prim for transmit.\n"); - -no_msg: - /* free burst memory */ - if (*bursts_p) { - talloc_free(*bursts_p); - *bursts_p = NULL; + if (msg == NULL) { + LOGL1SB(DL1P, LOGL_INFO, l1ts, br, "No prim for transmit.\n"); + return -ENODEV; } - return -ENODEV; -got_msg: /* check validity of message */ if (msgb_l2len(msg) != GSM_MACBLOCK_LEN) { LOGL1SB(DL1P, LOGL_FATAL, l1ts, br, "Prim has odd len=%u != %u\n", msgb_l2len(msg), GSM_MACBLOCK_LEN); /* free message */ msgb_free(msg); - goto no_msg; + return -EINVAL; } /* BURST BYPASS */ - /* handle loss detection of SACCH */ - if (L1SAP_IS_LINK_SACCH(trx_chan_desc[br->chan].link_id)) { - /* count and send BFI */ - if (++(l1ts->chan_state[br->chan].lost_frames) > 1) { - /* TODO: Should we pass old TOA here? Otherwise we risk - * unnecessary decreasing TA */ - - /* Note: RSSI is set to 0 to indicate to the higher - * layers that this is a faked ph_data_ind */ - _sched_compose_ph_data_ind(l1ts, 0, br->chan, NULL, 0, - 0, 0, 0, 10000, - PRES_INFO_INVALID); - } - } - - /* allocate burst memory, if not already */ - if (!*bursts_p) { - *bursts_p = talloc_zero_size(tall_bts_ctx, 464); - if (!*bursts_p) - return -ENOMEM; - } - /* encode bursts */ - gsm0503_xcch_encode(*bursts_p, msg->l2h); + gsm0503_xcch_encode(bursts_p, msg->l2h); /* free message */ msgb_free(msg); send_burst: /* compose burst */ - burst = *bursts_p + br->bid * 116; + burst = bursts_p + br->bid * 116; memcpy(br->burst + 3, burst, 58); memcpy(br->burst + 61, TRX_GMSK_NB_TSC(br), 26); memcpy(br->burst + 87, burst + 58, 58); br->burst_len = GSM_BURST_LEN; + *mask |= (1 << br->bid); + LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Transmitting burst=%u.\n", br->bid); return 0; diff --git a/src/osmo-bts-trx/sched_utils.h b/src/osmo-bts-trx/sched_utils.h index 4a1aaf5f..a88e06ee 100644 --- a/src/osmo-bts-trx/sched_utils.h +++ b/src/osmo-bts-trx/sched_utils.h @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -22,10 +22,25 @@ #pragma once #include <stdint.h> -#include <errno.h> + +/* Burst Payload LENgth (short alias) */ +#define BPLEN GSM_NBITS_NB_GMSK_PAYLOAD + +/* Burst BUFfer capacity (in BPLEN units). Why 24? Because CSD frames + * are interleaved over 22 bursts, but on TCH/F we decode every 4th burst, + * so it must be a multiple of 4. See also 'doc/trx_sched_tch.txt'. */ +#define BUFMAX 24 + +/* Burst BUFfer position macros */ +#define BUFPOS(buf, n) &buf[(n) * BPLEN] +#define BUFTAIL8(buf) BUFPOS(buf, (BUFMAX - 8)) extern void *tall_bts_ctx; +#define BAD_DATA_MSG_FMT "Received bad data (rc=%d, BER %d/%d) ending at fn=%u/%u" +#define BAD_DATA_MSG_ARGS \ + rc, n_errors, n_bits_total, bi->fn % l1ts->mf_period, l1ts->mf_period + /* Compute the bit error rate in 1/10000 units */ static inline uint16_t compute_ber10k(int n_bits_total, int n_errors) { @@ -34,9 +49,3 @@ static inline uint16_t compute_ber10k(int n_bits_total, int n_errors) else return 10000 * n_errors / n_bits_total; } - -/* determine if the FN is transmitting a CMR (1) or not (0) */ -static inline int fn_is_codec_mode_request(uint32_t fn) -{ - return (((fn + 4) % 26) >> 2) & 1; -} diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index 0a907fba..00143abe 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -3,7 +3,7 @@ /* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> * (C) 2015 by Alexander Chemeris <Alexander.Chemeris@fairwaves.co> * (C) 2015-2017 by Harald Welte <laforge@gnumonks.org> - * (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> * * All Rights Reserved * @@ -15,7 +15,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -50,88 +50,90 @@ #include "l1_if.h" #include "trx_if.h" +#include "btsconfig.h" + +#ifdef HAVE_SYSTEMTAP +/* include the generated probes header and put markers in code */ +#include "probes.h" +#define TRACE(probe) probe +#define TRACE_ENABLED(probe) probe ## _ENABLED() +#else +/* Wrap the probe to allow it to be removed when no systemtap available */ +#define TRACE(probe) +#define TRACE_ENABLED(probe) (0) +#endif /* HAVE_SYSTEMTAP */ + #define SCHED_FH_PARAMS_FMT "hsn=%u, maio=%u, ma_len=%u" #define SCHED_FH_PARAMS_VALS(ts) \ (ts)->hopping.hsn, (ts)->hopping.maio, (ts)->hopping.arfcn_num -static void ts_report_interf_meas(const struct gsm_bts_trx_ts *ts) +static void lchan_report_interf_meas(const struct gsm_lchan *lchan) { + const struct gsm_bts_trx_ts *ts = lchan->ts; const struct l1sched_ts *l1ts = ts->priv; - unsigned int ln; - - for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) { - const struct gsm_lchan *lchan = &ts->lchan[ln]; - enum trx_chan_type dcch, acch; - int interf_avg; + enum trx_chan_type dcch, acch; + int interf_avg; - /* We're not interested in active channels */ - if (lchan->state == LCHAN_S_ACTIVE) - continue; + /* We're not interested in active CS channels */ + if (lchan->state == LCHAN_S_ACTIVE) { + if (lchan->type != GSM_LCHAN_PDTCH) + return; + } - switch (lchan->type) { - case GSM_LCHAN_SDCCH: - if (ts->pchan == GSM_PCHAN_CCCH_SDCCH4 || - ts->pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) { - dcch = TRXC_SDCCH4_0 + ln; - acch = TRXC_SACCH4_0 + ln; - } else { /* SDCCH/8 otherwise */ - dcch = TRXC_SDCCH8_0 + ln; - acch = TRXC_SACCH8_0 + ln; - } - break; - case GSM_LCHAN_TCH_F: - dcch = TRXC_TCHF; - acch = TRXC_SACCHTF; - break; - case GSM_LCHAN_TCH_H: - dcch = TRXC_TCHH_0 + ln; - acch = TRXC_SACCHTH_0 + ln; - break; - default: - /* Skip other lchan types */ - continue; + switch (lchan->type) { + case GSM_LCHAN_SDCCH: + if (ts->pchan == GSM_PCHAN_CCCH_SDCCH4 || + ts->pchan == GSM_PCHAN_CCCH_SDCCH4_CBCH) { + dcch = TRXC_SDCCH4_0 + lchan->nr; + acch = TRXC_SACCH4_0 + lchan->nr; + } else { /* SDCCH/8 otherwise */ + dcch = TRXC_SDCCH8_0 + lchan->nr; + acch = TRXC_SACCH8_0 + lchan->nr; } + break; + case GSM_LCHAN_TCH_F: + dcch = TRXC_TCHF; + acch = TRXC_SACCHTF; + break; + case GSM_LCHAN_TCH_H: + dcch = TRXC_TCHH_0 + lchan->nr; + acch = TRXC_SACCHTH_0 + lchan->nr; + break; + case GSM_LCHAN_PDTCH: + /* We use idle TDMA frames on PDCH */ + dcch = TRXC_IDLE; + acch = TRXC_IDLE; + break; + default: + /* Skip other lchan types */ + return; + } - OSMO_ASSERT(dcch < ARRAY_SIZE(l1ts->chan_state)); - OSMO_ASSERT(acch < ARRAY_SIZE(l1ts->chan_state)); + OSMO_ASSERT(dcch < ARRAY_SIZE(l1ts->chan_state)); + OSMO_ASSERT(acch < ARRAY_SIZE(l1ts->chan_state)); - interf_avg = (l1ts->chan_state[dcch].meas.interf_avg + - l1ts->chan_state[acch].meas.interf_avg) / 2; + interf_avg = (l1ts->chan_state[dcch].meas.interf_avg + + l1ts->chan_state[acch].meas.interf_avg) / 2; - gsm_lchan_interf_meas_push((struct gsm_lchan *) lchan, interf_avg); - } + gsm_lchan_interf_meas_push((struct gsm_lchan *) lchan, interf_avg); } -static void bts_report_interf_meas(const struct gsm_bts *bts, - const uint32_t fn) +static void bts_report_interf_meas(const struct gsm_bts *bts) { const struct gsm_bts_trx *trx; + unsigned int tn, ln; llist_for_each_entry(trx, &bts->trx_list, list) { - uint8_t pdch_interf[8] = { 0 }; - unsigned int tn, pdch_num = 0; + /* Skip pushing interf_meas for disabled TRX */ + if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED || + trx->bb_transc.mo.nm_state.operational != NM_OPSTATE_ENABLED) + continue; for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; - const struct l1sched_ts *l1ts = ts->priv; - const struct l1sched_chan_state *l1cs; - - /* PS interference reports for the PCU */ - if (ts_pchan(ts) == GSM_PCHAN_PDCH) { - l1cs = &l1ts->chan_state[TRXC_IDLE]; - /* Interference value is encoded as -x dBm */ - pdch_interf[tn] = -1 * l1cs->meas.interf_avg; - pdch_num++; - continue; - } - - /* CS interference reports for the BSC */ - ts_report_interf_meas(ts); + for (ln = 0; ln < ARRAY_SIZE(ts->lchan); ln++) + lchan_report_interf_meas(&ts->lchan[ln]); } - - /* Report interference levels on PDCH to the PCU */ - if (pdch_num > 0) - pcu_tx_interf_ind(bts->nr, trx->nr, fn, pdch_interf); } } @@ -150,9 +152,12 @@ static struct phy_instance *dlfh_route_br(const struct trx_dl_burst_req *br, if (ts->fh_trx_list[idx] != NULL) return ts->fh_trx_list[idx]->pinst; + struct bts_trx_priv *priv = (struct bts_trx_priv *) ts->trx->bts->model_priv; + /* The "cache" may not be filled yet, lookup the transceiver */ llist_for_each_entry(trx, &ts->trx->bts->trx_list, list) { if (trx->arfcn == ts->hopping.arfcn_list[idx]) { + rate_ctr_inc2(priv->ctrs, BTSTRX_CTR_SCHED_DL_FH_CACHE_MISS); ts->fh_trx_list[idx] = trx; return trx->pinst; } @@ -162,8 +167,7 @@ static struct phy_instance *dlfh_route_br(const struct trx_dl_burst_req *br, "for a Downlink burst (fn=%u, tn=%u, " SCHED_FH_PARAMS_FMT ")\n", br->fn, br->tn, SCHED_FH_PARAMS_VALS(ts)); - struct bts_trx_priv *priv = (struct bts_trx_priv *) ts->trx->bts->model_priv; - rate_ctr_inc(rate_ctr_group_get_ctr(priv->ctrs, BTSTRX_CTR_SCHED_DL_FH_NO_CARRIER)); + rate_ctr_inc2(priv->ctrs, BTSTRX_CTR_SCHED_DL_FH_NO_CARRIER); return NULL; } @@ -270,7 +274,7 @@ static void bts_sched_fn(struct gsm_bts *bts, const uint32_t fn) /* Report interference measurements */ if (fn % 104 == 0) /* SACCH period */ - bts_report_interf_meas(bts, fn); + bts_report_interf_meas(bts); /* send time indication */ l1if_mph_time_ind(bts, fn); @@ -295,8 +299,10 @@ static void bts_sched_fn(struct gsm_bts *bts, const uint32_t fn) struct trx_dl_burst_req *br; /* ready-to-send */ + TRACE(OSMO_BTS_TRX_DL_RTS_START(trx->nr, tn, fn)); _sched_rts(l1ts, GSM_TDMA_FN_SUM(fn, plink->u.osmotrx.clock_advance + plink->u.osmotrx.rts_advance)); + TRACE(OSMO_BTS_TRX_DL_RTS_DONE(trx->nr, tn, fn)); /* pre-initialized buffer for the Downlink burst */ br = &pinst->u.osmotrx.br[tn]; @@ -347,7 +353,7 @@ static struct gsm_bts_trx *ulfh_route_bi(const struct trx_ul_burst_ind *bi, bi->fn, bi->tn, SCHED_FH_PARAMS_VALS(&src_trx->ts[bi->tn])); struct bts_trx_priv *priv = (struct bts_trx_priv *) src_trx->bts->model_priv; - rate_ctr_inc(rate_ctr_group_get_ctr(priv->ctrs, BTSTRX_CTR_SCHED_UL_FH_NO_CARRIER)); + rate_ctr_inc2(priv->ctrs, BTSTRX_CTR_SCHED_UL_FH_NO_CARRIER); return NULL; } @@ -621,6 +627,7 @@ void trx_sched_meas_push(struct l1sched_chan_state *chan_state, unsigned int current = chan_state->meas.current; chan_state->meas.buf[current] = (struct l1sched_meas_set) { + .fn = bi->fn, .ci_cb = (bi->flags & TRX_BI_F_CI_CB) ? bi->ci_cb : 0, .toa256 = bi->toa256, .rssi = bi->rssi, @@ -629,6 +636,19 @@ void trx_sched_meas_push(struct l1sched_chan_state *chan_state, chan_state->meas.current = (current + 1) % hist_size; } +/* Measurement averaging mode sets: [MODE] = { SHIFT, NUM } */ +static const uint8_t trx_sched_meas_modeset[][2] = { + [SCHED_MEAS_AVG_M_S24N22] = { 24, 22 }, + [SCHED_MEAS_AVG_M_S22N22] = { 22, 22 }, + [SCHED_MEAS_AVG_M_S4N4] = { 4, 4 }, + [SCHED_MEAS_AVG_M_S8N8] = { 8, 8 }, + [SCHED_MEAS_AVG_M_S6N4] = { 6, 4 }, + [SCHED_MEAS_AVG_M_S6N6] = { 6, 6 }, + [SCHED_MEAS_AVG_M_S8N4] = { 8, 4 }, + [SCHED_MEAS_AVG_M_S6N2] = { 6, 2 }, + [SCHED_MEAS_AVG_M_S4N2] = { 4, 2 }, +}; + /* Calculate the AVG of n measurements from the history */ void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, struct l1sched_meas_set *avg, @@ -637,44 +657,17 @@ void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, unsigned int hist_size = ARRAY_SIZE(chan_state->meas.buf); unsigned int current = chan_state->meas.current; const struct l1sched_meas_set *set; - unsigned int shift, pos, i, n; + unsigned int pos, i; float rssi_sum = 0; int toa256_sum = 0; int ci_cb_sum = 0; - switch (mode) { - /* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */ - case SCHED_MEAS_AVG_M_QUAD: - n = 4; shift = n; - break; - /* last 8 bursts (default for TCH/F and FACCH/F) */ - case SCHED_MEAS_AVG_M_OCTO: - n = 8; shift = n; - break; - /* last 6 bursts (default for FACCH/H) */ - case SCHED_MEAS_AVG_M_SIX: - n = 6; shift = n; - break; - /* first 4 of last 8 bursts */ - case SCHED_MEAS_AVG_M8_FIRST_QUAD: - n = 4; shift = 8; - break; - /* first 2 of last 6 bursts */ - case SCHED_MEAS_AVG_M6_FIRST_TWO: - n = 2; shift = 6; - break; - /* middle 2 of last 6 bursts */ - case SCHED_MEAS_AVG_M6_MIDDLE_TWO: - n = 2; shift = 4; - break; - default: - /* Shall not happen */ - OSMO_ASSERT(false); - } + const unsigned int shift = trx_sched_meas_modeset[mode][0]; + const unsigned int num = trx_sched_meas_modeset[mode][1]; /* Calculate the sum of n entries starting from pos */ - for (i = 0; i < n; i++) { + for (i = 0; i < num; i++) { pos = (current + hist_size - shift + i) % hist_size; set = &chan_state->meas.buf[pos]; @@ -683,14 +676,34 @@ void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, ci_cb_sum += set->ci_cb; } + /* First sample contains TDMA frame number of the first burst */ + pos = (current + hist_size - shift) % hist_size; + set = &chan_state->meas.buf[pos]; + /* Calculate the average for each value */ *avg = (struct l1sched_meas_set) { - .rssi = (rssi_sum / n), - .toa256 = (toa256_sum / n), - .ci_cb = (ci_cb_sum / n), + .fn = set->fn, /* first burst */ + .rssi = (rssi_sum / num), + .toa256 = (toa256_sum / num), + .ci_cb = (ci_cb_sum / num), }; - LOGP(DMEAS, LOGL_DEBUG, "Measurement AVG (num=%u, shift=%u): " - "RSSI %f, ToA256 %d, C/I %d cB\n", n, shift, - avg->rssi, avg->toa256, avg->ci_cb); + LOGP(DMEAS, LOGL_DEBUG, "%s%sMeasurement AVG (num=%u, shift=%u): " + "RSSI %f, ToA256 %d, C/I %d cB\n", + chan_state->lchan ? gsm_lchan_name(chan_state->lchan) : "", + chan_state->lchan ? " " : "", + num, shift, avg->rssi, avg->toa256, avg->ci_cb); +} + +/* Lookup TDMA frame number of the N-th sample in the history */ +uint32_t trx_sched_lookup_fn(const struct l1sched_chan_state *chan_state, + const unsigned int shift) +{ + const unsigned int hist_size = ARRAY_SIZE(chan_state->meas.buf); + const unsigned int current = chan_state->meas.current; + unsigned int pos; + + /* First sample contains TDMA frame number of the first burst */ + pos = (current + hist_size - shift) % hist_size; + return chan_state->meas.buf[pos].fn; } diff --git a/src/osmo-bts-trx/trx_if.c b/src/osmo-bts-trx/trx_if.c index 968c335e..b6b20e94 100644 --- a/src/osmo-bts-trx/trx_if.c +++ b/src/osmo-bts-trx/trx_if.c @@ -8,7 +8,7 @@ * Copyright (C) 2013 Andreas Eversberg <jolly@eversberg.eu> * Copyright (C) 2016-2017 Harald Welte <laforge@gnumonks.org> * Copyright (C) 2019 Vadim Yanitskiy <axilirator@gmail.com> - * Copyright (C) 2021 sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * Copyright (C) 2021 sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -51,6 +51,19 @@ #include "trx_if.h" #include "trx_provision_fsm.h" +#include "btsconfig.h" + +#ifdef HAVE_SYSTEMTAP +/* include the generated probes header and put markers in code */ +#include "probes.h" +#define TRACE(probe) probe +#define TRACE_ENABLED(probe) probe ## _ENABLED() +#else +/* Wrap the probe to allow it to be removed when no systemtap available */ +#define TRACE(probe) +#define TRACE_ENABLED(probe) (0) +#endif /* HAVE_SYSTEMTAP */ + /* * socket helper functions */ @@ -214,8 +227,8 @@ void trx_if_init(struct trx_l1h *l1h) * The new command will be added to the end of the control command * queue. */ -static int trx_ctrl_cmd_cb(struct trx_l1h *l1h, int critical, void *cb, const char *cmd, - const char *fmt, ...) +int trx_ctrl_cmd_cb(struct trx_l1h *l1h, int critical, void *cb, + const char *cmd, const char *fmt, ...) { struct trx_ctrl_msg *tcm; struct trx_ctrl_msg *prev = NULL; @@ -256,13 +269,14 @@ static int trx_ctrl_cmd_cb(struct trx_l1h *l1h, int critical, void *cb, const ch tcm->cmd, tcm->params_len ? " " : "", tcm->params); llist_add_tail(&tcm->list, &l1h->trx_ctrl_list); - /* send message, if we didn't already have pending messages */ - if (prev == NULL) + /* send message, if we didn't already have pending messages. + * If we are in the rx_rsp callback code path, skip sending, the + * callback will do so when returning to it. */ + if (prev == NULL && !l1h->in_trx_ctrl_read_cb) trx_ctrl_send(l1h); return 0; } -#define trx_ctrl_cmd(l1h, critical, cmd, fmt, ...) trx_ctrl_cmd_cb(l1h, critical, NULL, cmd, fmt, ##__VA_ARGS__) /*! Send "POWEROFF" command to TRX */ int trx_if_cmd_poweroff(struct trx_l1h *l1h, trx_if_cmd_poweronoff_cb *cb) @@ -332,8 +346,10 @@ int trx_if_cmd_setslot(struct trx_l1h *l1h, uint8_t tn, trx_if_cmd_setslot_cb *cb) { const struct trx_config *cfg = &l1h->config; + const struct phy_instance *pinst = l1h->phy_inst; - if (cfg->setslot[tn].tsc_valid) { /* PHY is instructed to use a custom TSC */ + if (cfg->setslot[tn].tsc_valid && cfg->setslot[tn].tsc_val != BTS_TSC(pinst->trx->bts)) { + /* PHY is instructed to use a custom TSC */ return trx_ctrl_cmd_cb(l1h, 1, cb, "SETSLOT", "%u %u C%u/S%u", tn, cfg->setslot[tn].slottype, cfg->setslot[tn].tsc_val, @@ -658,6 +674,7 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what) struct trx_ctrl_rsp rsp; int len, rc; struct trx_ctrl_msg *tcm; + bool flushed; len = recv(ofd->fd, buf, sizeof(buf) - 1, 0); if (len <= 0) @@ -670,8 +687,7 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what) LOGPPHI(l1h->phy_inst, DTRX, LOGL_INFO, "Response message: '%s'\n", buf); /* abort timer and send next message, if any */ - if (osmo_timer_pending(&l1h->trx_ctrl_timer)) - osmo_timer_del(&l1h->trx_ctrl_timer); + osmo_timer_del(&l1h->trx_ctrl_timer); /* get command for response message */ if (llist_empty(&l1h->trx_ctrl_list)) { @@ -708,21 +724,34 @@ static int trx_ctrl_read_cb(struct osmo_fd *ofd, unsigned int what) rsp.cb = tcm->cb; /* check for response code */ + l1h->in_trx_ctrl_read_cb = true; rc = trx_ctrl_rx_rsp(l1h, &rsp, tcm); + /* Reset state: */ + flushed = l1h->flushed_while_in_trx_ctrl_read_cb; + l1h->flushed_while_in_trx_ctrl_read_cb = false; + l1h->in_trx_ctrl_read_cb = false; + if (rc == -EINVAL) goto rsp_error; /* re-schedule last cmd in rc seconds time */ if (rc > 0) { - osmo_timer_schedule(&l1h->trx_ctrl_timer, rc, 0); + /* The queue may have been flushed in the trx_ctrl_rx_rsp(): */ + if (!llist_empty(&l1h->trx_ctrl_list)) + osmo_timer_schedule(&l1h->trx_ctrl_timer, rc, 0); return 0; } - /* remove command from list, save it to last_acked and removed previous last_acked */ - llist_del(&tcm->list); - talloc_free(l1h->last_acked); - l1h->last_acked = tcm; + if (!flushed) { + /* Remove command from list, save it to last_acked and removed + * previous last_acked */ + llist_del(&tcm->list); + talloc_free(l1h->last_acked); + l1h->last_acked = tcm; + } /* else: tcm was freed by trx_if_flush(), do not access it. */ + + /* Send next message waiting in the list: */ trx_ctrl_send(l1h); return 0; @@ -809,13 +838,18 @@ static inline int trx_data_parse_mts(struct phy_instance *phy_inst, /* | 7 6 5 4 3 2 1 0 | Bitmask / description * | . 0 0 X X . . . | GMSK, 4 TSC sets (0..3) - * | . 0 1 0 X . . . | 8-PSK, 2 TSC sets (0..1) */ + * | . 0 1 0 X . . . | 8-PSK, 2 TSC sets (0..1) + * | . 0 1 1 0 . . . | GMSK, Access Burst */ if ((mts >> 5) == 0x00) { bi->mod = TRX_MOD_T_GMSK; bi->tsc_set = (mts >> 3) & 0x03; } else if ((mts >> 4) == 0x02) { bi->mod = TRX_MOD_T_8PSK; bi->tsc_set = (mts >> 3) & 0x01; + } else if ((mts >> 3) == 0x06) { + bi->flags |= TRX_BI_F_ACCESS_BURST; + bi->mod = TRX_MOD_T_GMSK; + bi->tsc_set = 0; } else { LOGPPHI(phy_inst, DTRX, LOGL_ERROR, "Rx TRXD PDU with unknown or not supported " @@ -844,7 +878,7 @@ static int trx_data_handle_hdr_v1(struct phy_instance *phy_inst, /* MTS (Modulation and Training Sequence) */ rc = trx_data_parse_mts(phy_inst, bi, buf[0]); - if (rc < 0) + if (OSMO_UNLIKELY(rc < 0)) return rc; /* C/I: Carrier-to-Interference ratio (in centiBels) */ @@ -875,7 +909,7 @@ static int trx_data_handle_pdu_v2(struct phy_instance *phy_inst, /* MTS (Modulation and Training Sequence) */ rc = trx_data_parse_mts(phy_inst, bi, buf[2]); - if (rc < 0) + if (OSMO_UNLIKELY(rc < 0)) return rc; bi->rssi = -(int8_t)buf[3]; @@ -885,7 +919,7 @@ static int trx_data_handle_pdu_v2(struct phy_instance *phy_inst, /* TDMA frame number is absent in batched PDUs */ if (bi->_num_pdus == 0) { - if (buf_len < sizeof(bi->fn) + TRX_UL_V2HDR_LEN) { + if (OSMO_UNLIKELY(buf_len < sizeof(bi->fn) + TRX_UL_V2HDR_LEN)) { LOGPPHI(phy_inst, DTRX, LOGL_ERROR, "Rx malformed TRXDv2 PDU: not enough bytes " "to parse TDMA frame number\n"); @@ -918,7 +952,7 @@ static int trx_data_handle_burst(struct trx_ul_burst_ind *bi, }; bi->burst_len = bl[bi->mod]; - if (buf_len < bi->burst_len) + if (OSMO_UNLIKELY(buf_len < bi->burst_len)) return -EINVAL; /* Convert unsigned soft-bits [254..0] to soft-bits [-127..127] */ @@ -991,7 +1025,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) uint8_t pdu_ver; buf_len = recv(ofd->fd, trx_data_buf, sizeof(trx_data_buf), 0); - if (buf_len <= 0) { + if (OSMO_UNLIKELY(buf_len <= 0)) { strerror_r(errno, (char *) trx_data_buf, sizeof(trx_data_buf)); LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "recv() failed on TRXD with rc=%zd (%s)\n", @@ -1003,7 +1037,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) pdu_ver = buf[0] >> 4; /* Make sure that PDU version matches our expectations */ - if (pdu_ver != l1h->config.trxd_pdu_ver_use) { + if (OSMO_UNLIKELY(pdu_ver != l1h->config.trxd_pdu_ver_use)) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Rx TRXD PDU with unexpected version %u (expected %u)\n", pdu_ver, l1h->config.trxd_pdu_ver_use); @@ -1019,7 +1053,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) bi.flags = 0x00; /* Make sure that we have enough bytes to parse the header */ - if (buf_len < trx_data_rx_hdr_len[pdu_ver]) { + if (OSMO_UNLIKELY(buf_len < trx_data_rx_hdr_len[pdu_ver])) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Rx malformed TRXDv%u PDU: len=%zd < expected %u\n", pdu_ver, buf_len, trx_data_rx_hdr_len[pdu_ver]); @@ -1043,10 +1077,10 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) } /* Header parsing error */ - if (hdr_len < 0) + if (OSMO_UNLIKELY(hdr_len < 0)) return hdr_len; - if (bi.fn >= GSM_TDMA_HYPERFRAME) { + if (OSMO_UNLIKELY(bi.fn >= GSM_TDMA_HYPERFRAME)) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Rx malformed TRXDv%u PDU: illegal TDMA fn=%u\n", pdu_ver, bi.fn); @@ -1058,7 +1092,7 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) buf += hdr_len; /* Calculate burst length and parse it (if present) */ - if (trx_data_handle_burst(&bi, buf, buf_len) != 0) { + if (OSMO_UNLIKELY(trx_data_handle_burst(&bi, buf, buf_len) != 0)) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Rx malformed TRXDv%u PDU: odd burst length=%zd\n", pdu_ver, buf_len); @@ -1078,7 +1112,9 @@ static int trx_data_read_cb(struct osmo_fd *ofd, unsigned int what) bi._num_pdus++; /* feed received burst into scheduler code */ + TRACE(OSMO_BTS_TRX_UL_DATA_START(l1h->phy_inst->trx->nr, bi.tn, bi.fn)); trx_sched_route_burst_ind(l1h->phy_inst->trx, &bi); + TRACE(OSMO_BTS_TRX_UL_DATA_DONE(l1h->phy_inst->trx->nr, bi.tn, bi.fn)); } while (bi.flags & TRX_BI_F_BATCH_IND); return 0; @@ -1097,7 +1133,7 @@ int trx_if_send_burst(struct trx_l1h *l1h, const struct trx_dl_burst_req *br) ssize_t snd_len, buf_len; /* Make sure that the PHY is powered on */ - if (!trx_if_powered(l1h)) { + if (OSMO_UNLIKELY(!trx_if_powered(l1h))) { LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "Ignoring Tx data, transceiver is powered off\n"); return -ENODEV; @@ -1170,7 +1206,7 @@ sendall: pdu_num = 0; snd_len = send(l1h->trx_ofd_data.fd, trx_data_buf, buf_len, 0); - if (snd_len <= 0) { + if (OSMO_UNLIKELY(snd_len <= 0)) { strerror_r(errno, (char *) trx_data_buf, sizeof(trx_data_buf)); LOGPPHI(l1h->phy_inst, DTRX, LOGL_ERROR, "send() failed on TRXD with rc=%zd (%s)\n", @@ -1199,12 +1235,21 @@ void trx_if_flush(struct trx_l1h *l1h) talloc_free(tcm); } talloc_free(l1h->last_acked); + l1h->last_acked = NULL; + + /* Tx queue is now empty, so there's no point in keeping the retrans timer armed: */ + osmo_timer_del(&l1h->trx_ctrl_timer); + + /* If we are in read_cb, signal to the returning code path that we freed the list. */ + if (l1h->in_trx_ctrl_read_cb) + l1h->flushed_while_in_trx_ctrl_read_cb = true; } /*! close the TRX for given handle (data + control socket) */ void trx_if_close(struct trx_l1h *l1h) { - LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections\n"); + LOGPPHI(l1h->phy_inst, DTRX, LOGL_NOTICE, "Closing TRXC/TRXD connections to %s\n", + l1h->phy_inst->phy_link->u.osmotrx.remote_ip); trx_if_flush(l1h); @@ -1214,7 +1259,7 @@ void trx_if_close(struct trx_l1h *l1h) } /*! compute UDP port number used for TRX protocol */ -static uint16_t compute_port(struct phy_instance *pinst, int remote, int is_data) +static uint16_t compute_port(struct phy_instance *pinst, bool remote, bool is_data) { struct phy_link *plink = pinst->phy_link; uint16_t inc = 1; @@ -1235,21 +1280,21 @@ static int trx_if_open(struct trx_l1h *l1h) struct phy_link *plink = pinst->phy_link; int rc; - LOGPPHI(pinst, DTRX, LOGL_NOTICE, "Opening TRXC/TRXD connections\n"); + LOGPPHI(pinst, DTRX, LOGL_NOTICE, "Opening TRXC/TRXD connections to %s\n", plink->u.osmotrx.remote_ip); /* open sockets */ rc = trx_udp_open(l1h, &l1h->trx_ofd_ctrl, plink->u.osmotrx.local_ip, - compute_port(pinst, 0, 0), + compute_port(pinst, false, false), plink->u.osmotrx.remote_ip, - compute_port(pinst, 1, 0), trx_ctrl_read_cb); + compute_port(pinst, true, false), trx_ctrl_read_cb); if (rc < 0) return rc; rc = trx_udp_open(l1h, &l1h->trx_ofd_data, plink->u.osmotrx.local_ip, - compute_port(pinst, 0, 1), + compute_port(pinst, false, true), plink->u.osmotrx.remote_ip, - compute_port(pinst, 1, 1), trx_data_read_cb); + compute_port(pinst, true, true), trx_data_read_cb); if (rc < 0) return rc; @@ -1262,7 +1307,8 @@ static void trx_phy_inst_close(struct phy_instance *pinst) struct trx_l1h *l1h = pinst->u.osmotrx.hdl; trx_if_close(l1h); - trx_sched_clean(pinst->trx); + if (pinst->trx) + trx_sched_clean(pinst->trx); } /*! open the control + burst data sockets for one phy_instance */ @@ -1331,6 +1377,23 @@ cleanup: return -1; } +/*! close the PHY link using TRX protocol */ +int bts_model_phy_link_close(struct phy_link *plink) +{ + bool clock_stopped = false; + struct phy_instance *pinst; + llist_for_each_entry(pinst, &plink->instances, list) { + if (!clock_stopped) { + clock_stopped = true; + trx_sched_clock_stopped(pinst->trx->bts); + } + trx_phy_inst_close(pinst); + } + trx_udp_close(&plink->u.osmotrx.trx_ofd_clk); + phy_link_state_set(plink, PHY_LINK_SHUTDOWN); + return 0; +} + /*! determine if the TRX for given handle is powered up */ int trx_if_powered(struct trx_l1h *l1h) { diff --git a/src/osmo-bts-trx/trx_if.h b/src/osmo-bts-trx/trx_if.h index b838b76a..3a22a1b4 100644 --- a/src/osmo-bts-trx/trx_if.h +++ b/src/osmo-bts-trx/trx_if.h @@ -48,3 +48,7 @@ int trx_if_powered(struct trx_l1h *l1h); /* Format negotiation command */ int trx_if_cmd_setformat(struct trx_l1h *l1h, uint8_t ver, trx_if_cmd_generic_cb *cb); + +int trx_ctrl_cmd_cb(struct trx_l1h *l1h, int critical, void *cb, + const char *cmd, const char *fmt, ...); +#define trx_ctrl_cmd(l1h, critical, cmd, fmt, ...) trx_ctrl_cmd_cb(l1h, critical, NULL, cmd, fmt, ##__VA_ARGS__) diff --git a/src/osmo-bts-trx/trx_provision_fsm.c b/src/osmo-bts-trx/trx_provision_fsm.c index 5beca2ac..5ca23e31 100644 --- a/src/osmo-bts-trx/trx_provision_fsm.c +++ b/src/osmo-bts-trx/trx_provision_fsm.c @@ -1,6 +1,6 @@ /* TRX provision FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -33,6 +33,8 @@ #include <osmo-bts/bts_model.h> #include <osmo-bts/bts.h> #include <osmo-bts/rsl.h> +#include <osmo-bts/nm_common_fsm.h> +#include <osmo-bts/signal.h> #include "l1_if.h" #include "trx_provision_fsm.h" @@ -48,12 +50,14 @@ static void l1if_poweronoff_cb(struct trx_l1h *l1h, bool poweronoff, int rc) struct phy_link *plink = pinst->phy_link; plink->u.osmotrx.powered = poweronoff; - plink->u.osmotrx.poweronoff_sent = false; - if (poweronoff) + if (poweronoff) { + plink->u.osmotrx.poweron_sent = false; osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_POWERON_CNF, (void*)(intptr_t)rc); - else + } else { + plink->u.osmotrx.poweroff_sent = false; osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_POWEROFF_CNF, (void*)(intptr_t)rc); + } } @@ -92,6 +96,53 @@ void l1if_setformat_cb(struct trx_l1h *l1h, int rc) /* * transceiver provisioning */ + +static void trx_provision_reset(struct trx_l1h *l1h) +{ + struct phy_instance *pinst = l1h->phy_inst; + uint8_t tn; + + l1h->config.trxd_pdu_ver_req = pinst->phy_link->u.osmotrx.trxd_pdu_ver_max; + l1h->config.trxd_pdu_ver_use = 0; + l1h->config.setformat_sent = false; + l1h->config.setformat_acked = false; + + l1h->config.enabled = false; + l1h->config.arfcn_valid = false; + l1h->config.arfcn = 0; + l1h->config.rxtune_sent = false; + l1h->config.rxtune_acked = false; + l1h->config.txtune_sent = false; + l1h->config.txtune_acked = false; + + l1h->config.tsc_valid = false; + l1h->config.tsc = 0; + l1h->config.tsc_sent = false; + l1h->config.tsc_acked = false; + + l1h->config.bsic_valid = false; + l1h->config.bsic = 0; + l1h->config.bsic_sent = false; + l1h->config.bsic_acked = false; + + l1h->config.rxgain_sent = false; + + l1h->config.nomtxpower_sent = false; + l1h->config.nomtxpower_acked = false; + + l1h->config.maxdly_sent = false; + + l1h->config.maxdlynb_sent = false; + + for (tn = 0; tn < TRX_NR_TS; tn++) { + l1h->config.setslot_valid[tn] = false; + l1h->config.setslot_sent[tn] = false; + l1h->config.setslot[tn].slottype = 0; + l1h->config.setslot[tn].tsc_set = 0; + l1h->config.setslot[tn].tsc_val = 0; + l1h->config.setslot[tn].tsc_valid = 0; + } +} int l1if_provision_transceiver_trx(struct trx_l1h *l1h) { struct phy_instance *pinst = l1h->phy_inst; @@ -202,11 +253,11 @@ static void update_ts_data(struct trx_l1h *l1h, struct trx_prov_ev_cfg_ts_data * l1h->config.setslot_sent[data->tn] = false; } -/* Whether a given TRX is fully configured and can be powered on */ +/* Whether a given TRX is fully configured */ static bool trx_is_provisioned(struct trx_l1h *l1h) { struct phy_instance *pinst = l1h->phy_inst; - if (l1h->config.enabled && l1h->config.rxtune_acked && l1h->config.txtune_acked && + if (l1h->config.rxtune_acked && l1h->config.txtune_acked && (l1h->config.bsic_acked || !pinst->phy_link->u.osmotrx.use_legacy_setbsic) && (l1h->config.tsc_acked || pinst->phy_link->u.osmotrx.use_legacy_setbsic) && (l1h->config.nomtxpower_acked || l1h->config.nominal_power_set_by_vty) && @@ -216,6 +267,11 @@ static bool trx_is_provisioned(struct trx_l1h *l1h) return false; } +/* Whether a given TRX is fully configured and can be powered on */ +static bool trx_is_provisioned_and_enabled(struct trx_l1h *l1h) +{ + return l1h->config.enabled && trx_is_provisioned(l1h); +} static void trx_signal_ready_trx0(struct trx_l1h *l1h) { @@ -231,7 +287,7 @@ static void trx_signal_ready_trx0(struct trx_l1h *l1h) } } -/* Called from TRX0 to check if other TRX are already configured and powered so POWERON can be sent */ +/* Called from TRX0 to check if other TRX are already configured so POWERON can be sent */ static bool trx_other_trx0_ready(struct trx_l1h *l1h) { struct phy_instance *pinst = l1h->phy_inst; @@ -242,12 +298,54 @@ static bool trx_other_trx0_ready(struct trx_l1h *l1h) struct trx_l1h *l1h_it = pinst_it->u.osmotrx.hdl; if (l1h_it->phy_inst->num == 0) continue; - if (l1h_it->provision_fi->state != TRX_PROV_ST_OPEN_POWERON) + if (!trx_is_provisioned(l1h_it)) return false; } return true; } +/* Closes a phy_link and all its associated TRX */ +static void trx_prov_fsm_apply_close(struct phy_link *plink, int rc) +{ + struct trx_l1h *l1h; + struct phy_instance *pinst; + + if (plink->state == PHY_LINK_SHUTDOWN) + return; + + bts_model_phy_link_close(plink); + /* Notify TRX close on all TRX associated with this phy */ + llist_for_each_entry(pinst, &plink->instances, list) { + l1h = pinst->u.osmotrx.hdl; + trx_prov_fsm_state_chg(l1h->provision_fi, TRX_PROV_ST_CLOSED); + bts_model_trx_close_cb(pinst->trx, rc); + } +} + +static int trx_prov_fsm_signal_cb(unsigned int subsys, unsigned int signal, + void *hdlr_data, void *signal_data) +{ + struct nm_statechg_signal_data *nsd; + struct gsm_bts_trx *trx; + + if (subsys != SS_GLOBAL) + return -EINVAL; + + if (signal != S_NEW_OP_STATE) + return 0; + + nsd = (struct nm_statechg_signal_data *)signal_data; + + if (nsd->mo->obj_class != NM_OC_RADIO_CARRIER) + return 0; + + if (nsd->old_state != NM_OPSTATE_ENABLED && nsd->new_state == NM_OPSTATE_ENABLED) { + trx = gsm_objclass2obj(nsd->mo->bts, nsd->mo->obj_class, &nsd->mo->obj_inst, NULL); + l1if_trx_start_power_ramp(trx, NULL); + } + return 0; +} + ////////////////////////// // FSM STATE ACTIONS ////////////////////////// @@ -274,13 +372,18 @@ static void st_open_poweroff_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_st struct trx_l1h *l1h = (struct trx_l1h *)fi->priv; struct phy_instance *pinst = l1h->phy_inst; - l1h->config.trxd_pdu_ver_req = pinst->phy_link->u.osmotrx.trxd_pdu_ver_max; + trx_provision_reset(l1h); - /* Apply initial RFMUTE state */ - if (pinst->trx != NULL) - trx_if_cmd_rfmute(l1h, pinst->trx->mo.nm_state.administrative != NM_STATE_UNLOCKED); - else + if (pinst->trx == NULL) { trx_if_cmd_rfmute(l1h, true); + return; + } + + /* Apply initial RFMUTE state */ + trx_if_cmd_rfmute(l1h, pinst->trx->mo.nm_state.administrative != NM_STATE_UNLOCKED); + + osmo_fsm_inst_dispatch(pinst->trx->mo.fi, NM_EV_SW_ACT, NULL); + osmo_fsm_inst_dispatch(pinst->trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL); } static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -291,9 +394,17 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat uint16_t arfcn; int nominal_power; int status; - bool others_ready; + bool waiting_other_trx; + bool was_ready = trx_is_provisioned(l1h); switch (event) { + case TRX_PROV_EV_CLOSE: + /* In this state, we didn't for sure send a POWERON yet, hence we + are save directly applying the close as if we received a + POWEROFF RSP: */ + if (pinst->num == 0) + trx_prov_fsm_apply_close(pinst->phy_link, 0); + return; case TRX_PROV_EV_CFG_ENABLE: l1h->config.enabled =(bool)data; break; @@ -380,22 +491,22 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat l1if_provision_transceiver_trx(l1h); - if (l1h->phy_inst->num == 0) - others_ready = trx_other_trx0_ready(l1h); - else - others_ready = true; /* we don't care about others in TRX!=0 */ + if (l1h->phy_inst->num == 0) { + waiting_other_trx = !trx_other_trx0_ready(l1h); + } else { + waiting_other_trx = false; /* we don't care about others in TRX!=0 */ + /* If we just became ready for TRX0 POWERON (aka this TRX becomes provisioned), signal it to TRX0: */ + if (l1h->phy_inst->num != 0 && (!was_ready && trx_is_provisioned(l1h))) + trx_signal_ready_trx0(l1h); + } /* if we gathered all data and could go forward. For TRX0, only after * all other TRX are prepared, since it will send POWERON commad */ - if (trx_is_provisioned(l1h) && - (l1h->phy_inst->num != 0 || others_ready)) { - if (l1h->phy_inst->num != 0) { + if (trx_is_provisioned_and_enabled(l1h) && !waiting_other_trx) { + if (l1h->phy_inst->num != 0) trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWERON); - /* Once we are powered on, signal TRX0 in case it was waiting for us */ - trx_signal_ready_trx0(l1h); - } else { + else trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWERON_CNF); - } } else { LOGPFSML(fi, LOGL_INFO, "Delay poweron, wait for:%s%s%s%s%s%s%s%s\n", l1h->config.enabled ? "" :" enable", @@ -407,7 +518,7 @@ static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *dat l1h->config.txtune_acked ? "" : " txtune-ack", l1h->config.nominal_power_set_by_vty ? "" : (l1h->config.nomtxpower_acked ? "" : " nomtxpower-ack"), l1h->config.setformat_acked ? "" : " setformat-ack", - (l1h->phy_inst->num != 0 || others_ready) ? "" : " other-trx" + waiting_other_trx ? "" : " other-trx" ); } } @@ -419,7 +530,7 @@ static void st_open_wait_power_cnf_on_enter(struct osmo_fsm_inst *fi, uint32_t p struct phy_instance *pinst = l1h->phy_inst; trx_if_cmd_poweron(l1h, l1if_poweronoff_cb); - pinst->phy_link->u.osmotrx.poweronoff_sent = true; + pinst->phy_link->u.osmotrx.poweron_sent = true; } static void st_open_wait_power_cnf(struct osmo_fsm_inst *fi, uint32_t event, void *data) @@ -435,13 +546,6 @@ static void st_open_wait_power_cnf(struct osmo_fsm_inst *fi, uint32_t event, voi if (rc == 0 && plink->state != PHY_LINK_CONNECTED) { trx_sched_clock_started(pinst->trx->bts); phy_link_state_set(plink, PHY_LINK_CONNECTED); - - /* Begin to ramp up the power on all TRX associated with this phy */ - llist_for_each_entry(pinst, &plink->instances, list) { - if (pinst->trx->mo.nm_state.administrative == NM_STATE_UNLOCKED) - l1if_trx_start_power_ramp(pinst->trx, NULL); - } - trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWERON); } else if (rc != 0 && plink->state != PHY_LINK_SHUTDOWN) { trx_sched_clock_stopped(pinst->trx->bts); @@ -451,6 +555,14 @@ static void st_open_wait_power_cnf(struct osmo_fsm_inst *fi, uint32_t event, voi case TRX_PROV_EV_CFG_TS: update_ts_data(l1h, (struct trx_prov_ev_cfg_ts_data*)data); break; + case TRX_PROV_EV_CLOSE: + /* power off transceiver, if not already */ + if (pinst->num == 0 && !plink->u.osmotrx.poweroff_sent) { + trx_if_cmd_poweroff(l1h, l1if_poweronoff_cb); + plink->u.osmotrx.poweroff_sent = true; + } + trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF); + break; default: OSMO_ASSERT(0); } @@ -490,29 +602,15 @@ static void st_open_poweron(struct osmo_fsm_inst *fi, uint32_t event, void *data struct phy_instance *pinst = l1h->phy_inst; struct phy_link *plink = pinst->phy_link; struct trx_prov_ev_cfg_ts_data* ts_data; - uint8_t tn; switch (event) { case TRX_PROV_EV_CLOSE: /* power off transceiver, if not already */ - if (l1h->config.enabled) { - if (pinst->num == 0 && plink->u.osmotrx.powered && !plink->u.osmotrx.poweronoff_sent) { - trx_if_cmd_poweroff(l1h, l1if_poweronoff_cb); - plink->u.osmotrx.poweronoff_sent = true; - } - l1h->config.rxgain_sent = false; - l1h->config.maxdly_sent = false; - l1h->config.maxdlynb_sent = false; - for (tn = 0; tn < TRX_NR_TS; tn++) - l1h->config.setslot_sent[tn] = false; - } else if (!pinst->phy_link->u.osmotrx.poweronoff_sent) { - bts_model_trx_close_cb(pinst->trx, 0); - } /* else: poweroff in progress, cb will be called upon TRXC RSP */ - - if (pinst->num == 0) - trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF); - else - trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_POWEROFF); + if (pinst->num == 0 && plink->u.osmotrx.powered && !plink->u.osmotrx.poweroff_sent) { + trx_if_cmd_poweroff(l1h, l1if_poweronoff_cb); + plink->u.osmotrx.poweroff_sent = true; + } + trx_prov_fsm_state_chg(fi, TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF); break; case TRX_PROV_EV_CFG_TS: ts_data = (struct trx_prov_ev_cfg_ts_data*)data; @@ -536,15 +634,7 @@ static void st_open_wait_poweroff_cnf(struct osmo_fsm_inst *fi, uint32_t event, switch (event) { case TRX_PROV_EV_POWEROFF_CNF: rc = (uint16_t)(intptr_t)data; - if (plink->state != PHY_LINK_SHUTDOWN) { - trx_sched_clock_stopped(pinst->trx->bts); - phy_link_state_set(plink, PHY_LINK_SHUTDOWN); - - /* Notify TRX close on all TRX associated with this phy */ - llist_for_each_entry(pinst, &plink->instances, list) { - bts_model_trx_close_cb(pinst->trx, rc); - } - } + trx_prov_fsm_apply_close(plink, rc); break; default: OSMO_ASSERT(0); @@ -562,6 +652,7 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = { }, [TRX_PROV_ST_OPEN_POWEROFF] = { .in_event_mask = + X(TRX_PROV_EV_CLOSE) | X(TRX_PROV_EV_OTHER_TRX_READY) | X(TRX_PROV_EV_CFG_ENABLE) | X(TRX_PROV_EV_CFG_BSIC) | @@ -574,6 +665,7 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = { X(TRX_PROV_EV_SETTSC_CNF) | X(TRX_PROV_EV_SETFORMAT_CNF), .out_state_mask = + X(TRX_PROV_ST_CLOSED) | X(TRX_PROV_ST_OPEN_WAIT_POWERON_CNF) | X(TRX_PROV_ST_OPEN_POWERON), .name = "OPEN_POWEROFF", @@ -582,10 +674,12 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = { }, [TRX_PROV_ST_OPEN_WAIT_POWERON_CNF] = { .in_event_mask = + X(TRX_PROV_EV_CLOSE) | X(TRX_PROV_EV_POWERON_CNF) | X(TRX_PROV_EV_CFG_TS), .out_state_mask = - X(TRX_PROV_ST_OPEN_POWERON), + X(TRX_PROV_ST_OPEN_POWERON) | + X(TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF), .name = "OPEN_WAIT_POWERON_CNF", .onenter = st_open_wait_power_cnf_on_enter, .action = st_open_wait_power_cnf, @@ -595,8 +689,7 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = { X(TRX_PROV_EV_CLOSE) | X(TRX_PROV_EV_CFG_TS), .out_state_mask = - X(TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF) | - X(TRX_PROV_ST_OPEN_POWEROFF), + X(TRX_PROV_ST_OPEN_WAIT_POWEROFF_CNF), .name = "OPEN_POWERON", .onenter = st_open_poweron_on_enter, .action = st_open_poweron, @@ -605,7 +698,7 @@ static struct osmo_fsm_state trx_prov_fsm_states[] = { .in_event_mask = X(TRX_PROV_EV_POWEROFF_CNF), .out_state_mask = - X(TRX_PROV_ST_OPEN_POWEROFF), + X(TRX_PROV_ST_CLOSED), .name = "OPEN_WAIT_POWEROFF_CNF", .action = st_open_wait_poweroff_cnf, }, @@ -643,4 +736,5 @@ struct osmo_fsm trx_prov_fsm = { static __attribute__((constructor)) void trx_prov_fsm_init(void) { OSMO_ASSERT(osmo_fsm_register(&trx_prov_fsm) == 0); + OSMO_ASSERT(osmo_signal_register_handler(SS_GLOBAL, trx_prov_fsm_signal_cb, NULL) == 0); } diff --git a/src/osmo-bts-trx/trx_provision_fsm.h b/src/osmo-bts-trx/trx_provision_fsm.h index 8e6b97bf..e89cd328 100644 --- a/src/osmo-bts-trx/trx_provision_fsm.h +++ b/src/osmo-bts-trx/trx_provision_fsm.h @@ -1,6 +1,6 @@ /* Provision TRX over TRXC protocol FSM */ -/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> +/* (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * Author: Pau Espin Pedrol <pespin@sysmocom.de> * * All Rights Reserved @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/src/osmo-bts-trx/trx_vty.c b/src/osmo-bts-trx/trx_vty.c index bb9d1584..9056f027 100644 --- a/src/osmo-bts-trx/trx_vty.c +++ b/src/osmo-bts-trx/trx_vty.c @@ -46,7 +46,7 @@ #include "l1_if.h" #include "trx_if.h" -#include "loops.h" +#include "amr_loop.h" #define X(x) (1 << x) @@ -89,11 +89,16 @@ DEFUN(show_transceiver, show_transceiver_cmd, "show transceiver", else vty_out(vty, " bsic : undefined%s", VTY_NEWLINE); + /* trx->ts[tn].priv is NULL in absence of the A-bis connection */ + if (trx->bb_transc.rsl.link == NULL) + continue; + for (tn = 0; tn < ARRAY_SIZE(trx->ts); tn++) { const struct gsm_bts_trx_ts *ts = &trx->ts[tn]; const struct l1sched_ts *l1ts = ts->priv; const struct trx_sched_multiframe *mf; + OSMO_ASSERT(l1ts != NULL); mf = &trx_sched_multiframes[l1ts->mf_index]; vty_out(vty, " timeslot #%u (%s)%s", @@ -189,6 +194,39 @@ DEFUN(show_phy, show_phy_cmd, "show phy", return CMD_SUCCESS; } +DEFUN_HIDDEN(test_send_trxc, + test_send_trxc_cmd, + "test send-trxc-cmd <0-255> CMD [.ARGS]", + "Various testing commands\n" + "Send an arbitrary TRX command\n" + "Transceiver number\n" + "TRXC command\n" "TRXC command arguments\n") +{ + const struct gsm_bts_trx *trx; + const struct phy_instance *pinst; + struct trx_l1h *l1h; + int rc; + + trx = gsm_bts_trx_num(g_bts, atoi(argv[0])); + if (trx == NULL) { + vty_out(vty, "%% Could not find TRX%s", VTY_NEWLINE); + return CMD_WARNING; + } + + pinst = trx_phy_instance(trx); + l1h = pinst->u.osmotrx.hdl; + + if (argc > 2) { + char *cmd_args = argv_concat(argv, argc, 2); + rc = trx_ctrl_cmd(l1h, 0, argv[1], "%s", cmd_args); + talloc_free(cmd_args); + } else { + rc = trx_ctrl_cmd(l1h, 0, argv[1], ""); + } + + return (rc == 0) ? CMD_SUCCESS : CMD_WARNING; +} + DEFUN_USRATTR(cfg_trx_nominal_power, cfg_trx_nominal_power_cmd, X(BTS_VTY_TRX_POWERCYCLE), "nominal-tx-power <-10-100>", @@ -265,18 +303,12 @@ DEFUN_DEPRECATED(cfg_phy_no_timing_advance_loop, cfg_phy_no_timing_advance_loop_ return CMD_SUCCESS; } -DEFUN_ATTR(cfg_phyinst_maxdly, cfg_phyinst_maxdly_cmd, - "osmotrx maxdly <0-31>", - OSMOTRX_STR - "Set the maximum acceptable delay of an Access Burst (in GSM symbols)." - " Access Burst is the first burst a mobile transmits in order to establish" - " a connection and it is used to estimate Timing Advance (TA) which is" - " then applied to Normal Bursts to compensate for signal delay due to" - " distance. So changing this setting effectively changes maximum range of" - " the cell, because if we receive an Access Burst with a delay higher than" - " this value, it will be ignored and connection is dropped.\n" - "GSM symbols (approx. 1.1km per symbol)\n", - CMD_ATTR_IMMEDIATE) +DEFUN_USRATTR(cfg_phyinst_maxdly, cfg_phyinst_maxdly_cmd, + X(BTS_VTY_TRX_POWERCYCLE), + "osmotrx maxdly <0-63>", + OSMOTRX_STR + "Set the maximum acceptable delay of an Access Burst\n" + "Delay in GSMK symbol periods (approx. 550m per symbol)\n") { struct phy_instance *pinst = vty->index; struct trx_l1h *l1h = pinst->u.osmotrx.hdl; @@ -284,25 +316,17 @@ DEFUN_ATTR(cfg_phyinst_maxdly, cfg_phyinst_maxdly_cmd, l1h->config.maxdly = atoi(argv[0]); l1h->config.maxdly_valid = 1; l1h->config.maxdly_sent = false; - l1if_provision_transceiver_trx(l1h); return CMD_SUCCESS; } -DEFUN_ATTR(cfg_phyinst_maxdlynb, cfg_phyinst_maxdlynb_cmd, - "osmotrx maxdlynb <0-31>", - OSMOTRX_STR - "Set the maximum acceptable delay of a Normal Burst (in GSM symbols)." - " USE FOR TESTING ONLY, DON'T CHANGE IN PRODUCTION USE!" - " During normal operation, Normal Bursts delay are controlled by a Timing" - " Advance control loop and thus Normal Bursts arrive to a BTS with no more" - " than a couple GSM symbols, which is already taken into account in osmo-trx." - " So changing this setting will have no effect in production installations" - " except increasing osmo-trx CPU load. This setting is only useful when" - " testing with a transmitter which can't precisely synchronize to the BTS" - " downlink signal, like e.g. R&S CMD57.\n" - "GSM symbols (approx. 1.1km per symbol)\n", - CMD_ATTR_IMMEDIATE) +DEFUN_ATTR_USRATTR(cfg_phyinst_maxdlynb, cfg_phyinst_maxdlynb_cmd, + CMD_ATTR_HIDDEN, /* expert mode command */ + X(BTS_VTY_TRX_POWERCYCLE), + "osmotrx maxdlynb <0-63>", + OSMOTRX_STR + "Set the maximum acceptable delay of a Normal Burst\n" + "Delay in GMSK symbol periods (approx. 550m per symbol)\n") { struct phy_instance *pinst = vty->index; struct trx_l1h *l1h = pinst->u.osmotrx.hdl; @@ -310,7 +334,6 @@ DEFUN_ATTR(cfg_phyinst_maxdlynb, cfg_phyinst_maxdlynb_cmd, l1h->config.maxdlynb = atoi(argv[0]); l1h->config.maxdlynb_valid = 1; l1h->config.maxdlynb_sent = false; - l1if_provision_transceiver_trx(l1h); return CMD_SUCCESS; } @@ -404,12 +427,13 @@ DEFUN_USRATTR(cfg_phyinst_rxgain, cfg_phyinst_rxgain_cmd, return CMD_SUCCESS; } -DEFUN(cfg_phyinst_tx_atten, cfg_phyinst_tx_atten_cmd, - "osmotrx tx-attenuation (oml|<0-50>)", - OSMOTRX_STR - "Set the transmitter attenuation\n" - "Use NM_ATT_RF_MAXPOWR_R (max power reduction) from BSC via OML (default)\n" - "Fixed attenuation in dB, overriding OML (default)\n") +DEFUN_ATTR(cfg_phyinst_tx_atten, cfg_phyinst_tx_atten_cmd, + "osmotrx tx-attenuation (oml|<0-50>)", + OSMOTRX_STR + "Set the transmitter attenuation\n" + "Use NM_ATT_RF_MAXPOWR_R (max power reduction) from BSC via OML (default)\n" + "Fixed attenuation in dB, overriding OML (default)\n", + CMD_ATTR_IMMEDIATE) { struct phy_instance *pinst = vty->index; struct trx_l1h *l1h = pinst->u.osmotrx.hdl; @@ -419,6 +443,9 @@ DEFUN(cfg_phyinst_tx_atten, cfg_phyinst_tx_atten_cmd, else l1h->config.forced_max_power_red = atoi(argv[0]); + if (pinst->trx && pinst->trx->mo.nm_state.operational == NM_OPSTATE_ENABLED) + l1if_trx_start_power_ramp(pinst->trx, NULL); + return CMD_SUCCESS; } @@ -636,6 +663,8 @@ int bts_model_vty_init(void *ctx) install_element_ve(&show_transceiver_cmd); install_element_ve(&show_phy_cmd); + install_element(ENABLE_NODE, &test_send_trxc_cmd); + install_element(TRX_NODE, &cfg_trx_nominal_power_cmd); install_element(TRX_NODE, &cfg_trx_no_nominal_power_cmd); diff --git a/src/osmo-bts-virtual/Makefile.am b/src/osmo-bts-virtual/Makefile.am index 070efed6..bbb79eca 100644 --- a/src/osmo-bts-virtual/Makefile.am +++ b/src/osmo-bts-virtual/Makefile.am @@ -1,10 +1,50 @@ -AM_CFLAGS = -Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBGPS_CFLAGS) +AM_CFLAGS = \ + -Wall -fno-strict-aliasing \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCTRL_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBGPS_CFLAGS) \ + $(NULL) + AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -Iinclude -COMMON_LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCTRL_LIBS) -ldl -noinst_HEADERS = l1_if.h osmo_mcast_sock.h virtual_um.h +COMMON_LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCTRL_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + -ldl \ + $(NULL) + +noinst_HEADERS = \ + l1_if.h \ + osmo_mcast_sock.h \ + virtual_um.h \ + $(NULL) bin_PROGRAMS = osmo-bts-virtual -osmo_bts_virtual_SOURCES = main.c bts_model.c virtualbts_vty.c scheduler_virtbts.c l1_if.c virtual_um.c osmo_mcast_sock.c -osmo_bts_virtual_LDADD = $(top_builddir)/src/common/libl1sched.a $(top_builddir)/src/common/libbts.a $(COMMON_LDADD) +osmo_bts_virtual_SOURCES = \ + main.c \ + bts_model.c \ + virtualbts_vty.c \ + scheduler_virtbts.c \ + l1_if.c \ + virtual_um.c \ + osmo_mcast_sock.c \ + $(NULL) + +osmo_bts_virtual_LDADD = \ + $(top_builddir)/src/common/libl1sched.a \ + $(top_builddir)/src/common/libbts.a \ + $(COMMON_LDADD) \ + $(NULL) diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c index af8a6f2a..a70abfb3 100644 --- a/src/osmo-bts-virtual/bts_model.c +++ b/src/osmo-bts-virtual/bts_model.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -100,64 +100,95 @@ static uint8_t vbts_set_trx(struct gsm_bts_trx *trx) static uint8_t vbts_set_ts(struct gsm_bts_trx_ts *ts) { - if (trx_sched_set_pchan(ts, ts->pchan) != 0) + enum gsm_phys_chan_config pchan; + + /* For dynamic timeslots, pick the pchan type that should currently be + * active. This should only be called during init, PDCH transitions + * will call trx_set_ts_as_pchan() directly. */ + switch (ts->pchan) { + case GSM_PCHAN_TCH_F_PDCH: + OSMO_ASSERT((ts->flags & TS_F_PDCH_PENDING_MASK) == 0); + if (ts->flags & TS_F_PDCH_ACTIVE) + pchan = GSM_PCHAN_PDCH; + else + pchan = GSM_PCHAN_TCH_F; + break; + case GSM_PCHAN_OSMO_DYN: + OSMO_ASSERT(ts->dyn.pchan_is == ts->dyn.pchan_want); + pchan = ts->dyn.pchan_is; + break; + default: + pchan = ts->pchan; + break; + } + + if (trx_sched_set_pchan(ts, pchan) != 0) return NM_NACK_RES_NOTAVAIL; + /* activate lchans for [CBCH/]BCCH/CCCH */ + switch (pchan) { + case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: + /* using RSL_CHAN_OSMO_CBCH4 is correct here, because the scheduler + * does not distinguish between SDCCH/4+CBCH abd SDCCH/8+CBCH. */ + trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN], + RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true); + break; + case GSM_PCHAN_CCCH_SDCCH4_CBCH: + trx_sched_set_lchan(&ts->lchan[CBCH_LCHAN], + RSL_CHAN_OSMO_CBCH4, LID_DEDIC, true); + /* fall-through */ + case GSM_PCHAN_CCCH_SDCCH4: + case GSM_PCHAN_CCCH: + trx_sched_set_bcch_ccch(&ts->lchan[CCCH_LCHAN], true); + ts->lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; + lchan_set_state(&ts->lchan[CCCH_LCHAN], LCHAN_S_ACTIVE); + break; + default: + break; + } + return 0; } -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { struct abis_om_fom_hdr *foh = msgb_l3(msg); - int cause = 0; + int rc; switch (foh->msg_type) { case NM_MT_SET_BTS_ATTR: - cause = vbts_set_bts(obj); + rc = vbts_set_bts(obj); break; case NM_MT_SET_RADIO_ATTR: - cause = vbts_set_trx(obj); + rc = vbts_set_trx(obj); break; case NM_MT_SET_CHAN_ATTR: - cause = vbts_set_ts(obj); + rc = vbts_set_ts(obj); + break; + default: + rc = 0; break; } - return oml_fom_ack_nack(msg, cause); + + return rc; } /* MO: TS 12.21 Managed Object */ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) { int rc; - struct gsm_bts_bb_trx *bb_transc; - struct gsm_bts_trx* trx; - struct gsm_bts_trx_ts *ts; switch (mo->obj_class) { case NM_OC_SITE_MANAGER: - rc = osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BTS: - rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_RADIO_CARRIER: - trx = (struct gsm_bts_trx*) obj; - rc = osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_BASEB_TRANSC: - bb_transc = (struct gsm_bts_bb_trx *) obj; - rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_CHANNEL: - ts = (struct gsm_bts_trx_ts *) obj; - rc = osmo_fsm_inst_dispatch(ts->mo.fi, NM_EV_OPSTART_ACK, NULL); - break; case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: - oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - rc = oml_mo_opstart_ack(mo); + rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); diff --git a/src/osmo-bts-virtual/l1_if.c b/src/osmo-bts-virtual/l1_if.c index 444d6ad2..2408557d 100644 --- a/src/osmo-bts-virtual/l1_if.c +++ b/src/osmo-bts-virtual/l1_if.c @@ -42,6 +42,7 @@ #include <osmo-bts/amr.h> #include <osmo-bts/abis.h> #include <osmo-bts/scheduler.h> +#include <osmo-bts/handover.h> #include "virtual_um.h" extern int vbts_sched_start(struct gsm_bts *bts); @@ -187,6 +188,11 @@ nomessage: /* called by common part once OML link is established */ int bts_model_oml_estab(struct gsm_bts *bts) { + struct phy_instance *pinst = trx_phy_instance(bts->c0); + + if (vbts_sched_start(pinst->trx->bts) < 0) + return -ENOLINK; + return 0; } @@ -217,19 +223,6 @@ int bts_model_phy_link_open(struct phy_link *plink) if (pinst->trx == NULL) continue; trx_sched_init(pinst->trx); - /* Only start the scheduler for the transceiver on C0. - * If we have multiple transceivers, CCCH is always on C0 - * and has to be auto active */ - /* Other TRX are activated via OML by a PRIM_INFO_MODIFY - * / PRIM_INFO_ACTIVATE */ - if (pinst->trx == pinst->trx->bts->c0) { - vbts_sched_start(pinst->trx->bts); - /* init lapdm layer 3 callback for the trx on timeslot 0 == BCCH */ - lchan_init_lapdm(&pinst->trx->ts[0].lchan[CCCH_LCHAN]); - /* FIXME: This is probably the wrong location to set the CCCH to active... the OML link def. needs to be reworked and fixed. */ - pinst->trx->ts[0].lchan[CCCH_LCHAN].rel_act_kind = LCHAN_REL_ACT_OML; - lchan_set_state(&pinst->trx->ts[0].lchan[CCCH_LCHAN], LCHAN_S_ACTIVE); - } } /* this will automatically update the MO state of all associated TRX objects */ @@ -319,12 +312,12 @@ static int l1if_process_meas_res(struct gsm_bts_trx *trx, uint8_t tn, uint32_t f /* 100% BER is n_bits_total is 0 */ float ber = n_bits_total==0 ? 1.0 : (float)n_errors / (float)n_bits_total; - DEBUGPFN(DMEAS, fn, "RX L1 frame %s chan_nr=0x%02x MS pwr=%ddBm rssi=%.1f dBFS " - "ber=%.2f%% (%d/%d bits) L1_ta=%d rqd_ta=%d toa=%.2f\n", - gsm_lchan_name(lchan), chan_nr, ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power_ctrl.max), - rssi, ber*100, n_errors, n_bits_total, lchan->meas.l1_info.ta, lchan->rqd_ta, toa); + LOGPLCFN(lchan, fn, DMEAS, LOGL_DEBUG, "RX L1 frame chan_nr=0x%02x MS pwr=%ddBm rssi=%.1f dBFS " + "ber=%.2f%% (%d/%d bits) L1_ta=%d ta_ctrl.current=%d toa=%.2f\n", chan_nr, + ms_pwr_dbm(lchan->ts->trx->bts->band, lchan->ms_power_ctrl.max), rssi, ber * 100, n_errors, + n_bits_total, lchan->meas.l1_info.ta, lchan->ta_ctrl.current, toa); - l1if_fill_meas_res(&l1sap, chan_nr, lchan->rqd_ta + toa, ber, rssi, fn); + l1if_fill_meas_res(&l1sap, chan_nr, lchan->ta_ctrl.current + toa, ber, rssi, fn); return l1sap_up(trx, &l1sap); } @@ -336,7 +329,6 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) { struct msgb *msg = l1sap->oph.msg; uint8_t chan_nr; - uint8_t tn, ss; int rc = 0; struct gsm_lchan *lchan; @@ -352,79 +344,78 @@ int bts_model_l1sap_down(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap) /* put data into scheduler's queue */ return trx_sched_tch_req(trx, l1sap); case OSMO_PRIM(PRIM_MPH_INFO, PRIM_OP_REQUEST): + if (l1sap->u.info.type == PRIM_INFO_ACT_CIPH) + chan_nr = l1sap->u.info.u.ciph_req.chan_nr; + else /* u.act_req used by PRIM_INFO_{ACTIVATE,DEACTIVATE,MODIFY} */ + chan_nr = l1sap->u.info.u.act_req.chan_nr; + lchan = get_lchan_by_chan_nr(trx, chan_nr); + if (OSMO_UNLIKELY(lchan == NULL)) { + LOGP(DL1C, LOGL_ERROR, + "Rx MPH-INFO.req (type=0x%02x) for non-existent lchan (%s)\n", + l1sap->u.info.type, rsl_chan_nr_str(chan_nr)); + rc = -ENODEV; + break; + } + switch (l1sap->u.info.type) { case PRIM_INFO_ACT_CIPH: - chan_nr = l1sap->u.info.u.ciph_req.chan_nr; - tn = L1SAP_CHAN2TS(chan_nr); - ss = l1sap_chan2ss(chan_nr); - lchan = &trx->ts[tn].lchan[ss]; if (l1sap->u.info.u.ciph_req.uplink) l1if_set_ciphering(lchan, chan_nr, 0); if (l1sap->u.info.u.ciph_req.downlink) l1if_set_ciphering(lchan, chan_nr, 1); break; case PRIM_INFO_ACTIVATE: - case PRIM_INFO_DEACTIVATE: - case PRIM_INFO_MODIFY: - chan_nr = l1sap->u.info.u.act_req.chan_nr; - tn = L1SAP_CHAN2TS(chan_nr); - ss = l1sap_chan2ss(chan_nr); - lchan = &trx->ts[tn].lchan[ss]; - /* we receive a channel activation request from the BSC, - * e.g. as a response to a channel req on RACH */ - if (l1sap->u.info.type == PRIM_INFO_ACTIVATE) { - if ((chan_nr & 0xE0) == 0x80) { - LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate" - " channel %s\n", rsl_chan_nr_str(chan_nr)); - break; - } - /* activate dedicated channel */ - trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true); - /* activate associated channel */ - trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true); - /* set mode */ - trx_sched_set_mode(lchan->ts, chan_nr, - lchan->rsl_cmode, lchan->tch_mode, - lchan->tch.amr_mr.num_modes, - lchan->tch.amr_mr.bts_mode[0].mode, - lchan->tch.amr_mr.bts_mode[1].mode, - lchan->tch.amr_mr.bts_mode[2].mode, - lchan->tch.amr_mr.bts_mode[3].mode, - amr_get_initial_mode(lchan), - (lchan->ho.active == 1)); - /* init lapdm */ - lchan_init_lapdm(lchan); - /* set lchan active */ - lchan_set_state(lchan, LCHAN_S_ACTIVE); - /* set initial ciphering */ - l1if_set_ciphering(lchan, chan_nr, 0); - l1if_set_ciphering(lchan, chan_nr, 1); - if (lchan->encr.alg_id) - lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; - else - lchan->ciph_state = LCHAN_CIPH_NONE; - - /* confirm */ - mph_info_chan_confirm(trx, chan_nr, - PRIM_INFO_ACTIVATE, 0); - break; - } - if (l1sap->u.info.type == PRIM_INFO_MODIFY) { - /* change mode */ - trx_sched_set_mode(lchan->ts, chan_nr, - lchan->rsl_cmode, lchan->tch_mode, - lchan->tch.amr_mr.num_modes, - lchan->tch.amr_mr.bts_mode[0].mode, - lchan->tch.amr_mr.bts_mode[1].mode, - lchan->tch.amr_mr.bts_mode[2].mode, - lchan->tch.amr_mr.bts_mode[3].mode, - amr_get_initial_mode(lchan), - 0); + if ((chan_nr & 0xE0) == 0x80) { + LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot activate" + " channel %s\n", rsl_chan_nr_str(chan_nr)); + rc = -EPERM; break; } + /* activate dedicated channel */ + trx_sched_set_lchan(lchan, chan_nr, LID_DEDIC, true); + /* activate associated channel */ + trx_sched_set_lchan(lchan, chan_nr, LID_SACCH, true); + /* set mode */ + trx_sched_set_mode(lchan->ts, chan_nr, + lchan->rsl_cmode, lchan->tch_mode, + lchan->tch.amr_mr.num_modes, + lchan->tch.amr_mr.mode[0].mode, + lchan->tch.amr_mr.mode[1].mode, + lchan->tch.amr_mr.mode[2].mode, + lchan->tch.amr_mr.mode[3].mode, + amr_get_initial_mode(lchan), + (lchan->ho.active == HANDOVER_ENABLED || + rsl_chan_rt_is_asci(lchan->rsl_chan_rt))); + /* set lchan active */ + lchan_set_state(lchan, LCHAN_S_ACTIVE); + /* set initial ciphering */ + l1if_set_ciphering(lchan, chan_nr, 0); + l1if_set_ciphering(lchan, chan_nr, 1); + if (lchan->encr.alg_id) + lchan->ciph_state = LCHAN_CIPH_RXTX_CONF; + else + lchan->ciph_state = LCHAN_CIPH_NONE; + + /* confirm */ + mph_info_chan_confirm(trx, chan_nr, PRIM_INFO_ACTIVATE, 0); + break; + case PRIM_INFO_MODIFY: + /* change mode */ + trx_sched_set_mode(lchan->ts, chan_nr, + lchan->rsl_cmode, lchan->tch_mode, + lchan->tch.amr_mr.num_modes, + lchan->tch.amr_mr.mode[0].mode, + lchan->tch.amr_mr.mode[1].mode, + lchan->tch.amr_mr.mode[2].mode, + lchan->tch.amr_mr.mode[3].mode, + amr_get_initial_mode(lchan), + 0); + break; + case PRIM_INFO_DEACTIVATE: if ((chan_nr & 0xE0) == 0x80) { LOGPLCHAN(lchan, DL1C, LOGL_ERROR, "Cannot deactivate" " channel %s\n", rsl_chan_nr_str(chan_nr)); + rc = -EPERM; break; } /* deactivate associated channel */ diff --git a/src/osmo-bts-virtual/main.c b/src/osmo-bts-virtual/main.c index e5e44edf..367d923b 100644 --- a/src/osmo-bts-virtual/main.c +++ b/src/osmo-bts-virtual/main.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -61,26 +61,53 @@ int bts_model_init(struct gsm_bts *bts) bts->model_priv = bts_virt; bts->variant = BTS_OSMO_VIRTUAL; bts->support.ciphers = CIPHER_A5(1) | CIPHER_A5(2) | CIPHER_A5(3); + bts->gprs.cell.support.gprs_codings = NM_IPAC_MASK_GPRS_CODING_CS + | NM_IPAC_MASK_GPRS_CODING_MCS; + /* order alphabetically */ + osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); + osmo_bts_set_feature(bts->features, BTS_FEAT_EGPRS); + osmo_bts_set_feature(bts->features, BTS_FEAT_GPRS); osmo_bts_set_feature(bts->features, BTS_FEAT_OML_ALERTS); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); - osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_AMR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_EFR); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR); - osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH); + osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { + /* Frequency bands indicated to the BSC */ + trx->support.freq_bands = NM_IPAC_F_FREQ_BAND_PGSM + | NM_IPAC_F_FREQ_BAND_EGSM + | NM_IPAC_F_FREQ_BAND_RGSM + | NM_IPAC_F_FREQ_BAND_DCS + | NM_IPAC_F_FREQ_BAND_PCS + | NM_IPAC_F_FREQ_BAND_850 + | NM_IPAC_F_FREQ_BAND_480 + | NM_IPAC_F_FREQ_BAND_450; + + /* Channel types and modes indicated to the BSC */ + trx->support.chan_types = NM_IPAC_MASK_CHANT_COMMON + | NM_IPAC_F_CHANT_BCCH_SDCCH4_CBCH + | NM_IPAC_F_CHANT_SDCCH8_CBCH + | NM_IPAC_F_CHANT_PDCHF + | NM_IPAC_F_CHANT_TCHF_PDCHF; + trx->support.chan_modes = NM_IPAC_MASK_CHANM_SPEECH + | NM_IPAC_MASK_CHANM_CSD_NT + | NM_IPAC_MASK_CHANM_CSD_T; + /* TODO: NM_IPAC_F_CHANM_CSD_T_14k4 (see OS#6167) */ + trx->support.chan_modes &= ~NM_IPAC_F_CHANM_CSD_T_14k4; + return 0; } void bts_model_print_help() { - LOGP(DSUM, LOGL_NOTICE, "Unimplemented %s\n", __func__); + LOGP(DLGLOBAL, LOGL_NOTICE, "Unimplemented %s\n", __func__); } int bts_model_handle_options(int argc, char **argv) @@ -126,18 +153,18 @@ void bts_model_phy_link_set_defaults(struct phy_link *plink) void bts_model_phy_instance_set_defaults(struct phy_instance *pinst) { - LOGP(DSUM, LOGL_NOTICE, "Unimplemented %s\n", __func__); + LOGP(DLGLOBAL, LOGL_NOTICE, "Unimplemented %s\n", __func__); } int bts_model_ts_disconnect(struct gsm_bts_trx_ts *ts) { - LOGP(DSUM, LOGL_NOTICE, "Unimplemented %s\n", __func__); + LOGP(DLGLOBAL, LOGL_NOTICE, "Unimplemented %s\n", __func__); return -ENOTSUP; } void bts_model_ts_connect(struct gsm_bts_trx_ts *ts, enum gsm_phys_chan_config as_pchan) { - LOGP(DSUM, LOGL_NOTICE, "Unimplemented %s\n", __func__); + LOGP(DLGLOBAL, LOGL_NOTICE, "Unimplemented %s\n", __func__); } int main(int argc, char **argv) diff --git a/src/osmo-bts-virtual/osmo_mcast_sock.c b/src/osmo-bts-virtual/osmo_mcast_sock.c index 3e565142..c802e02d 100644 --- a/src/osmo-bts-virtual/osmo_mcast_sock.c +++ b/src/osmo-bts-virtual/osmo_mcast_sock.c @@ -3,6 +3,7 @@ #include <netdb.h> #include <osmocom/core/socket.h> #include <osmocom/core/select.h> +#include <osmocom/core/osmo_io.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,102 +11,133 @@ #include <unistd.h> #include "osmo_mcast_sock.h" +static void noop_write_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + /* nothing */ +} + +static const struct osmo_io_ops srv_ioops = { + /* no read call-back as we don't read from the socket */ + /* libosmcoore before change-id I0c071a29e508884bac331ada5e510bbfcf440bbf requires write call-back + * even if we don't care about it */ + .write_cb = noop_write_cb, +}; + /* server socket is what we use for transmission. It is not subscribed * to a multicast group or locally bound, but it is just a normal UDP * socket that's connected to the remote mcast group + port */ -int mcast_server_sock_setup(struct osmo_fd *ofd, const char* tx_mcast_group, - uint16_t tx_mcast_port, bool loopback) +static struct osmo_io_fd * +mcast_server_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, bool loopback) { - int rc; + int rc, fd; unsigned int flags = OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_UDP_REUSEADDR; + struct osmo_io_fd *iofd; if (!loopback) flags |= OSMO_SOCK_F_NO_MCAST_LOOP; /* setup mcast server socket */ - rc = osmo_sock_init_ofd(ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, - tx_mcast_group, tx_mcast_port, flags); + rc = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, tx_mcast_group, tx_mcast_port, flags); if (rc < 0) { perror("Failed to create Multicast Server Socket"); - return rc; + return NULL; } + fd = rc; - return 0; + iofd = osmo_iofd_setup(ctx, rc, "mcast_server_sock", OSMO_IO_FD_MODE_READ_WRITE, &srv_ioops, NULL); + if (!iofd) { + close(fd); + return NULL; + } + + osmo_iofd_register(iofd, -1); + return iofd; +} + +static void mcast_sock_read_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + struct mcast_bidir_sock *bidir_sock = osmo_iofd_get_data(iofd); + bidir_sock->read_cb(res, msg, bidir_sock->data); } +const struct osmo_io_ops clnt_ioops = { + .read_cb = mcast_sock_read_cb, + /* no write call-back as we don't write to the socket */ +}; + /* the client socket is what we use for reception. It is a UDP socket * that's bound to the GSMTAP UDP port and subscribed to the respective * multicast group */ -int mcast_client_sock_setup(struct osmo_fd *ofd, const char *mcast_group, uint16_t mcast_port, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data) +static struct osmo_io_fd * +mcast_client_sock_setup(void *ctx, const char *mcast_group, uint16_t mcast_port, + void (*read_cb)(int rc, struct msgb *msg, void *data)) { - int rc; + int rc, fd; unsigned int flags = OSMO_SOCK_F_BIND | OSMO_SOCK_F_NO_MCAST_ALL | OSMO_SOCK_F_UDP_REUSEADDR; - - osmo_fd_setup(ofd, -1, OSMO_FD_READ, fd_rx_cb, osmo_fd_data, 0); + struct osmo_io_fd *iofd; /* Create mcast client socket */ - rc = osmo_sock_init_ofd(ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, - NULL, mcast_port, flags); + rc = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, mcast_port, flags); if (rc < 0) { perror("Could not create mcast client socket"); - return rc; + return NULL; } + fd = rc; /* Configure and join the multicast group */ - rc = osmo_sock_mcast_subscribe(ofd->fd, mcast_group); + rc = osmo_sock_mcast_subscribe(fd, mcast_group); if (rc < 0) { perror("Failed to join to mcast goup"); - osmo_fd_close(ofd); - return rc; + close(fd); + return NULL; + } + + iofd = osmo_iofd_setup(ctx, fd, "mcast_client_sock", OSMO_IO_FD_MODE_READ_WRITE, &clnt_ioops, ctx); + if (!iofd) { + close(fd); + return NULL; } - return 0; + osmo_iofd_register(iofd, -1); + return iofd; } struct mcast_bidir_sock * mcast_bidir_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data) + void (*read_cb)(int rc, struct msgb *msg, void *data), + void *data) { struct mcast_bidir_sock *bidir_sock = talloc(ctx, struct mcast_bidir_sock); - int rc; if (!bidir_sock) return NULL; - rc = mcast_client_sock_setup(&bidir_sock->rx_ofd, rx_mcast_group, rx_mcast_port, - fd_rx_cb, osmo_fd_data); - if (rc < 0) { + bidir_sock->read_cb = read_cb; + bidir_sock->data = data; + + bidir_sock->rx_iofd = mcast_client_sock_setup(bidir_sock, rx_mcast_group, rx_mcast_port, read_cb); + if (!bidir_sock->rx_iofd) { talloc_free(bidir_sock); return NULL; } - rc = mcast_server_sock_setup(&bidir_sock->tx_ofd, tx_mcast_group, tx_mcast_port, loopback); - if (rc < 0) { - osmo_fd_close(&bidir_sock->rx_ofd); + bidir_sock->tx_iofd = mcast_server_sock_setup(bidir_sock, tx_mcast_group, tx_mcast_port, loopback); + if (!bidir_sock->tx_iofd) { + osmo_iofd_free(bidir_sock->rx_iofd); talloc_free(bidir_sock); return NULL; } return bidir_sock; - -} - -int mcast_bidir_sock_tx(struct mcast_bidir_sock *bidir_sock, const uint8_t *data, - unsigned int data_len) -{ - return send(bidir_sock->tx_ofd.fd, data, data_len, 0); } -int mcast_bidir_sock_rx(struct mcast_bidir_sock *bidir_sock, uint8_t *buf, unsigned int buf_len) +int mcast_bidir_sock_tx_msg(struct mcast_bidir_sock *bidir_sock, struct msgb *msg) { - return recv(bidir_sock->rx_ofd.fd, buf, buf_len, 0); + return osmo_iofd_write_msgb(bidir_sock->tx_iofd, msg); } void mcast_bidir_sock_close(struct mcast_bidir_sock *bidir_sock) { - osmo_fd_close(&bidir_sock->tx_ofd); - osmo_fd_close(&bidir_sock->rx_ofd); + osmo_iofd_free(bidir_sock->tx_iofd); + osmo_iofd_free(bidir_sock->rx_iofd); talloc_free(bidir_sock); } diff --git a/src/osmo-bts-virtual/osmo_mcast_sock.h b/src/osmo-bts-virtual/osmo_mcast_sock.h index aa2013c6..5f68415b 100644 --- a/src/osmo-bts-virtual/osmo_mcast_sock.h +++ b/src/osmo-bts-virtual/osmo_mcast_sock.h @@ -4,26 +4,20 @@ #include <stdint.h> #include <netinet/in.h> #include <osmocom/core/select.h> +#include <osmocom/core/osmo_io.h> struct mcast_bidir_sock { - struct osmo_fd tx_ofd; - struct osmo_fd rx_ofd; + struct osmo_io_fd *tx_iofd; + struct osmo_io_fd *rx_iofd; + void (*read_cb)(int rc, struct msgb *msg, void *data); + void *data; }; -struct mcast_bidir_sock *mcast_bidir_sock_setup(void *ctx, - const char *tx_mcast_group, uint16_t tx_mcast_port, - const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data); +struct mcast_bidir_sock * +mcast_bidir_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, + const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, + void (*read_cb)(int rc, struct msgb *msg, void *data), + void *data); -int mcast_server_sock_setup(struct osmo_fd *ofd, const char *tx_mcast_group, - uint16_t tx_mcast_port, bool loopback); - -int mcast_client_sock_setup(struct osmo_fd *ofd, const char *mcast_group, uint16_t mcast_port, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data); - -int mcast_bidir_sock_tx(struct mcast_bidir_sock *bidir_sock, const uint8_t *data, unsigned int data_len); -int mcast_bidir_sock_rx(struct mcast_bidir_sock *bidir_sock, uint8_t *buf, unsigned int buf_len); +int mcast_bidir_sock_tx_msg(struct mcast_bidir_sock *bidir_sock, struct msgb *msg); void mcast_bidir_sock_close(struct mcast_bidir_sock* bidir_sock); - diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c index 9d2adfc3..87596a79 100644 --- a/src/osmo-bts-virtual/scheduler_virtbts.c +++ b/src/osmo-bts-virtual/scheduler_virtbts.c @@ -14,7 +14,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -102,8 +102,6 @@ static void _tx_to_virt_um(struct l1sched_ts *l1ts, if (rc < 0) LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "GSMTAP msg could not send to virtual Um: %s\n", strerror(-rc)); - else if (rc == 0) - bts_shutdown(trx->bts, "VirtPHY write socket died\n"); else LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Sending GSMTAP message to virtual Um\n"); @@ -237,61 +235,13 @@ int tx_pdtch_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) static void tx_tch_common(struct l1sched_ts *l1ts, const struct trx_dl_burst_req *br, - struct msgb **_msg_tch, struct msgb **_msg_facch, - int codec_mode_request) + struct msgb **_msg_tch, struct msgb **_msg_facch) { struct msgb *msg1, *msg2, *msg_tch = NULL, *msg_facch = NULL; struct l1sched_chan_state *chan_state = &l1ts->chan_state[br->chan]; uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; struct osmo_phsap_prim *l1sap; -#if 0 - /* handle loss detection of received TCH frames */ - if (rsl_cmode == RSL_CMOD_SPD_SPEECH - && ++(chan_state->lost_frames) > 5) { - uint8_t tch_data[GSM_FR_BYTES]; - int len; - - LOGL1SB(DL1P, LOGL_NOTICE, l1ts, br, "Missing TCH bursts detected, sending " - "BFI for %s\n", trx_chan_desc[br->chan].name); - - /* indicate bad frame */ - switch (tch_mode) { - case GSM48_CMODE_SPEECH_V1: /* FR / HR */ - if (br->chan != TRXC_TCHF) { /* HR */ - tch_data[0] = 0x70; /* F = 0, FT = 111 */ - memset(tch_data + 1, 0, 14); - len = 15; - break; - } - memset(tch_data, 0, GSM_FR_BYTES); - len = GSM_FR_BYTES; - break; - case GSM48_CMODE_SPEECH_EFR: /* EFR */ - if (br->chan != TRXC_TCHF) - goto inval_mode1; - memset(tch_data, 0, GSM_EFR_BYTES); - len = GSM_EFR_BYTES; - break; - case GSM48_CMODE_SPEECH_AMR: /* AMR */ - len = amr_compose_payload(tch_data, - chan_state->codec[chan_state->dl_cmr], - chan_state->codec[chan_state->dl_ft], 1); - if (len < 2) - break; - memset(tch_data + 2, 0, len - 2); - _sched_compose_tch_ind(l1ts, 0, br->chan, tch_data, len); - break; - default: -inval_mode1: - LOGP(DL1P, LOGL_ERROR, "TCH mode invalid, please " - "fix!\n"); - len = 0; - } - if (len) - _sched_compose_tch_ind(l1ts, 0, br->chan, tch_data, len); - } -#endif /* get frame and unlink from queue */ msg1 = _sched_dequeue_prim(l1ts, br); @@ -419,7 +369,7 @@ int tx_tchf_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) if (br->bid > 0) return 0; - tx_tch_common(l1ts, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1); + tx_tch_common(l1ts, br, &msg_tch, &msg_facch); /* no message at all */ if (!msg_tch && !msg_facch) { @@ -447,15 +397,7 @@ int tx_tchh_fn(struct l1sched_ts *l1ts, struct trx_dl_burst_req *br) return 0; /* get TCH and/or FACCH */ - tx_tch_common(l1ts, br, &msg_tch, &msg_facch, (((br->fn + 4) % 26) >> 2) & 1); - - /* check for FACCH alignment */ - if (msg_facch && ((((br->fn + 4) % 26) >> 2) & 1)) { - LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "Cannot transmit FACCH starting on " - "even frames, please fix RTS!\n"); - msgb_free(msg_facch); - msg_facch = NULL; - } + tx_tch_common(l1ts, br, &msg_tch, &msg_facch); /* no message at all */ if (!msg_tch && !msg_facch && !chan_state->dl_ongoing_facch) { @@ -597,6 +539,9 @@ int vbts_sched_start(struct gsm_bts *bts) struct bts_virt_priv *bts_virt = (struct bts_virt_priv *)bts->model_priv; LOGP(DL1P, LOGL_NOTICE, "starting VBTS scheduler\n"); + if (!bts_virt) + return -EINVAL; + memset(&bts_virt->fn_timer, 0, sizeof(bts_virt->fn_timer)); bts_virt->fn_timer.cb = vbts_fn_timer_cb; bts_virt->fn_timer.data = bts; diff --git a/src/osmo-bts-virtual/virtual_um.c b/src/osmo-bts-virtual/virtual_um.c index de32e49d..711e75d3 100644 --- a/src/osmo-bts-virtual/virtual_um.c +++ b/src/osmo-bts-virtual/virtual_um.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -32,33 +32,15 @@ #include <errno.h> /** - * Virtual UM interface file descriptor callback. - * Should be called by select.c when the fd is ready for reading. + * Virtual UM interface file descriptor read callback. */ -static int virt_um_fd_cb(struct osmo_fd *ofd, unsigned int what) +static void virt_um_read_cb(int rc, struct msgb *msg, void *data) { - struct virt_um_inst *vui = ofd->data; + struct virt_um_inst *vui = data; + msg->l1h = msg->data; - if (what & OSMO_FD_READ) { - struct msgb *msg = msgb_alloc(VIRT_UM_MSGB_SIZE, "Virtual UM Rx"); - int rc; - - /* read message from fd into message buffer */ - rc = mcast_bidir_sock_rx(vui->mcast_sock, msgb_data(msg), msgb_tailroom(msg)); - if (rc > 0) { - msgb_put(msg, rc); - msg->l1h = msgb_data(msg); - /* call the l1 callback function for a received msg */ - vui->recv_cb(vui, msg); - } else if (rc == 0) { - vui->recv_cb(vui, NULL); - osmo_fd_close(ofd); - } else - perror("Read from multicast socket"); - - } - - return 0; + /* call the l1 callback function for a received msg */ + vui->recv_cb(vui, msg); } struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_mcast_port, @@ -69,7 +51,7 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m int rc; vui->mcast_sock = mcast_bidir_sock_setup(ctx, tx_mcast_group, tx_mcast_port, - rx_mcast_group, rx_mcast_port, 1, virt_um_fd_cb, vui); + rx_mcast_group, rx_mcast_port, 1, virt_um_read_cb, vui); if (!vui->mcast_sock) { perror("Unable to create VirtualUm multicast socket"); talloc_free(vui); @@ -79,7 +61,8 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m /* -1 means default, i.e. no TTL explicitly configured in VTY */ if (ttl >= 0) { - rc = osmo_sock_mcast_ttl_set(vui->mcast_sock->tx_ofd.fd, ttl); + int txfd = osmo_iofd_get_fd(vui->mcast_sock->tx_iofd); + rc = osmo_sock_mcast_ttl_set(txfd, ttl); if (rc < 0) { perror("Cannot set TTL of Virtual Um transmit socket"); goto out_close; @@ -87,12 +70,14 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m } if (dev_name) { - rc = osmo_sock_mcast_iface_set(vui->mcast_sock->tx_ofd.fd, dev_name); + int txfd = osmo_iofd_get_fd(vui->mcast_sock->tx_iofd); + rc = osmo_sock_mcast_iface_set(txfd, dev_name); if (rc < 0) { perror("Cannot bind multicast tx to given device"); goto out_close; } - rc = osmo_sock_mcast_iface_set(vui->mcast_sock->rx_ofd.fd, dev_name); + int rxfd = osmo_iofd_get_fd(vui->mcast_sock->rx_iofd); + rc = osmo_sock_mcast_iface_set(rxfd, dev_name); if (rc < 0) { perror("Cannot bind multicast rx to given device"); goto out_close; @@ -120,11 +105,11 @@ int virt_um_write_msg(struct virt_um_inst *vui, struct msgb *msg) { int rc; - rc = mcast_bidir_sock_tx(vui->mcast_sock, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) + rc = mcast_bidir_sock_tx_msg(vui->mcast_sock, msg); + if (rc < 0) { + msgb_free(msg); rc = -errno; - msgb_free(msg); + } return rc; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 57687eef..8d175be8 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control +SUBDIRS = paging cipher agch misc handover tx_power power meas ta_control amr csd if ENABLE_SYSMOBTS SUBDIRS += sysmobts @@ -22,12 +22,38 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac echo ' [$(PACKAGE_URL)])'; \ } >'$(srcdir)/package.m4' -EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) +EXTRA_DIST = \ + testsuite.at \ + $(srcdir)/package.m4 \ + $(TESTSUITE) \ + osmo-bts.vty \ + $(NULL) TESTSUITE = $(srcdir)/testsuite DISTCLEANFILES = atconfig +if ENABLE_EXT_TESTS +python-tests: + $(MAKE) vty-test +else +python-tests: + echo "Not running python-based tests (determined at configure-time)" +endif + +# Run a specific test with: 'make vty-test VTY_TEST=foo.vty' +VTY_TEST ?= *.vty + +# 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: $(top_builddir)/src/osmo-bts-virtual/osmo-bts-virtual + osmo_verify_transcript_vty.py -v \ + -n OsmoBTS -p 4241 \ + -r "$(top_builddir)/src/osmo-bts-virtual/osmo-bts-virtual --vty-test -c $(top_srcdir)/doc/examples/virtual/osmo-bts-virtual.cfg" \ + $(U) $(srcdir)/$(VTY_TEST) + check-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' $(TESTSUITEFLAGS) + $(MAKE) $(AM_MAKEFLAGS) python-tests installcheck-local: atconfig $(TESTSUITE) $(SHELL) '$(TESTSUITE)' AUTOTEST_PATH='$(bindir)' \ diff --git a/tests/agch/Makefile.am b/tests/agch/Makefile.am index 0c4fce45..d05fc626 100644 --- a/tests/agch/Makefile.am +++ b/tests/agch/Makefile.am @@ -1,7 +1,26 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCODEC_LIBS) -noinst_PROGRAMS = agch_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = agch_test EXTRA_DIST = agch_test.ok agch_test_SOURCES = agch_test.c $(srcdir)/../stubs.c diff --git a/tests/agch/agch_test.c b/tests/agch/agch_test.c index e6c56d97..07cf1d90 100644 --- a/tests/agch/agch_test.c +++ b/tests/agch/agch_test.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -23,6 +23,7 @@ #include <osmocom/core/application.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> @@ -124,13 +125,13 @@ static void test_agch_queue(void) for (round = 1; round <= num_rounds; round++) { for (idx = 0; idx < num_ima_per_round; idx++) { - msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + msg = msgb_alloc(GSM_MACBLOCK_LEN, __func__); put_imm_ass(msg, ++count); bts_agch_enqueue(bts, msg); imm_ass_count++; } for (idx = 0; idx < num_rej_per_round; idx++) { - msg = msgb_alloc(GSM_MACBLOCK_LEN, __FUNCTION__); + msg = msgb_alloc(GSM_MACBLOCK_LEN, __func__); put_imm_ass_rej(msg, ++count, 10); bts_agch_enqueue(bts, msg); imm_ass_rej_count++; @@ -158,7 +159,7 @@ static void test_agch_queue(void) if (is_agch) multiframes++; - rc = bts_ccch_copy_msg(bts, out_buf, &g_time, is_agch); + rc = bts_ccch_copy_msg(bts, out_buf, &g_time, (is_agch) ? CCCH_MSGT_AGCH : CCCH_MSGT_PCH); ima = (struct gsm48_imm_ass *)out_buf; switch (ima->msg_type) { case GSM48_MT_RR_IMM_ASS: @@ -225,7 +226,8 @@ int main(int argc, char **argv) osmo_init_logging2(tall_bts_ctx, &bts_log_info); - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + bts = gsm_bts_alloc(g_bts_sm, 0); if (bts_init(bts) < 0) { fprintf(stderr, "unable to open bts\n"); exit(1); diff --git a/tests/amr/Makefile.am b/tests/amr/Makefile.am new file mode 100644 index 00000000..a857d179 --- /dev/null +++ b/tests/amr/Makefile.am @@ -0,0 +1,26 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = amr_test +EXTRA_DIST = amr_test.ok amr_test.err + +amr_test_SOURCES = amr_test.c +amr_test_LDADD = $(top_builddir)/src/common/libbts.a \ + $(LDADD) diff --git a/tests/amr/amr_test.c b/tests/amr/amr_test.c new file mode 100644 index 00000000..07e8bf2c --- /dev/null +++ b/tests/amr/amr_test.c @@ -0,0 +1,71 @@ +/* (C) 2021 by sysmocom s.f.m.c. GmbH + * All Rights Reserved + * + * Author: Philipp Maier + * + * 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 <osmo-bts/logging.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/amr.h> + +#include <osmocom/core/application.h> +#include <osmocom/core/utils.h> + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> + +static void test_amr_parse_mr_conf(void) +{ + uint8_t mrc_enc[] = { 0x20, 0xa5, 0x0d, 0x46, 0x52, 0x54 }; + struct amr_multirate_conf mrc = { 0 }; + unsigned int i; + + printf("amr_parse_mr_conf() <- %s\n", osmo_hexdump(&mrc_enc[0], sizeof(mrc_enc))); + OSMO_ASSERT(amr_parse_mr_conf(&mrc, &mrc_enc[0], sizeof(mrc_enc)) > 0); + printf("amr_parse_mr_conf() -> num_modes=%u\n", mrc.num_modes); + for (i = 0; i < mrc.num_modes; i++) { + printf(" Mode[%u] = %u/%u/%u\n", + i, mrc.mode[i].mode, + mrc.mode[i].threshold, + mrc.mode[i].hysteresis); + } + + mrc_enc[1] = 0xff; /* all codec modes active */ + printf("amr_parse_mr_conf() <- %s\n", osmo_hexdump(&mrc_enc[0], sizeof(mrc_enc))); + OSMO_ASSERT(amr_parse_mr_conf(&mrc, &mrc_enc[0], sizeof(mrc_enc)) == -EINVAL); + + mrc_enc[0] = 0xff; /* unknown version */ + printf("amr_parse_mr_conf() <- %s\n", osmo_hexdump(&mrc_enc[0], sizeof(mrc_enc))); + OSMO_ASSERT(amr_parse_mr_conf(&mrc, &mrc_enc[0], sizeof(mrc_enc)) == -EINVAL); + + printf("amr_parse_mr_conf() <- %s\n", osmo_hexdump(&mrc_enc[0], 1)); /* short read */ + OSMO_ASSERT(amr_parse_mr_conf(&mrc, &mrc_enc[0], 1) == -EINVAL); +} + +int main(int argc, char **argv) +{ + osmo_init_logging2(NULL, &bts_log_info); + log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_print_category_hex(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 1); + log_set_print_level(osmo_stderr_target, 1); + log_set_use_color(osmo_stderr_target, 0); + + test_amr_parse_mr_conf(); + return EXIT_SUCCESS; +} diff --git a/tests/amr/amr_test.err b/tests/amr/amr_test.err new file mode 100644 index 00000000..0b7bdaf4 --- /dev/null +++ b/tests/amr/amr_test.err @@ -0,0 +1,3 @@ +DRSL ERROR AMR Multirate with 8 modes len=6 not possible +DRSL ERROR AMR Multirate Version 7 unknown +DRSL ERROR AMR Multirate IE is too short (1) diff --git a/tests/amr/amr_test.ok b/tests/amr/amr_test.ok new file mode 100644 index 00000000..921e8b9e --- /dev/null +++ b/tests/amr/amr_test.ok @@ -0,0 +1,9 @@ +amr_parse_mr_conf() <- 20 a5 0d 46 52 54 +amr_parse_mr_conf() -> num_modes=4 + Mode[0] = 0/13/4 + Mode[1] = 2/25/4 + Mode[2] = 5/37/4 + Mode[3] = 7/0/0 +amr_parse_mr_conf() <- 20 ff 0d 46 52 54 +amr_parse_mr_conf() <- ff ff 0d 46 52 54 +amr_parse_mr_conf() <- ff diff --git a/tests/cipher/Makefile.am b/tests/cipher/Makefile.am index 3c23718e..c33b05ef 100644 --- a/tests/cipher/Makefile.am +++ b/tests/cipher/Makefile.am @@ -1,7 +1,26 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCODEC_LIBS) -noinst_PROGRAMS = cipher_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = cipher_test EXTRA_DIST = cipher_test.ok cipher_test_SOURCES = cipher_test.c $(srcdir)/../stubs.c diff --git a/tests/cipher/cipher_test.c b/tests/cipher/cipher_test.c index 9303ed21..8ac4018c 100644 --- a/tests/cipher/cipher_test.c +++ b/tests/cipher/cipher_test.c @@ -10,7 +10,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -18,6 +18,7 @@ */ #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/logging.h> #include <osmo-bts/paging.h> #include <osmo-bts/gsm_data.h> @@ -71,7 +72,8 @@ int main(int argc, char **argv) osmo_init_logging2(tall_bts_ctx, &bts_log_info); - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + bts = gsm_bts_alloc(g_bts_sm, 0); if (bts_init(bts) < 0) { fprintf(stderr, "unable to open bts\n"); exit(1); diff --git a/tests/csd/Makefile.am b/tests/csd/Makefile.am new file mode 100644 index 00000000..2041dd7d --- /dev/null +++ b/tests/csd/Makefile.am @@ -0,0 +1,25 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = csd_test +EXTRA_DIST = csd_test.err + +csd_test_SOURCES = csd_test.c +csd_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/csd/csd_test.c b/tests/csd/csd_test.c new file mode 100644 index 00000000..13a64199 --- /dev/null +++ b/tests/csd/csd_test.c @@ -0,0 +1,157 @@ +/* + * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> + * Author: Vadim Yanitskiy <vyanitskiy@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdint.h> +#include <errno.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/utils.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/protocol/gsm_04_08.h> +#include <osmocom/isdn/v110.h> + +#include <osmo-bts/csd_v110.h> +#include <osmo-bts/lchan.h> + +#define BBUF_MAX 290 + +struct test_case { + const char *name; + enum gsm_chan_t lchan_type; + enum gsm48_chan_mode tch_mode; + enum lchan_csd_mode csd_mode; +}; + +static const struct test_case tests[] = { + { + .name = "TCH/F14.4", + .lchan_type = GSM_LCHAN_TCH_F, + .tch_mode = GSM48_CMODE_DATA_14k5, + .csd_mode = LCHAN_CSD_M_T_14400, + }, + { + .name = "TCH/F9.6", + .lchan_type = GSM_LCHAN_TCH_F, + .tch_mode = GSM48_CMODE_DATA_12k0, + .csd_mode = LCHAN_CSD_M_T_9600, + }, + { + .name = "TCH/F4.8", + .lchan_type = GSM_LCHAN_TCH_F, + .tch_mode = GSM48_CMODE_DATA_6k0, + .csd_mode = LCHAN_CSD_M_T_4800, + }, + { + .name = "TCH/H4.8", + .lchan_type = GSM_LCHAN_TCH_H, + .tch_mode = GSM48_CMODE_DATA_6k0, + .csd_mode = LCHAN_CSD_M_T_4800, + }, + { + .name = "TCH/F2.4", + .lchan_type = GSM_LCHAN_TCH_F, + .tch_mode = GSM48_CMODE_DATA_3k6, + .csd_mode = LCHAN_CSD_M_T_2400, + }, + { + .name = "TCH/H2.4", + .lchan_type = GSM_LCHAN_TCH_H, + .tch_mode = GSM48_CMODE_DATA_3k6, + .csd_mode = LCHAN_CSD_M_T_600, + }, +}; + +static void exec_test_case(const struct test_case *tc) +{ + const struct csd_v110_frame_desc *desc; + uint8_t rtp[RFC4040_RTP_PLEN] = { 0 }; + ubit_t data_enc[BBUF_MAX]; + ubit_t data_dec[BBUF_MAX]; + int rc; + + /* obtain a V.110 frame description for the given channel type/rate */ + OSMO_ASSERT(tc->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc)); + if (tc->lchan_type == GSM_LCHAN_TCH_F) + desc = &csd_v110_lchan_desc[tc->tch_mode].fr; + else + desc = &csd_v110_lchan_desc[tc->tch_mode].hr; + + /* total number of bits carried by a radio interface block */ + const unsigned int bit_num = desc->num_bits * desc->num_blocks; + if (bit_num == 0) { + fprintf(stderr, "[i] Skipping '%s' (not implemented)\n", tc->name); + return; + } + + fprintf(stderr, "[i] Testing '%s' (bitnum=%u)\n", tc->name, bit_num); + + struct gsm_lchan lchan = { + .type = tc->lchan_type, + .tch_mode = tc->tch_mode, + .csd_mode = tc->csd_mode, + }; + + /* populate the data_enc[] buffer with some bits */ + OSMO_ASSERT(bit_num <= BBUF_MAX); + for (unsigned int i = 0; i < bit_num; i++) + data_enc[i] = i & 0x01; + + /* encode an RTP frame and print it */ + rc = csd_v110_rtp_encode(&lchan, &rtp[0], &data_enc[0], bit_num); + fprintf(stderr, "[i] csd_v110_rtp_encode() returns %d\n", rc); + if (rc != RFC4040_RTP_PLEN) + return; + /* print the encoded RTP frame (16 bytes per row) */ + for (unsigned int i = 0; i < sizeof(rtp) / 16; i++) + fprintf(stderr, " %s\n", osmo_hexdump(&rtp[i * 16], 16)); + + /* decode the encoded RTP frame */ + rc = csd_v110_rtp_decode(&lchan, &data_dec[0], &rtp[0], sizeof(rtp)); + fprintf(stderr, "[i] csd_v110_rtp_decode() returns %d\n", rc); + if (rc != bit_num) + return; + /* compare data_dec[] vs data_enc[] */ + for (unsigned int i = 0; i < bit_num; i++) { + if (data_dec[i] == data_enc[i]) + continue; + fprintf(stderr, "[!] Data mismatch @ %03u: D%u vs E%u\n", + i, data_dec[i], data_enc[i]); + } + + fprintf(stderr, "[i] Testing '%s' (IDLE)\n", tc->name); + + /* encode an idle RTP frame and print it */ + rc = csd_v110_rtp_encode(&lchan, &rtp[0], &data_enc[0], 0); + fprintf(stderr, "[i] csd_v110_rtp_encode() returns %d\n", rc); + if (rc != RFC4040_RTP_PLEN) + return; + /* print the encoded RTP frame (16 bytes per row) */ + for (unsigned int i = 0; i < sizeof(rtp) / 16; i++) + fprintf(stderr, " %s\n", osmo_hexdump(&rtp[i * 16], 16)); +} + +int main(int argc, char **argv) +{ + for (unsigned int i = 0; i < ARRAY_SIZE(tests); i++) + exec_test_case(&tests[i]); + + return 0; +} diff --git a/tests/csd/csd_test.err b/tests/csd/csd_test.err new file mode 100644 index 00000000..b8623247 --- /dev/null +++ b/tests/csd/csd_test.err @@ -0,0 +1,126 @@ +[i] Skipping 'TCH/F14.4' (not implemented) +[i] Testing 'TCH/F9.6' (bitnum=240) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf + ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f + bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf + ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f + bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f + 3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf + ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f + bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf + ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f + bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f +[i] csd_v110_rtp_decode() returns 240 +[i] Testing 'TCH/F9.6' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +[i] Testing 'TCH/F4.8' (bitnum=120) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff 7f ff 7f ff 7f ff 7f + ff ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff 7f + ff ff 7f ff 7f ff 7f ff ff 7f ff ff 7f ff 7f ff + ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff + ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff + 7f 7f 7f 7f 7f 7f 7f 7f ff 7f ff 7f ff 7f ff 7f + ff ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff 7f + ff ff 7f ff 7f ff 7f ff ff 7f ff ff 7f ff 7f ff + ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff + ff 7f ff 7f ff 7f ff 7f ff ff 7f ff 7f ff 7f ff +[i] csd_v110_rtp_decode() returns 120 +[i] Testing 'TCH/F4.8' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +[i] Testing 'TCH/H4.8' (bitnum=240) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf + ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f + bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf + ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f + bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f + 3f 3f 3f 3f bf bf bf bf ff 7f 7f 7f bf bf bf bf + ff 7f 7f 7f bf ff 7f 7f bf bf bf bf ff 7f 7f 7f + bf bf bf bf ff 7f 7f 7f 3f 3f 3f 3f bf bf bf bf + ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f bf ff 7f 7f + bf bf bf bf ff 7f 7f 7f bf bf bf bf ff 7f 7f 7f +[i] csd_v110_rtp_decode() returns 240 +[i] Testing 'TCH/H4.8' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +[i] Testing 'TCH/F2.4' (bitnum=72) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff ff ff 7f 7f ff 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff + 7f 7f 7f 7f 7f 7f 7f 7f ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff ff ff 7f 7f ff 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff + ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff ff 7f 7f ff +[i] csd_v110_rtp_decode() returns 72 +[i] Testing 'TCH/F2.4' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 7f 7f 7f 7f 7f 7f 7f 7f ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff +[i] Testing 'TCH/H2.4' (bitnum=144) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f + bf 7f bf 7f ff 3f 7f 7f bf 7f bf 7f bf 7f bf 7f + bf 7f bf 7f bf 7f bf 7f 3f 3f 3f 3f bf 7f bf 7f + bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f ff 3f 7f 7f + bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f + 3f 3f 3f 3f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f + bf 7f bf 7f ff 3f 7f 7f bf 7f bf 7f bf 7f bf 7f + bf 7f bf 7f bf 7f bf 7f 3f 3f 3f 3f bf 7f bf 7f + bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f ff 3f 7f 7f + bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f bf 7f +[i] csd_v110_rtp_decode() returns 144 +[i] Testing 'TCH/H2.4' (IDLE) +[i] csd_v110_rtp_encode() returns 160 + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + 3f 3f 3f 3f ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff 3f 3f 3f 3f ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff diff --git a/tests/handover/Makefile.am b/tests/handover/Makefile.am index 53d09c96..789696e3 100644 --- a/tests/handover/Makefile.am +++ b/tests/handover/Makefile.am @@ -1,7 +1,24 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -noinst_PROGRAMS = handover_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = handover_test EXTRA_DIST = handover_test.ok handover_test_SOURCES = handover_test.c $(srcdir)/../stubs.c diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c index 9c9b0207..f1235f53 100644 --- a/tests/handover/handover_test.c +++ b/tests/handover/handover_test.c @@ -28,6 +28,7 @@ #include <osmo-bts/logging.h> #include <osmo-bts/abis.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/vty.h> #include <osmo-bts/bts_model.h> #include <osmo-bts/pcu_if.h> @@ -71,7 +72,12 @@ int main(int argc, char **argv) osmo_init_logging2(tall_bts_ctx, &bts_log_info); osmo_stderr_target->categories[DHO].loglevel = LOGL_DEBUG; - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) { + fprintf(stderr, "Failed to create BTS Site Manager structure\n"); + exit(1); + } + bts = gsm_bts_alloc(g_bts_sm, 0); if (!bts) { fprintf(stderr, "Failed to create BTS structure\n"); exit(1); @@ -93,24 +99,24 @@ int main(int argc, char **argv) OSMO_ASSERT(line); sign_ts = e1inp_line_ipa_rsl_ts(line, 0); e1inp_ts_config_sign(sign_ts, line); - trx->rsl_link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL, NULL, 0, 0); - OSMO_ASSERT(trx->rsl_link); - trx->rsl_link->trx = trx; + trx->bb_transc.rsl.link = e1inp_sign_link_create(sign_ts, E1INP_SIGN_RSL, NULL, 0, 0); + OSMO_ASSERT(trx->bb_transc.rsl.link); + trx->bb_transc.rsl.link->trx = trx; fprintf(stderr, "test 1: without timeout\n"); /* create two lchans for handover */ lchan = &trx->ts[1].lchan[0]; lchan->type = GSM_LCHAN_SDCCH; - l1sap_chan_act(lchan->ts->trx, 0x09, NULL); + l1sap_chan_act(lchan->ts->trx, 0x09); lchan = &trx->ts[2].lchan[0]; lchan->type = GSM_LCHAN_TCH_F; lchan->ho.active = HANDOVER_ENABLED; lchan->ho.ref = 23; - l1sap_chan_act(lchan->ts->trx, 0x0a, NULL); - OSMO_ASSERT(msgb_dequeue(&trx->rsl_link->tx_list)); - OSMO_ASSERT(msgb_dequeue(&trx->rsl_link->tx_list)); - OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list)); + l1sap_chan_act(lchan->ts->trx, 0x0a); + OSMO_ASSERT(msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); + OSMO_ASSERT(msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); + OSMO_ASSERT(!msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); /* send access burst with wrong ref */ memset(&nl1sap, 0, sizeof(nl1sap)); @@ -123,7 +129,7 @@ int main(int argc, char **argv) /* expect no action */ OSMO_ASSERT(modify_count == 0); - OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(!msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); /* send access burst with correct ref */ nl1sap.u.rach_ind.ra = 23; @@ -134,10 +140,10 @@ int main(int argc, char **argv) expect_phys_info(&trx->ts[2].lchan[0].lapdm_ch.lapdm_dcch); /* expect exactly one HO.DET */ - OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(msg = msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); rslh = msgb_l2(msg); OSMO_ASSERT(rslh->c.msg_type == RSL_MT_HANDO_DET); - OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(!msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); /* expect T3105 running */ OSMO_ASSERT(osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105)) @@ -165,10 +171,10 @@ int main(int argc, char **argv) expect_phys_info(&trx->ts[2].lchan[0].lapdm_ch.lapdm_dcch); /* expect exactly one HO.DET */ - OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(msg = msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); rslh = msgb_l2(msg); OSMO_ASSERT(rslh->c.msg_type == RSL_MT_HANDO_DET); - OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(!msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); for (i = 0; i < bts->ny1 - 1; i++) { /* expect T3105 running */ @@ -190,10 +196,10 @@ int main(int argc, char **argv) OSMO_ASSERT(!osmo_timer_pending(&trx->ts[2].lchan[0].ho.t3105)) /* expect exactly one CONN.FAIL */ - OSMO_ASSERT(msg = msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(msg = msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); rslh = msgb_l2(msg); OSMO_ASSERT(rslh->c.msg_type == RSL_MT_CONN_FAIL); - OSMO_ASSERT(!msgb_dequeue(&trx->rsl_link->tx_list)); + OSMO_ASSERT(!msgb_dequeue(&trx->bb_transc.rsl.link->tx_list)); #if 0 while (!quit) { diff --git a/tests/meas/Makefile.am b/tests/meas/Makefile.am index c04106e7..cb014f26 100644 --- a/tests/meas/Makefile.am +++ b/tests/meas/Makefile.am @@ -1,9 +1,26 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -noinst_PROGRAMS = meas_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = meas_test noinst_HEADERS = sysmobts_fr_samples.h meas_testcases.h -EXTRA_DIST = meas_test.ok +EXTRA_DIST = meas_test.ok meas_test.err meas_test_SOURCES = meas_test.c $(srcdir)/../stubs.c meas_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c index ab8ae28e..6936ed0e 100644 --- a/tests/meas/meas_test.c +++ b/tests/meas/meas_test.c @@ -8,6 +8,7 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/logging.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/measurement.h> #include <osmo-bts/rsl.h> @@ -329,7 +330,7 @@ void test_lchan_meas_process_measurement(bool no_sacch, bool dropouts) ulm.ber10k = 0; ulm.ta_offs_256bits = 256; - ulm.c_i = 0; + ulm.ci_cb = 0; ulm.is_sub = 0; ulm.inv_rssi = 90; @@ -373,73 +374,27 @@ void test_lchan_meas_process_measurement(bool no_sacch, bool dropouts) } } -static bool test_ts45008_83_is_sub_is_sacch(uint32_t fn) -{ - if (fn % 104 == 12) - return true; - if (fn % 104 == 25) - return true; - if (fn % 104 == 38) - return true; - if (fn % 104 == 51) - return true; - if (fn % 104 == 64) - return true; - if (fn % 104 == 77) - return true; - if (fn % 104 == 90) - return true; - if (fn % 104 == 103) - return true; - - return false; -} - -static bool test_ts45008_83_is_sub_is_sub(uint32_t fn, uint8_t ss) +static bool test_ts45008_83_is_sub_is_sub(const struct gsm_lchan *lchan, uint32_t fn) { fn = fn % 104; - if (fn >= 52 && fn <= 59) - return true; - - if (ss == 0) { - if (fn == 0) - return true; - if (fn == 2) - return true; - if (fn == 4) - return true; - if (fn == 6) - return true; - if (fn == 52) - return true; - if (fn == 54) - return true; - if (fn == 56) - return true; - if (fn == 58) - return true; - } else if (ss == 1) { - if (fn == 14) + switch (lchan->type) { + case GSM_LCHAN_TCH_F: + /* block {52, 53, 54, 55, 56, 57, 58, 59} */ + return fn == 52; + case GSM_LCHAN_TCH_H: + if (fn == 0) /* H0 block { 0, 2, 4, 6} */ return true; - if (fn == 16) + if (fn == 52) /* H0 block {52, 54, 56, 58} */ return true; - if (fn == 18) + if (fn == 14) /* H1 block {14, 16, 18, 20} */ return true; - if (fn == 20) + if (fn == 66) /* H1 block {66, 68, 70, 72} */ return true; - if (fn == 66) - return true; - if (fn == 68) - return true; - if (fn == 70) - return true; - if (fn == 72) - return true; - } else - OSMO_ASSERT(false); - - return false; + return false; + default: + return false; + } } static void test_ts45008_83_is_sub_single(uint8_t ts, uint8_t ss, bool fr) @@ -464,29 +419,17 @@ static void test_ts45008_83_is_sub_single(uint8_t ts, uint8_t ss, bool fr) lchan->tch_mode = GSM48_CMODE_SPEECH_V1; } - printf(" TS=%u ", ts); - printf("SS=%u", ss); + printf(" TS=%u SS=%u\n", ts, ss); /* Walk trough the first 100 intervals and check for unexpected * results (false positive and false negative) */ for (i = 0; i < 104 * 100; i++) { rc = ts45008_83_is_sub(lchan, i); - if (rc) { - if (!test_ts45008_83_is_sub_is_sacch(i) - && !test_ts45008_83_is_sub_is_sub(i, ss)) { - printf("==> Unexpected SUB frame at fn=%u", i); - OSMO_ASSERT(false); - } - } else { - if (test_ts45008_83_is_sub_is_sacch(i) - && test_ts45008_83_is_sub_is_sub(i, ss)) { - printf("==> Unexpected non-SUB frame at fn=%u", - i); - OSMO_ASSERT(false); - } + if (rc != test_ts45008_83_is_sub_is_sub(lchan, i)) { + printf(" ==> ts45008_83_is_sub(fn=%u) yields %s, expected %s\n", + i, rc ? "true" : "false", !rc ? "true" : "false"); } } - printf("\n"); } static void test_ts45008_83_is_sub(void) @@ -513,9 +456,20 @@ int main(int argc, char **argv) msgb_talloc_ctx_init(tall_bts_ctx, 0); osmo_init_logging2(tall_bts_ctx, &bts_log_info); - osmo_stderr_target->categories[DMEAS].loglevel = LOGL_DEBUG; - - bts = gsm_bts_alloc(tall_bts_ctx, 0); + log_set_log_level(osmo_stderr_target, LOGL_DEBUG); + log_set_print_category_hex(osmo_stderr_target, 0); + log_set_print_category(osmo_stderr_target, 0); + log_set_print_level(osmo_stderr_target, 1); + log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE); + log_set_use_color(osmo_stderr_target, 0); + log_parse_category_mask(osmo_stderr_target, "DMEAS,1:"); + + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) { + fprintf(stderr, "Failed to create BTS Site Manager structure\n"); + exit(1); + } + bts = gsm_bts_alloc(g_bts_sm, 0); if (!bts) { fprintf(stderr, "Failed to create BTS structure\n"); exit(1); diff --git a/tests/meas/meas_test.err b/tests/meas/meas_test.err new file mode 100644 index 00000000..f5176f11 --- /dev/null +++ b/tests/meas/meas_test.err @@ -0,0 +1,8241 @@ +DEBUG (bts=0,trx=1,ts=2,ss=0) 010958/08/12/44/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011062/08/12/46/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011166/08/12/48/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011270/08/12/50/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011374/08/12/01/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011478/08/12/03/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011491/08/25/16/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011582/08/12/05/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011595/08/25/18/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011686/08/12/07/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011699/08/25/20/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011790/08/12/09/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011803/08/25/22/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011894/08/12/11/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011907/08/25/24/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011998/09/12/13/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012011/09/25/26/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012102/09/12/15/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012115/09/25/28/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012206/09/12/17/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012219/09/25/30/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012310/09/12/19/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012323/09/25/32/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012414/09/12/21/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012427/09/25/34/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012518/09/12/23/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012531/09/25/36/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 012622/09/12/25/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012635/09/25/38/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 005888/04/12/23/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 005992/04/12/25/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006096/04/12/27/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006200/04/12/29/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006213/04/25/42/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006304/04/12/31/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006317/04/25/44/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006408/04/12/33/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006421/04/25/46/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006512/04/12/35/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006525/04/25/48/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006616/04/12/37/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006629/04/25/50/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006720/05/12/39/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006733/05/25/01/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006824/05/12/41/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006837/05/25/03/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 006928/05/12/43/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006941/05/25/05/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007032/05/12/45/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007045/05/25/07/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007136/05/12/47/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007149/05/25/09/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007240/05/12/49/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007253/05/25/11/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007344/05/12/00/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007357/05/25/13/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007448/05/12/02/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007461/05/25/15/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007552/05/12/04/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007565/05/25/17/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007656/05/12/06/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007669/05/25/19/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007773/05/25/21/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007877/05/25/23/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007981/06/25/25/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008085/06/25/27/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008592/06/12/24/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008605/06/25/37/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008696/06/12/26/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008709/06/25/39/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008800/06/12/28/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008813/06/25/41/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008904/06/12/30/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008917/06/25/43/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009008/06/12/32/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009021/06/25/45/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009112/06/12/34/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009125/06/25/47/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009216/06/12/36/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009229/06/25/49/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009320/07/12/38/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009333/07/25/00/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009424/07/12/40/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009437/07/25/02/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009528/07/12/42/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009541/07/25/04/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009632/07/12/44/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=5,ss=0) 009645/07/25/06/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008618/06/12/50/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008722/06/12/01/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008826/06/12/03/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008930/06/12/05/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 008943/06/25/18/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009034/06/12/07/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009047/06/25/20/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009138/06/12/09/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009151/06/25/22/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009242/06/12/11/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009255/06/25/24/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009346/07/12/13/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009359/07/25/26/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009450/07/12/15/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009463/07/25/28/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009554/07/12/17/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009567/07/25/30/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009658/07/12/19/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009671/07/25/32/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009762/07/12/21/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009775/07/25/34/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009866/07/12/23/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009879/07/25/36/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009970/07/12/25/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 009983/07/25/38/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010074/07/12/27/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010087/07/25/40/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010178/07/12/29/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010191/07/25/42/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010282/07/12/31/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010295/07/25/44/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010386/07/12/33/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010399/07/25/46/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010490/07/12/35/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010503/07/25/48/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010594/07/12/37/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010607/07/25/50/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010698/08/12/39/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010711/08/25/01/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010802/08/12/41/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010815/08/25/03/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010906/08/12/43/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 010919/08/25/05/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011010/08/12/45/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011023/08/25/07/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011114/08/12/47/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011127/08/25/09/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011218/08/12/49/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011231/08/25/11/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011322/08/12/00/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011335/08/25/13/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011426/08/12/02/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011439/08/25/15/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011530/08/12/04/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011543/08/25/17/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011634/08/12/06/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011647/08/25/19/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011738/08/12/08/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011751/08/25/21/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011842/08/12/10/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011855/08/25/23/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011946/09/12/12/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011959/09/25/25/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 012050/09/12/14/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012063/09/25/27/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=6,ss=0) 012154/09/12/16/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012167/09/25/29/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 24 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(96.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 008982/06/12/06/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009086/06/12/08/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009190/06/12/10/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009294/07/12/12/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009398/07/12/14/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009411/07/25/27/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009502/07/12/16/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009515/07/25/29/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009606/07/12/18/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009619/07/25/31/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009710/07/12/20/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009723/07/25/33/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009814/07/12/22/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009827/07/25/35/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 009918/07/12/24/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 009931/07/25/37/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010022/07/12/26/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010035/07/25/39/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010126/07/12/28/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010139/07/25/41/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010230/07/12/30/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010243/07/25/43/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010334/07/12/32/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010347/07/25/45/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010438/07/12/34/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010451/07/25/47/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010542/07/12/36/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010555/07/25/49/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010646/08/12/38/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010659/08/25/00/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010750/08/12/40/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010763/08/25/02/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010854/08/12/42/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010867/08/25/04/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 010958/08/12/44/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 010971/08/25/06/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011062/08/12/46/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 011075/08/25/08/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011166/08/12/48/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 011179/08/25/10/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011270/08/12/50/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 011283/08/25/12/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011374/08/12/01/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 011387/08/25/14/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011478/08/12/03/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=1) 011491/08/25/16/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=2,ss=0) 011582/08/12/05/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010022/07/12/26/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010035/07/25/39/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010126/07/12/28/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010139/07/25/41/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010230/07/12/30/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010243/07/25/43/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010334/07/12/32/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010347/07/25/45/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010438/07/12/34/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010451/07/25/47/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010542/07/12/36/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010555/07/25/49/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010646/08/12/38/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010659/08/25/00/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010750/08/12/40/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010763/08/25/02/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010854/08/12/42/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010867/08/25/04/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 010958/08/12/44/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 010971/08/25/06/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011062/08/12/46/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011075/08/25/08/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011166/08/12/48/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011179/08/25/10/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011270/08/12/50/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011283/08/25/12/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011374/08/12/01/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011387/08/25/14/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011478/08/12/03/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011491/08/25/16/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011582/08/12/05/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011595/08/25/18/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011686/08/12/07/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011699/08/25/20/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011790/08/12/09/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011803/08/25/22/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011894/08/12/11/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 011907/08/25/24/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 011998/09/12/13/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 012011/09/25/26/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=0) 012102/09/12/15/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=3,ss=1) 012115/09/25/28/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=3,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=3,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=3,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=3,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=3,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008592/06/12/24/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008605/06/25/37/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008696/06/12/26/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008709/06/25/39/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008800/06/12/28/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008813/06/25/41/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 008904/06/12/30/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 008917/06/25/43/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009008/06/12/32/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009021/06/25/45/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009112/06/12/34/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009125/06/25/47/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009216/06/12/36/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009229/06/25/49/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009320/07/12/38/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009333/07/25/00/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009424/07/12/40/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009437/07/25/02/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009528/07/12/42/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009541/07/25/04/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009632/07/12/44/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009645/07/25/06/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009736/07/12/46/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009749/07/25/08/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009840/07/12/48/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009853/07/25/10/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 009944/07/12/50/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 009957/07/25/12/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010048/07/12/01/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010061/07/25/14/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010152/07/12/03/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010165/07/25/16/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010256/07/12/05/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010269/07/25/18/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010360/07/12/07/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010373/07/25/20/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010464/07/12/09/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010477/07/25/22/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010568/07/12/11/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010581/07/25/24/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010672/08/12/13/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010685/08/25/26/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010776/08/12/15/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010789/08/25/28/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010880/08/12/17/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010893/08/25/30/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=0) 010984/08/12/19/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=4,ss=1) 010997/08/25/32/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=4,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=4,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=4,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=4,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=4,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005264/03/12/11/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005368/04/12/13/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005472/04/12/15/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005576/04/12/17/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005680/04/12/19/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 005693/04/25/32/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005784/04/12/21/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 005797/04/25/34/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005888/04/12/23/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 005901/04/25/36/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 005992/04/12/25/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006005/04/25/38/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006096/04/12/27/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006109/04/25/40/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006200/04/12/29/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006213/04/25/42/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006304/04/12/31/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006317/04/25/44/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006408/04/12/33/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006421/04/25/46/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006512/04/12/35/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006525/04/25/48/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006616/04/12/37/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006629/04/25/50/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006720/05/12/39/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006733/05/25/01/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006824/05/12/41/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006837/05/25/03/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 006928/05/12/43/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 006941/05/25/05/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007032/05/12/45/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007045/05/25/07/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007136/05/12/47/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007149/05/25/09/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007240/05/12/49/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007253/05/25/11/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007344/05/12/00/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007357/05/25/13/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007448/05/12/02/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007461/05/25/15/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007552/05/12/04/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007565/05/25/17/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007656/05/12/06/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007669/05/25/19/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007773/05/25/21/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007877/05/25/23/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 007981/06/25/25/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 008085/06/25/27/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=5,ss=1) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=5,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=5,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=5,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=5,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=5,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008098/06/12/40/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008202/06/12/42/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008306/06/12/44/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008410/06/12/46/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008423/06/25/08/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008514/06/12/48/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008527/06/25/10/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008618/06/12/50/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008631/06/25/12/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008722/06/12/01/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008735/06/25/14/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008826/06/12/03/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008839/06/25/16/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 008930/06/12/05/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 008943/06/25/18/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009034/06/12/07/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009047/06/25/20/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009138/06/12/09/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009151/06/25/22/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009242/06/12/11/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009255/06/25/24/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009346/07/12/13/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009359/07/25/26/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009450/07/12/15/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009463/07/25/28/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009554/07/12/17/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009567/07/25/30/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009658/07/12/19/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009671/07/25/32/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009762/07/12/21/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009775/07/25/34/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009866/07/12/23/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009879/07/25/36/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 009970/07/12/25/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 009983/07/25/38/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010074/07/12/27/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010087/07/25/40/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010178/07/12/29/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010191/07/25/42/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010282/07/12/31/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010295/07/25/44/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010386/07/12/33/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010399/07/25/46/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010490/07/12/35/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010503/07/25/48/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010594/07/12/37/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010607/07/25/50/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010698/08/12/39/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010711/08/25/01/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010802/08/12/41/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010815/08/25/03/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 010906/08/12/43/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 010919/08/25/05/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011010/08/12/45/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011023/08/25/07/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011114/08/12/47/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011127/08/25/09/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011218/08/12/49/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011231/08/25/11/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011322/08/12/00/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011335/08/25/13/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011426/08/12/02/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011439/08/25/15/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=0) 011530/08/12/04/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=6,ss=1) 011543/08/25/17/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=6,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=6,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=6,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=6,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=6,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011738/08/12/08/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011842/08/12/10/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 011946/09/12/12/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012050/09/12/14/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012063/09/25/27/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012154/09/12/16/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012167/09/25/29/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012258/09/12/18/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012271/09/25/31/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012362/09/12/20/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012375/09/25/33/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012466/09/12/22/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012479/09/25/35/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012570/09/12/24/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012583/09/25/37/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012674/09/12/26/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012687/09/25/39/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012778/09/12/28/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012791/09/25/41/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012882/09/12/30/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012895/09/25/43/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 012986/09/12/32/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 012999/09/25/45/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013090/09/12/34/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013103/09/25/47/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013194/09/12/36/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013207/09/25/49/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013298/10/12/38/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013311/10/25/00/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013402/10/12/40/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013415/10/25/02/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013506/10/12/42/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013519/10/25/04/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013610/10/12/44/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013623/10/25/06/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013714/10/12/46/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013727/10/25/08/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013818/10/12/48/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013831/10/25/10/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 013922/10/12/50/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 013935/10/25/12/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014026/10/12/01/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014039/10/25/14/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014130/10/12/03/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014143/10/25/16/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014234/10/12/05/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014247/10/25/18/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014338/10/12/07/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014351/10/25/20/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014442/10/12/09/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014455/10/25/22/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014546/10/12/11/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014559/10/25/24/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014650/11/12/13/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014663/11/25/26/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014754/11/12/15/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014767/11/25/28/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014858/11/12/17/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014871/11/25/30/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 014962/11/12/19/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 014975/11/25/32/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 015066/11/12/21/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 015079/11/25/34/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=0) 015170/11/12/23/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=0) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=0) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=0) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=0) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=7,ss=1) 015183/11/25/36/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) Received 1 UL measurements, expected 13 +DEBUG (bts=0,trx=1,ts=7,ss=1) Replaced 12 measurements with dummy values, from which 12 were SUB measurements +DEBUG (bts=0,trx=1,ts=7,ss=1) Received UL measurements contain 0 SUB measurements, expected 13 +ERROR (bts=0,trx=1,ts=7,ss=1) Incorrect number of SUB measurements detected! (12 vs exp 13) +INFO (bts=0,trx=1,ts=7,ss=1) Computed TA256( 0), BER-FULL(92.30%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=7,ss=1) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(12), num_ul_meas(13) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=-256, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 3 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 22 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 0), BER-FULL(88.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000004/00/04/04/04 adding a SUB measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000008/00/08/08/08 adding a SUB measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000011/00/11/11/11 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000016/00/16/16/16 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=17, fn_mod=16 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000017/00/17/17/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=18, fn_mod=17 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000018/00/18/18/18 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=19, fn_mod=18 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000019/00/19/19/19 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=20, fn_mod=19 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000020/00/20/20/20 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=21, fn_mod=20 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=258, ci_cB=10, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000022/00/22/22/22 adding a FULL measurement (ber10k=0, ta_offs=254, ci_cB=10, rssi=-90), num_ul_meas=23, fn_mod=22 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000023/00/23/23/23 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=24, fn_mod=23 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000024/00/24/24/24 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=10, rssi=-90), num_ul_meas=25, fn_mod=24 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=1,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 256), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-80), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-80), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-100), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=0, ci_cB=10, rssi=-100), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 5 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 20 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 0), BER-FULL(80.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 0 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 25 measurements with dummy values, from which 2 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 0 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 0), BER-FULL(100.00%), RSSI-FULL(-109dBm), C/I-FULL( 0 cB), BER-SUB(100.00%), RSSI-SUB(-109dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(1), RXLEV_SUB(1), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000002/00/02/02/02 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000013/00/13/13/13 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000016/00/16/16/16 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=17, fn_mod=16 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000017/00/17/17/17 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=18, fn_mod=17 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000018/00/18/18/18 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=19, fn_mod=18 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000019/00/19/19/19 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=20, fn_mod=19 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000020/00/20/20/20 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=21, fn_mod=20 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000022/00/22/22/22 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=23, fn_mod=22 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000023/00/23/23/23 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=24, fn_mod=23 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000024/00/24/24/24 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=25, fn_mod=24 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=26, fn_mod=25 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 26 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 1 excess UL measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=1,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000014/00/14/14/14 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000016/00/16/16/16 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=17, fn_mod=16 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000017/00/17/17/17 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=18, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000018/00/18/18/18 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=19, fn_mod=18 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000019/00/19/19/19 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=20, fn_mod=19 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000020/00/20/20/20 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=21, fn_mod=20 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000022/00/22/22/22 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=23, fn_mod=22 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000023/00/23/23/23 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=24, fn_mod=23 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000024/00/24/24/24 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=25, fn_mod=24 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 16 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 9 measurements with dummy values, from which 1 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 1 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL(36.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB(50.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000015/00/15/15/15 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 16 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 9 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL(36.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000014/00/14/14/14 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000016/00/16/16/16 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=17, fn_mod=16 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000017/00/17/17/17 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=18, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000018/00/18/18/18 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=19, fn_mod=18 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000019/00/19/19/19 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=20, fn_mod=19 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000020/00/20/20/20 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=21, fn_mod=20 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000022/00/22/22/22 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=23, fn_mod=22 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000023/00/23/23/23 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=24, fn_mod=23 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000024/00/24/24/24 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=25, fn_mod=24 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 5 SUB measurements, expected 3 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (5 vs exp 3) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(5), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 14 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 11 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 3 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL(44.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000002/00/02/02/02 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000003/00/03/03/03 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000007/00/07/07/07 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000012/00/12/12/12 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000015/00/15/15/15 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 16 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 9 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 5 SUB measurements, expected 3 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (5 vs exp 3) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 16384), BER-FULL(36.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(5), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=1,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000001/00/01/01/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000002/00/02/02/02 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000003/00/03/03/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=4, fn_mod=3 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=5, fn_mod=4 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000005/00/05/05/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=6, fn_mod=5 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000006/00/06/06/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=7, fn_mod=6 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000007/00/07/07/07 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=8, fn_mod=7 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=9, fn_mod=8 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000009/00/09/09/09 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=10, fn_mod=9 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000010/00/10/10/10 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=11, fn_mod=10 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000011/00/11/11/11 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=12, fn_mod=11 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000012/00/12/12/12 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=13, fn_mod=12 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000013/00/13/13/13 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=14, fn_mod=13 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000014/00/14/14/14 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=15, fn_mod=14 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000015/00/15/15/15 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=16, fn_mod=15 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000016/00/16/16/16 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=17, fn_mod=16 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000017/00/17/17/17 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=18, fn_mod=17 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000018/00/18/18/18 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=19, fn_mod=18 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000019/00/19/19/19 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=20, fn_mod=19 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000020/00/20/20/20 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=21, fn_mod=20 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000022/00/22/22/22 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=23, fn_mod=22 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000023/00/23/23/23 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=24, fn_mod=23 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000024/00/24/24/24 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=25, fn_mod=24 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=26, fn_mod=25 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000026/00/00/26/26 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=27, fn_mod=26 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000027/00/01/27/27 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=28, fn_mod=27 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000028/00/02/28/28 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=29, fn_mod=28 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000029/00/03/29/29 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=30, fn_mod=29 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000030/00/04/30/30 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=31, fn_mod=30 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000031/00/05/31/31 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=32, fn_mod=31 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000032/00/06/32/32 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=33, fn_mod=32 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000033/00/07/33/33 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=34, fn_mod=33 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000034/00/08/34/34 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=35, fn_mod=34 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000035/00/09/35/35 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=36, fn_mod=35 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000036/00/10/36/36 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=37, fn_mod=36 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000037/00/11/37/37 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=38, fn_mod=37 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000038/00/12/38/38 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=39, fn_mod=38 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000039/00/13/39/39 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=40, fn_mod=39 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000040/00/14/40/40 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=41, fn_mod=40 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000041/00/15/41/41 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=42, fn_mod=41 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000042/00/16/42/42 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=43, fn_mod=42 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000043/00/17/43/43 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=44, fn_mod=43 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000044/00/18/44/44 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=45, fn_mod=44 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000045/00/19/45/45 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=46, fn_mod=45 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000046/00/20/46/46 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=47, fn_mod=46 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000047/00/21/47/47 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=48, fn_mod=47 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000048/00/22/48/48 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=49, fn_mod=48 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000049/00/23/49/49 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=50, fn_mod=49 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000050/00/24/50/50 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=51, fn_mod=50 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000051/00/25/00/51 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=52, fn_mod=51 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000052/00/00/01/00 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=53, fn_mod=52 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000053/00/01/02/01 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=54, fn_mod=53 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000054/00/02/03/02 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=55, fn_mod=54 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000055/00/03/04/03 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=56, fn_mod=55 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000056/00/04/05/04 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=57, fn_mod=56 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000057/00/05/06/05 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=58, fn_mod=57 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000058/00/06/07/06 adding a FULL measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=59, fn_mod=58 +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 59 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=1,ss=0) Received 34 excess UL measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=1,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=1,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=1,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=1,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=0,ss=0) 000000/00/00/00/00 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000001/00/01/01/01 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000002/00/02/02/02 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000088/00/10/37/36 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) Calculating measurement results for physical channel: CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) Received 3 UL measurements, expected 3 +DEBUG (bts=0,trx=1,ts=0,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=0,ss=0) Received UL measurements contain 3 SUB measurements, expected 3 +INFO (bts=0,trx=1,ts=0,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=0,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(3) +DEBUG (bts=0,trx=1,ts=0,ss=0) 000000/00/00/00/00 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000001/00/01/01/01 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=2, fn_mod=1 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000002/00/02/02/02 adding a SUB measurement (ber10k=0, ta_offs=16384, ci_cB=10, rssi=-90), num_ul_meas=3, fn_mod=2 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000066/00/14/15/14 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) Calculating measurement results for physical channel: SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) Received 3 UL measurements, expected 3 +DEBUG (bts=0,trx=1,ts=0,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=0,ss=0) Received UL measurements contain 3 SUB measurements, expected 3 +INFO (bts=0,trx=1,ts=0,ss=0) Computed TA256( 16384), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 10 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 10 cB) +INFO (bts=0,trx=1,ts=0,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(3) +DEBUG (bts=0,trx=1,ts=0,ss=0) 000012/00/12/12/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000116/00/12/14/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000220/00/12/16/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000324/00/12/18/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000428/00/12/20/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000532/00/12/22/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000636/00/12/24/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000740/00/12/26/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000844/00/12/28/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000948/00/12/30/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001052/00/12/32/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001156/00/12/34/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001260/00/12/36/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001364/01/12/38/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001468/01/12/40/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001572/01/12/42/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001676/01/12/44/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001780/01/12/46/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001884/01/12/48/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 001988/01/12/50/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002092/01/12/01/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002196/01/12/03/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002300/01/12/05/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002404/01/12/07/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002508/01/12/09/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002612/01/12/11/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002716/02/12/13/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002820/02/12/15/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 002924/02/12/17/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003028/02/12/19/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003132/02/12/21/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003236/02/12/23/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003340/02/12/25/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003444/02/12/27/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003548/02/12/29/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003652/02/12/31/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003756/02/12/33/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003860/02/12/35/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 003964/02/12/37/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004068/03/12/39/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004172/03/12/41/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004276/03/12/43/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004380/03/12/45/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004484/03/12/47/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004588/03/12/49/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004692/03/12/00/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004796/03/12/02/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 004900/03/12/04/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005004/03/12/06/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005108/03/12/08/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005212/03/12/10/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005316/04/12/12/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005420/04/12/14/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005524/04/12/16/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005628/04/12/18/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005732/04/12/20/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005836/04/12/22/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 005940/04/12/24/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006044/04/12/26/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006148/04/12/28/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006252/04/12/30/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006356/04/12/32/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006460/04/12/34/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006564/04/12/36/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006668/05/12/38/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006772/05/12/40/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006876/05/12/42/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 006980/05/12/44/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007084/05/12/46/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007188/05/12/48/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007292/05/12/50/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007396/05/12/01/20 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007500/05/12/03/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007604/05/12/05/24 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007708/05/12/07/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007812/05/12/09/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 007916/05/12/11/28 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008020/06/12/13/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008124/06/12/15/32 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008228/06/12/17/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008332/06/12/19/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008436/06/12/21/36 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008540/06/12/23/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008644/06/12/25/40 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008748/06/12/27/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008852/06/12/29/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 008956/06/12/31/44 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009060/06/12/33/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009164/06/12/35/48 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009268/06/12/37/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009372/07/12/39/00 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009476/07/12/41/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009580/07/12/43/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009684/07/12/45/04 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009788/07/12/47/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009892/07/12/49/08 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 009996/07/12/00/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 010100/07/12/02/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 010204/07/12/04/12 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 010308/07/12/06/16 meas period end fn_mod:90, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000129/00/25/27/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000233/00/25/29/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000337/00/25/31/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000441/00/25/33/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000545/00/25/35/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000649/00/25/37/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000753/00/25/39/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000857/00/25/41/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 000961/00/25/43/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001065/00/25/45/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001169/00/25/47/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001273/00/25/49/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001377/01/25/00/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001481/01/25/02/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001585/01/25/04/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001689/01/25/06/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001793/01/25/08/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 001897/01/25/10/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002001/01/25/12/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002105/01/25/14/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002209/01/25/16/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002313/01/25/18/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002417/01/25/20/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002521/01/25/22/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002625/01/25/24/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002729/02/25/26/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002833/02/25/28/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 002937/02/25/30/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003041/02/25/32/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003145/02/25/34/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003249/02/25/36/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003353/02/25/38/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003457/02/25/40/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003561/02/25/42/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003665/02/25/44/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003769/02/25/46/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003873/02/25/48/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 003977/02/25/50/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004081/03/25/01/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004185/03/25/03/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004289/03/25/05/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004393/03/25/07/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004497/03/25/09/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004601/03/25/11/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004705/03/25/13/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004809/03/25/15/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 004913/03/25/17/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005017/03/25/19/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005121/03/25/21/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005225/03/25/23/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005329/04/25/25/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005433/04/25/27/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005537/04/25/29/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005641/04/25/31/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005745/04/25/33/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005849/04/25/35/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 005953/04/25/37/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006057/04/25/39/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006161/04/25/41/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006265/04/25/43/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006369/04/25/45/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006473/04/25/47/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006577/04/25/49/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006681/05/25/00/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006785/05/25/02/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006889/05/25/04/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 006993/05/25/06/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007097/05/25/08/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007201/05/25/10/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007305/05/25/12/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007409/05/25/14/33 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007513/05/25/16/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007617/05/25/18/37 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007721/05/25/20/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007825/05/25/22/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 007929/05/25/24/41 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008033/06/25/26/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008137/06/25/28/45 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008241/06/25/30/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008345/06/25/32/49 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008449/06/25/34/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008553/06/25/36/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008657/06/25/38/01 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008761/06/25/40/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008865/06/25/42/05 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 008969/06/25/44/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009073/06/25/46/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009177/06/25/48/09 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009281/06/25/50/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009385/07/25/01/13 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009489/07/25/03/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009593/07/25/05/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009697/07/25/07/17 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009801/07/25/09/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 009905/07/25/11/21 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 010009/07/25/13/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 010113/07/25/15/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 010217/07/25/17/25 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=1,ss=0) 010321/07/25/19/29 meas period end fn_mod:103, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000454/00/12/46/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000558/00/12/48/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000662/00/12/50/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000766/00/12/01/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000870/00/12/03/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 000974/00/12/05/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001078/00/12/07/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001182/00/12/09/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001286/00/12/11/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001390/01/12/13/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001494/01/12/15/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001598/01/12/17/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001702/01/12/19/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001806/01/12/21/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 001910/01/12/23/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002014/01/12/25/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002118/01/12/27/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002222/01/12/29/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002326/01/12/31/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002430/01/12/33/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002534/01/12/35/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002638/01/12/37/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002742/02/12/39/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002846/02/12/41/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 002950/02/12/43/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003054/02/12/45/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003158/02/12/47/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003262/02/12/49/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003366/02/12/00/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003470/02/12/02/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003574/02/12/04/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003678/02/12/06/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003782/02/12/08/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003886/02/12/10/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 003990/03/12/12/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004094/03/12/14/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004198/03/12/16/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004302/03/12/18/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004406/03/12/20/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004510/03/12/22/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004614/03/12/24/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004718/03/12/26/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004822/03/12/28/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 004926/03/12/30/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005030/03/12/32/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005134/03/12/34/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005238/03/12/36/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005342/04/12/38/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005446/04/12/40/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005550/04/12/42/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005654/04/12/44/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005758/04/12/46/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005862/04/12/48/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 005966/04/12/50/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006070/04/12/01/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006174/04/12/03/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006278/04/12/05/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006382/04/12/07/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006486/04/12/09/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006590/04/12/11/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006694/05/12/13/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006798/05/12/15/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 006902/05/12/17/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007006/05/12/19/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007110/05/12/21/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007214/05/12/23/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007318/05/12/25/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007422/05/12/27/46 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007526/05/12/29/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007630/05/12/31/50 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007734/05/12/33/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007838/05/12/35/02 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 007942/05/12/37/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008046/06/12/39/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008150/06/12/41/06 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008254/06/12/43/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008358/06/12/45/10 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008462/06/12/47/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008566/06/12/49/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008670/06/12/00/14 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008774/06/12/02/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008878/06/12/04/18 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 008982/06/12/06/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009086/06/12/08/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009190/06/12/10/22 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009294/07/12/12/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009398/07/12/14/26 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009502/07/12/16/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009606/07/12/18/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009710/07/12/20/30 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009814/07/12/22/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 009918/07/12/24/34 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 010022/07/12/26/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 010126/07/12/28/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 010230/07/12/30/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) 010334/07/12/32/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000051/00/25/00/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000155/00/25/02/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000259/00/25/04/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000363/00/25/06/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000467/00/25/08/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000571/00/25/10/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000675/00/25/12/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000779/00/25/14/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000883/00/25/16/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 000987/00/25/18/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001091/00/25/20/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001195/00/25/22/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001299/00/25/24/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001403/01/25/26/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001507/01/25/28/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001611/01/25/30/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001715/01/25/32/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001819/01/25/34/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 001923/01/25/36/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002027/01/25/38/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002131/01/25/40/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002235/01/25/42/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002339/01/25/44/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002443/01/25/46/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002547/01/25/48/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002651/01/25/50/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002755/02/25/01/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002859/02/25/03/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 002963/02/25/05/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003067/02/25/07/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003171/02/25/09/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003275/02/25/11/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003379/02/25/13/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003483/02/25/15/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003587/02/25/17/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003691/02/25/19/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003795/02/25/21/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 003899/02/25/23/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004003/03/25/25/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004107/03/25/27/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004211/03/25/29/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004315/03/25/31/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004419/03/25/33/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004523/03/25/35/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004627/03/25/37/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004731/03/25/39/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004835/03/25/41/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 004939/03/25/43/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005043/03/25/45/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005147/03/25/47/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005251/03/25/49/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005355/04/25/00/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005459/04/25/02/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005563/04/25/04/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005667/04/25/06/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005771/04/25/08/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005875/04/25/10/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 005979/04/25/12/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006083/04/25/14/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006187/04/25/16/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006291/04/25/18/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006395/04/25/20/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006499/04/25/22/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006603/04/25/24/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006707/05/25/26/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006811/05/25/28/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 006915/05/25/30/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007019/05/25/32/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007123/05/25/34/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007227/05/25/36/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007331/05/25/38/07 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007435/05/25/40/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007539/05/25/42/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007643/05/25/44/11 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007747/05/25/46/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007851/05/25/48/15 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 007955/05/25/50/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008059/06/25/01/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008163/06/25/03/19 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008267/06/25/05/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008371/06/25/07/23 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008475/06/25/09/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008579/06/25/11/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008683/06/25/13/27 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008787/06/25/15/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008891/06/25/17/31 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 008995/06/25/19/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009099/06/25/21/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009203/06/25/23/35 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009307/07/25/25/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009411/07/25/27/39 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009515/07/25/29/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009619/07/25/31/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009723/07/25/33/43 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009827/07/25/35/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 009931/07/25/37/47 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 010035/07/25/39/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 010139/07/25/41/51 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 010243/07/25/43/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=3,ss=0) 010347/07/25/45/03 meas period end fn_mod:25, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000064/00/12/13/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000168/00/12/15/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000272/00/12/17/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000376/00/12/19/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000480/00/12/21/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000584/00/12/23/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000688/00/12/25/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000792/00/12/27/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 000896/00/12/29/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001000/00/12/31/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001104/00/12/33/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001208/00/12/35/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001312/00/12/37/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001416/01/12/39/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001520/01/12/41/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001624/01/12/43/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001728/01/12/45/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001832/01/12/47/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 001936/01/12/49/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002040/01/12/00/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002144/01/12/02/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002248/01/12/04/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002352/01/12/06/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002456/01/12/08/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002560/01/12/10/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002664/02/12/12/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002768/02/12/14/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002872/02/12/16/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 002976/02/12/18/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003080/02/12/20/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003184/02/12/22/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003288/02/12/24/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003392/02/12/26/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003496/02/12/28/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003600/02/12/30/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003704/02/12/32/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003808/02/12/34/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 003912/02/12/36/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004016/03/12/38/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004120/03/12/40/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004224/03/12/42/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004328/03/12/44/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004432/03/12/46/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004536/03/12/48/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004640/03/12/50/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004744/03/12/01/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004848/03/12/03/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 004952/03/12/05/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005056/03/12/07/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005160/03/12/09/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005264/03/12/11/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005368/04/12/13/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005472/04/12/15/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005576/04/12/17/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005680/04/12/19/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005784/04/12/21/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005888/04/12/23/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 005992/04/12/25/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006096/04/12/27/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006200/04/12/29/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006304/04/12/31/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006408/04/12/33/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006512/04/12/35/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006616/04/12/37/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006720/05/12/39/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006824/05/12/41/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 006928/05/12/43/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007032/05/12/45/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007136/05/12/47/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007240/05/12/49/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007344/05/12/00/20 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007448/05/12/02/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007552/05/12/04/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007656/05/12/06/24 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008592/06/12/24/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008696/06/12/26/40 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008800/06/12/28/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 008904/06/12/30/44 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009008/06/12/32/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009112/06/12/34/48 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009216/06/12/36/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009320/07/12/38/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009424/07/12/40/00 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009528/07/12/42/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009632/07/12/44/04 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009736/07/12/46/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009840/07/12/48/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 009944/07/12/50/08 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 010048/07/12/01/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 010152/07/12/03/12 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 010256/07/12/05/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=4,ss=0) 010360/07/12/07/16 meas period end fn_mod:38, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000077/00/25/26/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000181/00/25/28/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000285/00/25/30/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000389/00/25/32/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000493/00/25/34/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000597/00/25/36/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000701/00/25/38/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000805/00/25/40/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 000909/00/25/42/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001013/00/25/44/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001117/00/25/46/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001221/00/25/48/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001325/00/25/50/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001429/01/25/01/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001533/01/25/03/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001637/01/25/05/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001741/01/25/07/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001845/01/25/09/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 001949/01/25/11/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002053/01/25/13/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002157/01/25/15/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002261/01/25/17/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002365/01/25/19/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002469/01/25/21/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002573/01/25/23/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002677/02/25/25/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002781/02/25/27/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002885/02/25/29/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 002989/02/25/31/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003093/02/25/33/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003197/02/25/35/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003301/02/25/37/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003405/02/25/39/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003509/02/25/41/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003613/02/25/43/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003717/02/25/45/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003821/02/25/47/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 003925/02/25/49/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004029/03/25/00/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004133/03/25/02/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004237/03/25/04/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004341/03/25/06/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004445/03/25/08/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004549/03/25/10/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004653/03/25/12/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004757/03/25/14/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004861/03/25/16/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 004965/03/25/18/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005069/03/25/20/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005173/03/25/22/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005277/03/25/24/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005381/04/25/26/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005485/04/25/28/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005589/04/25/30/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005693/04/25/32/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005797/04/25/34/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 005901/04/25/36/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006005/04/25/38/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006109/04/25/40/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006213/04/25/42/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006317/04/25/44/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006421/04/25/46/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006525/04/25/48/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006629/04/25/50/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006733/05/25/01/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006837/05/25/03/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 006941/05/25/05/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007045/05/25/07/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007149/05/25/09/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007253/05/25/11/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007357/05/25/13/33 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007461/05/25/15/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007565/05/25/17/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007669/05/25/19/37 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007773/05/25/21/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007877/05/25/23/41 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 007981/06/25/25/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008085/06/25/27/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008605/06/25/37/01 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008709/06/25/39/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008813/06/25/41/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 008917/06/25/43/05 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009021/06/25/45/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009125/06/25/47/09 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009229/06/25/49/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009333/07/25/00/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009437/07/25/02/13 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009541/07/25/04/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009645/07/25/06/17 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009749/07/25/08/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009853/07/25/10/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 009957/07/25/12/21 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 010061/07/25/14/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 010165/07/25/16/25 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 010269/07/25/18/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=5,ss=0) 010373/07/25/20/29 meas period end fn_mod:51, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000090/00/12/39/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000194/00/12/41/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000298/00/12/43/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000402/00/12/45/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000506/00/12/47/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000610/00/12/49/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000714/00/12/00/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000818/00/12/02/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 000922/00/12/04/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001026/00/12/06/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001130/00/12/08/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001234/00/12/10/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001338/01/12/12/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001442/01/12/14/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001546/01/12/16/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001650/01/12/18/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001754/01/12/20/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001858/01/12/22/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 001962/01/12/24/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002066/01/12/26/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002170/01/12/28/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002274/01/12/30/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002378/01/12/32/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002482/01/12/34/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002586/01/12/36/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002690/02/12/38/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002794/02/12/40/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 002898/02/12/42/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003002/02/12/44/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003106/02/12/46/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003210/02/12/48/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003314/02/12/50/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003418/02/12/01/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003522/02/12/03/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003626/02/12/05/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003730/02/12/07/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003834/02/12/09/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 003938/02/12/11/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004042/03/12/13/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004146/03/12/15/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004250/03/12/17/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004354/03/12/19/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004458/03/12/21/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004562/03/12/23/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004666/03/12/25/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004770/03/12/27/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004874/03/12/29/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 004978/03/12/31/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005082/03/12/33/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005186/03/12/35/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005290/03/12/37/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005394/04/12/39/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005498/04/12/41/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005602/04/12/43/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005706/04/12/45/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005810/04/12/47/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 005914/04/12/49/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006018/04/12/00/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006122/04/12/02/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006226/04/12/04/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006330/04/12/06/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006434/04/12/08/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006538/04/12/10/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006642/05/12/12/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006746/05/12/14/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006850/05/12/16/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 006954/05/12/18/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007058/05/12/20/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007162/05/12/22/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007266/05/12/24/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007370/05/12/26/46 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007474/05/12/28/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007578/05/12/30/50 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007682/05/12/32/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007786/05/12/34/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007890/05/12/36/02 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 007994/06/12/38/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008098/06/12/40/06 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008202/06/12/42/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008306/06/12/44/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008410/06/12/46/10 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008514/06/12/48/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008618/06/12/50/14 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008722/06/12/01/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008826/06/12/03/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 008930/06/12/05/18 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009034/06/12/07/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009138/06/12/09/22 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009242/06/12/11/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009346/07/12/13/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009450/07/12/15/26 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009554/07/12/17/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009658/07/12/19/30 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009762/07/12/21/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009866/07/12/23/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 009970/07/12/25/34 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 010074/07/12/27/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 010178/07/12/29/38 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 010282/07/12/31/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=6,ss=0) 010386/07/12/33/42 meas period end fn_mod:64, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000103/00/25/01/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000207/00/25/03/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000311/00/25/05/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000415/00/25/07/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000519/00/25/09/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000623/00/25/11/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000727/00/25/13/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000831/00/25/15/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 000935/00/25/17/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001039/00/25/19/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001143/00/25/21/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001247/00/25/23/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001351/01/25/25/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001455/01/25/27/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001559/01/25/29/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001663/01/25/31/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001767/01/25/33/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001871/01/25/35/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 001975/01/25/37/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002079/01/25/39/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002183/01/25/41/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002287/01/25/43/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002391/01/25/45/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002495/01/25/47/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002599/01/25/49/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002703/02/25/00/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002807/02/25/02/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 002911/02/25/04/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003015/02/25/06/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003119/02/25/08/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003223/02/25/10/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003327/02/25/12/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003431/02/25/14/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003535/02/25/16/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003639/02/25/18/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003743/02/25/20/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003847/02/25/22/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 003951/02/25/24/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004055/03/25/26/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004159/03/25/28/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004263/03/25/30/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004367/03/25/32/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004471/03/25/34/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004575/03/25/36/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004679/03/25/38/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004783/03/25/40/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004887/03/25/42/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 004991/03/25/44/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005095/03/25/46/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005199/03/25/48/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005303/03/25/50/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005407/04/25/01/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005511/04/25/03/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005615/04/25/05/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005719/04/25/07/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005823/04/25/09/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 005927/04/25/11/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006031/04/25/13/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006135/04/25/15/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006239/04/25/17/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006343/04/25/19/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006447/04/25/21/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006551/04/25/23/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006655/05/25/25/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006759/05/25/27/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006863/05/25/29/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 006967/05/25/31/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007071/05/25/33/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007175/05/25/35/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007279/05/25/37/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007383/05/25/39/07 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007487/05/25/41/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007591/05/25/43/11 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007695/05/25/45/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007799/05/25/47/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 007903/05/25/49/15 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008007/06/25/00/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008111/06/25/02/19 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008215/06/25/04/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008319/06/25/06/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008423/06/25/08/23 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008527/06/25/10/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008631/06/25/12/27 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008735/06/25/14/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008839/06/25/16/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 008943/06/25/18/31 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009047/06/25/20/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009151/06/25/22/35 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009255/06/25/24/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009359/07/25/26/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009463/07/25/28/39 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009567/07/25/30/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009671/07/25/32/43 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009775/07/25/34/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009879/07/25/36/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 009983/07/25/38/47 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 010087/07/25/40/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 010191/07/25/42/51 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 010295/07/25/44/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=7,ss=0) 010399/07/25/46/03 meas period end fn_mod:77, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=0,ss=0) 000012/00/12/12/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000116/00/12/14/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000220/00/12/16/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000324/00/12/18/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000428/00/12/20/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000532/00/12/22/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000636/00/12/24/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000740/00/12/26/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000844/00/12/28/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000948/00/12/30/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001052/00/12/32/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001156/00/12/34/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001260/00/12/36/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001364/01/12/38/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001468/01/12/40/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001572/01/12/42/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001676/01/12/44/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001780/01/12/46/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001884/01/12/48/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 001988/01/12/50/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002092/01/12/01/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002196/01/12/03/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002300/01/12/05/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002404/01/12/07/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002508/01/12/09/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002612/01/12/11/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002716/02/12/13/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002820/02/12/15/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 002924/02/12/17/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003028/02/12/19/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003132/02/12/21/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003236/02/12/23/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003340/02/12/25/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003444/02/12/27/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003548/02/12/29/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003652/02/12/31/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003756/02/12/33/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003860/02/12/35/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 003964/02/12/37/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004068/03/12/39/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004172/03/12/41/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004276/03/12/43/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004380/03/12/45/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004484/03/12/47/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004588/03/12/49/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004692/03/12/00/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004796/03/12/02/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 004900/03/12/04/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005004/03/12/06/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005108/03/12/08/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005212/03/12/10/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005316/04/12/12/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005420/04/12/14/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005524/04/12/16/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005628/04/12/18/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005732/04/12/20/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005836/04/12/22/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 005940/04/12/24/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006044/04/12/26/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006148/04/12/28/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006252/04/12/30/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006356/04/12/32/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006460/04/12/34/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006564/04/12/36/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006668/05/12/38/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006772/05/12/40/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006876/05/12/42/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 006980/05/12/44/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007084/05/12/46/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007188/05/12/48/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007292/05/12/50/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007396/05/12/01/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007500/05/12/03/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007604/05/12/05/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007708/05/12/07/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007812/05/12/09/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 007916/05/12/11/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008020/06/12/13/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008124/06/12/15/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008228/06/12/17/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008332/06/12/19/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008436/06/12/21/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008540/06/12/23/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008644/06/12/25/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008748/06/12/27/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008852/06/12/29/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 008956/06/12/31/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009060/06/12/33/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009164/06/12/35/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009268/06/12/37/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009372/07/12/39/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009476/07/12/41/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009580/07/12/43/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009684/07/12/45/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009788/07/12/47/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009892/07/12/49/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 009996/07/12/00/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 010100/07/12/02/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 010204/07/12/04/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 010308/07/12/06/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000012/00/12/12/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000116/00/12/14/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000220/00/12/16/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000324/00/12/18/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000428/00/12/20/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000532/00/12/22/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000636/00/12/24/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000740/00/12/26/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000844/00/12/28/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 000948/00/12/30/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001052/00/12/32/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001156/00/12/34/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001260/00/12/36/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001364/01/12/38/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001468/01/12/40/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001572/01/12/42/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001676/01/12/44/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001780/01/12/46/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001884/01/12/48/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 001988/01/12/50/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002092/01/12/01/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002196/01/12/03/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002300/01/12/05/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002404/01/12/07/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002508/01/12/09/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002612/01/12/11/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002716/02/12/13/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002820/02/12/15/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 002924/02/12/17/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003028/02/12/19/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003132/02/12/21/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003236/02/12/23/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003340/02/12/25/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003444/02/12/27/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003548/02/12/29/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003652/02/12/31/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003756/02/12/33/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003860/02/12/35/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 003964/02/12/37/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004068/03/12/39/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004172/03/12/41/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004276/03/12/43/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004380/03/12/45/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004484/03/12/47/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004588/03/12/49/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004692/03/12/00/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004796/03/12/02/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 004900/03/12/04/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005004/03/12/06/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005108/03/12/08/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005212/03/12/10/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005316/04/12/12/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005420/04/12/14/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005524/04/12/16/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005628/04/12/18/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005732/04/12/20/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005836/04/12/22/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 005940/04/12/24/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006044/04/12/26/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006148/04/12/28/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006252/04/12/30/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006356/04/12/32/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006460/04/12/34/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006564/04/12/36/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006668/05/12/38/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006772/05/12/40/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006876/05/12/42/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 006980/05/12/44/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007084/05/12/46/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007188/05/12/48/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007292/05/12/50/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007396/05/12/01/20 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007500/05/12/03/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007604/05/12/05/24 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007708/05/12/07/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007812/05/12/09/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 007916/05/12/11/28 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008020/06/12/13/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008124/06/12/15/32 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008228/06/12/17/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008332/06/12/19/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008436/06/12/21/36 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008540/06/12/23/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008644/06/12/25/40 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008748/06/12/27/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008852/06/12/29/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 008956/06/12/31/44 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009060/06/12/33/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009164/06/12/35/48 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009268/06/12/37/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009372/07/12/39/00 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009476/07/12/41/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009580/07/12/43/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009684/07/12/45/04 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009788/07/12/47/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009892/07/12/49/08 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 009996/07/12/00/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 010100/07/12/02/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 010204/07/12/04/12 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=0) 010308/07/12/06/16 meas period end fn_mod:90, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000129/00/25/27/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000233/00/25/29/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000337/00/25/31/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000441/00/25/33/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000545/00/25/35/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000649/00/25/37/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000753/00/25/39/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000857/00/25/41/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 000961/00/25/43/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001065/00/25/45/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001169/00/25/47/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001273/00/25/49/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001377/01/25/00/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001481/01/25/02/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001585/01/25/04/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001689/01/25/06/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001793/01/25/08/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 001897/01/25/10/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002001/01/25/12/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002105/01/25/14/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002209/01/25/16/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002313/01/25/18/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002417/01/25/20/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002521/01/25/22/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002625/01/25/24/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002729/02/25/26/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002833/02/25/28/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 002937/02/25/30/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003041/02/25/32/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003145/02/25/34/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003249/02/25/36/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003353/02/25/38/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003457/02/25/40/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003561/02/25/42/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003665/02/25/44/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003769/02/25/46/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003873/02/25/48/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 003977/02/25/50/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004081/03/25/01/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004185/03/25/03/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004289/03/25/05/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004393/03/25/07/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004497/03/25/09/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004601/03/25/11/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004705/03/25/13/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004809/03/25/15/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 004913/03/25/17/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005017/03/25/19/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005121/03/25/21/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005225/03/25/23/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005329/04/25/25/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005433/04/25/27/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005537/04/25/29/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005641/04/25/31/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005745/04/25/33/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005849/04/25/35/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 005953/04/25/37/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006057/04/25/39/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006161/04/25/41/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006265/04/25/43/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006369/04/25/45/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006473/04/25/47/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006577/04/25/49/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006681/05/25/00/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006785/05/25/02/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006889/05/25/04/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 006993/05/25/06/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007097/05/25/08/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007201/05/25/10/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007305/05/25/12/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007409/05/25/14/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007513/05/25/16/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007617/05/25/18/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007721/05/25/20/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007825/05/25/22/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 007929/05/25/24/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008033/06/25/26/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008137/06/25/28/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008241/06/25/30/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008345/06/25/32/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008449/06/25/34/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008553/06/25/36/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008657/06/25/38/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008761/06/25/40/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008865/06/25/42/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 008969/06/25/44/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009073/06/25/46/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009177/06/25/48/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009281/06/25/50/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009385/07/25/01/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009489/07/25/03/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009593/07/25/05/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009697/07/25/07/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009801/07/25/09/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 009905/07/25/11/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 010009/07/25/13/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 010113/07/25/15/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 010217/07/25/17/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=1) 010321/07/25/19/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000025/00/25/25/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000129/00/25/27/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000233/00/25/29/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000337/00/25/31/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000441/00/25/33/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000545/00/25/35/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000649/00/25/37/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000753/00/25/39/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000857/00/25/41/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 000961/00/25/43/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001065/00/25/45/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001169/00/25/47/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001273/00/25/49/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001377/01/25/00/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001481/01/25/02/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001585/01/25/04/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001689/01/25/06/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001793/01/25/08/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 001897/01/25/10/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002001/01/25/12/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002105/01/25/14/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002209/01/25/16/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002313/01/25/18/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002417/01/25/20/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002521/01/25/22/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002625/01/25/24/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002729/02/25/26/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002833/02/25/28/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 002937/02/25/30/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003041/02/25/32/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003145/02/25/34/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003249/02/25/36/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003353/02/25/38/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003457/02/25/40/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003561/02/25/42/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003665/02/25/44/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003769/02/25/46/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003873/02/25/48/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 003977/02/25/50/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004081/03/25/01/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004185/03/25/03/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004289/03/25/05/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004393/03/25/07/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004497/03/25/09/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004601/03/25/11/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004705/03/25/13/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004809/03/25/15/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 004913/03/25/17/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005017/03/25/19/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005121/03/25/21/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005225/03/25/23/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005329/04/25/25/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005433/04/25/27/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005537/04/25/29/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005641/04/25/31/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005745/04/25/33/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005849/04/25/35/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 005953/04/25/37/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006057/04/25/39/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006161/04/25/41/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006265/04/25/43/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006369/04/25/45/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006473/04/25/47/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006577/04/25/49/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006681/05/25/00/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006785/05/25/02/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006889/05/25/04/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 006993/05/25/06/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007097/05/25/08/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007201/05/25/10/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007305/05/25/12/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007409/05/25/14/33 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007513/05/25/16/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007617/05/25/18/37 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007721/05/25/20/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007825/05/25/22/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 007929/05/25/24/41 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008033/06/25/26/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008137/06/25/28/45 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008241/06/25/30/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008345/06/25/32/49 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008449/06/25/34/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008553/06/25/36/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008657/06/25/38/01 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008761/06/25/40/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008865/06/25/42/05 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 008969/06/25/44/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009073/06/25/46/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009177/06/25/48/09 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009281/06/25/50/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009385/07/25/01/13 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009489/07/25/03/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009593/07/25/05/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009697/07/25/07/17 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009801/07/25/09/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 009905/07/25/11/21 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 010009/07/25/13/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 010113/07/25/15/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 010217/07/25/17/25 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=1,ss=1) 010321/07/25/19/29 meas period end fn_mod:103, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000454/00/12/46/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000558/00/12/48/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000662/00/12/50/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000766/00/12/01/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000870/00/12/03/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 000974/00/12/05/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001078/00/12/07/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001182/00/12/09/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001286/00/12/11/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001390/01/12/13/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001494/01/12/15/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001598/01/12/17/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001702/01/12/19/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001806/01/12/21/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 001910/01/12/23/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002014/01/12/25/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002118/01/12/27/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002222/01/12/29/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002326/01/12/31/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002430/01/12/33/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002534/01/12/35/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002638/01/12/37/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002742/02/12/39/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002846/02/12/41/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 002950/02/12/43/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003054/02/12/45/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003158/02/12/47/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003262/02/12/49/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003366/02/12/00/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003470/02/12/02/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003574/02/12/04/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003678/02/12/06/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003782/02/12/08/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003886/02/12/10/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 003990/03/12/12/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004094/03/12/14/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004198/03/12/16/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004302/03/12/18/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004406/03/12/20/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004510/03/12/22/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004614/03/12/24/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004718/03/12/26/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004822/03/12/28/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 004926/03/12/30/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005030/03/12/32/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005134/03/12/34/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005238/03/12/36/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005342/04/12/38/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005446/04/12/40/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005550/04/12/42/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005654/04/12/44/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005758/04/12/46/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005862/04/12/48/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 005966/04/12/50/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006070/04/12/01/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006174/04/12/03/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006278/04/12/05/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006382/04/12/07/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006486/04/12/09/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006590/04/12/11/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006694/05/12/13/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006798/05/12/15/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 006902/05/12/17/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007006/05/12/19/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007110/05/12/21/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007214/05/12/23/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007318/05/12/25/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007422/05/12/27/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007526/05/12/29/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007630/05/12/31/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007734/05/12/33/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007838/05/12/35/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 007942/05/12/37/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008046/06/12/39/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008150/06/12/41/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008254/06/12/43/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008358/06/12/45/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008462/06/12/47/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008566/06/12/49/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008670/06/12/00/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008774/06/12/02/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008878/06/12/04/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 008982/06/12/06/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009086/06/12/08/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009190/06/12/10/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009294/07/12/12/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009398/07/12/14/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009502/07/12/16/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009606/07/12/18/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009710/07/12/20/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009814/07/12/22/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 009918/07/12/24/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 010022/07/12/26/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 010126/07/12/28/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 010230/07/12/30/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=0) 010334/07/12/32/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000142/00/12/40/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000246/00/12/42/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000350/00/12/44/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000454/00/12/46/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000558/00/12/48/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000662/00/12/50/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000766/00/12/01/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000870/00/12/03/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 000974/00/12/05/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001078/00/12/07/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001182/00/12/09/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001286/00/12/11/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001390/01/12/13/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001494/01/12/15/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001598/01/12/17/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001702/01/12/19/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001806/01/12/21/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 001910/01/12/23/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002014/01/12/25/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002118/01/12/27/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002222/01/12/29/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002326/01/12/31/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002430/01/12/33/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002534/01/12/35/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002638/01/12/37/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002742/02/12/39/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002846/02/12/41/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 002950/02/12/43/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003054/02/12/45/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003158/02/12/47/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003262/02/12/49/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003366/02/12/00/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003470/02/12/02/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003574/02/12/04/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003678/02/12/06/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003782/02/12/08/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003886/02/12/10/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 003990/03/12/12/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004094/03/12/14/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004198/03/12/16/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004302/03/12/18/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004406/03/12/20/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004510/03/12/22/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004614/03/12/24/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004718/03/12/26/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004822/03/12/28/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 004926/03/12/30/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005030/03/12/32/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005134/03/12/34/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005238/03/12/36/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005342/04/12/38/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005446/04/12/40/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005550/04/12/42/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005654/04/12/44/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005758/04/12/46/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005862/04/12/48/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 005966/04/12/50/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006070/04/12/01/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006174/04/12/03/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006278/04/12/05/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006382/04/12/07/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006486/04/12/09/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006590/04/12/11/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006694/05/12/13/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006798/05/12/15/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 006902/05/12/17/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007006/05/12/19/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007110/05/12/21/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007214/05/12/23/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007318/05/12/25/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007422/05/12/27/46 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007526/05/12/29/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007630/05/12/31/50 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007734/05/12/33/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007838/05/12/35/02 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 007942/05/12/37/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008046/06/12/39/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008150/06/12/41/06 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008254/06/12/43/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008358/06/12/45/10 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008462/06/12/47/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008566/06/12/49/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008670/06/12/00/14 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008774/06/12/02/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008878/06/12/04/18 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 008982/06/12/06/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009086/06/12/08/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009190/06/12/10/22 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009294/07/12/12/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009398/07/12/14/26 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009502/07/12/16/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009606/07/12/18/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009710/07/12/20/30 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009814/07/12/22/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 009918/07/12/24/34 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 010022/07/12/26/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 010126/07/12/28/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 010230/07/12/30/38 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=0) 010334/07/12/32/42 meas period end fn_mod:12, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000051/00/25/00/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000155/00/25/02/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000259/00/25/04/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000363/00/25/06/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000467/00/25/08/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000571/00/25/10/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000675/00/25/12/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000779/00/25/14/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000883/00/25/16/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 000987/00/25/18/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001091/00/25/20/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001195/00/25/22/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001299/00/25/24/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001403/01/25/26/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001507/01/25/28/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001611/01/25/30/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001715/01/25/32/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001819/01/25/34/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 001923/01/25/36/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002027/01/25/38/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002131/01/25/40/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002235/01/25/42/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002339/01/25/44/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002443/01/25/46/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002547/01/25/48/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002651/01/25/50/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002755/02/25/01/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002859/02/25/03/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 002963/02/25/05/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003067/02/25/07/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003171/02/25/09/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003275/02/25/11/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003379/02/25/13/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003483/02/25/15/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003587/02/25/17/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003691/02/25/19/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003795/02/25/21/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 003899/02/25/23/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004003/03/25/25/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004107/03/25/27/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004211/03/25/29/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004315/03/25/31/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004419/03/25/33/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004523/03/25/35/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004627/03/25/37/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004731/03/25/39/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004835/03/25/41/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 004939/03/25/43/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005043/03/25/45/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005147/03/25/47/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005251/03/25/49/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005355/04/25/00/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005459/04/25/02/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005563/04/25/04/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005667/04/25/06/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005771/04/25/08/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005875/04/25/10/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 005979/04/25/12/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006083/04/25/14/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006187/04/25/16/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006291/04/25/18/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006395/04/25/20/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006499/04/25/22/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006603/04/25/24/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006707/05/25/26/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006811/05/25/28/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 006915/05/25/30/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007019/05/25/32/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007123/05/25/34/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007227/05/25/36/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007331/05/25/38/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007435/05/25/40/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007539/05/25/42/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007643/05/25/44/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007747/05/25/46/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007851/05/25/48/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 007955/05/25/50/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008059/06/25/01/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008163/06/25/03/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008267/06/25/05/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008371/06/25/07/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008475/06/25/09/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008579/06/25/11/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008683/06/25/13/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008787/06/25/15/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008891/06/25/17/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 008995/06/25/19/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009099/06/25/21/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009203/06/25/23/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009307/07/25/25/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009411/07/25/27/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009515/07/25/29/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009619/07/25/31/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009723/07/25/33/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009827/07/25/35/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 009931/07/25/37/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 010035/07/25/39/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 010139/07/25/41/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 010243/07/25/43/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=2,ss=1) 010347/07/25/45/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000051/00/25/00/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000155/00/25/02/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000259/00/25/04/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000363/00/25/06/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000467/00/25/08/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000571/00/25/10/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000675/00/25/12/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000779/00/25/14/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000883/00/25/16/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 000987/00/25/18/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001091/00/25/20/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001195/00/25/22/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001299/00/25/24/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001403/01/25/26/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001507/01/25/28/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001611/01/25/30/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001715/01/25/32/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001819/01/25/34/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 001923/01/25/36/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002027/01/25/38/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002131/01/25/40/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002235/01/25/42/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002339/01/25/44/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002443/01/25/46/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002547/01/25/48/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002651/01/25/50/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002755/02/25/01/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002859/02/25/03/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 002963/02/25/05/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003067/02/25/07/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003171/02/25/09/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003275/02/25/11/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003379/02/25/13/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003483/02/25/15/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003587/02/25/17/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003691/02/25/19/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003795/02/25/21/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 003899/02/25/23/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004003/03/25/25/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004107/03/25/27/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004211/03/25/29/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004315/03/25/31/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004419/03/25/33/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004523/03/25/35/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004627/03/25/37/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004731/03/25/39/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004835/03/25/41/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 004939/03/25/43/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005043/03/25/45/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005147/03/25/47/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005251/03/25/49/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005355/04/25/00/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005459/04/25/02/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005563/04/25/04/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005667/04/25/06/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005771/04/25/08/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005875/04/25/10/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 005979/04/25/12/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006083/04/25/14/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006187/04/25/16/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006291/04/25/18/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006395/04/25/20/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006499/04/25/22/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006603/04/25/24/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006707/05/25/26/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006811/05/25/28/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 006915/05/25/30/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007019/05/25/32/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007123/05/25/34/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007227/05/25/36/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007331/05/25/38/07 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007435/05/25/40/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007539/05/25/42/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007643/05/25/44/11 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007747/05/25/46/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007851/05/25/48/15 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 007955/05/25/50/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008059/06/25/01/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008163/06/25/03/19 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008267/06/25/05/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008371/06/25/07/23 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008475/06/25/09/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008579/06/25/11/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008683/06/25/13/27 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008787/06/25/15/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008891/06/25/17/31 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 008995/06/25/19/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009099/06/25/21/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009203/06/25/23/35 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009307/07/25/25/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009411/07/25/27/39 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009515/07/25/29/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009619/07/25/31/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009723/07/25/33/43 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009827/07/25/35/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 009931/07/25/37/47 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 010035/07/25/39/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 010139/07/25/41/51 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 010243/07/25/43/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=3,ss=1) 010347/07/25/45/03 meas period end fn_mod:25, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000064/00/12/13/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000168/00/12/15/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000272/00/12/17/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000376/00/12/19/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000480/00/12/21/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000584/00/12/23/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000688/00/12/25/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000792/00/12/27/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 000896/00/12/29/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001000/00/12/31/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001104/00/12/33/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001208/00/12/35/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001312/00/12/37/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001416/01/12/39/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001520/01/12/41/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001624/01/12/43/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001728/01/12/45/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001832/01/12/47/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 001936/01/12/49/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002040/01/12/00/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002144/01/12/02/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002248/01/12/04/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002352/01/12/06/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002456/01/12/08/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002560/01/12/10/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002664/02/12/12/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002768/02/12/14/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002872/02/12/16/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 002976/02/12/18/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003080/02/12/20/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003184/02/12/22/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003288/02/12/24/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003392/02/12/26/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003496/02/12/28/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003600/02/12/30/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003704/02/12/32/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003808/02/12/34/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 003912/02/12/36/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004016/03/12/38/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004120/03/12/40/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004224/03/12/42/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004328/03/12/44/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004432/03/12/46/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004536/03/12/48/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004640/03/12/50/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004744/03/12/01/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004848/03/12/03/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 004952/03/12/05/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005056/03/12/07/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005160/03/12/09/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005264/03/12/11/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005368/04/12/13/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005472/04/12/15/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005576/04/12/17/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005680/04/12/19/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005784/04/12/21/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005888/04/12/23/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 005992/04/12/25/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006096/04/12/27/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006200/04/12/29/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006304/04/12/31/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006408/04/12/33/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006512/04/12/35/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006616/04/12/37/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006720/05/12/39/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006824/05/12/41/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 006928/05/12/43/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007032/05/12/45/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007136/05/12/47/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007240/05/12/49/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007344/05/12/00/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007448/05/12/02/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007552/05/12/04/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007656/05/12/06/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008592/06/12/24/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008696/06/12/26/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008800/06/12/28/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 008904/06/12/30/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009008/06/12/32/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009112/06/12/34/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009216/06/12/36/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009320/07/12/38/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009424/07/12/40/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009528/07/12/42/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009632/07/12/44/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009736/07/12/46/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009840/07/12/48/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 009944/07/12/50/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 010048/07/12/01/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 010152/07/12/03/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 010256/07/12/05/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=0) 010360/07/12/07/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000064/00/12/13/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000168/00/12/15/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000272/00/12/17/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000376/00/12/19/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000480/00/12/21/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000584/00/12/23/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000688/00/12/25/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000792/00/12/27/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 000896/00/12/29/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001000/00/12/31/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001104/00/12/33/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001208/00/12/35/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001312/00/12/37/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001416/01/12/39/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001520/01/12/41/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001624/01/12/43/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001728/01/12/45/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001832/01/12/47/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 001936/01/12/49/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002040/01/12/00/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002144/01/12/02/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002248/01/12/04/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002352/01/12/06/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002456/01/12/08/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002560/01/12/10/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002664/02/12/12/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002768/02/12/14/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002872/02/12/16/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 002976/02/12/18/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003080/02/12/20/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003184/02/12/22/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003288/02/12/24/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003392/02/12/26/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003496/02/12/28/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003600/02/12/30/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003704/02/12/32/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003808/02/12/34/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 003912/02/12/36/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004016/03/12/38/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004120/03/12/40/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004224/03/12/42/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004328/03/12/44/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004432/03/12/46/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004536/03/12/48/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004640/03/12/50/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004744/03/12/01/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004848/03/12/03/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 004952/03/12/05/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005056/03/12/07/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005160/03/12/09/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005264/03/12/11/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005368/04/12/13/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005472/04/12/15/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005576/04/12/17/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005680/04/12/19/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005784/04/12/21/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005888/04/12/23/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 005992/04/12/25/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006096/04/12/27/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006200/04/12/29/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006304/04/12/31/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006408/04/12/33/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006512/04/12/35/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006616/04/12/37/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006720/05/12/39/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006824/05/12/41/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 006928/05/12/43/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007032/05/12/45/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007136/05/12/47/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007240/05/12/49/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007344/05/12/00/20 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007448/05/12/02/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007552/05/12/04/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007656/05/12/06/24 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007760/05/12/08/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007864/05/12/10/28 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 007968/06/12/12/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008072/06/12/14/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008176/06/12/16/32 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008280/06/12/18/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008384/06/12/20/36 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008488/06/12/22/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008592/06/12/24/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008696/06/12/26/40 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008800/06/12/28/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 008904/06/12/30/44 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009008/06/12/32/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009112/06/12/34/48 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009216/06/12/36/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009320/07/12/38/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009424/07/12/40/00 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009528/07/12/42/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009632/07/12/44/04 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009736/07/12/46/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009840/07/12/48/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 009944/07/12/50/08 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 010048/07/12/01/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 010152/07/12/03/12 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 010256/07/12/05/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=0) 010360/07/12/07/16 meas period end fn_mod:38, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000077/00/25/26/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000181/00/25/28/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000285/00/25/30/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000389/00/25/32/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000493/00/25/34/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000597/00/25/36/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000701/00/25/38/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000805/00/25/40/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 000909/00/25/42/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001013/00/25/44/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001117/00/25/46/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001221/00/25/48/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001325/00/25/50/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001429/01/25/01/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001533/01/25/03/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001637/01/25/05/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001741/01/25/07/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001845/01/25/09/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 001949/01/25/11/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002053/01/25/13/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002157/01/25/15/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002261/01/25/17/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002365/01/25/19/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002469/01/25/21/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002573/01/25/23/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002677/02/25/25/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002781/02/25/27/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002885/02/25/29/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 002989/02/25/31/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003093/02/25/33/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003197/02/25/35/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003301/02/25/37/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003405/02/25/39/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003509/02/25/41/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003613/02/25/43/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003717/02/25/45/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003821/02/25/47/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 003925/02/25/49/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004029/03/25/00/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004133/03/25/02/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004237/03/25/04/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004341/03/25/06/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004445/03/25/08/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004549/03/25/10/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004653/03/25/12/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004757/03/25/14/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004861/03/25/16/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 004965/03/25/18/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005069/03/25/20/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005173/03/25/22/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005277/03/25/24/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005381/04/25/26/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005485/04/25/28/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005589/04/25/30/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005693/04/25/32/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005797/04/25/34/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 005901/04/25/36/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006005/04/25/38/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006109/04/25/40/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006213/04/25/42/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006317/04/25/44/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006421/04/25/46/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006525/04/25/48/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006629/04/25/50/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006733/05/25/01/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006837/05/25/03/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 006941/05/25/05/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007045/05/25/07/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007149/05/25/09/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007253/05/25/11/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007357/05/25/13/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007461/05/25/15/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007565/05/25/17/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007669/05/25/19/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007773/05/25/21/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007877/05/25/23/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 007981/06/25/25/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008085/06/25/27/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008605/06/25/37/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008709/06/25/39/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008813/06/25/41/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 008917/06/25/43/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009021/06/25/45/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009125/06/25/47/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009229/06/25/49/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009333/07/25/00/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009437/07/25/02/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009541/07/25/04/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009645/07/25/06/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009749/07/25/08/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009853/07/25/10/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 009957/07/25/12/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 010061/07/25/14/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 010165/07/25/16/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 010269/07/25/18/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=4,ss=1) 010373/07/25/20/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000077/00/25/26/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000181/00/25/28/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000285/00/25/30/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000389/00/25/32/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000493/00/25/34/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000597/00/25/36/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000701/00/25/38/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000805/00/25/40/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 000909/00/25/42/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001013/00/25/44/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001117/00/25/46/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001221/00/25/48/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001325/00/25/50/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001429/01/25/01/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001533/01/25/03/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001637/01/25/05/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001741/01/25/07/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001845/01/25/09/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 001949/01/25/11/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002053/01/25/13/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002157/01/25/15/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002261/01/25/17/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002365/01/25/19/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002469/01/25/21/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002573/01/25/23/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002677/02/25/25/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002781/02/25/27/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002885/02/25/29/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 002989/02/25/31/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003093/02/25/33/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003197/02/25/35/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003301/02/25/37/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003405/02/25/39/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003509/02/25/41/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003613/02/25/43/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003717/02/25/45/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003821/02/25/47/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 003925/02/25/49/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004029/03/25/00/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004133/03/25/02/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004237/03/25/04/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004341/03/25/06/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004445/03/25/08/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004549/03/25/10/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004653/03/25/12/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004757/03/25/14/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004861/03/25/16/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 004965/03/25/18/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005069/03/25/20/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005173/03/25/22/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005277/03/25/24/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005381/04/25/26/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005485/04/25/28/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005589/04/25/30/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005693/04/25/32/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005797/04/25/34/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 005901/04/25/36/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006005/04/25/38/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006109/04/25/40/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006213/04/25/42/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006317/04/25/44/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006421/04/25/46/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006525/04/25/48/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006629/04/25/50/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006733/05/25/01/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006837/05/25/03/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 006941/05/25/05/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007045/05/25/07/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007149/05/25/09/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007253/05/25/11/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007357/05/25/13/33 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007461/05/25/15/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007565/05/25/17/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007669/05/25/19/37 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007773/05/25/21/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007877/05/25/23/41 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 007981/06/25/25/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008085/06/25/27/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008189/06/25/29/45 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008293/06/25/31/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008397/06/25/33/49 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008501/06/25/35/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008605/06/25/37/01 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008709/06/25/39/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008813/06/25/41/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 008917/06/25/43/05 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009021/06/25/45/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009125/06/25/47/09 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009229/06/25/49/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009333/07/25/00/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009437/07/25/02/13 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009541/07/25/04/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009645/07/25/06/17 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009749/07/25/08/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009853/07/25/10/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 009957/07/25/12/21 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 010061/07/25/14/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 010165/07/25/16/25 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 010269/07/25/18/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=5,ss=1) 010373/07/25/20/29 meas period end fn_mod:51, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000090/00/12/39/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000194/00/12/41/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000298/00/12/43/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000402/00/12/45/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000506/00/12/47/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000610/00/12/49/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000714/00/12/00/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000818/00/12/02/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 000922/00/12/04/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001026/00/12/06/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001130/00/12/08/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001234/00/12/10/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001338/01/12/12/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001442/01/12/14/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001546/01/12/16/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001650/01/12/18/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001754/01/12/20/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001858/01/12/22/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 001962/01/12/24/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002066/01/12/26/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002170/01/12/28/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002274/01/12/30/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002378/01/12/32/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002482/01/12/34/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002586/01/12/36/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002690/02/12/38/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002794/02/12/40/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 002898/02/12/42/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003002/02/12/44/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003106/02/12/46/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003210/02/12/48/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003314/02/12/50/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003418/02/12/01/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003522/02/12/03/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003626/02/12/05/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003730/02/12/07/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003834/02/12/09/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 003938/02/12/11/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004042/03/12/13/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004146/03/12/15/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004250/03/12/17/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004354/03/12/19/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004458/03/12/21/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004562/03/12/23/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004666/03/12/25/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004770/03/12/27/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004874/03/12/29/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 004978/03/12/31/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005082/03/12/33/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005186/03/12/35/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005290/03/12/37/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005394/04/12/39/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005498/04/12/41/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005602/04/12/43/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005706/04/12/45/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005810/04/12/47/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 005914/04/12/49/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006018/04/12/00/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006122/04/12/02/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006226/04/12/04/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006330/04/12/06/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006434/04/12/08/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006538/04/12/10/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006642/05/12/12/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006746/05/12/14/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006850/05/12/16/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 006954/05/12/18/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007058/05/12/20/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007162/05/12/22/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007266/05/12/24/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007370/05/12/26/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007474/05/12/28/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007578/05/12/30/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007682/05/12/32/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007786/05/12/34/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007890/05/12/36/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 007994/06/12/38/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008098/06/12/40/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008202/06/12/42/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008306/06/12/44/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008410/06/12/46/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008514/06/12/48/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008618/06/12/50/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008722/06/12/01/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008826/06/12/03/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 008930/06/12/05/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009034/06/12/07/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009138/06/12/09/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009242/06/12/11/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009346/07/12/13/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009450/07/12/15/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009554/07/12/17/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009658/07/12/19/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009762/07/12/21/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009866/07/12/23/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 009970/07/12/25/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 010074/07/12/27/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 010178/07/12/29/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 010282/07/12/31/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=0) 010386/07/12/33/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000090/00/12/39/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000194/00/12/41/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000298/00/12/43/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000402/00/12/45/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000506/00/12/47/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000610/00/12/49/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000714/00/12/00/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000818/00/12/02/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 000922/00/12/04/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001026/00/12/06/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001130/00/12/08/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001234/00/12/10/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001338/01/12/12/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001442/01/12/14/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001546/01/12/16/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001650/01/12/18/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001754/01/12/20/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001858/01/12/22/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 001962/01/12/24/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002066/01/12/26/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002170/01/12/28/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002274/01/12/30/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002378/01/12/32/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002482/01/12/34/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002586/01/12/36/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002690/02/12/38/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002794/02/12/40/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 002898/02/12/42/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003002/02/12/44/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003106/02/12/46/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003210/02/12/48/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003314/02/12/50/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003418/02/12/01/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003522/02/12/03/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003626/02/12/05/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003730/02/12/07/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003834/02/12/09/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 003938/02/12/11/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004042/03/12/13/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004146/03/12/15/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004250/03/12/17/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004354/03/12/19/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004458/03/12/21/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004562/03/12/23/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004666/03/12/25/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004770/03/12/27/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004874/03/12/29/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 004978/03/12/31/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005082/03/12/33/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005186/03/12/35/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005290/03/12/37/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005394/04/12/39/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005498/04/12/41/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005602/04/12/43/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005706/04/12/45/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005810/04/12/47/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 005914/04/12/49/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006018/04/12/00/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006122/04/12/02/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006226/04/12/04/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006330/04/12/06/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006434/04/12/08/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006538/04/12/10/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006642/05/12/12/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006746/05/12/14/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006850/05/12/16/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 006954/05/12/18/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007058/05/12/20/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007162/05/12/22/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007266/05/12/24/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007370/05/12/26/46 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007474/05/12/28/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007578/05/12/30/50 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007682/05/12/32/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007786/05/12/34/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007890/05/12/36/02 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 007994/06/12/38/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008098/06/12/40/06 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008202/06/12/42/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008306/06/12/44/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008410/06/12/46/10 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008514/06/12/48/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008618/06/12/50/14 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008722/06/12/01/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008826/06/12/03/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 008930/06/12/05/18 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009034/06/12/07/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009138/06/12/09/22 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009242/06/12/11/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009346/07/12/13/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009450/07/12/15/26 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009554/07/12/17/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009658/07/12/19/30 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009762/07/12/21/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009866/07/12/23/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 009970/07/12/25/34 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 010074/07/12/27/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 010178/07/12/29/38 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 010282/07/12/31/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=0) 010386/07/12/33/42 meas period end fn_mod:64, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000103/00/25/01/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000207/00/25/03/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000311/00/25/05/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000415/00/25/07/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000519/00/25/09/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000623/00/25/11/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000727/00/25/13/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000831/00/25/15/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 000935/00/25/17/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001039/00/25/19/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001143/00/25/21/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001247/00/25/23/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001351/01/25/25/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001455/01/25/27/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001559/01/25/29/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001663/01/25/31/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001767/01/25/33/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001871/01/25/35/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 001975/01/25/37/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002079/01/25/39/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002183/01/25/41/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002287/01/25/43/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002391/01/25/45/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002495/01/25/47/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002599/01/25/49/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002703/02/25/00/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002807/02/25/02/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 002911/02/25/04/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003015/02/25/06/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003119/02/25/08/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003223/02/25/10/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003327/02/25/12/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003431/02/25/14/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003535/02/25/16/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003639/02/25/18/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003743/02/25/20/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003847/02/25/22/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 003951/02/25/24/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004055/03/25/26/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004159/03/25/28/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004263/03/25/30/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004367/03/25/32/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004471/03/25/34/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004575/03/25/36/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004679/03/25/38/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004783/03/25/40/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004887/03/25/42/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 004991/03/25/44/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005095/03/25/46/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005199/03/25/48/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005303/03/25/50/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005407/04/25/01/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005511/04/25/03/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005615/04/25/05/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005719/04/25/07/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005823/04/25/09/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 005927/04/25/11/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006031/04/25/13/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006135/04/25/15/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006239/04/25/17/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006343/04/25/19/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006447/04/25/21/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006551/04/25/23/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006655/05/25/25/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006759/05/25/27/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006863/05/25/29/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 006967/05/25/31/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007071/05/25/33/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007175/05/25/35/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007279/05/25/37/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007383/05/25/39/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007487/05/25/41/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007591/05/25/43/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007695/05/25/45/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007799/05/25/47/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 007903/05/25/49/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008007/06/25/00/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008111/06/25/02/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008215/06/25/04/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008319/06/25/06/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008423/06/25/08/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008527/06/25/10/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008631/06/25/12/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008735/06/25/14/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008839/06/25/16/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 008943/06/25/18/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009047/06/25/20/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009151/06/25/22/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009255/06/25/24/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009359/07/25/26/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009463/07/25/28/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009567/07/25/30/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009671/07/25/32/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009775/07/25/34/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009879/07/25/36/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 009983/07/25/38/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 010087/07/25/40/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 010191/07/25/42/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 010295/07/25/44/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=6,ss=1) 010399/07/25/46/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000103/00/25/01/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000207/00/25/03/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000311/00/25/05/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000415/00/25/07/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000519/00/25/09/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000623/00/25/11/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000727/00/25/13/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000831/00/25/15/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 000935/00/25/17/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001039/00/25/19/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001143/00/25/21/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001247/00/25/23/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001351/01/25/25/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001455/01/25/27/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001559/01/25/29/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001663/01/25/31/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001767/01/25/33/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001871/01/25/35/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 001975/01/25/37/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002079/01/25/39/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002183/01/25/41/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002287/01/25/43/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002391/01/25/45/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002495/01/25/47/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002599/01/25/49/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002703/02/25/00/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002807/02/25/02/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 002911/02/25/04/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003015/02/25/06/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003119/02/25/08/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003223/02/25/10/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003327/02/25/12/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003431/02/25/14/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003535/02/25/16/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003639/02/25/18/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003743/02/25/20/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003847/02/25/22/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 003951/02/25/24/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004055/03/25/26/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004159/03/25/28/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004263/03/25/30/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004367/03/25/32/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004471/03/25/34/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004575/03/25/36/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004679/03/25/38/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004783/03/25/40/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004887/03/25/42/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 004991/03/25/44/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005095/03/25/46/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005199/03/25/48/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005303/03/25/50/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005407/04/25/01/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005511/04/25/03/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005615/04/25/05/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005719/04/25/07/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005823/04/25/09/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 005927/04/25/11/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006031/04/25/13/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006135/04/25/15/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006239/04/25/17/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006343/04/25/19/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006447/04/25/21/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006551/04/25/23/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006655/05/25/25/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006759/05/25/27/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006863/05/25/29/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 006967/05/25/31/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007071/05/25/33/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007175/05/25/35/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007279/05/25/37/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007383/05/25/39/07 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007487/05/25/41/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007591/05/25/43/11 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007695/05/25/45/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007799/05/25/47/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 007903/05/25/49/15 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008007/06/25/00/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008111/06/25/02/19 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008215/06/25/04/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008319/06/25/06/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008423/06/25/08/23 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008527/06/25/10/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008631/06/25/12/27 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008735/06/25/14/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008839/06/25/16/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 008943/06/25/18/31 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009047/06/25/20/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009151/06/25/22/35 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009255/06/25/24/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009359/07/25/26/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009463/07/25/28/39 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009567/07/25/30/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009671/07/25/32/43 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009775/07/25/34/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009879/07/25/36/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 009983/07/25/38/47 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 010087/07/25/40/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 010191/07/25/42/51 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 010295/07/25/44/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=7,ss=1) 010399/07/25/46/03 meas period end fn_mod:77, status:1, pchan:TCH/H +DEBUG (bts=0,trx=1,ts=0,ss=0) 000066/00/14/15/14 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000168/00/12/15/12 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000270/00/10/15/14 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000372/00/08/15/12 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000474/00/06/15/10 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000576/00/04/15/12 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000678/00/02/15/10 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000780/00/00/15/12 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000882/00/24/15/10 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000984/00/22/15/08 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001086/00/20/15/10 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001188/00/18/15/08 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001290/00/16/15/10 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001392/01/14/15/08 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001494/01/12/15/06 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001596/01/10/15/08 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001698/01/08/15/06 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001800/01/06/15/08 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001902/01/04/15/06 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002004/01/02/15/04 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002106/01/00/15/06 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002208/01/24/15/04 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002310/01/22/15/06 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002412/01/20/15/04 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002514/01/18/15/02 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002616/01/16/15/04 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002718/02/14/15/02 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002820/02/12/15/04 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002922/02/10/15/02 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003024/02/08/15/00 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003126/02/06/15/02 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003228/02/04/15/00 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003330/02/02/15/02 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003432/02/00/15/00 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003534/02/24/15/50 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003636/02/22/15/00 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003738/02/20/15/50 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003840/02/18/15/00 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003942/02/16/15/50 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004044/03/14/15/48 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004146/03/12/15/50 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004248/03/10/15/48 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004350/03/08/15/46 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004452/03/06/15/48 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004554/03/04/15/46 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004656/03/02/15/48 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004758/03/00/15/46 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004860/03/24/15/44 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004962/03/22/15/46 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005064/03/20/15/44 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005166/03/18/15/46 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005268/03/16/15/44 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005370/04/14/15/42 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005472/04/12/15/44 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005574/04/10/15/42 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005676/04/08/15/44 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005778/04/06/15/42 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005880/04/04/15/40 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005982/04/02/15/42 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006084/04/00/15/40 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006186/04/24/15/42 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006288/04/22/15/40 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006390/04/20/15/38 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006492/04/18/15/40 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006594/04/16/15/38 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006696/05/14/15/40 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006798/05/12/15/38 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006900/05/10/15/36 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007002/05/08/15/38 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007104/05/06/15/36 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007206/05/04/15/38 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007308/05/02/15/36 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007410/05/00/15/34 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007512/05/24/15/36 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007614/05/22/15/34 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007716/05/20/15/36 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007818/05/18/15/34 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007920/05/16/15/32 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008022/06/14/15/34 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008124/06/12/15/32 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008226/06/10/15/34 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008328/06/08/15/32 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008430/06/06/15/30 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008532/06/04/15/32 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008634/06/02/15/30 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008736/06/00/15/32 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008838/06/24/15/30 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008940/06/22/15/28 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009042/06/20/15/30 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009144/06/18/15/28 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009246/06/16/15/30 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009348/07/14/15/28 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009450/07/12/15/26 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009552/07/10/15/28 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009654/07/08/15/26 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009756/07/06/15/28 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009858/07/04/15/26 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009960/07/02/15/24 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 010062/07/00/15/26 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 010164/07/24/15/24 meas period end fn_mod:66, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000070/00/18/19/18 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000172/00/16/19/16 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000274/00/14/19/18 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000376/00/12/19/16 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000478/00/10/19/14 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000580/00/08/19/16 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000682/00/06/19/14 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000784/00/04/19/16 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000886/00/02/19/14 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000988/00/00/19/12 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001090/00/24/19/14 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001192/00/22/19/12 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001294/00/20/19/14 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001396/01/18/19/12 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001498/01/16/19/10 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001600/01/14/19/12 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001702/01/12/19/10 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001804/01/10/19/12 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001906/01/08/19/10 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002008/01/06/19/08 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002110/01/04/19/10 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002212/01/02/19/08 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002314/01/00/19/10 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002416/01/24/19/08 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002518/01/22/19/06 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002620/01/20/19/08 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002722/02/18/19/06 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002824/02/16/19/08 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002926/02/14/19/06 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003028/02/12/19/04 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003130/02/10/19/06 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003232/02/08/19/04 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003334/02/06/19/06 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003436/02/04/19/04 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003538/02/02/19/02 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003640/02/00/19/04 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003742/02/24/19/02 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003844/02/22/19/04 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003946/02/20/19/02 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004048/03/18/19/00 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004150/03/16/19/02 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004252/03/14/19/00 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004354/03/12/19/02 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004456/03/10/19/00 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004558/03/08/19/50 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004660/03/06/19/00 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004762/03/04/19/50 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004864/03/02/19/00 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004966/03/00/19/50 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005068/03/24/19/48 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005170/03/22/19/50 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005272/03/20/19/48 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005374/04/18/19/46 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005476/04/16/19/48 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005578/04/14/19/46 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005680/04/12/19/48 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005782/04/10/19/46 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005884/04/08/19/44 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005986/04/06/19/46 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006088/04/04/19/44 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006190/04/02/19/46 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006292/04/00/19/44 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006394/04/24/19/42 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006496/04/22/19/44 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006598/04/20/19/42 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006700/05/18/19/44 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006802/05/16/19/42 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006904/05/14/19/40 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007006/05/12/19/42 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007108/05/10/19/40 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007210/05/08/19/42 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007312/05/06/19/40 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007414/05/04/19/38 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007516/05/02/19/40 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007618/05/00/19/38 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007720/05/24/19/40 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007822/05/22/19/38 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007924/05/20/19/36 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008026/06/18/19/38 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008128/06/16/19/36 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008230/06/14/19/38 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008332/06/12/19/36 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008434/06/10/19/34 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008536/06/08/19/36 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008638/06/06/19/34 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008740/06/04/19/36 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008842/06/02/19/34 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008944/06/00/19/32 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009046/06/24/19/34 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009148/06/22/19/32 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009250/06/20/19/34 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009352/07/18/19/32 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009454/07/16/19/30 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009556/07/14/19/32 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009658/07/12/19/30 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009760/07/10/19/32 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009862/07/08/19/30 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009964/07/06/19/28 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 010066/07/04/19/30 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=1) 010168/07/02/19/28 meas period end fn_mod:70, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000074/00/22/23/22 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000176/00/20/23/20 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000278/00/18/23/22 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000380/00/16/23/20 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000482/00/14/23/18 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000584/00/12/23/20 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000686/00/10/23/18 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000788/00/08/23/20 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000890/00/06/23/18 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000992/00/04/23/16 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001094/00/02/23/18 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001196/00/00/23/16 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001298/00/24/23/18 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001400/01/22/23/16 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001502/01/20/23/14 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001604/01/18/23/16 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001706/01/16/23/14 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001808/01/14/23/16 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001910/01/12/23/14 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002012/01/10/23/12 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002114/01/08/23/14 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002216/01/06/23/12 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002318/01/04/23/14 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002420/01/02/23/12 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002522/01/00/23/10 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002624/01/24/23/12 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002726/02/22/23/10 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002828/02/20/23/12 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002930/02/18/23/10 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003032/02/16/23/08 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003134/02/14/23/10 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003236/02/12/23/08 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003338/02/10/23/10 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003440/02/08/23/08 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003542/02/06/23/06 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003644/02/04/23/08 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003746/02/02/23/06 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003848/02/00/23/08 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003950/02/24/23/06 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004052/03/22/23/04 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004154/03/20/23/06 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004256/03/18/23/04 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004358/03/16/23/06 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004460/03/14/23/04 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004562/03/12/23/02 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004664/03/10/23/04 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004766/03/08/23/02 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004868/03/06/23/04 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004970/03/04/23/02 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005072/03/02/23/00 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005174/03/00/23/02 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005276/03/24/23/00 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005378/04/22/23/02 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005480/04/20/23/00 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005582/04/18/23/50 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005684/04/16/23/00 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005786/04/14/23/50 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005888/04/12/23/00 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005990/04/10/23/50 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006092/04/08/23/48 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006194/04/06/23/50 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006296/04/04/23/48 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006398/04/02/23/46 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006500/04/00/23/48 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006602/04/24/23/46 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006704/05/22/23/48 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006806/05/20/23/46 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006908/05/18/23/44 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007010/05/16/23/46 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007112/05/14/23/44 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007214/05/12/23/46 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007316/05/10/23/44 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007418/05/08/23/42 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007520/05/06/23/44 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007622/05/04/23/42 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007724/05/02/23/44 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007826/05/00/23/42 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007928/05/24/23/40 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008030/06/22/23/42 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008132/06/20/23/40 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008234/06/18/23/42 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008336/06/16/23/40 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008438/06/14/23/38 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008540/06/12/23/40 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008642/06/10/23/38 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008744/06/08/23/40 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008846/06/06/23/38 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008948/06/04/23/36 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009050/06/02/23/38 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009152/06/00/23/36 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009254/06/24/23/38 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009356/07/22/23/36 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009458/07/20/23/34 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009560/07/18/23/36 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009662/07/16/23/34 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009764/07/14/23/36 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009866/07/12/23/34 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009968/07/10/23/32 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 010070/07/08/23/34 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=2) 010172/07/06/23/32 meas period end fn_mod:74, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000078/00/00/27/26 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000180/00/24/27/24 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000282/00/22/27/26 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000384/00/20/27/24 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000486/00/18/27/22 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000588/00/16/27/24 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000690/00/14/27/22 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000792/00/12/27/24 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000894/00/10/27/22 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000996/00/08/27/20 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001098/00/06/27/22 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001200/00/04/27/20 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001302/00/02/27/22 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001404/01/00/27/20 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001506/01/24/27/18 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001608/01/22/27/20 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001710/01/20/27/18 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001812/01/18/27/20 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001914/01/16/27/18 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002016/01/14/27/16 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002118/01/12/27/18 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002220/01/10/27/16 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002322/01/08/27/18 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002424/01/06/27/16 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002526/01/04/27/14 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002628/01/02/27/16 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002730/02/00/27/14 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002832/02/24/27/16 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002934/02/22/27/14 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003036/02/20/27/12 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003138/02/18/27/14 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003240/02/16/27/12 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003342/02/14/27/14 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003444/02/12/27/12 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003546/02/10/27/10 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003648/02/08/27/12 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003750/02/06/27/10 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003852/02/04/27/12 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003954/02/02/27/10 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004056/03/00/27/08 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004158/03/24/27/10 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004260/03/22/27/08 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004362/03/20/27/10 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004464/03/18/27/08 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004566/03/16/27/06 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004668/03/14/27/08 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004770/03/12/27/06 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004872/03/10/27/08 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004974/03/08/27/06 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005076/03/06/27/04 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005178/03/04/27/06 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005280/03/02/27/04 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005382/04/00/27/06 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005484/04/24/27/04 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005586/04/22/27/02 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005688/04/20/27/04 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005790/04/18/27/02 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005892/04/16/27/04 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005994/04/14/27/02 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006096/04/12/27/00 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006198/04/10/27/02 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006300/04/08/27/00 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006402/04/06/27/02 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006504/04/04/27/00 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006606/04/02/27/50 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006708/05/00/27/00 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006810/05/24/27/50 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006912/05/22/27/00 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007014/05/20/27/50 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007116/05/18/27/48 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007218/05/16/27/50 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007320/05/14/27/48 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007422/05/12/27/46 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007524/05/10/27/48 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007626/05/08/27/46 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007728/05/06/27/48 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007830/05/04/27/46 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007932/05/02/27/44 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008034/06/00/27/46 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008136/06/24/27/44 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008238/06/22/27/46 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008340/06/20/27/44 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008442/06/18/27/42 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008544/06/16/27/44 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008646/06/14/27/42 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008748/06/12/27/44 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008850/06/10/27/42 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008952/06/08/27/40 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009054/06/06/27/42 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009156/06/04/27/40 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009258/06/02/27/42 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009360/07/00/27/40 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009462/07/24/27/38 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009564/07/22/27/40 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009666/07/20/27/38 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009768/07/18/27/40 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009870/07/16/27/38 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009972/07/14/27/36 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 010074/07/12/27/38 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=3) 010176/07/10/27/36 meas period end fn_mod:78, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000098/00/20/47/46 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000200/00/18/47/44 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000302/00/16/47/46 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000404/00/14/47/44 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000506/00/12/47/42 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000608/00/10/47/44 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000710/00/08/47/42 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000812/00/06/47/44 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 000914/00/04/47/42 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001016/00/02/47/40 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001118/00/00/47/42 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001220/00/24/47/40 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001322/00/22/47/42 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001424/01/20/47/40 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001526/01/18/47/38 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001628/01/16/47/40 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001730/01/14/47/38 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001832/01/12/47/40 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 001934/01/10/47/38 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002036/01/08/47/36 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002138/01/06/47/38 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002240/01/04/47/36 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002342/01/02/47/38 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002444/01/00/47/36 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002546/01/24/47/34 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002648/01/22/47/36 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002750/02/20/47/34 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002852/02/18/47/36 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 002954/02/16/47/34 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003056/02/14/47/32 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003158/02/12/47/34 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003260/02/10/47/32 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003362/02/08/47/34 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003464/02/06/47/32 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003566/02/04/47/30 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003668/02/02/47/32 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003770/02/00/47/30 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003872/02/24/47/32 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 003974/02/22/47/30 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004076/03/20/47/28 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004178/03/18/47/30 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004280/03/16/47/28 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004382/03/14/47/30 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004484/03/12/47/28 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004586/03/10/47/26 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004688/03/08/47/28 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004790/03/06/47/26 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004892/03/04/47/28 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 004994/03/02/47/26 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005096/03/00/47/24 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005198/03/24/47/26 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005300/03/22/47/24 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005402/04/20/47/26 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005504/04/18/47/24 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005606/04/16/47/22 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005708/04/14/47/24 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005810/04/12/47/22 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 005912/04/10/47/24 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006014/04/08/47/22 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006116/04/06/47/20 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006218/04/04/47/22 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006320/04/02/47/20 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006422/04/00/47/22 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006524/04/24/47/20 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006626/04/22/47/18 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006728/05/20/47/20 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006830/05/18/47/18 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 006932/05/16/47/20 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007034/05/14/47/18 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007136/05/12/47/16 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007238/05/10/47/18 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007340/05/08/47/16 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007442/05/06/47/18 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007544/05/04/47/16 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007646/05/02/47/14 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007748/05/00/47/16 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007850/05/24/47/14 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 007952/05/22/47/16 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008054/06/20/47/14 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008156/06/18/47/12 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008258/06/16/47/14 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008360/06/14/47/12 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008462/06/12/47/14 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008564/06/10/47/12 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008666/06/08/47/10 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008768/06/06/47/12 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008870/06/04/47/10 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 008972/06/02/47/12 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009074/06/00/47/10 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009176/06/24/47/08 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009278/06/22/47/10 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009380/07/20/47/08 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009482/07/18/47/10 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009584/07/16/47/08 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009686/07/14/47/06 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009788/07/12/47/08 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009890/07/10/47/06 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 009992/07/08/47/08 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 010094/07/06/47/06 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=4) 010196/07/04/47/04 meas period end fn_mod:98, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000000/00/00/00/00 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000102/00/24/00/50 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000204/00/22/00/48 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000306/00/20/00/50 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000408/00/18/00/48 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000510/00/16/00/46 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000612/00/14/00/48 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000714/00/12/00/46 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000816/00/10/00/48 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 000918/00/08/00/46 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001020/00/06/00/44 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001122/00/04/00/46 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001224/00/02/00/44 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001326/01/00/00/46 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001428/01/24/00/44 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001530/01/22/00/42 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001632/01/20/00/44 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001734/01/18/00/42 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001836/01/16/00/44 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 001938/01/14/00/42 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002040/01/12/00/40 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002142/01/10/00/42 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002244/01/08/00/40 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002346/01/06/00/42 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002448/01/04/00/40 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002550/01/02/00/38 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002652/02/00/00/40 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002754/02/24/00/38 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002856/02/22/00/40 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 002958/02/20/00/38 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003060/02/18/00/36 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003162/02/16/00/38 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003264/02/14/00/36 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003366/02/12/00/38 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003468/02/10/00/36 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003570/02/08/00/34 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003672/02/06/00/36 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003774/02/04/00/34 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003876/02/02/00/36 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 003978/03/00/00/34 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004080/03/24/00/32 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004182/03/22/00/34 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004284/03/20/00/32 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004386/03/18/00/34 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004488/03/16/00/32 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004590/03/14/00/30 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004692/03/12/00/32 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004794/03/10/00/30 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004896/03/08/00/32 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 004998/03/06/00/30 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005100/03/04/00/28 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005202/03/02/00/30 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005304/04/00/00/28 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005406/04/24/00/30 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005508/04/22/00/28 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005610/04/20/00/26 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005712/04/18/00/28 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005814/04/16/00/26 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 005916/04/14/00/28 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006018/04/12/00/26 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006120/04/10/00/24 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006222/04/08/00/26 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006324/04/06/00/24 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006426/04/04/00/26 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006528/04/02/00/24 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006630/05/00/00/22 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006732/05/24/00/24 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006834/05/22/00/22 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 006936/05/20/00/24 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007038/05/18/00/22 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007140/05/16/00/20 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007242/05/14/00/22 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007344/05/12/00/20 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007446/05/10/00/22 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007548/05/08/00/20 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007650/05/06/00/18 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007752/05/04/00/20 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007854/05/02/00/18 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 007956/06/00/00/20 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008058/06/24/00/18 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008160/06/22/00/16 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008262/06/20/00/18 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008364/06/18/00/16 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008466/06/16/00/18 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008568/06/14/00/16 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008670/06/12/00/14 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008772/06/10/00/16 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008874/06/08/00/14 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 008976/06/06/00/16 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009078/06/04/00/14 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009180/06/02/00/12 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009282/07/00/00/14 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009384/07/24/00/12 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009486/07/22/00/14 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009588/07/20/00/12 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009690/07/18/00/10 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009792/07/16/00/12 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009894/07/14/00/10 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 009996/07/12/00/12 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=5) 010098/07/10/00/10 meas period end fn_mod:0, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000004/00/04/04/04 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000106/00/02/04/02 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000208/00/00/04/00 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000310/00/24/04/02 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000412/00/22/04/00 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000514/00/20/04/02 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000616/00/18/04/00 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000718/00/16/04/50 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000820/00/14/04/00 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 000922/00/12/04/50 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001024/00/10/04/00 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001126/00/08/04/50 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001228/00/06/04/48 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001330/01/04/04/50 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001432/01/02/04/48 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001534/01/00/04/46 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001636/01/24/04/48 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001738/01/22/04/46 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001840/01/20/04/48 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 001942/01/18/04/46 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002044/01/16/04/44 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002146/01/14/04/46 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002248/01/12/04/44 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002350/01/10/04/46 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002452/01/08/04/44 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002554/01/06/04/42 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002656/02/04/04/44 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002758/02/02/04/42 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002860/02/00/04/44 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 002962/02/24/04/42 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003064/02/22/04/40 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003166/02/20/04/42 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003268/02/18/04/40 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003370/02/16/04/42 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003472/02/14/04/40 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003574/02/12/04/38 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003676/02/10/04/40 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003778/02/08/04/38 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003880/02/06/04/40 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 003982/03/04/04/38 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004084/03/02/04/36 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004186/03/00/04/38 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004288/03/24/04/36 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004390/03/22/04/38 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004492/03/20/04/36 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004594/03/18/04/34 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004696/03/16/04/36 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004798/03/14/04/34 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 004900/03/12/04/36 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005002/03/10/04/34 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005104/03/08/04/32 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005206/03/06/04/34 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005308/04/04/04/32 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005410/04/02/04/34 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005512/04/00/04/32 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005614/04/24/04/30 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005716/04/22/04/32 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005818/04/20/04/30 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 005920/04/18/04/32 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006022/04/16/04/30 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006124/04/14/04/28 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006226/04/12/04/30 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006328/04/10/04/28 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006430/04/08/04/30 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006532/04/06/04/28 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006634/05/04/04/26 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006736/05/02/04/28 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006838/05/00/04/26 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 006940/05/24/04/28 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007042/05/22/04/26 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007144/05/20/04/24 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007246/05/18/04/26 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007348/05/16/04/24 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007450/05/14/04/26 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007552/05/12/04/24 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007654/05/10/04/22 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007756/05/08/04/24 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007858/05/06/04/22 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 007960/06/04/04/24 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008062/06/02/04/22 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008164/06/00/04/20 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008266/06/24/04/22 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008368/06/22/04/20 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008470/06/20/04/22 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008572/06/18/04/20 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008674/06/16/04/18 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008776/06/14/04/20 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008878/06/12/04/18 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 008980/06/10/04/20 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009082/06/08/04/18 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009184/06/06/04/16 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009286/07/04/04/18 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009388/07/02/04/16 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009490/07/00/04/18 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009592/07/24/04/16 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009694/07/22/04/14 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009796/07/20/04/16 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 009898/07/18/04/14 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 010000/07/16/04/16 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=6) 010102/07/14/04/14 meas period end fn_mod:4, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000008/00/08/08/08 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000110/00/06/08/06 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000212/00/04/08/04 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000314/00/02/08/06 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000416/00/00/08/04 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000518/00/24/08/06 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000620/00/22/08/04 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000722/00/20/08/02 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000824/00/18/08/04 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 000926/00/16/08/02 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001028/00/14/08/04 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001130/00/12/08/02 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001232/00/10/08/00 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001334/01/08/08/02 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001436/01/06/08/00 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001538/01/04/08/02 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001640/01/02/08/00 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001742/01/00/08/50 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001844/01/24/08/00 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 001946/01/22/08/50 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002048/01/20/08/00 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002150/01/18/08/50 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002252/01/16/08/48 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002354/01/14/08/50 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002456/01/12/08/48 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002558/01/10/08/46 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002660/02/08/08/48 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002762/02/06/08/46 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002864/02/04/08/48 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 002966/02/02/08/46 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003068/02/00/08/44 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003170/02/24/08/46 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003272/02/22/08/44 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003374/02/20/08/46 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003476/02/18/08/44 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003578/02/16/08/42 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003680/02/14/08/44 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003782/02/12/08/42 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003884/02/10/08/44 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 003986/03/08/08/42 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004088/03/06/08/40 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004190/03/04/08/42 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004292/03/02/08/40 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004394/03/00/08/42 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004496/03/24/08/40 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004598/03/22/08/38 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004700/03/20/08/40 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004802/03/18/08/38 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 004904/03/16/08/40 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005006/03/14/08/38 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005108/03/12/08/36 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005210/03/10/08/38 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005312/04/08/08/36 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005414/04/06/08/38 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005516/04/04/08/36 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005618/04/02/08/34 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005720/04/00/08/36 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005822/04/24/08/34 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 005924/04/22/08/36 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006026/04/20/08/34 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006128/04/18/08/32 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006230/04/16/08/34 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006332/04/14/08/32 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006434/04/12/08/34 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006536/04/10/08/32 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006638/05/08/08/30 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006740/05/06/08/32 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006842/05/04/08/30 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 006944/05/02/08/32 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007046/05/00/08/30 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007148/05/24/08/28 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007250/05/22/08/30 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007352/05/20/08/28 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007454/05/18/08/30 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007556/05/16/08/28 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007658/05/14/08/26 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007760/05/12/08/28 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007862/05/10/08/26 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 007964/06/08/08/28 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008066/06/06/08/26 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008168/06/04/08/24 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008270/06/02/08/26 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008372/06/00/08/24 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008474/06/24/08/26 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008576/06/22/08/24 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008678/06/20/08/22 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008780/06/18/08/24 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008882/06/16/08/22 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 008984/06/14/08/24 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009086/06/12/08/22 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009188/06/10/08/20 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009290/07/08/08/22 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009392/07/06/08/20 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009494/07/04/08/22 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009596/07/02/08/20 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009698/07/00/08/18 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009800/07/24/08/20 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 009902/07/22/08/18 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 010004/07/20/08/20 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=7) 010106/07/18/08/18 meas period end fn_mod:8, status:1, pchan:SDCCH8 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000088/00/10/37/36 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000190/00/08/37/34 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000292/00/06/37/36 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000394/00/04/37/34 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000496/00/02/37/32 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000598/00/00/37/34 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000700/00/24/37/32 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000802/00/22/37/34 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 000904/00/20/37/32 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001006/00/18/37/30 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001108/00/16/37/32 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001210/00/14/37/30 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001312/00/12/37/32 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001414/01/10/37/30 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001516/01/08/37/28 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001618/01/06/37/30 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001720/01/04/37/28 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001822/01/02/37/30 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 001924/01/00/37/28 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002026/01/24/37/26 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002128/01/22/37/28 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002230/01/20/37/26 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002332/01/18/37/28 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002434/01/16/37/26 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002536/01/14/37/24 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002638/01/12/37/26 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002740/02/10/37/24 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002842/02/08/37/26 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 002944/02/06/37/24 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003046/02/04/37/22 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003148/02/02/37/24 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003250/02/00/37/22 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003352/02/24/37/24 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003454/02/22/37/22 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003556/02/20/37/20 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003658/02/18/37/22 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003760/02/16/37/20 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003862/02/14/37/22 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 003964/02/12/37/20 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004066/03/10/37/18 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004168/03/08/37/20 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004270/03/06/37/18 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004372/03/04/37/20 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004474/03/02/37/18 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004576/03/00/37/16 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004678/03/24/37/18 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004780/03/22/37/16 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004882/03/20/37/18 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 004984/03/18/37/16 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005086/03/16/37/14 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005188/03/14/37/16 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005290/03/12/37/14 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005392/04/10/37/16 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005494/04/08/37/14 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005596/04/06/37/12 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005698/04/04/37/14 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005800/04/02/37/12 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 005902/04/00/37/14 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006004/04/24/37/12 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006106/04/22/37/10 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006208/04/20/37/12 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006310/04/18/37/10 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006412/04/16/37/12 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006514/04/14/37/10 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006616/04/12/37/08 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006718/05/10/37/10 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006820/05/08/37/08 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 006922/05/06/37/10 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007024/05/04/37/08 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007126/05/02/37/06 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007228/05/00/37/08 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007330/05/24/37/06 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007432/05/22/37/08 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007534/05/20/37/06 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007636/05/18/37/04 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007738/05/16/37/06 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007840/05/14/37/04 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 007942/05/12/37/06 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008044/06/10/37/04 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008146/06/08/37/02 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008248/06/06/37/04 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008350/06/04/37/02 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008452/06/02/37/04 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008554/06/00/37/02 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008656/06/24/37/00 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008758/06/22/37/02 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008860/06/20/37/00 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 008962/06/18/37/02 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009064/06/16/37/00 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009166/06/14/37/50 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009268/06/12/37/00 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009370/07/10/37/50 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009472/07/08/37/00 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009574/07/06/37/50 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009676/07/04/37/48 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009778/07/02/37/50 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009880/07/00/37/48 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 009982/07/24/37/46 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 010084/07/22/37/48 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=0) 010186/07/20/37/46 meas period end fn_mod:88, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000092/00/14/41/40 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000194/00/12/41/38 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000296/00/10/41/40 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000398/00/08/41/38 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000500/00/06/41/36 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000602/00/04/41/38 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000704/00/02/41/36 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000806/00/00/41/38 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 000908/00/24/41/36 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001010/00/22/41/34 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001112/00/20/41/36 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001214/00/18/41/34 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001316/00/16/41/36 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001418/01/14/41/34 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001520/01/12/41/32 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001622/01/10/41/34 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001724/01/08/41/32 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001826/01/06/41/34 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 001928/01/04/41/32 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002030/01/02/41/30 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002132/01/00/41/32 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002234/01/24/41/30 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002336/01/22/41/32 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002438/01/20/41/30 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002540/01/18/41/28 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002642/01/16/41/30 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002744/02/14/41/28 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002846/02/12/41/30 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 002948/02/10/41/28 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003050/02/08/41/26 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003152/02/06/41/28 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003254/02/04/41/26 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003356/02/02/41/28 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003458/02/00/41/26 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003560/02/24/41/24 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003662/02/22/41/26 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003764/02/20/41/24 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003866/02/18/41/26 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 003968/02/16/41/24 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004070/03/14/41/22 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004172/03/12/41/24 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004274/03/10/41/22 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004376/03/08/41/24 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004478/03/06/41/22 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004580/03/04/41/20 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004682/03/02/41/22 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004784/03/00/41/20 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004886/03/24/41/22 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 004988/03/22/41/20 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005090/03/20/41/18 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005192/03/18/41/20 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005294/03/16/41/18 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005396/04/14/41/20 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005498/04/12/41/18 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005600/04/10/41/16 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005702/04/08/41/18 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005804/04/06/41/16 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 005906/04/04/41/18 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006008/04/02/41/16 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006110/04/00/41/14 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006212/04/24/41/16 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006314/04/22/41/14 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006416/04/20/41/16 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006518/04/18/41/14 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006620/04/16/41/12 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006722/05/14/41/14 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006824/05/12/41/12 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 006926/05/10/41/14 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007028/05/08/41/12 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007130/05/06/41/10 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007232/05/04/41/12 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007334/05/02/41/10 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007436/05/00/41/12 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007538/05/24/41/10 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007640/05/22/41/08 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007742/05/20/41/10 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007844/05/18/41/08 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 007946/05/16/41/10 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008048/06/14/41/08 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008150/06/12/41/06 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008252/06/10/41/08 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008354/06/08/41/06 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008456/06/06/41/08 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008558/06/04/41/06 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008660/06/02/41/04 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008762/06/00/41/06 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008864/06/24/41/04 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 008966/06/22/41/06 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009068/06/20/41/04 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009170/06/18/41/02 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009272/06/16/41/04 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009374/07/14/41/02 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009476/07/12/41/04 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009578/07/10/41/02 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009680/07/08/41/00 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009782/07/06/41/02 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009884/07/04/41/00 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 009986/07/02/41/02 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 010088/07/00/41/00 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=1) 010190/07/24/41/50 meas period end fn_mod:92, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000006/00/06/06/06 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000108/00/04/06/04 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000210/00/02/06/02 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000312/00/00/06/04 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000414/00/24/06/02 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000516/00/22/06/04 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000618/00/20/06/02 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000720/00/18/06/00 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000822/00/16/06/02 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 000924/00/14/06/00 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001026/00/12/06/02 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001128/00/10/06/00 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001230/00/08/06/50 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001332/01/06/06/00 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001434/01/04/06/50 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001536/01/02/06/00 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001638/01/00/06/50 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001740/01/24/06/48 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001842/01/22/06/50 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 001944/01/20/06/48 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002046/01/18/06/46 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002148/01/16/06/48 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002250/01/14/06/46 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002352/01/12/06/48 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002454/01/10/06/46 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002556/01/08/06/44 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002658/02/06/06/46 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002760/02/04/06/44 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002862/02/02/06/46 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 002964/02/00/06/44 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003066/02/24/06/42 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003168/02/22/06/44 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003270/02/20/06/42 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003372/02/18/06/44 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003474/02/16/06/42 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003576/02/14/06/40 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003678/02/12/06/42 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003780/02/10/06/40 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003882/02/08/06/42 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 003984/03/06/06/40 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004086/03/04/06/38 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004188/03/02/06/40 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004290/03/00/06/38 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004392/03/24/06/40 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004494/03/22/06/38 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004596/03/20/06/36 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004698/03/18/06/38 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004800/03/16/06/36 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 004902/03/14/06/38 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005004/03/12/06/36 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005106/03/10/06/34 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005208/03/08/06/36 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005310/04/06/06/34 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005412/04/04/06/36 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005514/04/02/06/34 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005616/04/00/06/32 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005718/04/24/06/34 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005820/04/22/06/32 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 005922/04/20/06/34 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006024/04/18/06/32 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006126/04/16/06/30 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006228/04/14/06/32 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006330/04/12/06/30 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006432/04/10/06/32 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006534/04/08/06/30 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006636/05/06/06/28 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006738/05/04/06/30 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006840/05/02/06/28 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 006942/05/00/06/30 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007044/05/24/06/28 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007146/05/22/06/26 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007248/05/20/06/28 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007350/05/18/06/26 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007452/05/16/06/28 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007554/05/14/06/26 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007656/05/12/06/24 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007758/05/10/06/26 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007860/05/08/06/24 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 007962/06/06/06/26 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008064/06/04/06/24 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008166/06/02/06/22 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008268/06/00/06/24 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008370/06/24/06/22 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008472/06/22/06/24 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008574/06/20/06/22 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008676/06/18/06/20 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008778/06/16/06/22 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008880/06/14/06/20 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 008982/06/12/06/22 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009084/06/10/06/20 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009186/06/08/06/18 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009288/07/06/06/20 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009390/07/04/06/18 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009492/07/02/06/20 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009594/07/00/06/18 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009696/07/24/06/16 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009798/07/22/06/18 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 009900/07/20/06/16 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 010002/07/18/06/18 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=2) 010104/07/16/06/16 meas period end fn_mod:6, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000010/00/10/10/10 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000112/00/08/10/08 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000214/00/06/10/06 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000316/00/04/10/08 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000418/00/02/10/06 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000520/00/00/10/08 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000622/00/24/10/06 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000724/00/22/10/04 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000826/00/20/10/06 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 000928/00/18/10/04 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001030/00/16/10/06 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001132/00/14/10/04 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001234/00/12/10/02 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001336/01/10/10/04 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001438/01/08/10/02 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001540/01/06/10/04 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001642/01/04/10/02 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001744/01/02/10/00 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001846/01/00/10/02 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 001948/01/24/10/00 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002050/01/22/10/02 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002152/01/20/10/00 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002254/01/18/10/50 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002356/01/16/10/00 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002458/01/14/10/50 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002560/01/12/10/00 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002662/02/10/10/50 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002764/02/08/10/48 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002866/02/06/10/50 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 002968/02/04/10/48 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003070/02/02/10/46 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003172/02/00/10/48 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003274/02/24/10/46 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003376/02/22/10/48 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003478/02/20/10/46 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003580/02/18/10/44 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003682/02/16/10/46 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003784/02/14/10/44 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003886/02/12/10/46 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 003988/03/10/10/44 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004090/03/08/10/42 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004192/03/06/10/44 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004294/03/04/10/42 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004396/03/02/10/44 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004498/03/00/10/42 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004600/03/24/10/40 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004702/03/22/10/42 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004804/03/20/10/40 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 004906/03/18/10/42 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005008/03/16/10/40 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005110/03/14/10/38 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005212/03/12/10/40 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005314/04/10/10/38 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005416/04/08/10/40 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005518/04/06/10/38 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005620/04/04/10/36 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005722/04/02/10/38 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005824/04/00/10/36 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 005926/04/24/10/38 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006028/04/22/10/36 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006130/04/20/10/34 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006232/04/18/10/36 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006334/04/16/10/34 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006436/04/14/10/36 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006538/04/12/10/34 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006640/05/10/10/32 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006742/05/08/10/34 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006844/05/06/10/32 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 006946/05/04/10/34 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007048/05/02/10/32 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007150/05/00/10/30 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007252/05/24/10/32 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007354/05/22/10/30 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007456/05/20/10/32 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007558/05/18/10/30 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007660/05/16/10/28 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007762/05/14/10/30 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007864/05/12/10/28 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 007966/06/10/10/30 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008068/06/08/10/28 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008170/06/06/10/26 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008272/06/04/10/28 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008374/06/02/10/26 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008476/06/00/10/28 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008578/06/24/10/26 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008680/06/22/10/24 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008782/06/20/10/26 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008884/06/18/10/24 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 008986/06/16/10/26 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009088/06/14/10/24 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009190/06/12/10/22 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009292/07/10/10/24 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009394/07/08/10/22 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009496/07/06/10/24 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009598/07/04/10/22 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009700/07/02/10/20 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009802/07/00/10/22 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 009904/07/24/10/20 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 010006/07/22/10/22 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=0,ss=3) 010108/07/20/10/20 meas period end fn_mod:10, status:1, pchan:CCCH+SDCCH4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000017/00/17/17/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000026/00/00/26/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000030/00/04/30/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000034/00/08/34/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 10 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 15 measurements with dummy values, from which 1 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 1 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL(60.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB(50.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000039/00/13/39/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000043/00/17/43/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000047/00/21/47/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000052/00/00/01/00 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000056/00/04/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000060/00/08/09/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000065/00/13/14/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000069/00/17/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000073/00/21/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000078/00/00/27/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000082/00/04/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000086/00/08/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000091/00/13/40/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000095/00/17/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000099/00/21/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000104/00/00/02/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000108/00/04/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000112/00/08/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000117/00/13/15/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000121/00/17/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=20, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000125/00/21/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=21, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000130/00/00/28/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=22, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000134/00/04/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=23, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000138/00/08/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=24, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=25, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000143/00/13/41/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000147/00/17/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000151/00/21/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000156/00/00/03/00 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000160/00/04/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000164/00/08/11/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000169/00/13/16/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000173/00/17/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000177/00/21/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000182/00/00/29/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000186/00/04/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000190/00/08/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000195/00/13/42/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000199/00/17/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000203/00/21/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000208/00/00/04/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000212/00/04/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000216/00/08/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000221/00/13/17/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000225/00/17/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=20, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000229/00/21/25/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=21, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000234/00/00/30/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=22, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000238/00/04/34/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=23, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000242/00/08/38/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=24, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=25, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000247/00/13/43/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000251/00/17/47/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000255/00/21/00/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000260/00/00/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000264/00/04/09/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000268/00/08/13/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000273/00/13/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000277/00/17/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000281/00/21/26/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000286/00/00/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000290/00/04/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000294/00/08/39/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000299/00/13/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000303/00/17/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000307/00/21/01/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000312/00/00/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000316/00/04/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000320/00/08/14/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000325/00/13/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000329/00/17/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=20, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000333/00/21/27/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=21, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000338/00/00/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=22, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000342/00/04/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=23, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000346/00/08/40/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=24, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=25, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 25 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 0 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 3 SUB measurements, expected 2 +ERROR (bts=0,trx=1,ts=2,ss=0) Incorrect number of SUB measurements detected! (3 vs exp 2) +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL( 0.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(0), RXQUAL_SUB(0), num_meas_sub(3), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000351/00/13/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000355/00/17/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000359/00/21/02/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000364/00/00/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000368/00/04/11/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000372/00/08/15/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000377/00/13/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000381/00/17/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000385/00/21/28/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000390/00/00/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000394/00/04/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000398/00/08/41/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000403/00/13/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000407/00/17/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000411/00/21/03/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000416/00/00/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000420/00/04/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000424/00/08/16/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000429/00/13/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000000/00/00/00/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000017/00/17/17/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000026/00/00/26/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000030/00/04/30/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000034/00/08/34/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000039/00/13/39/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000043/00/17/43/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000047/00/21/47/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000052/00/00/01/00 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000056/00/04/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000060/00/08/09/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000065/00/13/14/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000069/00/17/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000073/00/21/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000078/00/00/27/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000082/00/04/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=20, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000086/00/08/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=21, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000091/00/13/40/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=22, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000095/00/17/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=23, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000099/00/21/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=24, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000104/00/00/02/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=25, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000108/00/04/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=26, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000112/00/08/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=27, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000117/00/13/15/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=28, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000121/00/17/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=29, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000125/00/21/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=30, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000130/00/00/28/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=31, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000134/00/04/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=32, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000138/00/08/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=33, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000143/00/13/41/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=34, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000147/00/17/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=35, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000151/00/21/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=36, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000156/00/00/03/00 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=37, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000160/00/04/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=38, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000164/00/08/11/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=39, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000169/00/13/16/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=40, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000173/00/17/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=41, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000177/00/21/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=42, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000182/00/00/29/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=43, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000186/00/04/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=44, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000190/00/08/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=45, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000195/00/13/42/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=46, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000199/00/17/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=47, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000203/00/21/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=48, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000208/00/00/04/00 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=49, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000212/00/04/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=50, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000216/00/08/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=51, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000221/00/13/17/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=52, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000225/00/17/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=53, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000229/00/21/25/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=54, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000234/00/00/30/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=55, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000238/00/04/34/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=56, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000242/00/08/38/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=57, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000247/00/13/43/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=58, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000251/00/17/47/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=59, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000255/00/21/00/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=60, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000260/00/00/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=61, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000264/00/04/09/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=62, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000268/00/08/13/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=63, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000273/00/13/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=64, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000277/00/17/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=65, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000281/00/21/26/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=66, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000286/00/00/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=67, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000290/00/04/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=68, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000294/00/08/39/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=69, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000299/00/13/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=70, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000303/00/17/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=71, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000307/00/21/01/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=72, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000312/00/00/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=73, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000316/00/04/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=74, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000320/00/08/14/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=75, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000325/00/13/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=76, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000329/00/17/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=77, fn_mod=17 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000333/00/21/27/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=78, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000338/00/00/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=79, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000342/00/04/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=80, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000346/00/08/40/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=81, fn_mod=34 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000351/00/13/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=82, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000355/00/17/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=83, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000359/00/21/02/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=84, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000364/00/00/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=85, fn_mod=52 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000368/00/04/11/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=86, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000372/00/08/15/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=87, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000377/00/13/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=88, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000381/00/17/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=89, fn_mod=69 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000385/00/21/28/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=90, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000390/00/00/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=91, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000394/00/04/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=92, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000398/00/08/41/38 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=93, fn_mod=86 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000403/00/13/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=94, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000407/00/17/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=95, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000411/00/21/03/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=96, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000416/00/00/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=97, fn_mod=0 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000420/00/04/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=98, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000424/00/08/16/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=99, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000429/00/13/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=100, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000026/00/00/26/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000030/00/04/30/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000038/00/12/38/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 7 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 18 measurements with dummy values, from which 1 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 1 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL(72.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB(50.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(7), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000039/00/13/39/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000043/00/17/43/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000047/00/21/47/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000056/00/04/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000060/00/08/09/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000065/00/13/14/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000073/00/21/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000078/00/00/27/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000082/00/04/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000091/00/13/40/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000095/00/17/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000099/00/21/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000108/00/04/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000112/00/08/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000117/00/13/15/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000125/00/21/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000130/00/00/28/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000134/00/04/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000142/00/12/40/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 19 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 6 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 2 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL(24.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000143/00/13/41/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000147/00/17/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000151/00/21/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000160/00/04/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000164/00/08/11/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000169/00/13/16/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000177/00/21/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000182/00/00/29/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000186/00/04/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000195/00/13/42/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000199/00/17/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000203/00/21/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000212/00/04/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000216/00/08/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000221/00/13/17/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000229/00/21/25/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000234/00/00/30/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000238/00/04/34/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000246/00/12/42/38 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 19 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 6 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 2 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL(24.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000247/00/13/43/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000251/00/17/47/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000255/00/21/00/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000264/00/04/09/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000268/00/08/13/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000273/00/13/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000281/00/21/26/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000286/00/00/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000290/00/04/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000299/00/13/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000303/00/17/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000307/00/21/01/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000316/00/04/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000320/00/08/14/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000325/00/13/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000333/00/21/27/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000338/00/00/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000342/00/04/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=38 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000350/00/12/44/42 meas period end fn_mod:12, status:1, pchan:TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Calculating measurement results for physical channel: TCH/F +DEBUG (bts=0,trx=1,ts=2,ss=0) Received 19 UL measurements, expected 25 +DEBUG (bts=0,trx=1,ts=2,ss=0) Replaced 6 measurements with dummy values, from which 0 were SUB measurements +DEBUG (bts=0,trx=1,ts=2,ss=0) Received UL measurements contain 2 SUB measurements, expected 2 +INFO (bts=0,trx=1,ts=2,ss=0) Computed TA256( 256), BER-FULL(24.00%), RSSI-FULL(- 90dBm), C/I-FULL( 0 cB), BER-SUB( 0.00%), RSSI-SUB(- 90dBm), C/I-SUB( 0 cB) +INFO (bts=0,trx=1,ts=2,ss=0) UL MEAS RXLEV_FULL(20), RXLEV_SUB(20), RXQUAL_FULL(7), RXQUAL_SUB(0), num_meas_sub(2), num_ul_meas(25) +DEBUG (bts=0,trx=1,ts=2,ss=0) 000351/00/13/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000355/00/17/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000359/00/21/02/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000368/00/04/11/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000372/00/08/15/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000377/00/13/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000385/00/21/28/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000390/00/00/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000394/00/04/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000403/00/13/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000407/00/17/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000411/00/21/03/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000420/00/04/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000424/00/08/16/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000429/00/13/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000004/00/04/04/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=1, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000008/00/08/08/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=2, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000013/00/13/13/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=3, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000021/00/21/21/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=4, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000026/00/00/26/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=5, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000030/00/04/30/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=6, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000039/00/13/39/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=7, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000043/00/17/43/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=8, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000047/00/21/47/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=9, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000056/00/04/05/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=10, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000060/00/08/09/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=11, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000065/00/13/14/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=12, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000073/00/21/22/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=13, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000078/00/00/27/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=14, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000082/00/04/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=15, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000091/00/13/40/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=16, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000095/00/17/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=17, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000099/00/21/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=18, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000108/00/04/06/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=19, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000112/00/08/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=20, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000117/00/13/15/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=21, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000125/00/21/23/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=22, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000130/00/00/28/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=23, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000134/00/04/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=24, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000143/00/13/41/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=25, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000147/00/17/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=26, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000151/00/21/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=27, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000160/00/04/07/04 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=28, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000164/00/08/11/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=29, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000169/00/13/16/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=30, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000177/00/21/24/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=31, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000182/00/00/29/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=32, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000186/00/04/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=33, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000195/00/13/42/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=34, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000199/00/17/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=35, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000203/00/21/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=36, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000212/00/04/08/04 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=37, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000216/00/08/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=38, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000221/00/13/17/13 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=39, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000229/00/21/25/21 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=40, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000234/00/00/30/26 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=41, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000238/00/04/34/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=42, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000247/00/13/43/39 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=43, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000251/00/17/47/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=44, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000255/00/21/00/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=45, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000264/00/04/09/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=46, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000268/00/08/13/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=47, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000273/00/13/18/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=48, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000281/00/21/26/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=49, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000286/00/00/31/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=50, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000290/00/04/35/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=51, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000299/00/13/44/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=52, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000303/00/17/48/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=53, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000307/00/21/01/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=54, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000316/00/04/10/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=55, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000320/00/08/14/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=56, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000325/00/13/19/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=57, fn_mod=13 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000333/00/21/27/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=58, fn_mod=21 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000338/00/00/32/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=59, fn_mod=26 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000342/00/04/36/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=60, fn_mod=30 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000351/00/13/45/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=61, fn_mod=39 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000355/00/17/49/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=62, fn_mod=43 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000359/00/21/02/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=63, fn_mod=47 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000368/00/04/11/08 adding a SUB measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=64, fn_mod=56 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000372/00/08/15/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=65, fn_mod=60 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000377/00/13/20/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=66, fn_mod=65 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000385/00/21/28/25 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=67, fn_mod=73 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000390/00/00/33/30 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=68, fn_mod=78 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000394/00/04/37/34 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=69, fn_mod=82 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000403/00/13/46/43 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=70, fn_mod=91 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000407/00/17/50/47 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=71, fn_mod=95 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000411/00/21/03/51 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=72, fn_mod=99 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000420/00/04/12/08 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=73, fn_mod=4 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000424/00/08/16/12 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=74, fn_mod=8 +DEBUG (bts=0,trx=1,ts=2,ss=0) 000429/00/13/21/17 adding a FULL measurement (ber10k=0, ta_offs=256, ci_cB=0, rssi=-90), num_ul_meas=75, fn_mod=13 diff --git a/tests/meas/meas_testcases.h b/tests/meas/meas_testcases.h index d7eee5c3..1263ac35 100644 --- a/tests/meas/meas_testcases.h +++ b/tests/meas/meas_testcases.h @@ -1,5 +1,5 @@ #define ULM(ber, ta, sub, neg_rssi) \ - { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = sub, .inv_rssi = (neg_rssi) } + { .ber10k = (ber), .ta_offs_256bits = (ta), .ci_cb = 10, .is_sub = sub, .inv_rssi = (neg_rssi) } struct meas_testcase { const char *name; diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am index f232c493..8b8beda7 100644 --- a/tests/misc/Makefile.am +++ b/tests/misc/Makefile.am @@ -1,9 +1,24 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) \ - $(LIBOSMOABIS_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) \ - $(LIBOSMOABIS_LIBS) $(LIBOSMOTRAU_LIBS) -noinst_PROGRAMS = misc_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = misc_test EXTRA_DIST = misc_test.ok misc_test_SOURCES = misc_test.c $(srcdir)/../stubs.c diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c index e65fcb4d..bbf75579 100644 --- a/tests/misc/misc_test.c +++ b/tests/misc/misc_test.c @@ -13,7 +13,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -21,6 +21,7 @@ */ #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/msg_utils.h> #include <osmo-bts/logging.h> @@ -165,16 +166,17 @@ static void test_bts_supports_cm(void) struct rsl_ie_chan_mode cm; struct gsm_bts *bts; - bts = gsm_bts_alloc(ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(ctx); + bts = gsm_bts_alloc(g_bts_sm, 0); /* Signalling shall be supported regardless of the features */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Bm, .spd_ind = RSL_CMOD_SPD_SIGN }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/F */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/F */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Lm, .spd_ind = RSL_CMOD_SPD_SIGN }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/H */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/H */ osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_F_V1); osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_V1); @@ -184,27 +186,27 @@ static void test_bts_supports_cm(void) cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Bm, .spd_ind = RSL_CMOD_SPD_SPEECH, .chan_rate = RSL_CMOD_SP_GSM1 }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/FS */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/FS */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Lm, .spd_ind = RSL_CMOD_SPD_SPEECH, .chan_rate = RSL_CMOD_SP_GSM1 }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/HS */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/HS */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Bm, .spd_ind = RSL_CMOD_SPD_SPEECH, .chan_rate = RSL_CMOD_SP_GSM2 }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 0); /* TCH/EFS */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == false); /* TCH/EFS */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Bm, .spd_ind = RSL_CMOD_SPD_SPEECH, .chan_rate = RSL_CMOD_SP_GSM3 }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/AFS */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/AFS */ cm = (struct rsl_ie_chan_mode) { .chan_rt = RSL_CMOD_CRT_TCH_Lm, .spd_ind = RSL_CMOD_SPD_SPEECH, .chan_rate = RSL_CMOD_SP_GSM3 }; - OSMO_ASSERT(bts_supports_cm(bts, &cm) == 1); /* TCH/AHS */ + OSMO_ASSERT(bts_supports_cm(bts, &cm) == true); /* TCH/AHS */ talloc_free(bts); } diff --git a/tests/osmo-bts.vty b/tests/osmo-bts.vty new file mode 100644 index 00000000..97629d0a --- /dev/null +++ b/tests/osmo-bts.vty @@ -0,0 +1,323 @@ +OsmoBTS> list +... + show bts [<0-255>] + show trx [<0-255>] [<0-255>] + show timeslot [<0-255>] [<0-255>] [<0-7>] + show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>] + show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>] + show bts <0-255> gprs +... + show timer [(bts|abis)] [TNNNN] + show e1_driver + show e1_line [<0-255>] [stats] + show e1_timeslot [<0-255>] [<0-31>] +... +OsmoBTS> ? +... + show Show running system information +... + +OsmoBTS> show ? +... + bts Display information about a BTS + trx Display information about a TRX + timeslot Display information about a TS + lchan Display information about a logical channel + timer Show timers + e1_driver Display information about available E1 drivers + e1_line Display information about a E1 line + e1_timeslot Display information about a E1 timeslot +... +OsmoBTS> show bts ? + [<0-255>] BTS Number + <0-255> BTS Number +OsmoBTS> show bts 0 ? + gprs GPRS/EGPRS configuration + <cr> +OsmoBTS> show trx ? + [<0-255>] BTS Number +OsmoBTS> show trx 0 ? + [<0-255>] TRX Number +OsmoBTS> show timeslot ? + [<0-255>] BTS Number +OsmoBTS> show timeslot 0 ? + [<0-255>] TRX Number +OsmoBTS> show timeslot 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS> show lchan ? + [<0-255>] BTS Number + summary Short summary +OsmoBTS> show lchan 0 ? + [<0-255>] TRX Number +OsmoBTS> show lchan 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS> show lchan 0 0 0 ? + [<0-7>] Logical Channel Number +OsmoBTS> show lchan summary ? + [<0-255>] BTS Number +OsmoBTS> show lchan summary 0 ? + [<0-255>] TRX Number +OsmoBTS> show lchan summary 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS> show lchan summary 0 0 0 ? + [<0-7>] Logical Channel Number + +OsmoBTS> show timer ? + [bts] BTS process timers + [abis] Abis (RSL) related timers +OsmoBTS> show timer +bts: X1 = 300 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) +bts: X2 = 3 s Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s) (default: 3 s) +abis: X15 = 0 ms Time to wait between Channel Activation and dispatching a cached early Immediate Assignment (default: 0 ms) +OsmoBTS> show timer bts ? + [TNNNN] T- or X-timer-number -- 3GPP compliant timer number of the format '1234' or 'T1234' or 't1234'; Osmocom-specific timer number of the format: 'X1234' or 'x1234'. +OsmoBTS> show timer bts +bts: X1 = 300 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) +bts: X2 = 3 s Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s) (default: 3 s) +OsmoBTS> show timer bts X1 +bts: X1 = 300 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) +OsmoBTS> show timer bts X2 +bts: X2 = 3 s Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s) (default: 3 s) +OsmoBTS> show timer abis ? + [TNNNN] T- or X-timer-number -- 3GPP compliant timer number of the format '1234' or 'T1234' or 't1234'; Osmocom-specific timer number of the format: 'X1234' or 'x1234'. +OsmoBTS> show timer abis X15 +abis: X15 = 0 ms Time to wait between Channel Activation and dispatching a cached early Immediate Assignment (default: 0 ms) + +OsmoBTS> show e1_driver ? + <cr> +OsmoBTS> show e1_line ? + [<0-255>] E1 Line Number +OsmoBTS> show e1_line 0 ? + [stats] Include statistics +OsmoBTS> show e1_timeslot ? + [<0-255>] E1 Line Number +OsmoBTS> show e1_timeslot 0 ? + [<0-31>] E1 Timeslot Number + +OsmoBTS> enable +OsmoBTS# list +... + show bts [<0-255>] + show trx [<0-255>] [<0-255>] + show timeslot [<0-255>] [<0-255>] [<0-7>] + show lchan [<0-255>] [<0-255>] [<0-7>] [<0-7>] + show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>] + show bts <0-255> gprs +... + show timer [(bts|abis)] [TNNNN] + bts <0-0> trx <0-255> ts <0-7> (lchan|shadow-lchan) <0-7> rtp jitter-buffer <0-10000> + test send-failure-event-report <0-255> + bts <0-0> c0-power-red <0-6> + show e1_driver + show e1_line [<0-255>] [stats] + show e1_timeslot [<0-255>] [<0-31>] +... + +OsmoBTS# ? +... + show Show running system information +... + +OsmoBTS# show ? +... + bts Display information about a BTS + trx Display information about a TRX + timeslot Display information about a TS + lchan Display information about a logical channel + timer Show timers + e1_driver Display information about available E1 drivers + e1_line Display information about a E1 line + e1_timeslot Display information about a E1 timeslot +... +OsmoBTS# show bts ? + [<0-255>] BTS Number + <0-255> BTS Number +OsmoBTS# show bts 0 ? + gprs GPRS/EGPRS configuration + <cr> +OsmoBTS# show trx ? + [<0-255>] BTS Number +OsmoBTS# show trx 0 ? + [<0-255>] TRX Number +OsmoBTS# show timeslot ? + [<0-255>] BTS Number +OsmoBTS# show timeslot 0 ? + [<0-255>] TRX Number +OsmoBTS# show timeslot 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS# show lchan ? + [<0-255>] BTS Number + summary Short summary +OsmoBTS# show lchan 0 ? + [<0-255>] TRX Number +OsmoBTS# show lchan 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS# show lchan 0 0 0 ? + [<0-7>] Logical Channel Number +OsmoBTS# show lchan summary ? + [<0-255>] BTS Number +OsmoBTS# show lchan summary 0 ? + [<0-255>] TRX Number +OsmoBTS# show lchan summary 0 0 ? + [<0-7>] Timeslot Number +OsmoBTS# show lchan summary 0 0 0 ? + [<0-7>] Logical Channel Number +OsmoBTS# show e1_driver ? + <cr> +OsmoBTS# show e1_line ? + [<0-255>] E1 Line Number +OsmoBTS# show e1_line 0 ? + [stats] Include statistics +OsmoBTS# show e1_timeslot ? + [<0-255>] E1 Line Number +OsmoBTS# show e1_timeslot 0 ? + [<0-31>] E1 Timeslot Number + +OsmoBTS# configure terminal +OsmoBTS(config)# list +... + bts BTS_NR +... + timer [(bts|abis)] [TNNNN] [(<0-2147483647>|default)] + phy <0-255> + e1_input +... +OsmoBTS(config)# ? +... + bts Select a BTS to configure +... + timer Configure or show timers + phy Select a PHY to configure + e1_input Configure E1/T1/J1 TDM input +... +OsmoBTS(config)# bts ? + BTS_NR BTS Number +OsmoBTS(config)# phy ? + <0-255> PHY number + +OsmoBTS(config)# timer ? + [bts] BTS process timers + [abis] Abis (RSL) related timers +OsmoBTS(config)# timer bts ? + [TNNNN] T- or X-timer-number -- 3GPP compliant timer number of the format '1234' or 'T1234' or 't1234'; Osmocom-specific timer number of the format: 'X1234' or 'x1234'. +OsmoBTS(config)# timer bts X1 +bts: X1 = 300 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) +OsmoBTS(config)# timer bts X2 +bts: X2 = 3 s Time after which osmo-bts exits if requesting transceivers to stop during shut down process does not finish (s) (default: 3 s) +OsmoBTS(config)# timer bts X1 ? + [<0-2147483647>] New timer value + [default] Set to default timer value +OsmoBTS(config)# timer bts X1 123 +OsmoBTS(config)# timer bts X1 +bts: X1 = 123 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) +OsmoBTS(config)# timer bts X1 default +OsmoBTS(config)# timer bts X1 +bts: X1 = 300 s Time after which osmo-bts exits if regular ramp down during shut down process does not finish (s) (default: 300 s) + +OsmoBTS(config)# timer abis X15 +abis: X15 = 0 ms Time to wait between Channel Activation and dispatching a cached early Immediate Assignment (default: 0 ms) +OsmoBTS(config)# timer abis X15 123 +OsmoBTS(config)# timer abis X15 +abis: X15 = 123 ms Time to wait between Channel Activation and dispatching a cached early Immediate Assignment (default: 0 ms) +OsmoBTS(config)# timer abis X15 default +OsmoBTS(config)# timer abis X15 +abis: X15 = 0 ms Time to wait between Channel Activation and dispatching a cached early Immediate Assignment (default: 0 ms) + +OsmoBTS(config)# bts 0 +OsmoBTS(bts)# list +... + ipa unit-id <0-65534> <0-255> + oml remote-ip A.B.C.D + no oml remote-ip A.B.C.D + rtp jitter-buffer <0-10000> [adaptive] + rtp port-range <1-65534> <1-65534> + rtp ip-dscp <0-63> + rtp socket-priority <0-255> + rtp continuous-streaming + no rtp continuous-streaming + rtp internal-uplink-ecu + no rtp internal-uplink-ecu + rtp hr-format (rfc5993|ts101318) + band (450|GSM450|480|GSM480|750|GSM750|810|GSM810|850|GSM850|900|GSM900|1800|DCS1800|1900|PCS1900) + description .TEXT + no description + paging queue-size <1-1024> + paging lifetime <0-60> + agch-queue-mgmt default + agch-queue-mgmt threshold <0-100> low <0-100> high <0-100000> + min-qual-rach <-100-100> + min-qual-norm <-100-100> + max-ber10k-rach <0-10000> + pcu-socket PATH + pcu-socket-wqueue-length <1-2147483647> + supp-meas-info toa256 + no supp-meas-info toa256 + smscb queue-max-length <1-60> + smscb queue-target-length <1-30> + smscb queue-hysteresis <0-30> + gsmtap-remote-host [HOSTNAME] + no gsmtap-remote-host + gsmtap-local-host HOSTNAME + no gsmtap-local-host + gsmtap-sapi (enable-all|disable-all) + gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch) + no gsmtap-sapi (bcch|ccch|rach|agch|pch|sdcch|tch/f|tch/h|pacch|pdtch|ptcch|cbch|sacch) + gsmtap-rlp [skip-null] + no gsmtap-rlp + osmux + trx <0-254> +... +OsmoBTS(bts)# ? +... + ipa ip.access RSL commands + oml OML Parameters + no Negate a command or set its defaults + rtp RTP parameters + band Set the frequency band of this BTS + description Save human-readable description of the object + paging Paging related parameters + agch-queue-mgmt AGCH queue mgmt + min-qual-rach Set the minimum link quality level of Access Bursts to be accepted + min-qual-norm Set the minimum link quality level of Normal Bursts to be accepted + max-ber10k-rach Set the maximum BER for valid RACH requests + pcu-socket Configure the PCU socket file/path name + pcu-socket-wqueue-length Configure the PCU socket queue length + supp-meas-info Configure the RSL Supplementary Measurement Info + smscb SMSCB (SMS Cell Broadcast) / CBCH configuration + gsmtap-remote-host Enable GSMTAP Um logging (see also 'gsmtap-sapi') + gsmtap-local-host Enable local bind for GSMTAP Um logging (see also 'gsmtap-sapi') + gsmtap-sapi Enable/disable sending of UL/DL messages over GSMTAP + gsmtap-rlp Enable generation of GSMTAP frames for RLP (non-transparent CSD) + osmux Configure Osmux + trx Select a TRX to configure +... +OsmoBTS(bts)# trx 0 +OsmoBTS(trx)# list +... + user-gain <-100000-100000> (dB|mdB) + power-ramp max-initial <-10000-100000> (dBm|mdBm) + power-ramp step-size <1-100000> (dB|mdB) + power-ramp step-interval <1-100> + ms-power-control (dsp|osmo) + ta-control interval <0-31> + phy <0-255> instance <0-255> +... +OsmoBTS(trx)# ? +... + user-gain Inform BTS about additional, user-provided gain or attenuation at TRX output + power-ramp Power-Ramp settings + ms-power-control Mobile Station Power Level Control + ta-control Timing Advance Control Parameters + phy Configure PHY Link+Instance for this TRX +... +OsmoBTS(trx)# exit +OsmoBTS(bts)# osmux +OsmoBTS(osmux)# ? +... + use Configure Osmux usage + local-ip IP information + local-port Osmux port + batch-factor Batching factor + batch-size Batch size + dummy-padding Dummy padding + diff --git a/tests/paging/Makefile.am b/tests/paging/Makefile.am index 74d98265..06cc35e1 100644 --- a/tests/paging/Makefile.am +++ b/tests/paging/Makefile.am @@ -1,7 +1,26 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOCODEC_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) $(LIBOSMOCODEC_LIBS) -noinst_PROGRAMS = paging_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) +AM_LDFLAGS = -no-install + +check_PROGRAMS = paging_test EXTRA_DIST = paging_test.ok paging_test_SOURCES = paging_test.c $(srcdir)/../stubs.c diff --git a/tests/paging/paging_test.c b/tests/paging/paging_test.c index af8accc5..1676a107 100644 --- a/tests/paging/paging_test.c +++ b/tests/paging/paging_test.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -22,10 +22,12 @@ #include <osmocom/core/application.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/logging.h> #include <osmo-bts/paging.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/l1sap.h> +#include <osmo-bts/notification.h> #include <unistd.h> @@ -133,6 +135,7 @@ static struct gsm_bts_trx *test_is_ccch_for_agch_setup(uint8_t bs_ag_blks_res) si3.control_channel_desc.bs_ag_blks_res = bs_ag_blks_res; trx.bts = &bts; bts.si_valid |= 0x8; + bts.asci.pos_nch = -1; memcpy(&bts.si_buf[SYSINFO_TYPE_3][0], &si3, sizeof(si3)); return &trx; } @@ -142,7 +145,7 @@ static struct gsm_bts_trx *test_is_ccch_for_agch_setup(uint8_t bs_ag_blks_res) * Table 5 of 9 must occur. */ static void test_is_ccch_for_agch(void) { - int is_ag_res; + enum ccch_msgt ccch; int fn; uint8_t bs_ag_blks_res; struct gsm_bts_trx *trx; @@ -170,13 +173,174 @@ static void test_is_ccch_for_agch(void) /* Try allo possible settings for bs_ag_blks_res */ for (bs_ag_blks_res = 0; bs_ag_blks_res <= 7; bs_ag_blks_res++) { trx = test_is_ccch_for_agch_setup(bs_ag_blks_res); - is_ag_res = is_ccch_for_agch(trx, fn); - printf(" %u", is_ag_res); + ccch = get_ccch_msgt(trx, fn); + printf(" %u", (ccch == CCCH_MSGT_AGCH)); } printf("\n"); } } +static void test_paging_rest_octets1(void) +{ + uint8_t out_buf[17]; + struct p1_rest_octets p1ro = {}; + struct asci_notification notif = {}; + + struct bitvec bv = { + .data_len = sizeof(out_buf), + .data = out_buf, + }; + + /* no rest */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + append_p1_rest_octets(&bv, &p1ro, NULL); + ASSERT_TRUE(out_buf[0] == 0x2b); + + /* add NLN */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p1ro.nln_pch.present = true; + p1ro.nln_pch.nln = 3; + p1ro.nln_pch.nln_status = 1; + append_p1_rest_octets(&bv, &p1ro, NULL); + ASSERT_TRUE(out_buf[0] == 0xfb); /* H 1 11 1 */ + p1ro.nln_pch.present = 0; + + /* add group callref */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + notif.group_call_ref[0] = 0x12; + notif.group_call_ref[1] = 0x34; + notif.group_call_ref[2] = 0x56; + notif.group_call_ref[3] = 0x78; + notif.group_call_ref[4] = 0x90; + notif.chan_desc.present = true; + notif.chan_desc.len = 3; + notif.chan_desc.value[0] = 0x20; + notif.chan_desc.value[1] = 0x40; + notif.chan_desc.value[2] = 0x80; + append_p1_rest_octets(&bv, &p1ro, ¬if); + ASSERT_TRUE(out_buf[0] == 0x31); /* L L L H 0x123456789 */ + ASSERT_TRUE(out_buf[1] == 0x23); + ASSERT_TRUE(out_buf[2] == 0x45); + ASSERT_TRUE(out_buf[3] == 0x67); + ASSERT_TRUE(out_buf[4] == 0x89); + ASSERT_TRUE(out_buf[5] == 0x90); /* H 0x204080 0 */ + ASSERT_TRUE(out_buf[6] == 0x20); + ASSERT_TRUE(out_buf[7] == 0x40); + ASSERT_TRUE(out_buf[8] == 0x2b); + + /* add Packet Page Indication 1 */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p1ro.packet_page_ind[0] = true; + append_p1_rest_octets(&bv, &p1ro, NULL); + ASSERT_TRUE(out_buf[0] == 0x23); /* L L L L H L L L */ + p1ro.packet_page_ind[0] = false; + + /* add Packet Page Indication 2 */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p1ro.packet_page_ind[1] = true; + append_p1_rest_octets(&bv, &p1ro, NULL); + ASSERT_TRUE(out_buf[0] == 0x2f); /* L L L L L H L L */ + p1ro.packet_page_ind[1] = false; + + /* add ETWS */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p1ro.r8_present = true; + p1ro.r8.prio_ul_access = true; + p1ro.r8.etws_present = true; + p1ro.r8.etws.is_first = true; + p1ro.r8.etws.page_nr = 0x5; + uint8_t page[] = { 0x22, 0x44, 0x66 }; + p1ro.r8.etws.page_bytes = sizeof(page); + p1ro.r8.etws.page = page; + append_p1_rest_octets(&bv, &p1ro, NULL); + ASSERT_TRUE(out_buf[0] == 0x2b); /* L L L L L L L L */ + ASSERT_TRUE(out_buf[1] == 0xe5); /* H 1 1 0 0x5 */ + ASSERT_TRUE(out_buf[2] == 0x18); /* 0 len=24=0x18 */ + ASSERT_TRUE(out_buf[3] == 0x22); /* 0x224488 */ + ASSERT_TRUE(out_buf[4] == 0x44); + ASSERT_TRUE(out_buf[5] == 0x66); + p1ro.r8_present = false; +} + +static void test_paging_rest_octets2(void) +{ + uint8_t out_buf[11]; + struct p2_rest_octets p2ro = {}; + + struct bitvec bv = { + .data_len = sizeof(out_buf), + .data = out_buf, + }; + + /* nothing added */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + append_p2_rest_octets(&bv, &p2ro); + ASSERT_TRUE(out_buf[0] == 0x2b); /* L L */ + + /* add cneed */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p2ro.cneed.present = true; + p2ro.cneed.cn3 = 3; + append_p2_rest_octets(&bv, &p2ro); + ASSERT_TRUE(out_buf[0] == 0xeb); /* H 1 1 L */ + p2ro.cneed.present = false; + + /* add NLN */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p2ro.nln_pch.present = true; + p2ro.nln_pch.nln = 3; + p2ro.nln_pch.nln_status = 1; + append_p2_rest_octets(&bv, &p2ro); + ASSERT_TRUE(out_buf[0] == 0x7b); /* L H 1 11 1 */ + p2ro.nln_pch.present = 0; +} + +static void test_paging_rest_octets3(void) +{ + uint8_t out_buf[3]; + struct p3_rest_octets p3ro = {}; + + struct bitvec bv = { + .data_len = sizeof(out_buf), + .data = out_buf, + }; + + /* nothing added */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + append_p3_rest_octets(&bv, &p3ro); + ASSERT_TRUE(out_buf[0] == 0x2b); /* L L */ + + /* add cneed */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p3ro.cneed.present = true; + p3ro.cneed.cn3 = 3; + p3ro.cneed.cn4 = 3; + append_p3_rest_octets(&bv, &p3ro); + ASSERT_TRUE(out_buf[0] == 0xfb); /* H 1 1 1 1 L */ + p3ro.cneed.present = false; + + /* add NLN */ + memset(out_buf, GSM_MACBLOCK_PADDING, sizeof(out_buf)); + bv.cur_bit = 0; + p3ro.nln_pch.present = true; + p3ro.nln_pch.nln = 3; + p3ro.nln_pch.nln_status = 1; + append_p3_rest_octets(&bv, &p3ro); + ASSERT_TRUE(out_buf[0] == 0x7b); /* L H 1 11 1 */ + p3ro.nln_pch.present = 0; +} + int main(int argc, char **argv) { tall_bts_ctx = talloc_named_const(NULL, 1, "OsmoBTS context"); @@ -184,7 +348,12 @@ int main(int argc, char **argv) osmo_init_logging2(tall_bts_ctx, &bts_log_info); - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) { + fprintf(stderr, "Failed to create BTS Site Manager structure\n"); + exit(1); + } + bts = gsm_bts_alloc(g_bts_sm, 0); if (bts_init(bts) < 0) { fprintf(stderr, "unable to open bts\n"); exit(1); @@ -193,6 +362,9 @@ int main(int argc, char **argv) test_paging_smoke(); test_paging_sleep(); test_is_ccch_for_agch(); + test_paging_rest_octets1(); + test_paging_rest_octets2(); + test_paging_rest_octets3(); printf("Success\n"); return 0; diff --git a/tests/power/Makefile.am b/tests/power/Makefile.am index e428178a..81f3f2a5 100644 --- a/tests/power/Makefile.am +++ b/tests/power/Makefile.am @@ -1,8 +1,24 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) -noinst_PROGRAMS = ms_power_loop_test bs_power_loop_test +check_PROGRAMS = ms_power_loop_test bs_power_loop_test EXTRA_DIST = ms_power_loop_test.ok ms_power_loop_test.err \ bs_power_loop_test.ok bs_power_loop_test.err diff --git a/tests/power/bs_power_loop_test.c b/tests/power/bs_power_loop_test.c index 53fdbba6..8fbdcee6 100644 --- a/tests/power/bs_power_loop_test.c +++ b/tests/power/bs_power_loop_test.c @@ -1,5 +1,5 @@ /* - * (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 @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -47,14 +47,8 @@ { DL_MEAS_FULL(rxqual, rxlev), \ DL_MEAS_SUB(rxqual, rxlev) } -#define DL_MEAS_FULL_SUB_INV(rxqual, rxlev) \ - { DL_MEAS_FULL(rxqual, rxlev), \ - DL_MEAS_SUB(rxqual, rxlev), \ - .invalid = true } - enum power_test_step_type { PWR_TEST_ST_IND_MEAS = 0, - PWR_TEST_ST_IND_DUMMY, PWR_TEST_ST_SET_STATE, PWR_TEST_ST_SET_CTRL_INTERVAL, PWR_TEST_ST_SET_STEP_SIZE, @@ -78,7 +72,6 @@ struct power_test_step { uint8_t rxqual_sub; uint8_t rxlev_full; uint8_t rxlev_sub; - bool invalid; } meas; /* Increase / reduce step size */ struct { @@ -112,31 +105,32 @@ static void init_test(const char *name) g_bts->band = GSM_BAND_900; g_bts->c0 = g_trx; + /* Init defaultBS power control parameters, enable dynamic power control */ + struct gsm_power_ctrl_params *params = &g_trx->ts[0].lchan[0].bs_dpc_params; + g_trx->ts[0].lchan[0].bs_power_ctrl.dpc_params = params; + *params = power_ctrl_params_def; + + /* Disable loop SACCH block skip by default: */ + params->ctrl_interval = 0; + printf("\nStarting test case '%s'\n", name); } -static void enc_meas_rep(struct gsm48_hdr *gh, +static void enc_meas_rep(struct gsm48_meas_res *mr, const unsigned int n, const struct power_test_step *step) { - struct gsm48_meas_res *mr = (struct gsm48_meas_res *) gh->data; - - gh->proto_discr = GSM48_PDISC_RR; - gh->msg_type = GSM48_MT_RR_MEAS_REP; - *mr = (struct gsm48_meas_res) { .rxlev_full = step->meas.rxlev_full, .rxlev_sub = step->meas.rxlev_sub, .rxqual_full = step->meas.rxqual_full, .rxqual_sub = step->meas.rxqual_sub, - /* NOTE: inversed logic (1 means invalid) */ - .meas_valid = step->meas.invalid, }; - printf("#%02u %s() -> Measurement Results (%svalid): " + printf("#%02u %s() -> Measurement Results (valid): " "RXLEV-FULL(%02u), RXQUAL-FULL(%u), " "RXLEV-SUB(%02u), RXQUAL-SUB(%u)\n", - n, __func__, step->meas.invalid ? "in" : "", + n, __func__, mr->rxlev_full, mr->rxqual_full, mr->rxlev_sub, mr->rxqual_sub); } @@ -145,11 +139,8 @@ static int exec_power_step(struct gsm_lchan *lchan, const unsigned int n, const struct power_test_step *step) { - struct gsm48_hdr *gh; + struct gsm48_meas_res mr; uint8_t old, new; - uint8_t buf[18]; - - gh = (struct gsm48_hdr *) buf; switch (step->type) { case PWR_TEST_ST_SET_STATE: @@ -184,20 +175,16 @@ static int exec_power_step(struct gsm_lchan *lchan, printf("#%02u %s() <- Enable DTXd\n", n, __func__); lchan->tch.dtx.dl_active = true; return 0; /* we're done */ - case PWR_TEST_ST_IND_DUMMY: - printf("#%02u %s() <- Dummy block\n", n, __func__); - memset(buf, 0x2b, sizeof(buf)); - break; case PWR_TEST_ST_IND_MEAS: - enc_meas_rep(gh, n, step); + enc_meas_rep(&mr, n, step); break; } - printf("#%02u lchan_bs_pwr_ctrl() <- UL SACCH: %s\n", - n, osmo_hexdump(buf, sizeof(buf))); + printf("#%02u lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 %s\n", + n, osmo_hexdump((void *)&mr, sizeof(mr))); old = lchan->bs_power_ctrl.current; - lchan_bs_pwr_ctrl(lchan, gh); + lchan_bs_pwr_ctrl(lchan, &mr); new = lchan->bs_power_ctrl.current; printf("#%02u lchan_bs_pwr_ctrl() -> BS power reduction: " @@ -219,9 +206,6 @@ static void exec_power_test(const struct power_test_step *steps, struct gsm_lchan *lchan = &g_trx->ts[0].lchan[0]; struct gsm_power_ctrl_params *params = &lchan->bs_dpc_params; - /* Default BS power control parameters */ - memcpy(params, &power_ctrl_params_def, sizeof(*params)); - /* No RxLev hysteresis: lower == upper */ params->rxlev_meas.lower_thresh = PWR_TEST_RXLEV_TARGET; params->rxlev_meas.upper_thresh = PWR_TEST_RXLEV_TARGET; @@ -401,24 +385,6 @@ static const struct power_test_step TC_rxqual_ber[] = { { .meas = DL_MEAS_FULL_SUB(7, PWR_TEST_RXLEV_TARGET) }, /* max */ }; -/* Verify that invalid and dummy SACCH blocks are ignored. */ -static const struct power_test_step TC_inval_dummy[] = { - /* Initial state: 16 dB, up to 20 dB */ - { .type = PWR_TEST_ST_SET_STATE, - .state = { .current = 16, .max = 2 * 10 } }, - - /* MS sends invalid measurement results which must be ignored */ - { .meas = DL_MEAS_FULL_SUB_INV(7, 63), .exp_txred = 16 }, - { .meas = DL_MEAS_FULL_SUB_INV(0, 0), .exp_txred = 16 }, - - /* Let's say SMS (SAPI=3) blocks substitute some of the reports */ - { .meas = DL_MEAS_FULL_SUB(0, PWR_TEST_RXLEV_TARGET), .exp_txred = 16 }, - { .type = PWR_TEST_ST_IND_DUMMY, /* not a report */ .exp_txred = 16 }, - { .meas = DL_MEAS_FULL_SUB(0, PWR_TEST_RXLEV_TARGET), .exp_txred = 16 }, - { .type = PWR_TEST_ST_IND_DUMMY, /* not a report */ .exp_txred = 16 }, - { .meas = DL_MEAS_FULL_SUB(0, PWR_TEST_RXLEV_TARGET), .exp_txred = 16 }, -}; - /* Verify handling of optional power control interval (P_Con_INTERVAL). */ static const struct power_test_step TC_ctrl_interval[] = { /* Initial state: 0 dB, up to 20 dB */ @@ -540,7 +506,6 @@ int main(int argc, char **argv) exec_test(TC_dtxd_mode); exec_test(TC_rxqual_ber); - exec_test(TC_inval_dummy); exec_test(TC_ctrl_interval); exec_test(TC_rxlev_hyst); diff --git a/tests/power/bs_power_loop_test.err b/tests/power/bs_power_loop_test.err index c4726b1b..24107ba9 100644 --- a/tests/power/bs_power_loop_test.err +++ b/tests/power/bs_power_loop_test.err @@ -1,196 +1,191 @@ (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 0 -> 2 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 0 dB => 2 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 2 -> 4 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 2 dB => 4 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 6 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 4 dB => 6 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 6 -> 8 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 6 dB => 8 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 10 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 8 dB => 10 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 10 -> 12 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 10 dB => 12 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 12 -> 14 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 12 dB => 14 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 14 -> 16 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 14 dB => 16 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 16 -> 18 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 16 dB => 18 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 18 -> 20 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 18 dB => 20 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 20 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 20 dB: max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 20 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 20 dB: max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 20 -> 16 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 20 dB => 16 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 16 -> 12 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 16 dB => 12 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 12 -> 8 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 12 dB => 8 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 4 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 8 dB => 4 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 0 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 4 dB => 0 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 0 -> 4 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 0 dB => 4 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 8 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 4 dB => 8 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 12 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 8 dB => 12 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 12 -> 16 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 12 dB => 16 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 16 -> 20 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 16 dB => 20 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 20 dB (maximum 20 dB, suggested delta 4 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 20 dB: max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 20 -> 14 dB (maximum 20 dB, suggested delta -6 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 20 dB => 14 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 14 -> 8 dB (maximum 20 dB, suggested delta -6 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 14 dB => 8 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 2 dB (maximum 20 dB, suggested delta -6 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 8 dB => 2 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 2 -> 0 dB (maximum 20 dB, suggested delta -6 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 2 dB => 0 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta -6 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(31), RXQUAL-FULL(0), RXLEV-SUB(31), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 10 -> 11 dB (maximum 20 dB, suggested delta 1 dB, RxLev current 31 (-79 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 10 dB => 11 dB:max 20 dB, RSSI[curr -79, avg -79, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 11 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 11 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(32), RXQUAL-FULL(0), RXLEV-SUB(32), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 11 -> 13 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 32 (-78 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 11 dB => 13 dB:max 20 dB, RSSI[curr -78, avg -78, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 13 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 13 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(33), RXQUAL-FULL(0), RXLEV-SUB(33), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 13 -> 16 dB (maximum 20 dB, suggested delta 3 dB, RxLev current 33 (-77 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 13 dB => 16 dB:max 20 dB, RSSI[curr -77, avg -77, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(29), RXQUAL-FULL(0), RXLEV-SUB(29), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 10 -> 9 dB (maximum 20 dB, suggested delta -1 dB, RxLev current 29 (-81 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 10 dB => 9 dB:max 20 dB, RSSI[curr -81, avg -81, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 9 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 9 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(27), RXQUAL-FULL(0), RXLEV-SUB(27), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 9 -> 6 dB (maximum 20 dB, suggested delta -3 dB, RxLev current 27 (-83 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 9 dB => 6 dB:max 20 dB, RSSI[curr -83, avg -83, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 6 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 6 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(25), RXQUAL-FULL(0), RXLEV-SUB(25), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 6 -> 1 dB (maximum 20 dB, suggested delta -5 dB, RxLev current 25 (-85 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 6 dB => 1 dB:max 20 dB, RSSI[curr -85, avg -85, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 1 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 1 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(00), RXQUAL-FULL(7), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is enabled => using SUB -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(3), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is enabled => using SUB -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(63), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is enabled => using SUB -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 0 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(1), RXLEV-SUB(30), RXQUAL-SUB(1), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 1, avg 1, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(2), RXLEV-SUB(30), RXQUAL-SUB(2), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 2, avg 2, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(3), RXLEV-SUB(30), RXQUAL-SUB(3), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 3, avg 3, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(4), RXLEV-SUB(30), RXQUAL-SUB(4), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Reducing Downlink attenuation: 16 -> 12 dB due to RxQual 4 worse than L_RXQUAL_XX_P 3 +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 16 dB => 12 dB:max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 4, avg 4, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(34), RXQUAL-FULL(5), RXLEV-SUB(34), RXQUAL-SUB(5), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Reducing Downlink attenuation: 12 -> 8 dB due to RxQual 5 worse than L_RXQUAL_XX_P 3 +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 12 dB => 8 dB:max 20 dB, RSSI[curr -76, avg -76, thresh -80..-80] dBm, RxQual[curr 5, avg 5, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(38), RXQUAL-FULL(6), RXLEV-SUB(38), RXQUAL-SUB(6), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Reducing Downlink attenuation: 8 -> 4 dB due to RxQual 6 worse than L_RXQUAL_XX_P 3 +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 8 dB => 4 dB:max 20 dB, RSSI[curr -72, avg -72, thresh -80..-80] dBm, RxQual[curr 6, avg 6, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(42), RXQUAL-FULL(7), RXLEV-SUB(42), RXQUAL-SUB(7), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Reducing Downlink attenuation: 4 -> 0 dB due to RxQual 7 worse than L_RXQUAL_XX_P 3 +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 4 dB => 0 dB:max 20 dB, RSSI[curr -68, avg -68, thresh -80..-80] dBm, RxQual[curr 7, avg 7, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(46), RXQUAL-FULL(7), RXLEV-SUB(46), RXQUAL-SUB(7), DTx is disabled => using FULL +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -64, avg -64, thresh -80..-80] dBm, RxQual[curr 7, avg 7, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(46), RXQUAL-FULL(0), RXLEV-SUB(46), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 0 -> 2 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 46 (-64 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 0 dB => 2 dB:max 20 dB, RSSI[curr -64, avg -64, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(44), RXQUAL-FULL(0), RXLEV-SUB(44), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 2 -> 4 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 44 (-66 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 2 dB => 4 dB:max 20 dB, RSSI[curr -66, avg -66, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(42), RXQUAL-FULL(0), RXLEV-SUB(42), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 6 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 42 (-68 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 4 dB => 6 dB:max 20 dB, RSSI[curr -68, avg -68, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(7), RXLEV-SUB(30), RXQUAL-SUB(7), DTx is disabled => using FULL +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 7, avg 7, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(7), RXLEV-SUB(30), RXQUAL-SUB(7), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) The measurement results are not valid -(bts=0,trx=0,ts=0,ss=0) The measurement results are not valid -(bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) -(bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) -(bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 20 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 0 dB: max 20 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 7, avg 7, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 0 -> 2 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 0 dB => 2 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 2 -> 4 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 2 dB => 4 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 6 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 4 dB => 6 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 6 -> 8 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 6 dB => 8 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 4 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 8 dB => 4 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 0 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 4 dB => 0 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 0 -> 2 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 0 dB => 2 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 2 -> 4 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 2 dB => 4 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 6 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 4 dB => 6 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 6 -> 8 dB (maximum 20 dB, suggested delta 2 dB, RxLev current 60 (-50 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 6 dB => 8 dB:max 20 dB, RSSI[curr -50, avg -50, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(60), RXQUAL-FULL(0), RXLEV-SUB(60), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 8 -> 4 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 8 dB => 4 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(10), RXQUAL-FULL(0), RXLEV-SUB(10), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 4 -> 0 dB (maximum 20 dB, suggested delta -4 dB, RxLev current 10 (-100 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 4 dB => 0 dB:max 20 dB, RSSI[curr -100, avg -100, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(31), RXQUAL-FULL(0), RXLEV-SUB(31), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 12 -> 13 dB (maximum 16 dB, suggested delta 1 dB, RxLev current 31 (-79 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 12 dB => 13 dB:max 16 dB, RSSI[curr -79, avg -79, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(28), RXQUAL-FULL(0), RXLEV-SUB(28), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 13 -> 11 dB (maximum 16 dB, suggested delta -2 dB, RxLev current 28 (-82 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 13 dB => 11 dB:max 16 dB, RSSI[curr -82, avg -82, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(33), RXQUAL-FULL(0), RXLEV-SUB(33), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 11 -> 13 dB (maximum 16 dB, suggested delta 2 dB, RxLev current 33 (-77 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 11 dB => 13 dB:max 16 dB, RSSI[curr -77, avg -77, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(28), RXQUAL-FULL(0), RXLEV-SUB(28), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 13 -> 11 dB (maximum 16 dB, suggested delta -2 dB, RxLev current 28 (-82 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 13 dB => 11 dB:max 16 dB, RSSI[curr -82, avg -82, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(31), RXQUAL-FULL(0), RXLEV-SUB(31), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 11 dB (maximum 16 dB, suggested delta 0 dB, RxLev current 31 (-79 dBm), thresholds 27 .. 33) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 11 dB: max 16 dB, RSSI[curr -79, avg -79, thresh -83..-77] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(28), RXQUAL-FULL(0), RXLEV-SUB(28), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 11 dB (maximum 16 dB, suggested delta 0 dB, RxLev current 28 (-82 dBm), thresholds 27 .. 33) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 11 dB: max 16 dB, RSSI[curr -82, avg -82, thresh -83..-77] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(33), RXQUAL-FULL(0), RXLEV-SUB(33), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 11 dB (maximum 16 dB, suggested delta 0 dB, RxLev current 33 (-77 dBm), thresholds 27 .. 33) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 11 dB: max 16 dB, RSSI[curr -77, avg -77, thresh -83..-77] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(28), RXQUAL-FULL(0), RXLEV-SUB(28), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 11 dB (maximum 16 dB, suggested delta 0 dB, RxLev current 28 (-82 dBm), thresholds 27 .. 33) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 11 dB: max 16 dB, RSSI[curr -82, avg -82, thresh -83..-77] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 30 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 30 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Keeping Downlink attenuation at 16 dB (maximum 30 dB, suggested delta 0 dB, RxLev current 30 (-80 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Keeping DL attenuation at 16 dB: max 30 dB, RSSI[curr -80, avg -80, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(26), RXQUAL-FULL(0), RXLEV-SUB(26), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 16 -> 14 dB (maximum 30 dB, suggested delta -2 dB, RxLev current 26 (-84 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 16 dB => 14 dB:max 30 dB, RSSI[curr -84, avg -82, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(26), RXQUAL-FULL(0), RXLEV-SUB(26), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 14 -> 11 dB (maximum 30 dB, suggested delta -3 dB, RxLev current 26 (-84 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Lowering DL attenuation 14 dB => 11 dB:max 30 dB, RSSI[curr -84, avg -83, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(35), RXQUAL-FULL(0), RXLEV-SUB(35), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 11 -> 12 dB (maximum 30 dB, suggested delta 1 dB, RxLev current 35 (-75 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 11 dB => 12 dB:max 30 dB, RSSI[curr -75, avg -79, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] (bts=0,trx=0,ts=0,ss=0) Rx DL Measurement Report: RXLEV-FULL(35), RXQUAL-FULL(0), RXLEV-SUB(35), RXQUAL-SUB(0), DTx is disabled => using FULL -(bts=0,trx=0,ts=0,ss=0) Changing Downlink attenuation: 12 -> 14 dB (maximum 30 dB, suggested delta 2 dB, RxLev current 35 (-75 dBm), thresholds 30 .. 30) +(bts=0,trx=0,ts=0,ss=0) Raising DL attenuation 12 dB => 14 dB:max 30 dB, RSSI[curr -75, avg -77, thresh -80..-80] dBm, RxQual[curr 0, avg 0, thresh 3..0] diff --git a/tests/power/bs_power_loop_test.ok b/tests/power/bs_power_loop_test.ok index 2c123928..18a94ba7 100644 --- a/tests/power/bs_power_loop_test.ok +++ b/tests/power/bs_power_loop_test.ok @@ -243,31 +243,6 @@ Starting test case 'TC_rxqual_ber' #16 lchan_bs_pwr_ctrl() -> BS power reduction: 0 -> 0 (expected 0) Test case verdict: SUCCESS -Starting test case 'TC_inval_dummy' -#00 exec_power_step() <- State (re)set (current 16 dB, max 20 dB) -#01 enc_meas_rep() -> Measurement Results (invalid): RXLEV-FULL(63), RXQUAL-FULL(7), RXLEV-SUB(63), RXQUAL-SUB(7) -#01 lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 3f 7f 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 -#01 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#02 enc_meas_rep() -> Measurement Results (invalid): RXLEV-FULL(00), RXQUAL-FULL(0), RXLEV-SUB(00), RXQUAL-SUB(0) -#02 lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#02 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#03 enc_meas_rep() -> Measurement Results (valid): RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0) -#03 lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 1e 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#03 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#04 exec_power_step() <- Dummy block -#04 lchan_bs_pwr_ctrl() <- UL SACCH: 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b -#04 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#05 enc_meas_rep() -> Measurement Results (valid): RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0) -#05 lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 1e 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#05 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#06 exec_power_step() <- Dummy block -#06 lchan_bs_pwr_ctrl() <- UL SACCH: 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b 2b -#06 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -#07 enc_meas_rep() -> Measurement Results (valid): RXLEV-FULL(30), RXQUAL-FULL(0), RXLEV-SUB(30), RXQUAL-SUB(0) -#07 lchan_bs_pwr_ctrl() <- UL SACCH: 06 15 1e 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -#07 lchan_bs_pwr_ctrl() -> BS power reduction: 16 -> 16 (expected 16) -Test case verdict: SUCCESS - Starting test case 'TC_ctrl_interval' #00 exec_power_step() <- State (re)set (current 0 dB, max 20 dB) #01 exec_power_step() <- (Re)set power control interval: 0 -> 0 diff --git a/tests/power/ms_power_loop_test.c b/tests/power/ms_power_loop_test.c index 0d863108..47df68e2 100644 --- a/tests/power/ms_power_loop_test.c +++ b/tests/power/ms_power_loop_test.c @@ -1,6 +1,6 @@ /* * (C) 2013,2014 by Holger Hans Peter Freyther - * Contributions by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * Contributions by sysmocom - s.f.m.c. GmbH <info@sysmocom.de> * * All Rights Reserved * @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -59,6 +59,9 @@ static void init_test(const char *name) g_trx->ts[0].lchan[0].ms_power_ctrl.dpc_params = params; *params = power_ctrl_params_def; + /* Disable loop SACCH block skip by default: */ + params->ctrl_interval = 0; + /* Disable RxLev pre-processing and hysteresis by default */ struct gsm_power_ctrl_meas_params *mp = ¶ms->rxlev_meas; mp->lower_thresh = mp->upper_thresh = PWR_TEST_RXLEV_TARGET; @@ -67,13 +70,11 @@ static void init_test(const char *name) printf("\nStarting test case '%s'\n", name); } -static inline void apply_power_test(struct gsm_lchan *lchan, int rxlev, int exp_ret, uint8_t exp_current) +static void apply_power_test_ext(struct gsm_lchan *lchan, uint8_t ms_pwr, int rxlev, int lqual_cb, int exp_ret, uint8_t exp_current) { - uint8_t old; int ret; - old = lchan->ms_power_ctrl.current; - ret = lchan_ms_pwr_ctrl(lchan, lchan->ms_power_ctrl.current, rxlev); + ret = lchan_ms_pwr_ctrl(lchan, ms_pwr, rxlev, lqual_cb); /* Keep the measurement counter updated */ lchan->meas.res_nr++; @@ -81,15 +82,25 @@ static inline void apply_power_test(struct gsm_lchan *lchan, int rxlev, int exp_ printf("lchan_ms_pwr_ctrl(RxLvl=%d dBm) returns %d (expected %d)\n", rxlev, ret, exp_ret); printf("\tMS current power %u -> %u (expected %u)\n", - old, lchan->ms_power_ctrl.current, exp_current); + ms_pwr, lchan->ms_power_ctrl.current, exp_current); +} + +static inline void apply_power_test(struct gsm_lchan *lchan, int rxlev, int lqual_cb, int exp_ret, uint8_t exp_current) +{ + apply_power_test_ext(lchan, lchan->ms_power_ctrl.current, rxlev, lqual_cb, exp_ret, exp_current); } static void test_power_loop(void) { struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual; init_test(__func__); lchan = &g_trx->ts[0].lchan[0]; + params = lchan->ms_power_ctrl.dpc_params; + lchan->type = GSM_LCHAN_SDCCH; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; lchan->ms_power_ctrl.current = ms_pwr_ctl_lvl(GSM_BAND_1800, 0); OSMO_ASSERT(lchan->ms_power_ctrl.current == 15); @@ -97,73 +108,78 @@ static void test_power_loop(void) OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); /* Simply clamping */ - apply_power_test(lchan, -60, 0, 15); + apply_power_test(lchan, -60, good_lqual, 0, 15); /* * Now 15 dB too little and we should power it up. Could be a * power level of 7 or 8 for 15 dBm. However, since we limit peace at * which we change values, expect several steps of MS_RAISE_MAX_DB/2 levels: */ - apply_power_test(lchan, -90, 1, 13); - apply_power_test(lchan, -90, 1, 11); - apply_power_test(lchan, -90, 1, 9); - apply_power_test(lchan, -90, 1, 7); - apply_power_test(lchan, -90, 1, 5); + apply_power_test(lchan, -90, good_lqual, 1, 13); + apply_power_test(lchan, -90, good_lqual, 1, 11); + apply_power_test(lchan, -90, good_lqual, 1, 9); + apply_power_test(lchan, -90, good_lqual, 1, 7); + apply_power_test(lchan, -90, good_lqual, 1, 5); /* Check good RSSI value keeps it at same power level: */ - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, 0, 5); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, good_lqual, 0, 5); - apply_power_test(lchan, -90, 1, 3); - apply_power_test(lchan, -90, 1, 2); /* .max is pwr lvl 2 */ - apply_power_test(lchan, -90, 0, 2); /* .max is pwr lvl 2 */ + apply_power_test(lchan, -90, good_lqual, 1, 3); + apply_power_test(lchan, -90, good_lqual, 1, 2); /* .max is pwr lvl 2 */ + apply_power_test(lchan, -90, good_lqual, 0, 2); /* .max is pwr lvl 2 */ lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 30); OSMO_ASSERT(lchan->ms_power_ctrl.max == 0); - apply_power_test(lchan, -90, 1, 0); /* .max is pwr lvl 0 */ - apply_power_test(lchan, -90, 0, 0); /* .max is pwr lvl 0 */ + apply_power_test(lchan, -90, good_lqual, 1, 0); /* .max is pwr lvl 0 */ + apply_power_test(lchan, -90, good_lqual, 0, 0); /* .max is pwr lvl 0 */ lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 36); OSMO_ASSERT(lchan->ms_power_ctrl.max == 29); - apply_power_test(lchan, -90, 1, 30); - apply_power_test(lchan, -90, 1, 29); - apply_power_test(lchan, -90, 0, 29); + apply_power_test(lchan, -90, good_lqual, 1, 30); + apply_power_test(lchan, -90, good_lqual, 1, 29); + apply_power_test(lchan, -90, good_lqual, 0, 29); /* Check good RSSI value keeps it at same power level: */ - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, 0, 29); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, good_lqual, 0, 29); /* Now go down, steps are double size in this direction: */ - apply_power_test(lchan, -45, 1, 1); - apply_power_test(lchan, -45, 1, 5); - apply_power_test(lchan, -45, 1, 9); + apply_power_test(lchan, -45, good_lqual, 1, 1); + apply_power_test(lchan, -45, good_lqual, 1, 5); + apply_power_test(lchan, -45, good_lqual, 1, 9); /* Go down only one level down and up: */ - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 2, 1, 10); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 2, 1, 9); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 2, good_lqual, 1, 10); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 2, good_lqual, 1, 9); /* Check if BSC requesting a low max power is applied after loop calculation: */ lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 2); OSMO_ASSERT(lchan->ms_power_ctrl.max == 14); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 2, 1, 14); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 2, good_lqual, 1, 14); /* Set back a more normal max: */ lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 30); OSMO_ASSERT(lchan->ms_power_ctrl.max == 0); /* Disable dynamic power control and jump down */ lchan->ms_power_ctrl.dpc_params = NULL; - apply_power_test(lchan, -60, 0, 14); + apply_power_test(lchan, -60, good_lqual, 0, 14); /* Enable and leave it again */ lchan->ms_power_ctrl.dpc_params = &lchan->ms_dpc_params; - apply_power_test(lchan, -40, 1, 15); + apply_power_test(lchan, -40, good_lqual, 1, 15); } static void test_pf_algo_ewma(void) { struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual; const int *avg100; init_test(__func__); lchan = &g_trx->ts[0].lchan[0]; + lchan->type = GSM_LCHAN_SDCCH; + params = lchan->ms_power_ctrl.dpc_params; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; avg100 = &lchan->ms_power_ctrl.rxlev_meas_proc.ewma.Avg100; struct gsm_power_ctrl_meas_params *mp = &lchan->ms_dpc_params.rxlev_meas; @@ -175,32 +191,30 @@ static void test_pf_algo_ewma(void) lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26); OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); -#define CHECK_UL_RSSI_AVG100(exp) \ - printf("\tAvg[t] is %2.2f dBm (expected %2.2f dBm)\n", \ +#define CHECK_RXLEV_AVG100(exp) \ + printf("\tAvg[t] is RxLev %2.2f (expected %2.2f)\n", \ ((float) *avg100) / 100, exp); /* UL RSSI remains constant => no UL power change */ - apply_power_test(lchan, -75, 0, 15); - CHECK_UL_RSSI_AVG100(-75.00); + apply_power_test(lchan, -75, good_lqual, 0, 15); + CHECK_RXLEV_AVG100((float)dbm2rxlev(-75)); /* RXLEV 35 */ - /* Avg[t] = (0.2 * -90) + (0.8 * -75) = -78.0 dBm */ - apply_power_test(lchan, -90, 1, 13); - CHECK_UL_RSSI_AVG100(-78.00); + /* Avg[t] = (0.2 * 20) + (0.8 * 35) = RXLEV 32, (-78 dBm) */ + apply_power_test(lchan, -90, good_lqual, 1, 13); /* -90 dBm = RXLEV 20 */ + CHECK_RXLEV_AVG100(32.00); - /* Avg[t] = (0.2 * -90) + (0.8 * -78) = -80.4 dBm */ - apply_power_test(lchan, -90, 1, 11); - CHECK_UL_RSSI_AVG100(-80.40); + /* Avg[t] = (0.2 * 20) + (0.8 * 32) = RXLEV 29.6 (-80.4 dBm) */ + apply_power_test(lchan, -90, good_lqual, 1, 11); /* -90 dBm = RXLEV 20 */ + CHECK_RXLEV_AVG100(29.60); - /* Avg[t] = (0.2 * -70) + (0.8 * -80.4) = -78.32 dBm, + /* Avg[t] = (0.2 * 40) + (0.8 * 29.60) = RXLEV 31.68 (-78.32 dBm), * but due to up-/down-scaling artefacts we get the following: * Avg100[t] = Avg100[t - 1] + A * (Pwr - Avg[t] / 100) - * Avg100[t] = -8040 + 20 * (-70 - (-8040 / 100)) - * Avg100[t] = -8040 + 20 * (-70 - (-8040 / 100)) - * Avg100[t] = -8040 + 20 * (-70 + 80) - * Avg100[t] = -8040 + 200 = -7840 - * Avg[t] = -7840 / 100 = -78.4 */ - apply_power_test(lchan, -70, 1, 9); - CHECK_UL_RSSI_AVG100(-78.40); + * Avg100[t] = 2960 + 20 * (40 - ((2960+50) / 100)) <- HERE we lose 0.1: (2960+50) / 100) = 30.1 + * Avg100[t] = 2960 + 20 * (40 - 30) <- HERE we lose 20*0.1 = 2.0! (upscaled, hence we lose finally 2.0/100=0.2) + * Avg[t] = (3160) / 100 = 31.60*/ + apply_power_test(lchan, -70, good_lqual, 1, 9); /* RXLEV 40 */ + CHECK_RXLEV_AVG100(31.60); mp->ewma.alpha = 70; /* 30% smoothing */ lchan->ms_power_ctrl.current = 15; @@ -208,25 +222,30 @@ static void test_pf_algo_ewma(void) (struct gsm_power_ctrl_meas_proc_state) { 0 }; /* This is the first sample, the filter outputs it as-is */ - apply_power_test(lchan, -50, 0, 15); - CHECK_UL_RSSI_AVG100(-50.00); + apply_power_test(lchan, -50, good_lqual, 0, 15); /* RXLEV 60 */ + CHECK_RXLEV_AVG100((float)dbm2rxlev(-50)); - /* Avg[t] = (0.7 * -50) + (0.3 * -50) = -50.0 dBm */ - apply_power_test(lchan, -50, 0, 15); - CHECK_UL_RSSI_AVG100(-50.0); + /* Avg[t] = (0.7 * 60) + (0.3 * 60) = RXLEV 60 (-50.0 dBm) */ + apply_power_test(lchan, -50, good_lqual, 0, 15); + CHECK_RXLEV_AVG100((float)dbm2rxlev(-50)); /* Simulate SACCH block loss (-110 dBm): - * Avg[t] = (0.7 * -110) + (0.3 * -50) = -92.0 dBm */ - apply_power_test(lchan, -110, 1, 13); - CHECK_UL_RSSI_AVG100(-92.0); + * Avg[t] = (0.7 * 0) + (0.3 * 60) = RXLEV 18.0 (-92.0 dBm) */ + apply_power_test(lchan, -110, good_lqual, 1, 13); /* RXLEV 0 */ + CHECK_RXLEV_AVG100(18.0); } static void test_power_hysteresis(void) { struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual; init_test(__func__); lchan = &g_trx->ts[0].lchan[0]; + lchan->type = GSM_LCHAN_SDCCH; + params = lchan->ms_power_ctrl.dpc_params; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; /* Tolerate power deviations in range -80 .. -70 */ lchan->ms_dpc_params.rxlev_meas.lower_thresh = 30; @@ -237,61 +256,66 @@ static void test_power_hysteresis(void) lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26); OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 3, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 3, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, good_lqual, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 3, good_lqual, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 3, good_lqual, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 5, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 5, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM, good_lqual, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM + 5, good_lqual, 0, 15); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 5, good_lqual, 0, 15); - apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 10, 1, 13); + apply_power_test(lchan, PWR_TEST_RXLEV_TARGET_DBM - 10, good_lqual, 1, 13); } static void test_power_ctrl_interval(void) { struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual; unsigned int i, j; init_test(__func__); lchan = &g_trx->ts[0].lchan[0]; + lchan->type = GSM_LCHAN_SDCCH; + params = lchan->ms_power_ctrl.dpc_params; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26); OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); - static const int script[][8][3] = { + const int script[][8][4] = { { /* P_Con_INTERVAL=0 (480 ms) */ /* { UL RxLev, expected rc, expected Tx power level } */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 13 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 11 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 9 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 7 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 5 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 3 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 2 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 2 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 13 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 11 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 9 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 7 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 5 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 3 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 2 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 2 }, }, { /* P_Con_INTERVAL=1 (960 ms) */ /* { UL RxLev, expected rc, expected Tx power level } */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 13 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 13 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 11 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 11 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 9 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 9 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 7 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 7 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 13 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 13 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 11 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 11 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 9 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 9 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 7 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 7 }, /* skipped */ }, { /* P_Con_INTERVAL=2 (1920 ms) */ /* { UL RxLev, expected rc, expected Tx power level } */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 13 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 13 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 13 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 13 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 1, 11 }, - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 11 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 11 }, /* skipped */ - { PWR_TEST_RXLEV_TARGET_DBM - 15, 0, 11 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 13 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 13 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 13 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 13 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 1, 11 }, + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 11 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 11 }, /* skipped */ + { PWR_TEST_RXLEV_TARGET_DBM - 15, good_lqual, 0, 11 }, /* skipped */ }, }; @@ -305,14 +329,82 @@ static void test_power_ctrl_interval(void) for (j = 0; j < ARRAY_SIZE(script[i]); j++) { apply_power_test(lchan, script[i][j][0], /* UL RxLev */ - script[i][j][1], /* expected rc */ - script[i][j][2]); /* expected Tx power level */ + script[i][j][1], /* UL C/I */ + script[i][j][2], /* expected rc */ + script[i][j][3]); /* expected Tx power level */ } printf("\n"); } } +static void test_power_loop_ci(void) +{ + struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual, too_low_lqual, too_high_lqual; + + init_test(__func__); + lchan = &g_trx->ts[0].lchan[0]; + params = lchan->ms_power_ctrl.dpc_params; + lchan->type = GSM_LCHAN_SDCCH; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; + too_low_lqual = (params->ci_sdcch_meas.lower_thresh - 1) * 10; + too_high_lqual = (params->ci_sdcch_meas.upper_thresh + 1) * 10; + + lchan->ms_power_ctrl.current = ms_pwr_ctl_lvl(GSM_BAND_1800, 0); + OSMO_ASSERT(lchan->ms_power_ctrl.current == 15); + lchan->ms_power_ctrl.max = ms_pwr_ctl_lvl(GSM_BAND_1800, 26); + OSMO_ASSERT(lchan->ms_power_ctrl.max == 2); + + /* Simply clamping */ + apply_power_test(lchan, -60, good_lqual, 0, 15); + + /* Now UL C/I is too bad as well as RSSI: */ + apply_power_test(lchan, -100, too_low_lqual, 1, 13); + apply_power_test(lchan, -100, too_low_lqual, 1, 11); + + /* Now UL C/I is good again while RSSI is good: */ + apply_power_test(lchan, -60, good_lqual, 1, 12); + apply_power_test(lchan, -60, too_high_lqual, 1, 13); + + /* Now UL C/I is good while RSSI is bad, C/I mandates: */ + apply_power_test(lchan, -100, good_lqual, 1, 11); + apply_power_test(lchan, -100, too_high_lqual, 1, 12); + + /* Now UL C/I is bad again while RSSI is good, C/I mandates: */ + apply_power_test(lchan, -60, good_lqual, 1, 13); + apply_power_test(lchan, -60, too_high_lqual, 1, 14); +} + +/* Test whether ping pong between requested MS Power Level and announced MS + * Power level occurs, oscillating between considered good levels all the time: + * FIXME: Current code shows there's an issue with oscillating values. */ +static void test_good_threshold_convergence(void) +{ + struct gsm_lchan *lchan; + const struct gsm_power_ctrl_params *params; + int16_t good_lqual, good_rxlev; + + init_test(__func__); + lchan = &g_trx->ts[0].lchan[0]; + params = lchan->ms_power_ctrl.dpc_params; + lchan->ms_dpc_params.rxlev_meas.upper_thresh = 37; + lchan->ms_dpc_params.rxlev_meas.lower_thresh = 30; + lchan->type = GSM_LCHAN_SDCCH; + good_lqual = (params->ci_sdcch_meas.lower_thresh + 2) * 10; + good_rxlev = rxlev2dbm(params->rxlev_meas.lower_thresh + 2); + + lchan->ms_power_ctrl.current = 10; + lchan->ms_power_ctrl.max = 2; + + apply_power_test_ext(lchan, 9, good_rxlev, good_lqual, 0, 10); + apply_power_test_ext(lchan, 10, good_rxlev, good_lqual, 0, 10); + apply_power_test_ext(lchan, 9, good_rxlev, good_lqual, 0, 10); + apply_power_test_ext(lchan, 10, good_rxlev, good_lqual, 0, 10); + apply_power_test_ext(lchan, 9, good_rxlev, good_lqual, 0, 10); +} + int main(int argc, char **argv) { printf("Testing power loop...\n"); @@ -332,6 +424,8 @@ int main(int argc, char **argv) test_pf_algo_ewma(); test_power_hysteresis(); test_power_ctrl_interval(); + test_power_loop_ci(); + test_good_threshold_convergence(); printf("Power loop test OK\n"); diff --git a/tests/power/ms_power_loop_test.err b/tests/power/ms_power_loop_test.err index ae8ad033..07d90691 100644 --- a/tests/power/ms_power_loop_test.err +++ b/tests/power/ms_power_loop_test.err @@ -1,51 +1,65 @@ -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -60 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 13 (4 dBm) to 11, 8 dBm (rx-ms-pwr-lvl 13, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 11 (8 dBm) to 9, 12 dBm (rx-ms-pwr-lvl 11, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 9 (12 dBm) to 7, 16 dBm (rx-ms-pwr-lvl 9, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 7 (16 dBm) to 5, 20 dBm (rx-ms-pwr-lvl 7, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 5, 20 dBm (rx-ms-pwr-lvl 5, max-ms-pwr-lvl 2, rx-current -75 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 5 (20 dBm) to 3, 24 dBm (rx-ms-pwr-lvl 5, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 3 (24 dBm) to 2, 26 dBm (rx-ms-pwr-lvl 3, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 2, 26 dBm (rx-ms-pwr-lvl 2, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 2 (26 dBm) to 0, 30 dBm (rx-ms-pwr-lvl 2, max-ms-pwr-lvl 0, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 0, 30 dBm (rx-ms-pwr-lvl 0, max-ms-pwr-lvl 0, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 0 (30 dBm) to 30, 34 dBm (rx-ms-pwr-lvl 0, max-ms-pwr-lvl 29, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 30 (34 dBm) to 29, 36 dBm (rx-ms-pwr-lvl 30, max-ms-pwr-lvl 29, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 29, 36 dBm (rx-ms-pwr-lvl 29, max-ms-pwr-lvl 29, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 29, 36 dBm (rx-ms-pwr-lvl 29, max-ms-pwr-lvl 29, rx-current -75 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 29 (36 dBm) to 30, 34 dBm (rx-ms-pwr-lvl 29, max-ms-pwr-lvl 29, rx-current -45 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 30 (34 dBm) to 31, 32 dBm (rx-ms-pwr-lvl 30, max-ms-pwr-lvl 29, rx-current -45 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 31 (32 dBm) to 0, 30 dBm (rx-ms-pwr-lvl 31, max-ms-pwr-lvl 29, rx-current -45 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 0 (30 dBm) to 1, 28 dBm (rx-ms-pwr-lvl 0, max-ms-pwr-lvl 29, rx-current -73 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 1 (28 dBm) to 0, 30 dBm (rx-ms-pwr-lvl 1, max-ms-pwr-lvl 29, rx-current -77 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 0 (30 dBm) to 14, 2 dBm (rx-ms-pwr-lvl 0, max-ms-pwr-lvl 14, rx-current -73 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Lowering MS power from control level 14 (2 dBm) to 15, 0 dBm (rx-ms-pwr-lvl 14, max-ms-pwr-lvl 0, rx-current -40 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -75 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 3 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 13 (4 dBm) to 11, 8 dBm (rx-ms-pwr-lvl 13, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 11 (8 dBm) to 9, 11 dBm (rx-ms-pwr-lvl 11, max-ms-pwr-lvl 2, rx-current -70 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -50 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -50 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -110 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -75 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -72 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -78 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -75 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -70 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15, 0 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -80 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -85 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 13 (4 dBm) to 11, 8 dBm (rx-ms-pwr-lvl 13, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 11 (8 dBm) to 9, 12 dBm (rx-ms-pwr-lvl 11, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 9 (12 dBm) to 7, 16 dBm (rx-ms-pwr-lvl 9, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 7 (16 dBm) to 5, 20 dBm (rx-ms-pwr-lvl 7, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 5 (20 dBm) to 3, 24 dBm (rx-ms-pwr-lvl 5, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 3 (24 dBm) to 2, 26 dBm (rx-ms-pwr-lvl 3, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 2, 26 dBm (rx-ms-pwr-lvl 2, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 13 (4 dBm) to 11, 8 dBm (rx-ms-pwr-lvl 13, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 11 (8 dBm) to 9, 12 dBm (rx-ms-pwr-lvl 11, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 9 (12 dBm) to 7, 16 dBm (rx-ms-pwr-lvl 9, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 15 (0 dBm) to 13, 4 dBm (rx-ms-pwr-lvl 15, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) -(bts=0,trx=0,ts=0,ss=0) Raising MS power from control level 13 (4 dBm) to 11, 8 dBm (rx-ms-pwr-lvl 13, max-ms-pwr-lvl 2, rx-current -90 dBm, rx-target -75 dBm) +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (12 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 9 (12 dBm) => 7 (16 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 7 (16 dBm) => 5 (20 dBm): ms-pwr-lvl[curr 7, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 5 (20 dBm): ms-pwr-lvl[curr 5, max 2], RSSI[curr -75, avg -75, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 5 (20 dBm) => 3 (24 dBm): ms-pwr-lvl[curr 5, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 3 (24 dBm) => 2 (26 dBm): ms-pwr-lvl[curr 3, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 2 (26 dBm): ms-pwr-lvl[curr 2, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 2 (26 dBm) => 0 (30 dBm): ms-pwr-lvl[curr 2, max 0], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 0 (30 dBm): ms-pwr-lvl[curr 0, max 0], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 0 (30 dBm) => 30 (34 dBm): ms-pwr-lvl[curr 0, max 29], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 30 (34 dBm) => 29 (36 dBm): ms-pwr-lvl[curr 30, max 29], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 29 (36 dBm): ms-pwr-lvl[curr 29, max 29], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 29 (36 dBm): ms-pwr-lvl[curr 29, max 29], RSSI[curr -75, avg -75, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 29 (36 dBm) => 30 (34 dBm): ms-pwr-lvl[curr 29, max 29], RSSI[curr -45, avg -47, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 30 (34 dBm) => 31 (32 dBm): ms-pwr-lvl[curr 30, max 29], RSSI[curr -45, avg -47, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 31 (32 dBm) => 0 (30 dBm): ms-pwr-lvl[curr 31, max 29], RSSI[curr -45, avg -47, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 0 (30 dBm) => 1 (28 dBm): ms-pwr-lvl[curr 0, max 29], RSSI[curr -73, avg -73, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 1 (28 dBm) => 0 (30 dBm): ms-pwr-lvl[curr 1, max 29], RSSI[curr -77, avg -77, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 0 (30 dBm) => 14 (2 dBm): ms-pwr-lvl[curr 0, max 14], RSSI[curr -73, avg -73, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 14 (2 dBm) => 15 (0 dBm): ms-pwr-lvl[curr 14, max 0], RSSI[curr -40, avg -47, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -75, avg -75, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (3 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -78, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -80, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (11 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -70, avg -78, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -50, avg -50, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -50, avg -50, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -110, avg -92, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -75, avg -75, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -72, avg -72, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -78, avg -78, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -75, avg -75, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -70, avg -70, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -80, avg -80, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -85, avg -85, thresh -80..-70] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (12 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 9 (12 dBm) => 7 (16 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 7 (16 dBm) => 5 (20 dBm): ms-pwr-lvl[curr 7, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 5 (20 dBm) => 3 (24 dBm): ms-pwr-lvl[curr 5, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 3 (24 dBm) => 2 (26 dBm): ms-pwr-lvl[curr 3, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 2 (26 dBm): ms-pwr-lvl[curr 2, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 11 (8 dBm) => 9 (12 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 9 (12 dBm) => 7 (16 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -90, avg -90, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 15 (0 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 15 (0 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 15, max 2], RSSI[curr -100, avg -100, thresh -75..-75] dBm, C/I[curr 11, avg 11, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -100, avg -100, thresh -75..-75] dBm, C/I[curr 11, avg 11, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 11 (8 dBm) => 12 (6 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 12 (6 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 12, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 17, avg 17, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Raising MS power control level 13 (4 dBm) => 11 (8 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -100, avg -100, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 11 (8 dBm) => 12 (6 dBm): ms-pwr-lvl[curr 11, max 2], RSSI[curr -100, avg -100, thresh -75..-75] dBm, C/I[curr 17, avg 17, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 12 (6 dBm) => 13 (4 dBm): ms-pwr-lvl[curr 12, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Lowering MS power control level 13 (4 dBm) => 14 (2 dBm): ms-pwr-lvl[curr 13, max 2], RSSI[curr -60, avg -60, thresh -75..-75] dBm, C/I[curr 17, avg 17, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 9 (12 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -78, avg -78, thresh -80..-73] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 10 (10 dBm): ms-pwr-lvl[curr 10, max 2], RSSI[curr -78, avg -78, thresh -80..-73] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 9 (12 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -78, avg -78, thresh -80..-73] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 10 (10 dBm): ms-pwr-lvl[curr 10, max 2], RSSI[curr -78, avg -78, thresh -80..-73] dBm, C/I[curr 14, avg 14, thresh 12..16] dB +(bts=0,trx=0,ts=0,ss=0) Keeping MS power at control level 9 (12 dBm): ms-pwr-lvl[curr 9, max 2], RSSI[curr -78, avg -78, thresh -80..-73] dBm, C/I[curr 14, avg 14, thresh 12..16] dB diff --git a/tests/power/ms_power_loop_test.ok b/tests/power/ms_power_loop_test.ok index 5fea4747..09e19ad4 100644 --- a/tests/power/ms_power_loop_test.ok +++ b/tests/power/ms_power_loop_test.ok @@ -53,25 +53,25 @@ lchan_ms_pwr_ctrl(RxLvl=-40 dBm) returns 1 (expected 1) Starting test case 'test_pf_algo_ewma' lchan_ms_pwr_ctrl(RxLvl=-75 dBm) returns 0 (expected 0) MS current power 15 -> 15 (expected 15) - Avg[t] is -75.00 dBm (expected -75.00 dBm) + Avg[t] is RxLev 35.00 (expected 35.00) lchan_ms_pwr_ctrl(RxLvl=-90 dBm) returns 1 (expected 1) MS current power 15 -> 13 (expected 13) - Avg[t] is -78.00 dBm (expected -78.00 dBm) + Avg[t] is RxLev 32.00 (expected 32.00) lchan_ms_pwr_ctrl(RxLvl=-90 dBm) returns 1 (expected 1) MS current power 13 -> 11 (expected 11) - Avg[t] is -80.40 dBm (expected -80.40 dBm) + Avg[t] is RxLev 29.60 (expected 29.60) lchan_ms_pwr_ctrl(RxLvl=-70 dBm) returns 1 (expected 1) MS current power 11 -> 9 (expected 9) - Avg[t] is -78.40 dBm (expected -78.40 dBm) + Avg[t] is RxLev 31.60 (expected 31.60) lchan_ms_pwr_ctrl(RxLvl=-50 dBm) returns 0 (expected 0) MS current power 15 -> 15 (expected 15) - Avg[t] is -50.00 dBm (expected -50.00 dBm) + Avg[t] is RxLev 60.00 (expected 60.00) lchan_ms_pwr_ctrl(RxLvl=-50 dBm) returns 0 (expected 0) MS current power 15 -> 15 (expected 15) - Avg[t] is -50.00 dBm (expected -50.00 dBm) + Avg[t] is RxLev 60.00 (expected 60.00) lchan_ms_pwr_ctrl(RxLvl=-110 dBm) returns 1 (expected 1) MS current power 15 -> 13 (expected 13) - Avg[t] is -92.00 dBm (expected -92.00 dBm) + Avg[t] is RxLev 18.00 (expected 18.00) Starting test case 'test_power_hysteresis' lchan_ms_pwr_ctrl(RxLvl=-75 dBm) returns 0 (expected 0) @@ -144,4 +144,36 @@ lchan_ms_pwr_ctrl(RxLvl=-90 dBm) returns 0 (expected 0) lchan_ms_pwr_ctrl(RxLvl=-90 dBm) returns 0 (expected 0) MS current power 11 -> 11 (expected 11) + +Starting test case 'test_power_loop_ci' +lchan_ms_pwr_ctrl(RxLvl=-60 dBm) returns 0 (expected 0) + MS current power 15 -> 15 (expected 15) +lchan_ms_pwr_ctrl(RxLvl=-100 dBm) returns 1 (expected 1) + MS current power 15 -> 13 (expected 13) +lchan_ms_pwr_ctrl(RxLvl=-100 dBm) returns 1 (expected 1) + MS current power 13 -> 11 (expected 11) +lchan_ms_pwr_ctrl(RxLvl=-60 dBm) returns 1 (expected 1) + MS current power 11 -> 12 (expected 12) +lchan_ms_pwr_ctrl(RxLvl=-60 dBm) returns 1 (expected 1) + MS current power 12 -> 13 (expected 13) +lchan_ms_pwr_ctrl(RxLvl=-100 dBm) returns 1 (expected 1) + MS current power 13 -> 11 (expected 11) +lchan_ms_pwr_ctrl(RxLvl=-100 dBm) returns 1 (expected 1) + MS current power 11 -> 12 (expected 12) +lchan_ms_pwr_ctrl(RxLvl=-60 dBm) returns 1 (expected 1) + MS current power 12 -> 13 (expected 13) +lchan_ms_pwr_ctrl(RxLvl=-60 dBm) returns 1 (expected 1) + MS current power 13 -> 14 (expected 14) + +Starting test case 'test_good_threshold_convergence' +lchan_ms_pwr_ctrl(RxLvl=-78 dBm) returns 0 (expected 0) + MS current power 9 -> 10 (expected 10) +lchan_ms_pwr_ctrl(RxLvl=-78 dBm) returns 0 (expected 0) + MS current power 10 -> 10 (expected 10) +lchan_ms_pwr_ctrl(RxLvl=-78 dBm) returns 0 (expected 0) + MS current power 9 -> 10 (expected 10) +lchan_ms_pwr_ctrl(RxLvl=-78 dBm) returns 0 (expected 0) + MS current power 10 -> 10 (expected 10) +lchan_ms_pwr_ctrl(RxLvl=-78 dBm) returns 0 (expected 0) + MS current power 9 -> 10 (expected 10) Power loop test OK diff --git a/tests/stubs.c b/tests/stubs.c index b24dfc90..72a77a5e 100644 --- a/tests/stubs.c +++ b/tests/stubs.c @@ -18,8 +18,8 @@ int bts_model_init(struct gsm_bts *bts) { return 0; } int bts_model_trx_init(struct gsm_bts_trx *trx) { return 0; } -int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg, - struct tlv_parsed *new_attr, int kind, void *obj) +int bts_model_apply_oml(struct gsm_bts *bts, const struct msgb *msg, + struct gsm_abis_mo *mo, void *obj) { return 0; } int bts_model_trx_deact_rf(struct gsm_bts_trx *trx) diff --git a/tests/sysmobts/Makefile.am b/tests/sysmobts/Makefile.am index 53180d11..ff80fb34 100644 --- a/tests/sysmobts/Makefile.am +++ b/tests/sysmobts/Makefile.am @@ -1,11 +1,36 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_srcdir)/src/osmo-bts-sysmo $(SYSMOBTS_INCDIR) -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOTRAU_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) $(LIBOSMOTRAU_LIBS) +AM_CPPFLAGS = \ + $(all_includes) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/osmo-bts-sysmo \ + $(SYSMOBTS_INCDIR) \ + $(NULL) +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOVTY_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOVTY_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) -noinst_PROGRAMS = sysmobts_test +check_PROGRAMS = sysmobts_test EXTRA_DIST = sysmobts_test.ok -sysmobts_test_SOURCES = sysmobts_test.c $(top_srcdir)/src/osmo-bts-sysmo/utils.c \ +sysmobts_test_SOURCES = \ + sysmobts_test.c \ + $(top_srcdir)/src/osmo-bts-sysmo/utils.c \ $(top_srcdir)/src/osmo-bts-sysmo/l1_if.c \ $(top_srcdir)/src/osmo-bts-sysmo/oml.c \ $(top_srcdir)/src/osmo-bts-sysmo/l1_transp_hw.c \ @@ -15,4 +40,7 @@ sysmobts_test_SOURCES = sysmobts_test.c $(top_srcdir)/src/osmo-bts-sysmo/utils.c $(top_srcdir)/src/osmo-bts-sysmo/misc/sysmobts_par.c \ $(top_srcdir)/src/osmo-bts-sysmo/femtobts.c \ $(top_srcdir)/src/osmo-bts-sysmo/eeprom.c -sysmobts_test_LDADD = $(top_builddir)/src/common/libbts.a $(LIBOSMOABIS_LIBS) $(LDADD) +sysmobts_test_LDADD = \ + $(top_builddir)/src/common/libbts.a \ + $(LDADD) \ + $(NULL) diff --git a/tests/sysmobts/sysmobts_test.c b/tests/sysmobts/sysmobts_test.c index d1e9e69f..27273d8d 100644 --- a/tests/sysmobts/sysmobts_test.c +++ b/tests/sysmobts/sysmobts_test.c @@ -11,7 +11,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. diff --git a/tests/ta_control/Makefile.am b/tests/ta_control/Makefile.am index 4c89dd29..12c32ac3 100644 --- a/tests/ta_control/Makefile.am +++ b/tests/ta_control/Makefile.am @@ -1,6 +1,23 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -noinst_PROGRAMS = ta_control_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) + +check_PROGRAMS = ta_control_test EXTRA_DIST = ta_control_test.ok ta_control_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/ta_control/ta_control_test.c b/tests/ta_control/ta_control_test.c index 2e981b38..253491a8 100644 --- a/tests/ta_control/ta_control_test.c +++ b/tests/ta_control/ta_control_test.c @@ -26,36 +26,35 @@ #include <osmo-bts/logging.h> #include <osmo-bts/gsm_data.h> #include <osmo-bts/ta_control.h> +#include <osmo-bts/bts_trx.h> void lchan_ms_ta_ctrl_test(int16_t toa256_start, unsigned int steps) { - struct gsm_lchan lchan = { }; + struct gsm_bts_trx trx = { }; + struct gsm_bts_trx_ts ts = { .trx = &trx }; + struct gsm_lchan lchan = { .ts = &ts }; unsigned int i; uint8_t rqd_ta_after; uint8_t rqd_ta_before; int16_t toa256 = toa256_start; - /* Arbitrary value, high enough so that a computation can happen. */ - lchan.meas.num_ul_meas = 10; - printf("toa256_start = %u / 256 = %u, steps = %u\n", toa256_start, toa256_start / 256, steps); for (i = 0; i < steps; i++) { printf("Step #%u\n", i); - printf(" lchan.rqd_ta (before) = %u\n", lchan.rqd_ta); + printf(" lchan.ta_ctrl.current (before) = %u\n", lchan.ta_ctrl.current); printf(" toa256 (before) = %u / 256 = %u\n", toa256, toa256 / 256); - rqd_ta_before = lchan.rqd_ta; + rqd_ta_before = lchan.ta_ctrl.current; - lchan.meas.ms_toa256 = toa256; - lchan_ms_ta_ctrl(&lchan); + lchan_ms_ta_ctrl(&lchan, rqd_ta_before, toa256); - rqd_ta_after = lchan.rqd_ta; + rqd_ta_after = lchan.ta_ctrl.current; toa256 -= (rqd_ta_after - rqd_ta_before) * 256; - printf(" lchan.rqd_ta (after) = %u\n", lchan.rqd_ta); + printf(" lchan.ta_ctrl.current (after) = %u\n", lchan.ta_ctrl.current); printf(" toa256 (after) = %u / 256 = %u\n", toa256, toa256 / 256); } diff --git a/tests/ta_control/ta_control_test.ok b/tests/ta_control/ta_control_test.ok index 8ebe5d54..a1586759 100644 --- a/tests/ta_control/ta_control_test.ok +++ b/tests/ta_control/ta_control_test.ok @@ -1,609 +1,609 @@ toa256_start = 4096 / 256 = 16, steps = 20 Step #0 - lchan.rqd_ta (before) = 0 + lchan.ta_ctrl.current (before) = 0 toa256 (before) = 4096 / 256 = 16 - lchan.rqd_ta (after) = 1 - toa256 (after) = 3840 / 256 = 15 -Step #1 - lchan.rqd_ta (before) = 1 - toa256 (before) = 3840 / 256 = 15 - lchan.rqd_ta (after) = 2 + lchan.ta_ctrl.current (after) = 2 toa256 (after) = 3584 / 256 = 14 -Step #2 - lchan.rqd_ta (before) = 2 +Step #1 + lchan.ta_ctrl.current (before) = 2 toa256 (before) = 3584 / 256 = 14 - lchan.rqd_ta (after) = 3 - toa256 (after) = 3328 / 256 = 13 -Step #3 - lchan.rqd_ta (before) = 3 - toa256 (before) = 3328 / 256 = 13 - lchan.rqd_ta (after) = 4 + lchan.ta_ctrl.current (after) = 4 toa256 (after) = 3072 / 256 = 12 -Step #4 - lchan.rqd_ta (before) = 4 +Step #2 + lchan.ta_ctrl.current (before) = 4 toa256 (before) = 3072 / 256 = 12 - lchan.rqd_ta (after) = 5 - toa256 (after) = 2816 / 256 = 11 -Step #5 - lchan.rqd_ta (before) = 5 - toa256 (before) = 2816 / 256 = 11 - lchan.rqd_ta (after) = 6 + lchan.ta_ctrl.current (after) = 6 toa256 (after) = 2560 / 256 = 10 -Step #6 - lchan.rqd_ta (before) = 6 +Step #3 + lchan.ta_ctrl.current (before) = 6 toa256 (before) = 2560 / 256 = 10 - lchan.rqd_ta (after) = 7 - toa256 (after) = 2304 / 256 = 9 -Step #7 - lchan.rqd_ta (before) = 7 - toa256 (before) = 2304 / 256 = 9 - lchan.rqd_ta (after) = 8 + lchan.ta_ctrl.current (after) = 8 toa256 (after) = 2048 / 256 = 8 -Step #8 - lchan.rqd_ta (before) = 8 +Step #4 + lchan.ta_ctrl.current (before) = 8 toa256 (before) = 2048 / 256 = 8 - lchan.rqd_ta (after) = 9 - toa256 (after) = 1792 / 256 = 7 -Step #9 - lchan.rqd_ta (before) = 9 - toa256 (before) = 1792 / 256 = 7 - lchan.rqd_ta (after) = 10 + lchan.ta_ctrl.current (after) = 10 toa256 (after) = 1536 / 256 = 6 -Step #10 - lchan.rqd_ta (before) = 10 +Step #5 + lchan.ta_ctrl.current (before) = 10 toa256 (before) = 1536 / 256 = 6 - lchan.rqd_ta (after) = 11 - toa256 (after) = 1280 / 256 = 5 -Step #11 - lchan.rqd_ta (before) = 11 - toa256 (before) = 1280 / 256 = 5 - lchan.rqd_ta (after) = 12 + lchan.ta_ctrl.current (after) = 12 toa256 (after) = 1024 / 256 = 4 -Step #12 - lchan.rqd_ta (before) = 12 +Step #6 + lchan.ta_ctrl.current (before) = 12 toa256 (before) = 1024 / 256 = 4 - lchan.rqd_ta (after) = 13 - toa256 (after) = 768 / 256 = 3 -Step #13 - lchan.rqd_ta (before) = 13 - toa256 (before) = 768 / 256 = 3 - lchan.rqd_ta (after) = 14 + lchan.ta_ctrl.current (after) = 14 toa256 (after) = 512 / 256 = 2 -Step #14 - lchan.rqd_ta (before) = 14 +Step #7 + lchan.ta_ctrl.current (before) = 14 toa256 (before) = 512 / 256 = 2 - lchan.rqd_ta (after) = 15 - toa256 (after) = 256 / 256 = 1 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #8 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #9 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #10 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #11 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #12 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #13 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 +Step #14 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 + toa256 (after) = 0 / 256 = 0 Step #15 - lchan.rqd_ta (before) = 15 - toa256 (before) = 256 / 256 = 1 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (before) = 16 + toa256 (before) = 0 / 256 = 0 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 0 / 256 = 0 Step #16 - lchan.rqd_ta (before) = 16 + lchan.ta_ctrl.current (before) = 16 toa256 (before) = 0 / 256 = 0 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 0 / 256 = 0 Step #17 - lchan.rqd_ta (before) = 16 + lchan.ta_ctrl.current (before) = 16 toa256 (before) = 0 / 256 = 0 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 0 / 256 = 0 Step #18 - lchan.rqd_ta (before) = 16 + lchan.ta_ctrl.current (before) = 16 toa256 (before) = 0 / 256 = 0 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 0 / 256 = 0 Step #19 - lchan.rqd_ta (before) = 16 + lchan.ta_ctrl.current (before) = 16 toa256 (before) = 0 / 256 = 0 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 0 / 256 = 0 Done. toa256_start = 4000 / 256 = 15, steps = 50 Step #0 - lchan.rqd_ta (before) = 0 + lchan.ta_ctrl.current (before) = 0 toa256 (before) = 4000 / 256 = 15 - lchan.rqd_ta (after) = 1 - toa256 (after) = 3744 / 256 = 14 -Step #1 - lchan.rqd_ta (before) = 1 - toa256 (before) = 3744 / 256 = 14 - lchan.rqd_ta (after) = 2 + lchan.ta_ctrl.current (after) = 2 toa256 (after) = 3488 / 256 = 13 -Step #2 - lchan.rqd_ta (before) = 2 +Step #1 + lchan.ta_ctrl.current (before) = 2 toa256 (before) = 3488 / 256 = 13 - lchan.rqd_ta (after) = 3 - toa256 (after) = 3232 / 256 = 12 -Step #3 - lchan.rqd_ta (before) = 3 - toa256 (before) = 3232 / 256 = 12 - lchan.rqd_ta (after) = 4 + lchan.ta_ctrl.current (after) = 4 toa256 (after) = 2976 / 256 = 11 -Step #4 - lchan.rqd_ta (before) = 4 +Step #2 + lchan.ta_ctrl.current (before) = 4 toa256 (before) = 2976 / 256 = 11 - lchan.rqd_ta (after) = 5 - toa256 (after) = 2720 / 256 = 10 -Step #5 - lchan.rqd_ta (before) = 5 - toa256 (before) = 2720 / 256 = 10 - lchan.rqd_ta (after) = 6 + lchan.ta_ctrl.current (after) = 6 toa256 (after) = 2464 / 256 = 9 -Step #6 - lchan.rqd_ta (before) = 6 +Step #3 + lchan.ta_ctrl.current (before) = 6 toa256 (before) = 2464 / 256 = 9 - lchan.rqd_ta (after) = 7 - toa256 (after) = 2208 / 256 = 8 -Step #7 - lchan.rqd_ta (before) = 7 - toa256 (before) = 2208 / 256 = 8 - lchan.rqd_ta (after) = 8 + lchan.ta_ctrl.current (after) = 8 toa256 (after) = 1952 / 256 = 7 -Step #8 - lchan.rqd_ta (before) = 8 +Step #4 + lchan.ta_ctrl.current (before) = 8 toa256 (before) = 1952 / 256 = 7 - lchan.rqd_ta (after) = 9 - toa256 (after) = 1696 / 256 = 6 -Step #9 - lchan.rqd_ta (before) = 9 - toa256 (before) = 1696 / 256 = 6 - lchan.rqd_ta (after) = 10 + lchan.ta_ctrl.current (after) = 10 toa256 (after) = 1440 / 256 = 5 -Step #10 - lchan.rqd_ta (before) = 10 +Step #5 + lchan.ta_ctrl.current (before) = 10 toa256 (before) = 1440 / 256 = 5 - lchan.rqd_ta (after) = 11 - toa256 (after) = 1184 / 256 = 4 -Step #11 - lchan.rqd_ta (before) = 11 - toa256 (before) = 1184 / 256 = 4 - lchan.rqd_ta (after) = 12 + lchan.ta_ctrl.current (after) = 12 toa256 (after) = 928 / 256 = 3 -Step #12 - lchan.rqd_ta (before) = 12 +Step #6 + lchan.ta_ctrl.current (before) = 12 toa256 (before) = 928 / 256 = 3 - lchan.rqd_ta (after) = 13 - toa256 (after) = 672 / 256 = 2 -Step #13 - lchan.rqd_ta (before) = 13 - toa256 (before) = 672 / 256 = 2 - lchan.rqd_ta (after) = 14 + lchan.ta_ctrl.current (after) = 14 toa256 (after) = 416 / 256 = 1 -Step #14 - lchan.rqd_ta (before) = 14 +Step #7 + lchan.ta_ctrl.current (before) = 14 toa256 (before) = 416 / 256 = 1 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #8 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #9 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #10 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #11 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #12 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #13 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 + toa256 (after) = 160 / 256 = 0 +Step #14 + lchan.ta_ctrl.current (before) = 15 + toa256 (before) = 160 / 256 = 0 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #15 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #16 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #17 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #18 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #19 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #20 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #21 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #22 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #23 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #24 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #25 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #26 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #27 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #28 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #29 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #30 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #31 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #32 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #33 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #34 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #35 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #36 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #37 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #38 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #39 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #40 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #41 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #42 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #43 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #44 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #45 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #46 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #47 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #48 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Step #49 - lchan.rqd_ta (before) = 15 + lchan.ta_ctrl.current (before) = 15 toa256 (before) = 160 / 256 = 0 - lchan.rqd_ta (after) = 15 + lchan.ta_ctrl.current (after) = 15 toa256 (after) = 160 / 256 = 0 Done. toa256_start = 12345 / 256 = 48, steps = 50 Step #0 - lchan.rqd_ta (before) = 0 + lchan.ta_ctrl.current (before) = 0 toa256 (before) = 12345 / 256 = 48 - lchan.rqd_ta (after) = 1 - toa256 (after) = 12089 / 256 = 47 -Step #1 - lchan.rqd_ta (before) = 1 - toa256 (before) = 12089 / 256 = 47 - lchan.rqd_ta (after) = 2 + lchan.ta_ctrl.current (after) = 2 toa256 (after) = 11833 / 256 = 46 -Step #2 - lchan.rqd_ta (before) = 2 +Step #1 + lchan.ta_ctrl.current (before) = 2 toa256 (before) = 11833 / 256 = 46 - lchan.rqd_ta (after) = 3 - toa256 (after) = 11577 / 256 = 45 -Step #3 - lchan.rqd_ta (before) = 3 - toa256 (before) = 11577 / 256 = 45 - lchan.rqd_ta (after) = 4 + lchan.ta_ctrl.current (after) = 4 toa256 (after) = 11321 / 256 = 44 -Step #4 - lchan.rqd_ta (before) = 4 +Step #2 + lchan.ta_ctrl.current (before) = 4 toa256 (before) = 11321 / 256 = 44 - lchan.rqd_ta (after) = 5 - toa256 (after) = 11065 / 256 = 43 -Step #5 - lchan.rqd_ta (before) = 5 - toa256 (before) = 11065 / 256 = 43 - lchan.rqd_ta (after) = 6 + lchan.ta_ctrl.current (after) = 6 toa256 (after) = 10809 / 256 = 42 -Step #6 - lchan.rqd_ta (before) = 6 +Step #3 + lchan.ta_ctrl.current (before) = 6 toa256 (before) = 10809 / 256 = 42 - lchan.rqd_ta (after) = 7 - toa256 (after) = 10553 / 256 = 41 -Step #7 - lchan.rqd_ta (before) = 7 - toa256 (before) = 10553 / 256 = 41 - lchan.rqd_ta (after) = 8 + lchan.ta_ctrl.current (after) = 8 toa256 (after) = 10297 / 256 = 40 -Step #8 - lchan.rqd_ta (before) = 8 +Step #4 + lchan.ta_ctrl.current (before) = 8 toa256 (before) = 10297 / 256 = 40 - lchan.rqd_ta (after) = 9 - toa256 (after) = 10041 / 256 = 39 -Step #9 - lchan.rqd_ta (before) = 9 - toa256 (before) = 10041 / 256 = 39 - lchan.rqd_ta (after) = 10 + lchan.ta_ctrl.current (after) = 10 toa256 (after) = 9785 / 256 = 38 -Step #10 - lchan.rqd_ta (before) = 10 +Step #5 + lchan.ta_ctrl.current (before) = 10 toa256 (before) = 9785 / 256 = 38 - lchan.rqd_ta (after) = 11 - toa256 (after) = 9529 / 256 = 37 -Step #11 - lchan.rqd_ta (before) = 11 - toa256 (before) = 9529 / 256 = 37 - lchan.rqd_ta (after) = 12 + lchan.ta_ctrl.current (after) = 12 toa256 (after) = 9273 / 256 = 36 -Step #12 - lchan.rqd_ta (before) = 12 +Step #6 + lchan.ta_ctrl.current (before) = 12 toa256 (before) = 9273 / 256 = 36 - lchan.rqd_ta (after) = 13 - toa256 (after) = 9017 / 256 = 35 -Step #13 - lchan.rqd_ta (before) = 13 - toa256 (before) = 9017 / 256 = 35 - lchan.rqd_ta (after) = 14 + lchan.ta_ctrl.current (after) = 14 toa256 (after) = 8761 / 256 = 34 -Step #14 - lchan.rqd_ta (before) = 14 +Step #7 + lchan.ta_ctrl.current (before) = 14 toa256 (before) = 8761 / 256 = 34 - lchan.rqd_ta (after) = 15 - toa256 (after) = 8505 / 256 = 33 -Step #15 - lchan.rqd_ta (before) = 15 - toa256 (before) = 8505 / 256 = 33 - lchan.rqd_ta (after) = 16 + lchan.ta_ctrl.current (after) = 16 toa256 (after) = 8249 / 256 = 32 -Step #16 - lchan.rqd_ta (before) = 16 +Step #8 + lchan.ta_ctrl.current (before) = 16 toa256 (before) = 8249 / 256 = 32 - lchan.rqd_ta (after) = 17 - toa256 (after) = 7993 / 256 = 31 -Step #17 - lchan.rqd_ta (before) = 17 - toa256 (before) = 7993 / 256 = 31 - lchan.rqd_ta (after) = 18 + lchan.ta_ctrl.current (after) = 18 toa256 (after) = 7737 / 256 = 30 -Step #18 - lchan.rqd_ta (before) = 18 +Step #9 + lchan.ta_ctrl.current (before) = 18 toa256 (before) = 7737 / 256 = 30 - lchan.rqd_ta (after) = 19 - toa256 (after) = 7481 / 256 = 29 -Step #19 - lchan.rqd_ta (before) = 19 - toa256 (before) = 7481 / 256 = 29 - lchan.rqd_ta (after) = 20 + lchan.ta_ctrl.current (after) = 20 toa256 (after) = 7225 / 256 = 28 -Step #20 - lchan.rqd_ta (before) = 20 +Step #10 + lchan.ta_ctrl.current (before) = 20 toa256 (before) = 7225 / 256 = 28 - lchan.rqd_ta (after) = 21 - toa256 (after) = 6969 / 256 = 27 -Step #21 - lchan.rqd_ta (before) = 21 - toa256 (before) = 6969 / 256 = 27 - lchan.rqd_ta (after) = 22 + lchan.ta_ctrl.current (after) = 22 toa256 (after) = 6713 / 256 = 26 -Step #22 - lchan.rqd_ta (before) = 22 +Step #11 + lchan.ta_ctrl.current (before) = 22 toa256 (before) = 6713 / 256 = 26 - lchan.rqd_ta (after) = 23 - toa256 (after) = 6457 / 256 = 25 -Step #23 - lchan.rqd_ta (before) = 23 - toa256 (before) = 6457 / 256 = 25 - lchan.rqd_ta (after) = 24 + lchan.ta_ctrl.current (after) = 24 toa256 (after) = 6201 / 256 = 24 -Step #24 - lchan.rqd_ta (before) = 24 +Step #12 + lchan.ta_ctrl.current (before) = 24 toa256 (before) = 6201 / 256 = 24 - lchan.rqd_ta (after) = 25 - toa256 (after) = 5945 / 256 = 23 -Step #25 - lchan.rqd_ta (before) = 25 - toa256 (before) = 5945 / 256 = 23 - lchan.rqd_ta (after) = 26 + lchan.ta_ctrl.current (after) = 26 toa256 (after) = 5689 / 256 = 22 -Step #26 - lchan.rqd_ta (before) = 26 +Step #13 + lchan.ta_ctrl.current (before) = 26 toa256 (before) = 5689 / 256 = 22 - lchan.rqd_ta (after) = 27 - toa256 (after) = 5433 / 256 = 21 -Step #27 - lchan.rqd_ta (before) = 27 - toa256 (before) = 5433 / 256 = 21 - lchan.rqd_ta (after) = 28 + lchan.ta_ctrl.current (after) = 28 toa256 (after) = 5177 / 256 = 20 -Step #28 - lchan.rqd_ta (before) = 28 +Step #14 + lchan.ta_ctrl.current (before) = 28 toa256 (before) = 5177 / 256 = 20 - lchan.rqd_ta (after) = 29 - toa256 (after) = 4921 / 256 = 19 -Step #29 - lchan.rqd_ta (before) = 29 - toa256 (before) = 4921 / 256 = 19 - lchan.rqd_ta (after) = 30 + lchan.ta_ctrl.current (after) = 30 toa256 (after) = 4665 / 256 = 18 -Step #30 - lchan.rqd_ta (before) = 30 +Step #15 + lchan.ta_ctrl.current (before) = 30 toa256 (before) = 4665 / 256 = 18 - lchan.rqd_ta (after) = 31 - toa256 (after) = 4409 / 256 = 17 -Step #31 - lchan.rqd_ta (before) = 31 - toa256 (before) = 4409 / 256 = 17 - lchan.rqd_ta (after) = 32 + lchan.ta_ctrl.current (after) = 32 toa256 (after) = 4153 / 256 = 16 -Step #32 - lchan.rqd_ta (before) = 32 +Step #16 + lchan.ta_ctrl.current (before) = 32 toa256 (before) = 4153 / 256 = 16 - lchan.rqd_ta (after) = 33 - toa256 (after) = 3897 / 256 = 15 -Step #33 - lchan.rqd_ta (before) = 33 - toa256 (before) = 3897 / 256 = 15 - lchan.rqd_ta (after) = 34 + lchan.ta_ctrl.current (after) = 34 toa256 (after) = 3641 / 256 = 14 -Step #34 - lchan.rqd_ta (before) = 34 +Step #17 + lchan.ta_ctrl.current (before) = 34 toa256 (before) = 3641 / 256 = 14 - lchan.rqd_ta (after) = 35 - toa256 (after) = 3385 / 256 = 13 -Step #35 - lchan.rqd_ta (before) = 35 - toa256 (before) = 3385 / 256 = 13 - lchan.rqd_ta (after) = 36 + lchan.ta_ctrl.current (after) = 36 toa256 (after) = 3129 / 256 = 12 -Step #36 - lchan.rqd_ta (before) = 36 +Step #18 + lchan.ta_ctrl.current (before) = 36 toa256 (before) = 3129 / 256 = 12 - lchan.rqd_ta (after) = 37 - toa256 (after) = 2873 / 256 = 11 -Step #37 - lchan.rqd_ta (before) = 37 - toa256 (before) = 2873 / 256 = 11 - lchan.rqd_ta (after) = 38 + lchan.ta_ctrl.current (after) = 38 toa256 (after) = 2617 / 256 = 10 -Step #38 - lchan.rqd_ta (before) = 38 +Step #19 + lchan.ta_ctrl.current (before) = 38 toa256 (before) = 2617 / 256 = 10 - lchan.rqd_ta (after) = 39 - toa256 (after) = 2361 / 256 = 9 -Step #39 - lchan.rqd_ta (before) = 39 - toa256 (before) = 2361 / 256 = 9 - lchan.rqd_ta (after) = 40 + lchan.ta_ctrl.current (after) = 40 toa256 (after) = 2105 / 256 = 8 -Step #40 - lchan.rqd_ta (before) = 40 +Step #20 + lchan.ta_ctrl.current (before) = 40 toa256 (before) = 2105 / 256 = 8 - lchan.rqd_ta (after) = 41 - toa256 (after) = 1849 / 256 = 7 -Step #41 - lchan.rqd_ta (before) = 41 - toa256 (before) = 1849 / 256 = 7 - lchan.rqd_ta (after) = 42 + lchan.ta_ctrl.current (after) = 42 toa256 (after) = 1593 / 256 = 6 -Step #42 - lchan.rqd_ta (before) = 42 +Step #21 + lchan.ta_ctrl.current (before) = 42 toa256 (before) = 1593 / 256 = 6 - lchan.rqd_ta (after) = 43 - toa256 (after) = 1337 / 256 = 5 -Step #43 - lchan.rqd_ta (before) = 43 - toa256 (before) = 1337 / 256 = 5 - lchan.rqd_ta (after) = 44 + lchan.ta_ctrl.current (after) = 44 toa256 (after) = 1081 / 256 = 4 -Step #44 - lchan.rqd_ta (before) = 44 +Step #22 + lchan.ta_ctrl.current (before) = 44 toa256 (before) = 1081 / 256 = 4 - lchan.rqd_ta (after) = 45 - toa256 (after) = 825 / 256 = 3 -Step #45 - lchan.rqd_ta (before) = 45 - toa256 (before) = 825 / 256 = 3 - lchan.rqd_ta (after) = 46 + lchan.ta_ctrl.current (after) = 46 toa256 (after) = 569 / 256 = 2 -Step #46 - lchan.rqd_ta (before) = 46 +Step #23 + lchan.ta_ctrl.current (before) = 46 toa256 (before) = 569 / 256 = 2 - lchan.rqd_ta (after) = 47 - toa256 (after) = 313 / 256 = 1 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #24 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #25 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #26 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #27 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #28 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #29 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #30 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #31 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #32 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #33 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #34 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #35 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #36 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #37 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #38 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #39 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #40 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #41 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #42 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #43 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #44 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #45 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 +Step #46 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 + toa256 (after) = 57 / 256 = 0 Step #47 - lchan.rqd_ta (before) = 47 - toa256 (before) = 313 / 256 = 1 - lchan.rqd_ta (after) = 48 + lchan.ta_ctrl.current (before) = 48 + toa256 (before) = 57 / 256 = 0 + lchan.ta_ctrl.current (after) = 48 toa256 (after) = 57 / 256 = 0 Step #48 - lchan.rqd_ta (before) = 48 + lchan.ta_ctrl.current (before) = 48 toa256 (before) = 57 / 256 = 0 - lchan.rqd_ta (after) = 48 + lchan.ta_ctrl.current (after) = 48 toa256 (after) = 57 / 256 = 0 Step #49 - lchan.rqd_ta (before) = 48 + lchan.ta_ctrl.current (before) = 48 toa256 (before) = 57 / 256 = 0 - lchan.rqd_ta (after) = 48 + lchan.ta_ctrl.current (after) = 48 toa256 (after) = 57 / 256 = 0 Done. diff --git a/tests/testsuite.at b/tests/testsuite.at index ba5a409b..6e2677e2 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -55,7 +55,8 @@ AT_CLEANUP AT_SETUP([meas]) AT_KEYWORDS([meas]) cat $abs_srcdir/meas/meas_test.ok > expout -AT_CHECK([$abs_top_builddir/tests/meas/meas_test], [], [expout], [ignore]) +cat $abs_srcdir/meas/meas_test.err > experr +AT_CHECK([$abs_top_builddir/tests/meas/meas_test], [], [expout], [experr]) AT_CLEANUP AT_SETUP([ta_control]) @@ -63,3 +64,16 @@ AT_KEYWORDS([ta_control]) cat $abs_srcdir/ta_control/ta_control_test.ok > expout AT_CHECK([$abs_top_builddir/tests/ta_control/ta_control_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([amr]) +AT_KEYWORDS([amr]) +cat $abs_srcdir/amr/amr_test.ok > expout +cat $abs_srcdir/amr/amr_test.err > experr +AT_CHECK([$abs_top_builddir/tests/amr/amr_test], [], [expout], [experr]) +AT_CLEANUP + +AT_SETUP([csd]) +AT_KEYWORDS([csd]) +cat $abs_srcdir/csd/csd_test.err > experr +AT_CHECK([$abs_top_builddir/tests/csd/csd_test], [], [ignore], [experr]) +AT_CLEANUP diff --git a/tests/tx_power/Makefile.am b/tests/tx_power/Makefile.am index cd7ccc2f..8c3db1eb 100644 --- a/tests/tx_power/Makefile.am +++ b/tests/tx_power/Makefile.am @@ -1,7 +1,23 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOCODEC_CFLAGS) $(LIBOSMOTRAU_CFLAGS) $(LIBOSMOABIS_CFLAGS) -LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOCODEC_LIBS) $(LIBOSMOTRAU_LIBS) $(LIBOSMOABIS_LIBS) -noinst_PROGRAMS = tx_power_test +AM_CFLAGS = \ + -Wall \ + $(LIBOSMOCORE_CFLAGS) \ + $(LIBOSMOGSM_CFLAGS) \ + $(LIBOSMOCODEC_CFLAGS) \ + $(LIBOSMOABIS_CFLAGS) \ + $(LIBOSMOTRAU_CFLAGS) \ + $(LIBOSMONETIF_CFLAGS) \ + $(NULL) +AM_LDFLAGS = -no-install +LDADD = \ + $(LIBOSMOCORE_LIBS) \ + $(LIBOSMOGSM_LIBS) \ + $(LIBOSMOCODEC_LIBS) \ + $(LIBOSMOABIS_LIBS) \ + $(LIBOSMOTRAU_LIBS) \ + $(LIBOSMONETIF_LIBS) \ + $(NULL) +check_PROGRAMS = tx_power_test EXTRA_DIST = tx_power_test.ok tx_power_test.err tx_power_test_SOURCES = tx_power_test.c $(srcdir)/../stubs.c diff --git a/tests/tx_power/tx_power_test.c b/tests/tx_power/tx_power_test.c index 3724f564..e0f88bc9 100644 --- a/tests/tx_power/tx_power_test.c +++ b/tests/tx_power/tx_power_test.c @@ -12,7 +12,7 @@ * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. @@ -28,6 +28,7 @@ #include <osmo-bts/gsm_data.h> #include <osmo-bts/bts.h> +#include <osmo-bts/bts_sm.h> #include <osmo-bts/logging.h> #include <osmo-bts/tx_power.h> @@ -252,7 +253,12 @@ int main(int argc, char **argv) log_set_print_category(osmo_stderr_target, 0); log_set_print_category_hex(osmo_stderr_target, 0); - bts = gsm_bts_alloc(tall_bts_ctx, 0); + g_bts_sm = gsm_bts_sm_alloc(tall_bts_ctx); + if (!g_bts_sm) { + fprintf(stderr, "Failed to create BTS Site Manager structure\n"); + exit(1); + } + bts = gsm_bts_alloc(g_bts_sm, 0); if (!bts) { fprintf(stderr, "Failed to create BTS structure\n"); exit(1); |