[PATCH] osmo-bts[master]: DTX: force ONSET on talkspurt

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/.

Max gerrit-no-reply at lists.osmocom.org
Tue Sep 27 18:00:32 UTC 2016


Review at  https://gerrit.osmocom.org/961

DTX: force ONSET on talkspurt

Ideally AMR have special ONSET event for speech resume which is
propagated into RTP header Marker bit. However this packet could be lost
so we should infer this event also by the presence os speech frames and
correspondingly drop saved SID.

Fixes: OS#1802

Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347
---
M src/osmo-bts-litecell15/l1_if.c
M src/osmo-bts-litecell15/l1_if.h
M src/osmo-bts-litecell15/tch.c
M src/osmo-bts-sysmo/l1_if.c
M src/osmo-bts-sysmo/l1_if.h
M src/osmo-bts-sysmo/tch.c
6 files changed, 54 insertions(+), 26 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/61/961/1

diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 0779dac..f78276a 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -443,6 +443,7 @@
 	uint8_t chan_nr;
 	GsmL1_Prim_t *l1p;
 	struct msgb *nmsg = NULL;
+	int rc;
 
 	chan_nr = l1sap->u.tch.chan_nr;
 	u32Fn = l1sap->u.tch.fn;
@@ -466,14 +467,18 @@
 		if (!nmsg)
 			return -ENOMEM;
 		l1p = msgb_l1prim(nmsg);
-		if (!l1if_tch_encode(lchan,
+		rc = l1if_tch_encode(lchan,
 				     l1p->u.phDataReq.msgUnitParam.u8Buffer,
 				     &l1p->u.phDataReq.msgUnitParam.u8Size,
 				     msg->data, msg->len, u32Fn,
-				     l1sap->u.tch.marker)) {
+				     l1sap->u.tch.marker);
+		if (rc < 0) {
 			msgb_free(nmsg);
 			nmsg = NULL;
 		}
+
+		if (rc > 0) /* force ONSET event */
+			l1sap->u.tch.marker = 1;
 	}
 
 	/* no message/data, we generate an empty traffic msg */
diff --git a/src/osmo-bts-litecell15/l1_if.h b/src/osmo-bts-litecell15/l1_if.h
index 88d71bf..adb197d 100644
--- a/src/osmo-bts-litecell15/l1_if.h
+++ b/src/osmo-bts-litecell15/l1_if.h
@@ -89,7 +89,7 @@
 struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer);
 
 /* tch.c */
-bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
+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 marker);
 int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c
index 2fd935e..fb3dca7 100644
--- a/src/osmo-bts-litecell15/tch.c
+++ b/src/osmo-bts-litecell15/tch.c
@@ -214,7 +214,9 @@
  *  \param[in] rtp_pl buffer containing RTP payload
  *  \param[in] rtp_pl_len length of \a rtp_pl
  *  \param[in] marker RTP header Marker bit (indicates speech onset)
- *  \returns true if encoding result can be sent further to L1, false otherwise
+ *  \returns 0 if encoding result can be sent further to L1 without extra actions
+ *           positive value if data is ready AND extra actions are required
+ *           negative value otherwise
  *
  * This function prepares a msgb with a L1 PH-DATA.req primitive and
  * queues it into lchan->dl_tch_queue.
@@ -223,7 +225,7 @@
  * yet, as things like the frame number, etc. are unknown at the time we
  * pre-fill the primtive.
  */
-bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
+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 marker)
 {
 	uint8_t *payload_type;
@@ -231,7 +233,7 @@
 	enum osmo_amr_type ft;
 	enum osmo_amr_quality bfi;
 	int8_t sti, cmi;
-	int rc;
+	int rc = 0;
 	bool is_sid = false;
 
 	DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -270,24 +272,31 @@
 		if (ft == AMR_SID) {
 			save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr,
 				      cmi);
-			return false;
+			return -EAGAIN;
 		}
 		if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) {
 			LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n",
 			     ft);
-			return false;
+			return -ENOTSUP;
 		}
 		if (osmo_amr_is_speech(ft)) {
-			if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */
+			if (lchan->tch.last_sid.len) { /* force ONSET */
 				marker = true;
+				rc = 1;
 			}
 			/* We received AMR SPEECH frame - invalidate saved SID */
 			lchan->tch.last_sid.len = 0;
 		}
 		if (marker) {
 			*payload_type = GsmL1_TchPlType_Amr_Onset;
-			rc = 0;
-			LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n",
+			*len = 1;
+			if (rc != 0) {
+				LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without"
+				     " Marker: ONSET forced\n",
+				     get_value_string(osmo_amr_type_names, ft));
+				return rc;
+			}
+			LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
 			     get_value_string(osmo_amr_type_names, ft));
 		}
 		else {
@@ -305,14 +314,14 @@
 	if (rc < 0) {
 		LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n",
 		     gsm_lchan_name(lchan));
-		return false;
+		return -EBADMSG;
 	}
 
 	*len = rc + 1;
 
 	DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
 		osmo_hexdump(data, *len));
