[PATCH] osmo-bts[master]: DTX: move ONSET detection into separate function

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
Thu Sep 29 09:42:05 UTC 2016


Hello Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/969

to look at the new patch set (#4).

DTX: move ONSET detection into separate function

Move code from tch.c (lc15, sysmo) into generic function which:
- check if talkspurt is happening
- cache SID if necessary or invalidate cache
- fill in CMR & CMI prefix

This also fixes the problem when SID FIRST was cached without sending
just like SID UPDATE instead of being sent right away.

Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916
---
M include/osmo-bts/msg_utils.h
M src/common/msg_utils.c
M src/osmo-bts-litecell15/tch.c
M src/osmo-bts-sysmo/tch.c
4 files changed, 96 insertions(+), 70 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/69/969/4

diff --git a/include/osmo-bts/msg_utils.h b/include/osmo-bts/msg_utils.h
index f07623d..f99f3c4 100644
--- a/include/osmo-bts/msg_utils.h
+++ b/include/osmo-bts/msg_utils.h
@@ -29,6 +29,9 @@
 void save_last_sid(struct gsm_lchan *lchan, const uint8_t *l1_payload,
 		   size_t length, uint32_t fn, int update, uint8_t cmr,
 		   int8_t cmi);
+int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
+			size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload,
+			uint8_t *ft_out);
 uint8_t repeat_last_sid(struct gsm_lchan *lchan, uint8_t *dst, uint32_t fn);
 int msg_verify_ipa_structure(struct msgb *msg);
 int msg_verify_oml_structure(struct msgb *msg);
diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index 4b944dc..adff134 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -29,7 +29,7 @@
 #include <osmocom/trau/osmo_ortp.h>
 
 #include <arpa/inet.h>
-
+#include <errno.h>
 
 static int check_fom(struct abis_om_hdr *omh, size_t len)
 {
@@ -99,7 +99,7 @@
 	}
 }
 
-/* store the last SID frame in lchan context */
+
 /*! \brief Store the last SID frame in lchan context
  *  \param[in] lchan Logical channel on which we check scheduling
  *  \param[in] l1_payload buffer with SID data
@@ -126,6 +126,59 @@
 	memcpy(lchan->tch.last_sid.buf + amr, l1_payload, copy_len);
 }
 
+/*! \brief Check current and cached SID to decide if talkspurt takes place
+ *  \param[in] lchan Logical channel on which we check scheduling
+ *  \param[in] rtp_pl buffer with RTP data
+ *  \param[in] rtp_pl_len length of rtp_pl
+ *  \param[in] fn Frame Number for which we check scheduling
+ *  \param[in] l1_payload buffer where CMR and CMI prefix should be added
+ *  \param[out] ft_out Frame Type to be populated after decoding
+ *  \returns 0 if frame should be send immediately (2 byte CMR,CMI prefix added:
+ *           caller must adjust length as necessary),
+ *           1 if ONSET event is detected
+ *           negative if no sending is necessary (either error or cached SID
+ *           UPDATE)
+ */
+int dtx_amr_check_onset(struct gsm_lchan *lchan, const uint8_t *rtp_pl,
+			size_t rtp_pl_len, uint32_t fn, uint8_t *l1_payload,
+			uint8_t *ft_out)
+{
+	uint8_t cmr;
+	enum osmo_amr_type ft;
+	enum osmo_amr_quality bfi;
+	int8_t sti, cmi;
+	osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi, &sti);
+	*ft_out = ft;
+
+	if (ft == AMR_SID) {
+		save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr, cmi);
+		if (sti) /* SID_UPDATE should be cached and send later */
+			return -EAGAIN;
+		else { /* SID_FIRST got to be send right away */
+			amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr,
+					  cmi, cmr);
+			return 0;
+		}
+	}
+
+	if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) {
+		LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n", ft);
+		return -ENOTSUP;
+	}
+
+	if (osmo_amr_is_speech(ft)) {
+		if (lchan->tch.last_sid.len) { /* force ONSET */
+			lchan->tch.last_sid.len = 0;
+			return 1;
+		}
+		/* We received AMR SPEECH frame - invalidate saved SID */
+		lchan->tch.last_sid.len = 0;
+	}
+
+	amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr);
+	return 0;
+}
+
 /*! \brief Check if enough time has passed since last SID (if any) to repeat it
  *  \param[in] lchan Logical channel on which we check scheduling
  *  \param[in] fn Frame Number for which we check scheduling
diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c
index 46ad24c..08c64ab 100644
--- a/src/osmo-bts-litecell15/tch.c
+++ b/src/osmo-bts-litecell15/tch.c
@@ -199,12 +199,10 @@
  */
 static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
 				uint8_t payload_len,
-				struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi)
+				struct gsm_lchan *lchan, uint8_t ft)
 {
-	memcpy(l1_payload+2, rtp_payload, payload_len);
-	amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr);
-
-	return payload_len + 2;
+	memcpy(l1_payload, rtp_payload, payload_len);
+	return payload_len;
 }
 
 #define RTP_MSGB_ALLOC_SIZE	512
