[MERGED] osmo-bts[master]: DTXd: store/repeat last SID

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Harald Welte gerrit-no-reply at lists.osmocom.org
Tue Jun 14 10:19:00 UTC 2016


Harald Welte has submitted this change and it was merged.

Change subject: DTXd: store/repeat last SID
......................................................................


DTXd: store/repeat last SID

Store last SID received over RTP and repeat is if necessary (no new SID
or SPEECH frames) according to codec-specific scheduling rules.

Change-Id: I4d23846a27d3dbd2a6e75e481c1efcdb2a85f305
Related: OS#1563
---
M src/osmo-bts-sysmo/l1_if.c
M src/osmo-bts-sysmo/l1_if.h
M src/osmo-bts-sysmo/tch.c
3 files changed, 119 insertions(+), 18 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index d6d0cdd..84fad99 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -414,7 +414,7 @@
 
 	/* no message/data, we generate an empty traffic msg */
 	if (!nmsg)
-		nmsg = gen_empty_tch_msg(lchan);
+		nmsg = gen_empty_tch_msg(lchan, u32Fn);
 
 	/* no traffic message, we generate an empty msg */
 	if (!nmsg) {
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index bb1d5a5..2fc8a29 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -111,7 +111,7 @@
 	const uint8_t *rtp_pl, unsigned int rtp_pl_len);
 int l1if_tch_rx(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);
+struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn);
 
 /* ciphering */
 int l1if_set_ciphering(struct femtol1_hdl *fl1h,
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 63d90af..07a0efb 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -23,7 +23,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
-
+#include <stdbool.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -577,7 +577,66 @@
 	return -EINVAL;
 }
 
-struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan)
+static inline bool fn_chk(uint8_t *t, uint32_t fn)
+{
+	uint8_t i;
+	for (i = 0; i < ARRAY_SIZE(t); i++)
+		if (fn % 104 == t[i])
+			return false;
+	return true;
+}
+
+static bool dtx_sched_optional(struct gsm_lchan *lchan, uint32_t fn)
+{
+	/* 3GPP TS 45.008 § 8.3 */
+	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) {
+		if (lchan->type == GSM_LCHAN_TCH_F)
+			return fn_chk(f, fn);
+		else
+			return fn_chk(lchan->nr ? h1 : h0, fn);
+	}
+	return false;
+}
+
+static bool repeat_last_sid(struct gsm_lchan *lchan, struct msgb *msg)
+{
+	GsmL1_Prim_t *l1p;
+	GsmL1_PhDataReq_t *data_req;
+	GsmL1_MsgUnitParam_t *msu_param;
+	uint8_t *l1_payload;
+
+	l1p = msgb_l1prim(msg);
+	data_req = &l1p->u.phDataReq;
+	msu_param = &data_req->msgUnitParam;
+	l1_payload = &msu_param->u8Buffer[1];
+
+	if (lchan->tch.last_sid.len) {
+		memcpy(l1_payload, lchan->tch.last_sid.buf,
+		       lchan->tch.last_sid.len);
+		msu_param->u8Size = lchan->tch.last_sid.len + 1;
+		return true;
+	}
+	return false;
+}
+
+/* store the last SID frame in lchan context */
+void save_last_sid(struct gsm_lchan *lchan, uint8_t *l1_payload, size_t length,
+		   uint32_t fn, bool update)
+{
+	size_t copy_len = OSMO_MIN(length + 1,
+				   ARRAY_SIZE(lchan->tch.last_sid.buf));
+
+	lchan->tch.last_sid.len = copy_len;
+	lchan->tch.last_sid.fn = fn;
+	lchan->tch.last_sid.is_update = update;
+
+	memcpy(lchan->tch.last_sid.buf, l1_payload, copy_len);
+}
+
+struct msgb *gen_empty_tch_msg(struct gsm_lchan *lchan, uint32_t fn)
 {
 	struct msgb *msg;
 	GsmL1_Prim_t *l1p;
@@ -599,21 +658,63 @@
 	switch (lchan->tch_mode) {
 	case GSM48_CMODE_SPEECH_AMR:
 		*payload_type = GsmL1_TchPlType_Amr;
-		if (lchan->tch.last_sid.len) {
-			memcpy(l1_payload, lchan->tch.last_sid.buf,
-				lchan->tch.last_sid.len);
-			msu_param->u8Size = lchan->tch.last_sid.len+1;
+		/* according to 3GPP TS 26.093 A.5.1.1: */
+		if (lchan->tch.last_sid.is_update) {
+			/* SID UPDATE should be repeated every 8th frame */
+			if (fn - lchan->tch.last_sid.fn < 7) {
+				msgb_free(msg);
+				return NULL;
+			}
 		} else {
-			/* FIXME: decide if we should send SPEECH_BAD or
-			 * SID_BAD */
-#if 0
-			*payload_type = GsmL1_TchPlType_Amr_SidBad;
-			memset(l1_payload, 0xFF, 5);
-			msu_param->u8Size = 5 + 3;
-#else
-			/* send an all-zero SID */
-			msu_param->u8Size = 8;
-#endif
+			/* 3rd frame after SID FIRST should be SID UPDATE */
+			if (fn - lchan->tch.last_sid.fn < 3) {
+				msgb_free(msg);
+				return NULL;
+			}
+		}
+		if (repeat_last_sid(lchan, msg))
+			return msg;
+		else {
+			LOGP(DL1C, LOGL_NOTICE, "Have to send AMR frame on TCH "
+			     "(FN=%u) but SID buffer is empty - sent NO_DATA\n",
+			     fn);
+			osmo_amr_rtp_enc(l1_payload, 0, AMR_NO_DATA,
+					 AMR_GOOD);
+			return msg;
+		}
+		break;
+	case GSM48_CMODE_SPEECH_V1:
+		if (lchan->type == GSM_LCHAN_TCH_F)
+			*payload_type = GsmL1_TchPlType_Fr;
+		else
+			*payload_type = GsmL1_TchPlType_Hr;
+		/* unlike AMR, FR & HR schedued based on absolute FN value */
+		if (dtx_sched_optional(lchan, fn)) {
+			msgb_free(msg);
+			return NULL;
+		}
+		if (repeat_last_sid(lchan, msg))
+			return msg;
+		else {
+			LOGP(DL1C, LOGL_NOTICE, "Have to send V1 frame on TCH "
+			     "(FN=%u) but SID buffer is empty - sent nothing\n",
+			     fn);
+			return NULL;
+		}
+		break;
+	case GSM48_CMODE_SPEECH_EFR:
+		*payload_type = GsmL1_TchPlType_Efr;
+		if (dtx_sched_optional(lchan, fn)) {
+			msgb_free(msg);
+			return NULL;
+		}
+		if (repeat_last_sid(lchan, msg))
+			return msg;
+		else {
+			LOGP(DL1C, LOGL_NOTICE, "Have to send EFR frame on TCH "
+			     "(FN=%u) but SID buffer is empty - sent nothing\n",
+			     fn);
+			return NULL;
 		}
 		break;
 	default:

-- 
To view, visit https://gerrit.osmocom.org/225
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I4d23846a27d3dbd2a6e75e481c1efcdb2a85f305
Gerrit-PatchSet: 2
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list