falconia has submitted this change. (
https://gerrit.osmocom.org/c/osmo-bts/+/36896?usp=email )
Change subject: common: add support for TW-TS-001
......................................................................
common: add support for TW-TS-001
Themyscira Wireless Technical Specification TW-TS-001 defines
an enhanced RTP transport format for FR and EFR codecs within
an IP-based GSM RAN, restoring the full functionality and semantics
of GSM 08.60 TRAU-UL format that were lost in the industry transition
to RTP with payload formats standardized by TIPHON and IETF.
Given that this new enhanced RTP transport format runs counter
to commonly accepted standards, it is strictly optional. OsmoBTS
always accepts both basic and extended RTP formats, but it sends
the extended RTP format of TW-TS-001 only when commanded to do so
by the BSC via an RSL extension IE; OsmoBSC will in turn direct
the BTS to use this extension only when the CN asks for it via
the BSSMAP extension defined in TW-TS-003.
Spec references:
https://www.freecalypso.org/specs/tw-ts-001-v010100.txt
https://www.freecalypso.org/specs/tw-ts-003-v010002.txt
Related: OS#6448
Depends: I0eccfe5ddcf44f8f20440acb01e2d4870ec0cd91 (libosmocore)
Change-Id: Id997e8666bc19e60936aaa83b43a968d30320bd7
---
M TODO-RELEASE
M include/osmo-bts/lchan.h
M src/common/bts.c
M src/common/l1sap.c
M src/common/rsl.c
M src/common/rtp_input_preen.c
6 files changed, 151 insertions(+), 18 deletions(-)
Approvals:
falconia: Verified
laforge: Looks good to me, approved
pespin: Looks good to me, but someone else must approve
diff --git a/TODO-RELEASE b/TODO-RELEASE
index 96426a5..6448b19 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -9,4 +9,5 @@
#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
+libosmogsm >1.9.0 BTS feature & RSL defs for ThemWi RTP extensions
libosmoctrl >1.9.0 use ctrl_cmd_send2()
diff --git a/include/osmo-bts/lchan.h b/include/osmo-bts/lchan.h
index 585483b..60c2710 100644
--- a/include/osmo-bts/lchan.h
+++ b/include/osmo-bts/lchan.h
@@ -168,6 +168,7 @@
uint16_t conn_id;
uint8_t rtp_payload;
uint8_t rtp_payload2;
+ uint8_t rtp_extensions;
uint8_t speech_mode;
struct {
bool use;
diff --git a/src/common/bts.c b/src/common/bts.c
index 56765ec..633e0d1 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -393,6 +393,7 @@
osmo_bts_set_feature(bts->features, BTS_FEAT_ETWS_PN);
osmo_bts_set_feature(bts->features, BTS_FEAT_IPV6_NSVC);
osmo_bts_set_feature(bts->features, BTS_FEAT_PAGING_COORDINATION);
+ osmo_bts_set_feature(bts->features, BTS_FEAT_TWTS001);
/* Maximum TA supported by the PHY (can be overridden by PHY specific code) */
bts->support.max_ta = MAX_TA_DEF;
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index 5f275cd..5a900f8 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -34,6 +34,7 @@
#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>
@@ -1990,13 +1991,42 @@
send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len);
}
+/* a helper function for emitting FR/EFR UL in TW-TS-001 format */
+static void send_rtp_twts001(struct gsm_lchan *lchan, uint32_t fn,
+ struct msgb *msg, bool good_frame)
+{
+ uint8_t teh;
+ bool send_frame;
+
+ if (msg->len == GSM_FR_BYTES || msg->len == GSM_EFR_BYTES) {
+ if (good_frame)
+ teh = 0xE0;
+ else
+ teh = 0xE2;
+ send_frame = true;
+ } else {
+ teh = 0xE6;
+ send_frame = false;
+ }
+ /* always set DTXd and TAF bits */
+ if (lchan->ts->trx->bts->dtxd)
+ teh |= 0x08;
+ if (fn % 104 == 52)
+ teh |= 0x01;
+ if (send_frame) {
+ msgb_push_u8(msg, teh);
+ send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len);
+ } else {
+ send_ul_rtp_packet_speech(lchan, fn, &teh, 1);
+ }
+}
+
/* 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.
+ * Please note that the msgb passed to this function is used only when
+ * the CN asked the BSS to emit extended RTP formats (currently TW-TS-001,
+ * later TW-TS-002 as well) that can indicate 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)
@@ -2005,6 +2035,20 @@
uint8_t ecu_out[GSM_FR_BYTES];
int rc;
+ /* Are we on TCH/FS or TCH/EFS, configured to emit TW-TS-001 extended
+ * RTP format? If so, emit BFI per that spec. The placement of
+ * this check before the ECU is intentional: the modes of TW-TS-001
+ * UL output (closely replicating the classic GSM architecture in which
+ * a BTS never applies an ECU to its UL output) and internal UL ECU
+ * are mutually exclusive. */
+ if ((lchan->abis_ip.rtp_extensions & OSMO_RTP_EXT_TWTS001) &&
+ lchan->type == GSM_LCHAN_TCH_F &&
+ (lchan->tch_mode == GSM48_CMODE_SPEECH_V1 ||
+ lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)) {
+ send_rtp_twts001(lchan, fn, msg, false);
+ return;
+ }
+
/* 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)) {
@@ -2084,11 +2128,27 @@
/* hand msg to RTP code for transmission */
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
+ /* support different RTP output formats per codec */
+ if (lchan->type == GSM_LCHAN_TCH_F &&
+ (lchan->tch_mode == GSM48_CMODE_SPEECH_V1 ||
+ lchan->tch_mode == GSM48_CMODE_SPEECH_EFR)) {
+ /* FR and EFR codecs */
+ 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);
+ } else if (lchan->type == GSM_LCHAN_TCH_H &&
+ lchan->tch_mode == GSM48_CMODE_SPEECH_V1) {
+ /* HR codec: TS 101 318 or RFC 5993,
+ * will also support TW-TS-002 in the future. */
+ if (bts->emit_hr_rfc5993)
+ send_rtp_rfc5993(lchan, fn, msg);
+ else
+ send_ul_rtp_packet_speech(lchan, fn, msg->data, msg->len);
+ } else {
+ /* generic case, no RTP alterations */
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);
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 40690f0..cc802c8 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -2979,7 +2979,7 @@
struct gsm_lchan *lchan = msg->lchan;
struct gsm_bts *bts = lchan->ts->trx->bts;
const uint8_t *payload_type, *speech_mode, *payload_type2, *csd_fmt;
- const uint8_t *osmux_cid = NULL;
+ const uint8_t *osmux_cid = NULL, *rtp_extensions = NULL;
uint32_t connect_ip = 0;
uint16_t connect_port = 0;
int rc, inc_ip_port = 0;
@@ -3036,6 +3036,12 @@
if (osmux_cid)
LOGPC(DRSL, LOGL_DEBUG, "osmux_cid=%u ", *osmux_cid);
+ /* same here */
+ if (TLVP_PRES_LEN(&tp, RSL_IE_OSMO_RTP_EXTENSIONS, 1))
+ rtp_extensions = TLVP_VAL(&tp, RSL_IE_OSMO_RTP_EXTENSIONS);
+ if (rtp_extensions)
+ LOGPC(DRSL, LOGL_DEBUG, "rtp_extensions=%u ", *rtp_extensions);
+
if (dch->c.msg_type == RSL_MT_IPAC_CRCX && connect_ip &&
connect_port)
inc_ip_port = 1;
@@ -3164,6 +3170,12 @@
if (speech_mode)
lchan->abis_ip.speech_mode = *speech_mode;
+ /* Configure non-standard RTP extensions */
+ if (rtp_extensions)
+ lchan->abis_ip.rtp_extensions = *rtp_extensions;
+ else
+ lchan->abis_ip.rtp_extensions = 0;
+
/* FIXME: CSD, jitterbuffer, compression */
return rsl_tx_ipac_XXcx_ack(lchan, payload_type2 ? 1 : 0,
diff --git a/src/common/rtp_input_preen.c b/src/common/rtp_input_preen.c
index 5729229..addd55b 100644
--- a/src/common/rtp_input_preen.c
+++ b/src/common/rtp_input_preen.c
@@ -64,21 +64,49 @@
static enum pl_input_decision
input_preen_fr(const uint8_t *rtp_pl, unsigned rtp_pl_len)
{
- if (rtp_pl_len != GSM_FR_BYTES)
+ switch (rtp_pl_len) {
+ case GSM_FR_BYTES: /* standard TS 101 318 or RFC 3551 format */
+ /* magic must be correct */
+ if ((rtp_pl[0] & 0xF0) != 0xD0)
+ return PL_DECISION_DROP;
+ return PL_DECISION_ACCEPT;
+ case GSM_FR_BYTES+1: /* Themyscira TW-TS-001 format */
+ /* TEH octet must be correct, and not a BFI */
+ if ((rtp_pl[0] & 0xF6) != 0xE0)
+ return PL_DECISION_DROP;
+ /* standard FR magic must be correct too */
+ if ((rtp_pl[1] & 0xF0) != 0xD0)
+ return PL_DECISION_DROP;
+ /* Strip TEH octet, leaving only standard FR payload. */
+ return PL_DECISION_STRIP_HDR_OCTET;
+ default:
+ /* invalid payload */
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)
+ switch (rtp_pl_len) {
+ case GSM_EFR_BYTES: /* standard TS 101 318 or RFC 3551 format */
+ /* magic must be correct */
+ if ((rtp_pl[0] & 0xF0) != 0xC0)
+ return PL_DECISION_DROP;
+ return PL_DECISION_ACCEPT;
+ case GSM_EFR_BYTES+1: /* Themyscira TW-TS-001 format */
+ /* TEH octet must be correct, and not a BFI */
+ if ((rtp_pl[0] & 0xF6) != 0xE0)
+ return PL_DECISION_DROP;
+ /* standard EFR magic must be correct too */
+ if ((rtp_pl[1] & 0xF0) != 0xC0)
+ return PL_DECISION_DROP;
+ /* Strip TEH octet, leaving only standard EFR payload. */
+ return PL_DECISION_STRIP_HDR_OCTET;
+ default:
+ /* invalid payload */
return PL_DECISION_DROP;
- if ((rtp_pl[0] & 0xF0) != 0xC0)
- return PL_DECISION_DROP;
- return PL_DECISION_ACCEPT;
+ }
}
static enum pl_input_decision
--
To view, visit
https://gerrit.osmocom.org/c/osmo-bts/+/36896?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: Id997e8666bc19e60936aaa83b43a968d30320bd7
Gerrit-Change-Number: 36896
Gerrit-PatchSet: 5
Gerrit-Owner: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: falconia <falcon(a)freecalypso.org>
Gerrit-Reviewer: fixeria <vyanitskiy(a)sysmocom.de>
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: pespin <pespin(a)sysmocom.de>
Gerrit-CC: osmith <osmith(a)sysmocom.de>
Gerrit-MessageType: merged