@@ -226,11 +224,8 @@
 	const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker)
 {
 	uint8_t *payload_type;
-	uint8_t *l1_payload, cmr;
-	enum osmo_amr_type ft;
-	enum osmo_amr_quality bfi;
-	int8_t sti, cmi;
-	int rc;
+	uint8_t *l1_payload, ft;
+	int rc = 0;
 	bool is_sid = false;
 
 	DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -264,35 +259,25 @@
 		/* FIXME: detect and save EFR SID */
 		break;
 	case GSM48_CMODE_SPEECH_AMR:
-		osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi,
-				 &sti);
-		if (ft == AMR_SID) {
-			save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr,
-				      cmi);
-			return false;
-		}
-		if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) {
-			LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n",
-			     ft);
-			return false;
-		}
-		if (osmo_amr_is_speech(ft)) {
-			if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */
-				marker = true;
-			}
-			/* We received AMR SPEECH frame - invalidate saved SID */
-			lchan->tch.last_sid.len = 0;
-		}
-		if (marker) {
+		rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn,
+					 l1_payload, &ft);
+
+		if (marker || rc) {
 			*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 true;
+			}
+			LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
 			     get_value_string(osmo_amr_type_names, ft));
 		}
 		else {
 			*payload_type = GsmL1_TchPlType_Amr;
-			rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
-						  rtp_pl_len, lchan, cmr, cmi);
+			rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl,
+						      rtp_pl_len, lchan, ft);
 		}
 		break;
 	default:
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 81cd791..3eb9bfd 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -282,10 +282,10 @@
  */
 static int rtppayload_to_l1_amr(uint8_t *l1_payload, const uint8_t *rtp_payload,
 				uint8_t payload_len,
-				struct gsm_lchan *lchan, uint8_t cmr, int8_t cmi)
+				struct gsm_lchan *lchan, uint8_t ft)
 {
 #ifdef USE_L1_RTP_MODE
-	memcpy(l1_payload+2, rtp_payload, payload_len);
+	memcpy(l1_payload, rtp_payload, payload_len);
 #else
 	uint8_t amr_if2_core_len = payload_len - 2;
 
@@ -298,9 +298,7 @@
 	/* lower 4 bit of first FR2 byte contains FT */
 	l1_payload[2] |= ft;
 #endif /* USE_L1_RTP_MODE */
-	amr_set_mode_pref(l1_payload, &lchan->tch.amr_mr, cmi, cmr);
-
-	return payload_len + 2;
+	return payload_len;
 }
 
 #define RTP_MSGB_ALLOC_SIZE	512
@@ -322,11 +320,8 @@
 	const uint8_t *rtp_pl, unsigned int rtp_pl_len, uint32_t fn, bool marker)
 {
 	uint8_t *payload_type;
-	uint8_t *l1_payload, cmr;
-	enum osmo_amr_type ft;
-	enum osmo_amr_quality bfi;
-	int8_t sti, cmi;
-	int rc;
+	uint8_t *l1_payload, ft;
+	int rc = 0;
 	bool is_sid = false;
 
 	DEBUGP(DRTP, "%s RTP IN: %s\n", gsm_lchan_name(lchan),
@@ -362,35 +357,25 @@
 		break;
 #endif
 	case GSM48_CMODE_SPEECH_AMR:
-		osmo_amr_rtp_dec(rtp_pl, rtp_pl_len, &cmr, &cmi, &ft, &bfi,
-				 &sti);
-		if (ft == AMR_SID) {
-			save_last_sid(lchan, rtp_pl, rtp_pl_len, fn, sti, cmr,
-				      cmi);
-			return false;
-		}
-		if (ft != AMR_NO_DATA && !osmo_amr_is_speech(ft)) {
-			LOGP(DRTP, LOGL_ERROR, "unsupported AMR FT 0x%02x\n",
-			     ft);
-			return false;
-		}
-		if (osmo_amr_is_speech(ft)) {
-			if (lchan->tch.last_sid.len) { /* FIXME: force ONSET */
-				marker = true;
-			}
-			/* We received AMR SPEECH frame - invalidate saved SID */
-			lchan->tch.last_sid.len = 0;
-		}
-		if (marker) {
+		rc = dtx_amr_check_onset(lchan, rtp_pl, rtp_pl_len, fn,
+					 l1_payload, &ft);
+
+		if (marker || rc) {
 			*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 true;
+			}
+			LOGP(DRTP, LOGL_DEBUG, "%s SPEECH frame with Marker\n",
 			     get_value_string(osmo_amr_type_names, ft));
 		}
 		else {
 			*payload_type = GsmL1_TchPlType_Amr;
-			rc = rtppayload_to_l1_amr(l1_payload, rtp_pl,
-						  rtp_pl_len, lchan, cmr, cmi);
+			rc = 2 + rtppayload_to_l1_amr(l1_payload + 2, rtp_pl,
+						      rtp_pl_len, lchan, ft);
 		}
 		break;
 	default:

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

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I6c7016a54749abadeef4fd4f5b6f750b256fb916
Gerrit-PatchSet: 4
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list