-	return true;
+	return 0;
 }
 
 static int is_recv_only(uint8_t speech_mode)
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 3c6db43..06711e4 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -436,6 +436,7 @@
 	uint8_t chan_nr;
 	GsmL1_Prim_t *l1p;
 	struct msgb *nmsg = NULL;
+	int rc;
 
 	chan_nr = l1sap->u.tch.chan_nr;
 	u32Fn = l1sap->u.tch.fn;
@@ -459,14 +460,18 @@
 		if (!nmsg)
 			return -ENOMEM;
 		l1p = msgb_l1prim(nmsg);
-		if (!l1if_tch_encode(lchan,
+		rc = l1if_tch_encode(lchan,
 				     l1p->u.phDataReq.msgUnitParam.u8Buffer,
 				     &l1p->u.phDataReq.msgUnitParam.u8Size,
 				     msg->data, msg->len, u32Fn,
-				     l1sap->u.tch.marker)) {
+				     l1sap->u.tch.marker);
+		if (rc < 0) {
 			msgb_free(nmsg);
 			nmsg = NULL;
 		}
+
+		if (rc > 0) /* force ONSET event */
+			l1sap->u.tch.marker = 1;
 	}
 
 	/* no message/data, we generate an empty traffic msg */
diff --git a/src/osmo-bts-sysmo/l1_if.h b/src/osmo-bts-sysmo/l1_if.h
index a90c39b..ece7a01 100644
--- a/src/osmo-bts-sysmo/l1_if.h
+++ b/src/osmo-bts-sysmo/l1_if.h
@@ -109,7 +109,7 @@
 struct gsm_lchan *l1if_hLayer_to_lchan(struct gsm_bts_trx *trx, uint32_t hLayer);
 
 /* tch.c */
-bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
+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 marker);
 int l1if_tch_rx(struct gsm_bts_trx *trx, uint8_t chan_nr, struct msgb *l1p_msg);
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 714570c..879ed33 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -310,7 +310,9 @@
  *  \param[in] rtp_pl buffer containing RTP payload
  *  \param[in] rtp_pl_len length of \a rtp_pl
  *  \param[in] marker RTP header Marker bit (indicates speech onset)
- *  \returns true if encoding result can be sent further to L1, false otherwise
+ *  \returns 0 if encoding result can be sent further to L1 without extra actions
+ *           positive value if data is ready AND extra actions are required
+ *           negative value otherwise
  *
  * This function prepares a msgb with a L1 PH-DATA.req primitive and
  * queues it into lchan->dl_tch_queue.
@@ -319,7 +321,7 @@
  * yet, as things like the frame number, etc. are unknown at the time we
  * pre-fill the primtive.
  */
-bool l1if_tch_encode(struct gsm_lchan *lchan, uint8_t *data, uint8_t *len,
+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 marker)
 {
 	uint8_t *payload_type;
@@ -327,7 +329,7 @@
 	enum osmo_amr_type ft;
 	enum osmo_amr_quality bfi;
 	int8_t sti, cmi;
-	int rc;
+	int rc = 0;
 	bool is_sid = false;
 
 	DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -368,24 +370,31 @@
 		if (ft == AMR_SID) {
 			save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr,
 				      cmi);
-			return false;
+			return -EAGAIN;
 		}
 		if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) {
 			LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n",
 			     ft);
-			return false;
+			return -ENOTSUP;
 		}
 		if (osmo_amr_is_speech(ft)) {
-			if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */
+			if (lchan->tch.last_sid.len) { /* force ONSET */
 				marker = true;
+				rc = 1;
 			}
 			/* We received AMR SPEECH frame - invalidate saved SID */
 			lchan->tch.last_sid.len = 0;
 		}
 		if (marker) {
 			*payload_type = GsmL1_TchPlType_Amr_Onset;
-			rc = 0;
-			LOGP(DRTP, LOGL_ERROR, "Marker SPEECH frame AMR %s\n",
+			*len = 1;
+			if (rc != 0) {
+				LOGP(DRTP, LOGL_NOTICE, "%s SPEECH frame without"
+				     " Marker: ONSET forced\n",
+				     get_value_string(osmo_amr_type_names, ft));
+				return rc;
+			}
+			LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
 			     get_value_string(osmo_amr_type_names, ft));
 		}
 		else {
@@ -403,14 +412,14 @@
 	if (rc < 0) {
 		LOGP(DRTP, LOGL_ERROR, "%s unable to parse RTP payload\n",
 		     gsm_lchan_name(lchan));
-		return false;
+		return -EBADMSG;
 	}
 
 	*len = rc + 1;
 
 	DEBUGP(DRTP, "%s RTP->L1: %s\n", gsm_lchan_name(lchan),
 		osmo_hexdump(data, *len));
-	return true;
+	return 0;
 }
 
 static int is_recv_only(uint8_t speech_mode)

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I2a7b89430ca49eee4a350c5f980bd6bcbc386347
Gerrit-PatchSet: 1
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>



More information about the gerrit-log mailing list