Projects
osmocom:master
osmo-bts
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 205
View file
commit_0a34af1530760bb6b69173f31bfd47cfe62ab002.txt
Added
View file
commit_82d500ccac605d30c31a114369b377478b9f3abd.txt
Deleted
View file
osmo-bts_1.8.0.13.0a34.dsc
Added
@@ -0,0 +1,24 @@ +Format: 3.0 (native) +Source: osmo-bts +Binary: osmo-bts, osmo-bts-trx, osmo-bts-trx-dbg, osmo-bts-virtual, osmo-bts-virtual-dbg, osmo-bts-doc +Architecture: any all +Version: 1.8.0.13.0a34 +Maintainer: Osmocom team <openbsc@lists.osmocom.org> +Homepage: https://projects.osmocom.org/projects/osmobts +Standards-Version: 3.9.8 +Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts +Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts +Build-Depends: debhelper (>= 10), pkg-config, dh-autoreconf, autotools-dev, libosmocore-dev (>= 1.10.0), libosmo-abis-dev (>= 1.6.0), libosmo-netif-dev (>= 1.5.0), libgps-dev, txt2man, osmo-gsm-manuals-dev (>= 1.6.0) +Package-List: + osmo-bts deb net optional arch=any + osmo-bts-doc deb doc optional arch=all + osmo-bts-trx deb net optional arch=any + osmo-bts-trx-dbg deb debug extra arch=any + osmo-bts-virtual deb net optional arch=any + osmo-bts-virtual-dbg deb debug extra arch=any +Checksums-Sha1: + 0d3bdfd80f50f79c58b188a430eb6300ff1e0355 514588 osmo-bts_1.8.0.13.0a34.tar.xz +Checksums-Sha256: + e259822013b52d3f1fc309d05d1be5273093502b2d8b98448ccabe5d9798c451 514588 osmo-bts_1.8.0.13.0a34.tar.xz +Files: + 88b09b9320cda00b392ddf28c216a0b3 514588 osmo-bts_1.8.0.13.0a34.tar.xz
View file
osmo-bts_1.8.0.6.82d5.tar.xz/.tarball-version -> osmo-bts_1.8.0.13.0a34.tar.xz/.tarball-version
Changed
@@ -1 +1 @@ -1.8.0.6-82d5 +1.8.0.13-0a34
View file
osmo-bts_1.8.0.6.82d5.tar.xz/debian/changelog -> osmo-bts_1.8.0.13.0a34.tar.xz/debian/changelog
Changed
@@ -1,8 +1,8 @@ -osmo-bts (1.8.0.6.82d5) unstable; urgency=medium +osmo-bts (1.8.0.13.0a34) unstable; urgency=medium * Automatically generated changelog entry for building the Osmocom master feed - -- Osmocom OBS scripts <info@osmocom.org> Sun, 13 Oct 2024 12:57:50 +0000 + -- Osmocom OBS scripts <info@osmocom.org> Tue, 05 Nov 2024 09:32:56 +0000 osmo-bts (1.8.0) unstable; urgency=medium
View file
osmo-bts_1.8.0.6.82d5.tar.xz/include/osmo-bts/Makefile.am -> osmo-bts_1.8.0.13.0a34.tar.xz/include/osmo-bts/Makefile.am
Changed
@@ -24,6 +24,7 @@ tx_power.h \ control_if.h \ cbch.h \ + csd_rlp.h \ csd_v110.h \ l1sap.h \ lchan.h \
View file
osmo-bts_1.8.0.13.0a34.tar.xz/include/osmo-bts/csd_rlp.h
Added
@@ -0,0 +1,36 @@ +/* + * Declarations for functions in csd_rlp.c: alignment of downlink RLP frames + * and RLP GSMTAP mechanism for CSD NT modes. + */ + +#pragma once + +#include <stdint.h> +#include <stdbool.h> +#include <osmocom/core/bits.h> +#include <osmocom/gsm/l1sap.h> +#include <osmo-bts/lchan.h> + +extern const uint8_t csd_tchf48_nt_e2_map26; + +/* Per TS 48.020 section 15.1, the cadence of E2+E3 bits in a properly + * aligned sequence of pseudo-V.110 frames forming a single RLP frame + * is 00-01-10-11. The following constant captures this bit sequence + * in hex, for comparison against align_bits output from + * csd_v110_rtp_decode() or against rlpdl_align_bits accumulator + * in CSD NT lchan state. + */ +#define NTCSD_ALIGNED_EBITS 0x1B + +void ntcsd_dl_reset(struct gsm_lchan *lchan); +void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits, + uint8_t align_bits); +void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits, + uint8_t align_bits); +bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out); + +void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink, + const struct ph_tch_param *tch_ind, + const ubit_t *data, unsigned int data_len); +void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn, + const ubit_t *data, unsigned int data_len);
View file
osmo-bts_1.8.0.6.82d5.tar.xz/include/osmo-bts/csd_v110.h -> osmo-bts_1.8.0.13.0a34.tar.xz/include/osmo-bts/csd_v110.h
Changed
@@ -5,19 +5,16 @@ struct gsm_lchan; -struct csd_v110_frame_desc { +struct csd_v110_lchan_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; + uint8_t ra2_ir; /* intermediate rate (8 or 16 kbit/s) for RA2 step */ }; extern const struct csd_v110_lchan_desc csd_v110_lchan_desc256; int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, - const uint8_t *data, size_t data_len); + const uint8_t *data, size_t data_len, + uint8_t nt48_half_num); int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, - const uint8_t *rtp, size_t rtp_len); + uint8_t *align_bits, const uint8_t *rtp, size_t rtp_len);
View file
osmo-bts_1.8.0.6.82d5.tar.xz/include/osmo-bts/lchan.h -> osmo-bts_1.8.0.13.0a34.tar.xz/include/osmo-bts/lchan.h
Changed
@@ -4,6 +4,7 @@ #include <stdint.h> #include <netinet/in.h> +#include <osmocom/core/bits.h> #include <osmocom/core/timer.h> #include <osmocom/core/linuxlist.h> #include <osmocom/core/logging.h> @@ -295,9 +296,14 @@ uint8_t last_cmr; uint32_t last_fn; struct { - /* buffers to re-combine RLP frame from multiple Um blocks */ + /* RLP GSMTAP mechanism */ uint8_t rlp_buf_ul576/8; /* maximum size of RLP frame */ uint8_t rlp_buf_dl576/8; /* maximum size of RLP frame */ + /* alignment of RLP frames in DL for NT modes */ + ubit_t rlpdl_data_bits60 * 7; + uint16_t rlpdl_align_bits; + uint8_t rlpdl_fill_level; + ubit_t tchf48_nt_2ndhalf120; } csd; } tch;
View file
osmo-bts_1.8.0.6.82d5.tar.xz/include/osmo-bts/msg_utils.h -> osmo-bts_1.8.0.13.0a34.tar.xz/include/osmo-bts/msg_utils.h
Changed
@@ -25,6 +25,9 @@ /* Access 4th part of msgb control buffer */ #define rtpmsg_is_rfc5993_sid(x) ((x)->cb3) +/* Access 5th part of msgb control buffer */ +#define rtpmsg_csd_align_bits(x) ((x)->cb4) + /** * Classification of OML message. ETSI for plain GSM 12.21 * messages and IPA/Osmo for manufacturer messages.
View file
osmo-bts_1.8.0.6.82d5.tar.xz/src/common/Makefile.am -> osmo-bts_1.8.0.13.0a34.tar.xz/src/common/Makefile.am
Changed
@@ -51,6 +51,7 @@ bts_ctrl_commands.c \ bts_ctrl_lookup.c \ bts_shutdown_fsm.c \ + csd_rlp.c \ csd_v110.c \ l1sap.c \ cbch.c \
View file
osmo-bts_1.8.0.13.0a34.tar.xz/src/common/csd_rlp.c
Added
@@ -0,0 +1,228 @@ +/* This module has been split from l1sap.c; original header comments preserved: + * + * (C) 2011 by Harald Welte <laforge@gnumonks.org> + * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <stdint.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> + +#include <osmocom/core/bits.h> +#include <osmocom/core/msgb.h> +#include <osmocom/gsm/l1sap.h> +#include <osmocom/gsm/gsm_utils.h> +#include <osmocom/gsm/rsl.h> +#include <osmocom/gsm/rlp.h> +#include <osmocom/gsm/rtp_extensions.h> +#include <osmocom/core/gsmtap.h> +#include <osmocom/core/gsmtap_util.h> +#include <osmocom/core/utils.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/lchan.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/csd_rlp.h> + +/* In the case of TCH/F4.8 NT, each 240-bit RLP frame is split between + * two channel-coding blocks of 120 bits each. We need to know which + * frame numbers correspond to which half: in the UL-to-RTP path we have + * to set bit E2 based on the TDMA frame number at which we received the + * block in question, and in the DL direction we have to transmit the + * right half at the right time. + * + * See GSM 05.03 section 3.4.1 and the mapping tables of GSM 05.02; + * having "e2_map" in the array name shall serve as a mnemonic as to + * the sense of this array: 0 means 1st half and 1 means 2nd half, + * exactly as the value of bit E2 per TS 48.020 section 15.1. + */ +const uint8_t csd_tchf48_nt_e2_map26 = { + 4 = 1, /* B1 position */ + 13 = 1, /* B3 position */ + 21 = 1, /* B5 position */ +}; + +/* This function resets (clears) the state of the DL alignment buffer. + * It needs to be called when we encounter a gap (packet loss, invalid + * packets, etc) in our RTP input stream. */ +void ntcsd_dl_reset(struct gsm_lchan *lchan) +{ + lchan->tch.csd.rlpdl_fill_level = 0; +} + +/* This function is to be called with the decoded content of a single + * incoming RTP packet (data and alignment bits) for TCH/FH4.8 NT. */ +void ntcsd_dl_input_48(struct gsm_lchan *lchan, const ubit_t *data_bits, + uint8_t align_bits) +{ + memmove(lchan->tch.csd.rlpdl_data_bits, + lchan->tch.csd.rlpdl_data_bits + 60 * 2, 60 * 5); + memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 5, data_bits, 60 * 2); + lchan->tch.csd.rlpdl_align_bits <<= 4; + lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xF); + lchan->tch.csd.rlpdl_fill_level += 2; + if (lchan->tch.csd.rlpdl_fill_level > 7) + lchan->tch.csd.rlpdl_fill_level = 7; +} + +/* This function is to be called with the decoded content of a single + * incoming RTP packet (data and alignment bits) for TCH/F9.6 NT. */ +void ntcsd_dl_input_96(struct gsm_lchan *lchan, const ubit_t *data_bits, + uint8_t align_bits) +{ + memmove(lchan->tch.csd.rlpdl_data_bits, + lchan->tch.csd.rlpdl_data_bits + 60 * 4, 60 * 3); + memcpy(lchan->tch.csd.rlpdl_data_bits + 60 * 3, data_bits, 60 * 4); + lchan->tch.csd.rlpdl_align_bits <<= 8; + lchan->tch.csd.rlpdl_align_bits |= (align_bits & 0xFF); + lchan->tch.csd.rlpdl_fill_level += 4; + if (lchan->tch.csd.rlpdl_fill_level > 7) + lchan->tch.csd.rlpdl_fill_level = 7; +} + +/* This function is to be called to obtain a complete RLP frame for + * downlink transmission. It will provide either a properly aligned + * frame (return value true) or a filler (return value false). */ +bool ntcsd_dl_output(struct gsm_lchan *lchan, ubit_t *rlp_frame_out) +{ + if (lchan->tch.csd.rlpdl_fill_level < 4) + goto no_frame_out; + if (((lchan->tch.csd.rlpdl_align_bits >> 0) & 0xFF) == NTCSD_ALIGNED_EBITS) { + memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 3, + 60 * 4); + return true; + } + if (lchan->tch.csd.rlpdl_fill_level < 5) + goto no_frame_out; + if (((lchan->tch.csd.rlpdl_align_bits >> 2) & 0xFF) == NTCSD_ALIGNED_EBITS) { + memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 2, + 60 * 4); + return true; + } + if (lchan->tch.csd.rlpdl_fill_level < 6) + goto no_frame_out; + if (((lchan->tch.csd.rlpdl_align_bits >> 4) & 0xFF) == NTCSD_ALIGNED_EBITS) { + memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits + 60 * 1, + 60 * 4); + return true; + } + if (lchan->tch.csd.rlpdl_fill_level < 7) + goto no_frame_out; + if (((lchan->tch.csd.rlpdl_align_bits >> 6) & 0xFF) == NTCSD_ALIGNED_EBITS) { + memcpy(rlp_frame_out, lchan->tch.csd.rlpdl_data_bits, 60 * 4); + return true; + } +no_frame_out: + /* TS 44.021 section 12.1 says that a missing/unavailable 240-bit + * RLP frame is to be filled with 0 bits, unlike ones-fill + * used everywhere else in the world of V.110 and CSD. */ + memset(rlp_frame_out, 0, 60 * 4); + return false; +} + +/* process one MAC block of unpacked bits of a non-transparent CSD channel */ +void gsmtap_csd_rlp_process(struct gsm_lchan *lchan, bool is_uplink, + const struct ph_tch_param *tch_ind, + const ubit_t *data, unsigned int data_len) +{ + struct gsm_bts_trx *trx = lchan->ts->trx; + struct gsmtap_inst *inst = trx->bts->gsmtap.inst; + pbit_t *rlp_buf; + uint16_t arfcn; + int byte_len; + + if (!inst || !trx->bts->gsmtap.rlp) + return; + + if (lchan->csd_mode != LCHAN_CSD_M_NT) + return; + + if (is_uplink) + rlp_buf = lchan->tch.csd.rlp_buf_ul; + else + rlp_buf = lchan->tch.csd.rlp_buf_dl; + + /* TCH/F 9.6: 4x60bit block => 240bit RLP frame + * TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame + * TCH/H 4.8: 4x60bit block => 240bit RLP frame + * TCH/F 2.4: 2x36bit blocks => transparent only + * TCH/H 2.4: 4x36bit blocks => transparent only + * TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame + */ + + if (lchan->type == GSM_LCHAN_TCH_F && + lchan->tch_mode == GSM48_CMODE_DATA_6k0 && is_uplink) { + /* In this mode we have 120-bit MAC blocks; two of them need + * to be concatenated to render a 240-bit RLP frame. The first + * block is present in B0/B2/B4, and we have to use FN to + * detect this position. + * This code path is only for UL: in the case of DL, + * alignment logic elsewhere in the code will present us + * with a fully assembled RLP frame. */ + OSMO_ASSERT(data_len == 120); + if (csd_tchf48_nt_e2_maptch_ind->fn % 26 == 0) { + osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1); + return; + } + osmo_ubit2pbit_ext(rlp_buf, 120, data, 0, data_len, 1); + byte_len = 240/8; + } else if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_14k5) { + /* in this mode we have 290bit MAC blocks containing M1, M2 and 288 data bits; + * two of them need to be concatenated to render a + * 576-bit RLP frame. The start of a RLP frame is + * denoted by a block with M1-bit set to 0. */ + OSMO_ASSERT(data_len == 290); + ubit_t m1 = data0; + if (m1 == 0) { + osmo_ubit2pbit_ext(rlp_buf, 0, data, 2, data_len, 1); + return; + } + osmo_ubit2pbit_ext(rlp_buf, 288, data, 2, data_len, 1); + byte_len = 576/8; + } else { + byte_len = osmo_ubit2pbit_ext(rlp_buf, 0, data, 0, data_len, 1); + } + + if (trx->bts->gsmtap.rlp_skip_null) { + struct osmo_rlp_frame_decoded rlpf; + int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len); + if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL) + return; + } + + arfcn = trx->arfcn; + if (is_uplink) + arfcn |= GSMTAP_ARFCN_F_UPLINK; + + gsmtap_send_ex(inst, GSMTAP_TYPE_GSM_RLP, arfcn, lchan->ts->nr, + lchan->type == GSM_LCHAN_TCH_H ? GSMTAP_CHANNEL_VOICE_H : GSMTAP_CHANNEL_VOICE_F, + lchan->nr, tch_ind->fn, tch_ind->rssi, 0, rlp_buf, byte_len); + +} + +/* wrapper for downlink path */ +void gsmtap_csd_rlp_dl(struct gsm_lchan *lchan, uint32_t fn, + const ubit_t *data, unsigned int data_len) +{ + /* 'fake' tch_ind containing all-zero so gsmtap code can be shared + * between UL and DL */ + const struct ph_tch_param fake_tch_ind = { .fn = fn }; + gsmtap_csd_rlp_process(lchan, false, &fake_tch_ind, data, data_len); +}
View file
osmo-bts_1.8.0.6.82d5.tar.xz/src/common/csd_v110.c -> osmo-bts_1.8.0.13.0a34.tar.xz/src/common/csd_v110.c
Changed
@@ -20,6 +20,7 @@ */ #include <stdint.h> +#include <stdbool.h> #include <errno.h> #include <osmocom/core/bits.h> @@ -37,24 +38,28 @@ #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 }, + .num_blocks = 1, + .num_bits = 290, + .ra2_ir = 16, }, #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 }, + .num_blocks = 4, + .num_bits = 60, + .ra2_ir = 16, }, 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 }, + /* TCH/FH4.8: 2 * 60 bits every 20 ms (6.0 kbit/s) */ + .num_blocks = 2, + .num_bits = 60, + .ra2_ir = 8, }, 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 }, + /* TCH/FH2.4: 2 * 36 bits every 20 ms (3.6 kbit/s) */ + .num_blocks = 2, + .num_bits = 36, + .ra2_ir = 8, }, }; @@ -74,16 +79,14 @@ }; int csd_v110_rtp_encode(const struct gsm_lchan *lchan, uint8_t *rtp, - const uint8_t *data, size_t data_len) + const uint8_t *data, size_t data_len, + uint8_t nt48_half_num) { - const struct csd_v110_frame_desc *desc; + const struct csd_v110_lchan_desc *desc; ubit_t ra_bits80 * 4; OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc)); - if (lchan->type == GSM_LCHAN_TCH_F) - desc = &csd_v110_lchan_desclchan->tch_mode.fr; - else - desc = &csd_v110_lchan_desclchan->tch_mode.hr; + desc = &csd_v110_lchan_desclchan->tch_mode; if (OSMO_UNLIKELY(desc->num_blocks == 0)) return -ENOTSUP; @@ -109,9 +112,15 @@ /* 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_bits0 = 0; /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */ - df.e_bits1 = (i >> 1) & 0x01; /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */ - df.e_bits2 = (i >> 0) & 0x01; /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */ + /* E1: as per 15.1.2, shall be set to 0 (for BSS-MSC) */ + df.e_bits0 = 0; + /* E2: 0 for Q1/Q2, 1 for Q3/Q4 */ + if (desc->num_blocks == 4) + df.e_bits1 = (i >> 1) & 0x01; + else + df.e_bits1 = nt48_half_num; + /* E3: 0 for Q1/Q3, 1 for Q2/Q4 */ + df.e_bits2 = (i >> 0) & 0x01; } else { /* transparent: as per 3GPP TS 44.021, Figure 4 */ df.e_bits0 = e1e2e3_maplchan->csd_mode0; /* E1 */ @@ -124,7 +133,7 @@ ra1_ra2: /* RA1/RA2: convert from an intermediate rate to 64 kbit/s */ - if (desc->num_blocks == 4) { + if (desc->ra2_ir == 16) { /* 4 * 80 bits (16 kbit/s) => 2 bits per octet */ for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) { rtpi = (0xff >> 2); @@ -142,17 +151,29 @@ return RFC4040_RTP_PLEN; } +static bool check_v110_align(const ubit_t *ra_bits) +{ + int i; + ubit_t bit0 = 0, bit1 = 1; + + /* The weird code structure is for performance optimization, + * to avoid conditionals inside loops. */ + for (i = 0; i < 8; i++) + bit0 |= ra_bitsi; + for (i = 1; i < 10; i++) + bit1 &= ra_bitsi * 8; + return (bit0 == 0) && (bit1 == 1); +} + int csd_v110_rtp_decode(const struct gsm_lchan *lchan, uint8_t *data, - const uint8_t *rtp, size_t rtp_len) + uint8_t *align_bits, const uint8_t *rtp, size_t rtp_len) { - const struct csd_v110_frame_desc *desc; + const struct csd_v110_lchan_desc *desc; ubit_t ra_bits80 * 4; + uint8_t align_accum = 0; OSMO_ASSERT(lchan->tch_mode < ARRAY_SIZE(csd_v110_lchan_desc)); - if (lchan->type == GSM_LCHAN_TCH_F) - desc = &csd_v110_lchan_desclchan->tch_mode.fr; - else - desc = &csd_v110_lchan_desclchan->tch_mode.hr; + desc = &csd_v110_lchan_desclchan->tch_mode; if (OSMO_UNLIKELY(desc->num_blocks == 0)) return -ENOTSUP; @@ -160,7 +181,7 @@ return -EINVAL; /* RA1/RA2: convert from 64 kbit/s to an intermediate rate */ - if (desc->num_blocks == 4) { + if (desc->ra2_ir == 16) { /* 4 * 80 bits (16 kbit/s) => 2 bits per octet */ for (unsigned int i = 0, j = 0; i < RFC4040_RTP_PLEN; i++) { ra_bitsj++ = (rtpi >> 7); @@ -176,13 +197,24 @@ for (unsigned int i = 0; i < desc->num_blocks; i++) { struct osmo_v110_decoded_frame df; + /* We require our RTP input to consist of aligned V.110 + * frames. If we get misaligned input, let's catch it + * explicitly, rather than send garbage downstream. */ + if (!check_v110_align(&ra_bitsi * 80)) + return -EINVAL; /* convert a V.110 80-bit frame to a V.110 36-/60-bit frame */ osmo_v110_decode_frame(&df, &ra_bitsi * 80, 80); if (desc->num_bits == 60) osmo_csd_12k_6k_encode_frame(&datai * 60, 60, &df); else /* desc->num_bits == 36 */ osmo_csd_3k6_encode_frame(&datai * 36, 36, &df); + /* save bits E2 & E3 that may be needed for RLP alignment */ + align_accum <<= 2; + align_accum |= df.e_bits1 << 1; + align_accum |= df.e_bits2 << 0; } + if (align_bits) + *align_bits = align_accum; return desc->num_blocks * desc->num_bits; }
View file
osmo-bts_1.8.0.6.82d5.tar.xz/src/common/l1sap.c -> osmo-bts_1.8.0.13.0a34.tar.xz/src/common/l1sap.c
Changed
@@ -60,6 +60,7 @@ #include <osmo-bts/pcuif_proto.h> #include <osmo-bts/cbch.h> #include <osmo-bts/asci.h> +#include <osmo-bts/csd_rlp.h> #include <osmo-bts/csd_v110.h> /* determine the CCCH block number based on the frame number */ @@ -1490,6 +1491,216 @@ lchan->tch.dtx_fr_hr_efr.dl_sid_transmitted = true; } +/* TDMA frame number of burst 'a' % 26 is the table index. + * This mapping is valid for both TCH/H(0) and TCH/H(1). */ +const uint8_t sched_tchh_dl_csd_map26 = { + 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) */ +}; + +/* In the case of half-rate CSD, we need to send TCH.req every 40 ms instead of + * every 20 ms. However, both TS 48.103 and common sense desire for + * interoperability (between FR and HR, between OsmoBTS and E1 BTS) + * require 20 ms RTP packetization interval. Hence a special adapter + * function is needed. */ +static int tch_rts_ind_csd_hr(struct gsm_bts_trx *trx, struct gsm_lchan *lchan, + struct ph_tch_param *rts_ind) +{ + uint8_t chan_nr = rts_ind->chan_nr; + uint32_t fn = rts_ind->fn; + const struct csd_v110_lchan_desc *desc; + unsigned bits_per_20ms; + struct msgb *input_msg2, *phy_msg; + struct osmo_phsap_prim *resp_l1sap, empty_l1sap; + uint8_t *phy_data; + struct gsm_time g_time; + int i; + + /* The generic scheduler still sends us TCH-RTS.ind every 20 ms, + * hence we have to filter out half of them here. */ + if (!sched_tchh_dl_csd_mapfn % 26) + return 0; + + gsm_fn2gsmtime(&g_time, fn); + + desc = &csd_v110_lchan_desclchan->tch_mode; + bits_per_20ms = desc->num_blocks * desc->num_bits; + OSMO_ASSERT(bits_per_20ms != 0); + + for (i = 0; i < ARRAY_SIZE(input_msg); i++) { + if (!lchan->loopback && lchan->abis_ip.rtp_socket) { + osmo_rtp_socket_poll(lchan->abis_ip.rtp_socket); + lchan->abis_ip.rtp_socket->rx_user_ts += GSM_RTP_DURATION; + } + input_msgi = msgb_dequeue_count(&lchan->dl_tch_queue, + &lchan->dl_tch_queue_len); + } + + if (lchan->csd_mode == LCHAN_CSD_M_NT) { + for (i = 0; i < ARRAY_SIZE(input_msg); i++) { + if (input_msgi) { + ntcsd_dl_input_48(lchan, input_msgi->data, + rtpmsg_csd_align_bits(input_msgi)); + } else { + ntcsd_dl_reset(lchan); + } + } + } + + phy_msg = l1sap_msgb_alloc(bits_per_20ms * 2); + if (phy_msg) { + resp_l1sap = msgb_l1sap_prim(phy_msg); + phy_msg->l2h = phy_msg->tail; + if (lchan->csd_mode == LCHAN_CSD_M_NT) { + bool good_rlp; + phy_data = msgb_put(phy_msg, 240); /* RLP frame */ + good_rlp = ntcsd_dl_output(lchan, phy_data); + if (good_rlp) + gsmtap_csd_rlp_dl(lchan, fn, phy_data, 240); + } else { + for (i = 0; i < ARRAY_SIZE(input_msg); i++) { + phy_data = msgb_put(phy_msg, bits_per_20ms); + if (input_msgi) { + memcpy(phy_data, input_msgi->data, + bits_per_20ms); + } else { + /* IDLE frame, filled with 1 bits */ + memset(phy_data, 0x01, bits_per_20ms); + } + } + } + } else { + resp_l1sap = &empty_l1sap; + } + + for (i = 0; i < ARRAY_SIZE(input_msg); i++) { + if (input_msgi) + msgb_free(input_msgi); + } + + memset(resp_l1sap, 0, sizeof(*resp_l1sap)); + osmo_prim_init(&resp_l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_REQUEST, + phy_msg); + resp_l1sap->u.tch.chan_nr = chan_nr; + resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = 0; /* M bit is undefined for clearmode */ + + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Tx TCH.req\n"); + + l1sap_down(trx, resp_l1sap); + + return 0; +} + +/* The case of TCH/F4.8 NT also requires special processing that is + * somewhat similar to half-rate CSD. We have to produce an RLP frame + * for DL every 40 ms, thus it makes the most sense for us to poll + * the Rx jitter buffer every 40 ms just like with CSD-HR. However, + * we need to send TCH.req to the PHY every 20 ms, sending either + * the first half or the second half of the RLP frame we put together + * every 40 ms. */ +static int tch_rts_ind_tchf48_nt(struct gsm_bts_trx *trx, + struct gsm_lchan *lchan, + struct ph_tch_param *rts_ind) +{ + uint8_t chan_nr = rts_ind->chan_nr; + uint32_t fn = rts_ind->fn; + struct msgb *input_msg, *phy_msg; + struct osmo_phsap_prim *resp_l1sap, empty_l1sap; + ubit_t rlp_frame240; + bool good_rlp; + struct gsm_time g_time; + int i; + + gsm_fn2gsmtime(&g_time, fn); + + /* Input processing happens every 40 ms */ + if (csd_tchf48_nt_e2_mapfn % 26 == 0) { + for (i = 0; i < 2; i++) { + if (!lchan->loopback && lchan->abis_ip.rtp_socket) { + osmo_rtp_socket_poll(lchan->abis_ip.rtp_socket); + lchan->abis_ip.rtp_socket->rx_user_ts += GSM_RTP_DURATION; + } + input_msg = msgb_dequeue_count(&lchan->dl_tch_queue, + &lchan->dl_tch_queue_len); + if (input_msg) { + ntcsd_dl_input_48(lchan, input_msg->data, + rtpmsg_csd_align_bits(input_msg)); + msgb_free(input_msg); + } else { + ntcsd_dl_reset(lchan); + } + } + good_rlp = ntcsd_dl_output(lchan, rlp_frame); + if (good_rlp) + gsmtap_csd_rlp_dl(lchan, fn, rlp_frame, 240); + memcpy(lchan->tch.csd.tchf48_nt_2ndhalf, rlp_frame+120, 120); + } + + /* back to every 20 ms code path */ + phy_msg = l1sap_msgb_alloc(120); /* half of RLP frame */ + if (phy_msg) { + resp_l1sap = msgb_l1sap_prim(phy_msg); + phy_msg->l2h = msgb_put(phy_msg, 120); + if (csd_tchf48_nt_e2_mapfn % 26 == 0) + memcpy(phy_msg->l2h, rlp_frame, 120); + else + memcpy(phy_msg->l2h, lchan->tch.csd.tchf48_nt_2ndhalf, 120); + } else { + resp_l1sap = &empty_l1sap; + } + + memset(resp_l1sap, 0, sizeof(*resp_l1sap)); + osmo_prim_init(&resp_l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_REQUEST, + phy_msg); + resp_l1sap->u.tch.chan_nr = chan_nr; + resp_l1sap->u.tch.fn = fn; + resp_l1sap->u.tch.marker = 0; /* M bit is undefined for clearmode */ + + LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Tx TCH.req\n"); + + l1sap_down(trx, resp_l1sap); + + return 0; +} + +/* For TCH/F9.6 NT we need much less special processing than for TCH/F4.8 NT + * or for CSD-HR, but we still need to handle the possibility of misaligned + * RTP input, i.e., pseudo-V.110 frames aligned in the packet, but not + * forming proper RLP frame alignment via E2 & E3 bits. */ +static void tchf96_nt_dl_alignment(struct gsm_lchan *lchan, struct msgb *msg, + uint32_t fn) +{ + bool good_rlp; + + if (!msg) { + ntcsd_dl_reset(lchan); + /* FIXME: do we really need to generate a PHY packet filled + * with 0 bits to satisfy TS 44.021 section 12.1, or can we + * get by with letting the PHY fill in ones like it does + * for all other CSD modes? */ + return; + } + /* Fast path: handle the good case of already proper alignment */ + if ((rtpmsg_csd_align_bits(msg) & 0xFF) == NTCSD_ALIGNED_EBITS) { + /* clear the buffer in case we have to do misaligned packets + * later, but otherwise let it go! */ + ntcsd_dl_reset(lchan); + gsmtap_csd_rlp_dl(lchan, fn, msgb_l2(msg), msgb_l2len(msg)); + return; + } + /* Slow path: realign like in other NT modes */ + OSMO_ASSERT(msgb_l2len(msg) == 240); + ntcsd_dl_input_96(lchan, msgb_l2(msg), rtpmsg_csd_align_bits(msg)); + good_rlp = ntcsd_dl_output(lchan, msgb_l2(msg)); + if (good_rlp) + gsmtap_csd_rlp_dl(lchan, fn, msgb_l2(msg), msgb_l2len(msg)); +} + /* TCH-RTS-IND prim received from bts model */ static int l1sap_tch_rts_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_tch_param *rts_ind) @@ -1515,6 +1726,15 @@ LOGPLCGT(lchan, &g_time, DL1P, LOGL_DEBUG, "Rx TCH-RTS.ind\n"); } + /* CSD-HR requires special processing */ + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA && + lchan->type == GSM_LCHAN_TCH_H) + return tch_rts_ind_csd_hr(trx, lchan, rts_ind); + /* so does TCH/F4.8 NT mode */ + if (lchan->tch_mode == GSM48_CMODE_DATA_6k0 && + lchan->csd_mode == LCHAN_CSD_M_NT) + return tch_rts_ind_tchf48_nt(trx, lchan, rts_ind); + if (!lchan->loopback && lchan->abis_ip.rtp_socket) { osmo_rtp_socket_poll(lchan->abis_ip.rtp_socket); /* FIXME: we _assume_ that we never miss TDMA @@ -1561,6 +1781,24 @@ &resp_l1sap, &empty_l1sap); } + /* minimal extra handling for the remaining CSD NT modes */ + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA && + lchan->csd_mode == LCHAN_CSD_M_NT) { + switch (lchan->tch_mode) { + case GSM48_CMODE_DATA_12k0: + tchf96_nt_dl_alignment(lchan, resp_msg, fn); + break; + case GSM48_CMODE_DATA_14k5: + gsmtap_csd_rlp_dl(lchan, fn, msgb_l2(resp_msg), + msgb_l2len(resp_msg)); + break; + default: + LOGPLCGT(lchan, &g_time, DL1P, LOGL_ERROR, + "Invalid TCH mode in TCH-RTS.ind under CSD NT\n"); + break; + } + } + memset(resp_l1sap, 0, sizeof(*resp_l1sap)); osmo_prim_init(&resp_l1sap->oph, SAP_GSM_PH, PRIM_TCH, PRIM_OP_REQUEST, resp_msg); @@ -1850,127 +2088,112 @@ 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) +/* a helper function for the logic in l1sap_tch_ind() */ +static void send_ul_rtp_packet(struct gsm_lchan *lchan, uint32_t fn, + const uint8_t *rtp_pl, uint16_t rtp_pl_len) { - struct gsm_bts_trx *trx = lchan->ts->trx; - struct gsmtap_inst *inst = trx->bts->gsmtap.inst; - pbit_t *rlp_buf; - uint16_t arfcn; - int byte_len; - - if (!inst || !trx->bts->gsmtap.rlp) - return; - - if (lchan->csd_mode != LCHAN_CSD_M_NT) - return; - - if (is_uplink) - rlp_buf = lchan->tch.csd.rlp_buf_ul; - else - rlp_buf = lchan->tch.csd.rlp_buf_dl; - - /* TCH/F 9.6: 4x60bit block => 240bit RLP frame - * TCH/F 4.8: 2x 2x60bit blocks starting at B0/B2/B4 => 240bit RLP frame - * TCH/H 4.8: 4x60bit block => 240bit RLP frame - * TCH/F 2.4: 2x36bit blocks => transparent only - * TCH/H 2.4: 4x36bit blocks => transparent only - * TCH/F 14.4: 2x 290 bit block (starting with M1=0) => 576-bit RLP frame - */ - - if (lchan->type == GSM_LCHAN_TCH_F && lchan->tch_mode == GSM48_CMODE_DATA_6k0) { - /* 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 = data4*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 = data0; - 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); - } + struct gsm_bts *bts = lchan->ts->trx->bts; - if (trx->bts->gsmtap.rlp_skip_null) { - struct osmo_rlp_frame_decoded rlpf; - int rc = osmo_rlp_decode(&rlpf, 0, rlp_buf, byte_len); - if (rc == 0 && rlpf.ftype == OSMO_RLP_FT_U && rlpf.u_ftype == OSMO_RLP_U_FT_NULL) - return; + 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; +} - arfcn = trx->arfcn; - if (is_uplink) - arfcn |= GSMTAP_ARFCN_F_UPLINK; +/* A modified version of send_ul_rtp_packet() that skips fn_ms_adj() check: + * this check will produce a lot of noise when we send two RTP packets + * back-to-back every 40 ms on the same frame number, */ +static void send_ul_rtp_packet_hrdata(struct gsm_lchan *lchan, + const uint8_t *rtp_pl, uint16_t rtp_pl_len) +{ + struct gsm_bts *bts = lchan->ts->trx->bts; - 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); + 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, rtp_pl_len, + GSM_RTP_DURATION, + lchan->rtp_tx_marker); + /* Only clear the marker bit once we have sent a RTP packet with it */ + lchan->rtp_tx_marker = false; } -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) +static void handle_tch_ind_csd_fr(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_plRFC4040_RTP_PLEN; + uint8_t tchf48_half = csd_tchf48_nt_e2_maptch_ind->fn % 26; int rc; gsmtap_csd_rlp_process(lchan, true, tch_ind, data, data_len); - rc = csd_v110_rtp_encode(lchan, &rtp_pl0, data, data_len); + /* the last argument matters only for TCH/F4.8 NT mode, + * ignored in all other cases. */ + rc = csd_v110_rtp_encode(lchan, rtp_pl, data, data_len, tchf48_half); 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); + send_ul_rtp_packet(lchan, tch_ind->fn, rtp_pl, sizeof(rtp_pl)); +} - osmo_rtp_send_frame_ext(lchan->abis_ip.rtp_socket, - &rtp_pl0, 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; +static void handle_csd_hr_bfi(struct gsm_lchan *lchan) +{ + uint8_t rtp_plRFC4040_RTP_PLEN; + int rc, i; + + rc = csd_v110_rtp_encode(lchan, rtp_pl, NULL, 0, 0); + if (rc < 0) + return; + + for (i = 0; i < 2; i++) + send_ul_rtp_packet_hrdata(lchan, rtp_pl, sizeof(rtp_pl)); } -/* 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) +static void handle_tch_ind_csd_hr(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; + const struct csd_v110_lchan_desc *desc; + unsigned bits_per_20ms; + uint8_t rtp_plRFC4040_RTP_PLEN; + int rc, i; - 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); + desc = &csd_v110_lchan_desclchan->tch_mode; + bits_per_20ms = desc->num_blocks * desc->num_bits; + OSMO_ASSERT(bits_per_20ms != 0); + + if (data_len != bits_per_20ms * 2) { + handle_csd_hr_bfi(lchan); + return; + } + gsmtap_csd_rlp_process(lchan, true, tch_ind, data, data_len); + + for (i = 0; i < 2; i++) { + rc = csd_v110_rtp_encode(lchan, rtp_pl, + data + i * bits_per_20ms, + bits_per_20ms, i); + if (rc < 0) + return; + send_ul_rtp_packet_hrdata(lchan, rtp_pl, sizeof(rtp_pl)); } - /* Only clear the marker bit once we have sent a RTP packet with it */ - lchan->rtp_tx_marker = false; +} + +static void handle_tch_ind_csd(struct gsm_lchan *lchan, const struct ph_tch_param *tch_ind, + const uint8_t *data, uint16_t data_len) +{ + if (lchan->type == GSM_LCHAN_TCH_F) + handle_tch_ind_csd_fr(lchan, tch_ind, data, data_len); + else + handle_tch_ind_csd_hr(lchan, tch_ind, data, data_len); } /* a helper function for emitting HR1 UL in RFC 5993 format */ @@ -1988,7 +2211,7 @@ else toc = 0x00; msgb_push_u8(msg, toc); - send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + send_ul_rtp_packet(lchan, fn, msg->data, msg->len); } /* a helper function for emitting FR/EFR UL in TW-TS-001 format */ @@ -2015,9 +2238,9 @@ teh |= 0x01; if (send_frame) { msgb_push_u8(msg, teh); - send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + send_ul_rtp_packet(lchan, fn, msg->data, msg->len); } else { - send_ul_rtp_packet_speech(lchan, fn, &teh, 1); + send_ul_rtp_packet(lchan, fn, &teh, 1); } } @@ -2056,7 +2279,7 @@ /* 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); + send_ul_rtp_packet(lchan, fn, ecu_out, rc); return; } } @@ -2064,7 +2287,7 @@ /* 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); + send_ul_rtp_packet(lchan, fn, NULL, 0); return; } @@ -2136,7 +2359,7 @@ if (lchan->abis_ip.rtp_extensions & OSMO_RTP_EXT_TWTS001) send_rtp_twts001(lchan, fn, msg, true); else - send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + send_ul_rtp_packet(lchan, fn, msg->data, msg->len); } else if (lchan->type == GSM_LCHAN_TCH_H && lchan->tch_mode == GSM48_CMODE_SPEECH_V1) { /* HR codec: TS 101 318 or RFC 5993, @@ -2144,14 +2367,14 @@ if (bts->emit_hr_rfc5993) send_rtp_rfc5993(lchan, fn, msg); else - send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + send_ul_rtp_packet(lchan, fn, msg->data, msg->len); } else { /* generic case, no RTP alterations */ - send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len); + send_ul_rtp_packet(lchan, fn, msg->data, msg->len); } break; case RSL_CMOD_SPD_DATA: - send_ul_rtp_packet_data(lchan, tch_ind, msg->data, msg->len); + handle_tch_ind_csd(lchan, tch_ind, msg->data, msg->len); break; case RSL_CMOD_SPD_SIGN: return 0; /* drop stale TCH.ind */ @@ -2166,7 +2389,11 @@ return 1; } } else { - tch_ul_bfi_handler(lchan, &g_time, msg); + if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA && + lchan->type == GSM_LCHAN_TCH_H) + handle_csd_hr_bfi(lchan); + else + tch_ul_bfi_handler(lchan, &g_time, msg); } lchan->tch.last_fn = fn; @@ -2433,6 +2660,7 @@ struct gsm_bts *bts = lchan->ts->trx->bts; struct msgb *msg; bool rfc5993_sid = false; + uint8_t csd_align_bits = 0; rate_ctr_inc2(bts->ctrs, BTS_CTR_RTP_RX_TOTAL); if (marker) @@ -2467,13 +2695,9 @@ return; if (lchan->rsl_cmode == RSL_CMOD_SPD_DATA) { - int rc = csd_v110_rtp_decode(lchan, msg->tail, + int rc = csd_v110_rtp_decode(lchan, msg->tail, &csd_align_bits, 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); @@ -2500,6 +2724,8 @@ rtpmsg_ts(msg) = timestamp; /* Store RFC 5993 SID flag likewise */ rtpmsg_is_rfc5993_sid(msg) = rfc5993_sid; + /* ditto with CSD alignment bits */ + rtpmsg_csd_align_bits(msg) = csd_align_bits; /* make sure the queue doesn't get too long */ lchan_dl_tch_queue_enqueue(lchan, msg, 1);
View file
osmo-bts_1.8.0.6.82d5.tar.xz/src/osmo-bts-trx/sched_lchan_tchh.c -> osmo-bts_1.8.0.13.0a34.tar.xz/src/osmo-bts-trx/sched_lchan_tchh.c
Changed
@@ -117,14 +117,7 @@ /* 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_map26 = { - 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) */ -}; +extern const uint8_t sched_tchh_dl_csd_map26; static int decode_hr_facch(struct l1sched_ts *l1ts, const struct trx_ul_burst_ind *bi)
View file
osmo-bts_1.8.0.6.82d5.tar.xz/tests/csd/csd_test.c -> osmo-bts_1.8.0.13.0a34.tar.xz/tests/csd/csd_test.c
Changed
@@ -93,7 +93,7 @@ static void exec_test_case(const struct test_case *tc) { - const struct csd_v110_frame_desc *desc; + const struct csd_v110_lchan_desc *desc; uint8_t rtpRFC4040_RTP_PLEN = { 0 }; ubit_t data_encBBUF_MAX; ubit_t data_decBBUF_MAX; @@ -101,10 +101,7 @@ /* 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_desctc->tch_mode.fr; - else - desc = &csd_v110_lchan_desctc->tch_mode.hr; + desc = &csd_v110_lchan_desctc->tch_mode; /* total number of bits carried by a radio interface block */ const unsigned int bit_num = desc->num_bits * desc->num_blocks; @@ -127,7 +124,7 @@ data_enci = i & 0x01; /* encode an RTP frame and print it */ - rc = csd_v110_rtp_encode(&lchan, &rtp0, &data_enc0, bit_num); + rc = csd_v110_rtp_encode(&lchan, &rtp0, &data_enc0, bit_num, 0); fprintf(stderr, "i csd_v110_rtp_encode() returns %d\n", rc); if (rc != RFC4040_RTP_PLEN) return; @@ -136,7 +133,7 @@ fprintf(stderr, " %s\n", osmo_hexdump(&rtpi * 16, 16)); /* decode the encoded RTP frame */ - rc = csd_v110_rtp_decode(&lchan, &data_dec0, &rtp0, sizeof(rtp)); + rc = csd_v110_rtp_decode(&lchan, &data_dec0, NULL, &rtp0, sizeof(rtp)); fprintf(stderr, "i csd_v110_rtp_decode() returns %d\n", rc); if (rc != bit_num) return; @@ -151,7 +148,7 @@ fprintf(stderr, "i Testing '%s' (IDLE)\n", tc->name); /* encode an idle RTP frame and print it */ - rc = csd_v110_rtp_encode(&lchan, &rtp0, &data_enc0, 0); + rc = csd_v110_rtp_encode(&lchan, &rtp0, &data_enc0, 0, 0); fprintf(stderr, "i csd_v110_rtp_encode() returns %d\n", rc); if (rc != RFC4040_RTP_PLEN) return;
View file
osmo-bts_1.8.0.6.82d5.tar.xz/tests/csd/csd_test.err -> osmo-bts_1.8.0.13.0a34.tar.xz/tests/csd/csd_test.err
Changed
@@ -99,29 +99,29 @@ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 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 Testing 'TCH/H4.8' (bitnum=120) 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 + 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/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 + 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 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 + 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 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) @@ -149,28 +149,28 @@ ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 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 Testing 'TCH/H2.4' (bitnum=72) 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 + 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 7f 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 7f 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/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 + 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 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 + 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 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
View file
osmo-bts_1.8.0.6.82d5.dsc
Deleted
@@ -1,24 +0,0 @@ -Format: 3.0 (native) -Source: osmo-bts -Binary: osmo-bts, osmo-bts-trx, osmo-bts-trx-dbg, osmo-bts-virtual, osmo-bts-virtual-dbg, osmo-bts-doc -Architecture: any all -Version: 1.8.0.6.82d5 -Maintainer: Osmocom team <openbsc@lists.osmocom.org> -Homepage: https://projects.osmocom.org/projects/osmobts -Standards-Version: 3.9.8 -Vcs-Browser: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts -Vcs-Git: https://gitea.osmocom.org/cellular-infrastructure/osmo-bts -Build-Depends: debhelper (>= 10), pkg-config, dh-autoreconf, autotools-dev, libosmocore-dev (>= 1.10.0), libosmo-abis-dev (>= 1.6.0), libosmo-netif-dev (>= 1.5.0), libgps-dev, txt2man, osmo-gsm-manuals-dev (>= 1.6.0) -Package-List: - osmo-bts deb net optional arch=any - osmo-bts-doc deb doc optional arch=all - osmo-bts-trx deb net optional arch=any - osmo-bts-trx-dbg deb debug extra arch=any - osmo-bts-virtual deb net optional arch=any - osmo-bts-virtual-dbg deb debug extra arch=any -Checksums-Sha1: - 9b0396846ee7a49c1ebef1d66b0b9fefbca1a293 511256 osmo-bts_1.8.0.6.82d5.tar.xz -Checksums-Sha256: - 27a31e91f498f66710d401db31054ee2906715ed489cfa91022612bcbc8a9a7d 511256 osmo-bts_1.8.0.6.82d5.tar.xz -Files: - c45ad3aa27e20cb8ec754b63cc808008 511256 osmo-bts_1.8.0.6.82d5.tar.xz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.