[MERGED] osmo-bts[master]: Fix AMR HR DTX FSM logic.

Harald Welte gerrit-no-reply at lists.osmocom.org
Wed Feb 1 19:13:16 UTC 2017


Harald Welte has submitted this change and it was merged.

Change subject: Fix AMR HR DTX FSM logic.
......................................................................


Fix AMR HR DTX FSM logic.

Fix SID_FIRST_INH detection during speech and when SID_FIRST is interrupted by FACCH.
Fix SID_UPDATE_INH detection during silence and when SID_UPDATE is interrupted by FACCH.
Add a delay for SID_FIRST to appear at the right time after FACCH.
Fix extra byte sent in downlink for SID_FIRST and SID_UPDATE.

Change-Id: Ia811305e15541f2376005df736bd610e8b0d2f69
---
M include/osmo-bts/dtx_dl_amr_fsm.h
M include/osmo-bts/rsl.h
M src/common/dtx_dl_amr_fsm.c
M src/common/msg_utils.c
M src/osmo-bts-litecell15/l1_if.c
M src/osmo-bts-litecell15/tch.c
M src/osmo-bts-sysmo/l1_if.c
M src/osmo-bts-sysmo/tch.c
8 files changed, 195 insertions(+), 73 deletions(-)

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



diff --git a/include/osmo-bts/dtx_dl_amr_fsm.h b/include/osmo-bts/dtx_dl_amr_fsm.h
index f747f9f..c66ac7d 100644
--- a/include/osmo-bts/dtx_dl_amr_fsm.h
+++ b/include/osmo-bts/dtx_dl_amr_fsm.h
@@ -12,11 +12,15 @@
 	ST_VOICE,
 	ST_SID_F1,
 	ST_SID_F2,
-	ST_F1_INH,
-	ST_U_INH,
+	ST_F1_INH_V,
+	ST_F1_INH_F,
+	ST_U_INH_V,
+	ST_U_INH_F,
 	ST_U_NOINH,
-	ST_F1_INH_REC,
-	ST_U_INH_REC,
+	ST_F1_INH_V_REC,
+	ST_F1_INH_F_REC,
+	ST_U_INH_V_REC,
+	ST_U_INH_F_REC,
 	ST_SID_U,
 	ST_ONSET_V,
 	ST_ONSET_F,
diff --git a/include/osmo-bts/rsl.h b/include/osmo-bts/rsl.h
index a2a6e3d..d5d0f1a 100644
--- a/include/osmo-bts/rsl.h
+++ b/include/osmo-bts/rsl.h
@@ -13,6 +13,7 @@
 };
 
 #define LCHAN_FN_DUMMY 0xFFFFFFFF
+#define LCHAN_FN_WAIT 0xFFFFFFFE
 
 int msgb_queue_flush(struct llist_head *list);
 
diff --git a/src/common/dtx_dl_amr_fsm.c b/src/common/dtx_dl_amr_fsm.c
index 832e8b4..d599048 100644
--- a/src/common/dtx_dl_amr_fsm.c
+++ b/src/common/dtx_dl_amr_fsm.c
@@ -29,8 +29,13 @@
 	case E_FACCH:
 		break;
 	case E_SID_F:
-	case E_SID_U:
 		osmo_fsm_inst_state_chg(fi, ST_SID_F1, 0, 0);
+		break;
+	case E_SID_U:
+		osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
+		break;
+	case E_INHIB:
+		osmo_fsm_inst_state_chg(fi, ST_F1_INH_V, 0, 0);
 		break;
 	default:
 		LOGP(DL1P, LOGL_ERROR, "Inexpected event %d\n", event);
@@ -49,17 +54,11 @@
 	case E_SID_U:
 		osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
 		break;
-	case E_VOICE:
-		osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
-		break;
 	case E_FACCH:
-		osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_F1_INH_F, 0, 0);
 		break;
 	case E_FIRST:
 		osmo_fsm_inst_state_chg(fi, ST_SID_F2, 0, 0);
-		break;
-	case E_INHIB:
-		osmo_fsm_inst_state_chg(fi, ST_F1_INH, 0, 0);
 		break;
 	case E_ONSET:
 		osmo_fsm_inst_state_chg(fi, ST_ONSET_V, 0, 0);
@@ -75,10 +74,7 @@
 {
 	switch (event) {
 	case E_COMPL:
-		osmo_fsm_inst_state_chg(fi, ST_SID_U, 0, 0);
-		break;
-	case E_VOICE:
-		osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_U_NOINH, 0, 0);
 		break;
 	case E_FACCH:
 		osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
@@ -93,11 +89,11 @@
 	}
 }
 
-void dtx_fsm_f1_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+void dtx_fsm_f1_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	switch (event) {
 	case E_COMPL:
-		osmo_fsm_inst_state_chg(fi, ST_F1_INH_REC, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_F1_INH_V_REC, 0, 0);
 		break;
 	default:
 		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
@@ -106,11 +102,11 @@
 	}
 }
 
-void dtx_fsm_u_inh(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+void dtx_fsm_f1_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	switch (event) {
 	case E_COMPL:
-		osmo_fsm_inst_state_chg(fi, ST_U_INH_REC, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_F1_INH_F_REC, 0, 0);
 		break;
 	default:
 		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
@@ -119,9 +115,36 @@
 	}
 }
 
-void dtx_fsm_f1_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+void dtx_fsm_u_inh_v(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	switch (event) {
+	case E_COMPL:
+		osmo_fsm_inst_state_chg(fi, ST_U_INH_V_REC, 0, 0);
+		break;
+	default:
+		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
+		OSMO_ASSERT(0);
+		break;
+	}
+}
+
+void dtx_fsm_u_inh_f(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case E_COMPL:
+		osmo_fsm_inst_state_chg(fi, ST_U_INH_F_REC, 0, 0);
+		break;
+	default:
+		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
+		OSMO_ASSERT(0);
+		break;
+	}
+}
+
+void dtx_fsm_f1_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case E_VOICE:
 	case E_COMPL:
 		osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
 		break;
@@ -132,11 +155,40 @@
 	}
 }
 
-void dtx_fsm_u_inh_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+void dtx_fsm_f1_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
 {
 	switch (event) {
+	case E_FACCH:
+	case E_COMPL:
+		osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
+		break;
+	default:
+		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
+		OSMO_ASSERT(0);
+		break;
+	}
+}
+
+void dtx_fsm_u_inh_v_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case E_VOICE:
 	case E_COMPL:
 		osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
+		break;
+	default:
+		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
+		OSMO_ASSERT(0);
+		break;
+	}
+}
+
+void dtx_fsm_u_inh_f_rec(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+	switch (event) {
+	case E_FACCH:
+	case E_COMPL:
+		osmo_fsm_inst_state_chg(fi, ST_FACCH, 0, 0);
 		break;
 	default:
 		LOGP(DL1P, LOGL_ERROR, "Unexpected event %d\n", event);
@@ -176,13 +228,13 @@
 {
 	switch (event) {
 	case E_FACCH:
-		osmo_fsm_inst_state_chg(fi, ST_ONSET_F, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_U_INH_F, 0, 0);
 		break;
 	case E_VOICE:
 		osmo_fsm_inst_state_chg(fi, ST_VOICE, 0, 0);
 		break;
 	case E_INHIB:
-		osmo_fsm_inst_state_chg(fi, ST_U_INH, 0, 0);
+		osmo_fsm_inst_state_chg(fi, ST_U_INH_V, 0, 0);
 		break;
 	case E_SID_U:
 	case E_SID_F:
@@ -270,40 +322,54 @@
 static struct osmo_fsm_state dtx_dl_amr_fsm_states[] = {
 	/* default state for non-DTX and DTX when SPEECH is in progress */
 	[ST_VOICE] = {
-		.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH),
-		.out_state_mask = X(ST_SID_F1),
+		.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH) | X(E_INHIB),
+		.out_state_mask = X(ST_SID_F1) | X(ST_U_NOINH) | X(ST_F1_INH_V),
 		.name = "Voice",
 		.action = dtx_fsm_voice,
 	},
 	/* SID-FIRST or SID-FIRST-P1 in case of AMR HR:
 	   start of silence period (might be interrupted in case of AMR HR) */
 	[ST_SID_F1]= {
-		.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_VOICE) | X(E_FACCH) | X(E_FIRST) | X(E_INHIB) | X(E_ONSET),
-		.out_state_mask = X(ST_U_NOINH) | X(ST_VOICE) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_F1_INH) | X(ST_ONSET_V),
+		.in_event_mask = X(E_SID_F) | X(E_SID_U) | X(E_FACCH) | X(E_FIRST) | X(E_ONSET),
+		.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_SID_F2) | X(ST_ONSET_V),
 		.name = "SID-FIRST (P1)",
 		.action = dtx_fsm_sid_f1,
 	},
 	/* SID-FIRST P2 (only for AMR HR):
 	   actual start of silence period in case of AMR HR */
 	[ST_SID_F2]= {
-		.in_event_mask = X(E_COMPL) | X(E_VOICE) | X(E_FACCH) | X(E_ONSET),
-		.out_state_mask = X(ST_SID_U) | X(ST_VOICE) | X(ST_ONSET_F) | X(ST_ONSET_V),
+		.in_event_mask = X(E_COMPL) | X(E_FACCH) | X(E_ONSET),
+		.out_state_mask = X(ST_U_NOINH) | X(ST_ONSET_F) | X(ST_ONSET_V),
 		.name = "SID-FIRST (P2)",
 		.action = dtx_fsm_sid_f2,
 	},
 	/* SID-FIRST Inhibited: incoming SPEECH (only for AMR HR) */
-	[ST_F1_INH]= {
+	[ST_F1_INH_V]= {
 		.in_event_mask = X(E_COMPL),
-		.out_state_mask = X(ST_F1_INH_REC),
-		.name = "SID-FIRST (Inh)",
-		.action = dtx_fsm_f1_inh,
+		.out_state_mask = X(ST_F1_INH_V_REC),
+		.name = "SID-FIRST (Inh, SPEECH)",
+		.action = dtx_fsm_f1_inh_v,
+	},
+	/* SID-FIRST Inhibited: incoming FACCH frame (only for AMR HR) */
+	[ST_F1_INH_F]= {
+		.in_event_mask = X(E_COMPL),
+		.out_state_mask = X(ST_F1_INH_F_REC),
+		.name = "SID-FIRST (Inh, FACCH)",
+		.action = dtx_fsm_f1_inh_f,
 	},
 	/* SID-UPDATE Inhibited: incoming SPEECH (only for AMR HR) */
-	[ST_U_INH]= {
+	[ST_U_INH_V]= {
 		.in_event_mask = X(E_COMPL),
-		.out_state_mask = X(ST_U_INH_REC),
-		.name = "SID-UPDATE (Inh)",
-		.action = dtx_fsm_u_inh,
+		.out_state_mask = X(ST_U_INH_V_REC),
+		.name = "SID-UPDATE (Inh, SPEECH)",
+		.action = dtx_fsm_u_inh_v,
+	},
+	/* SID-UPDATE Inhibited: incoming FACCH frame (only for AMR HR) */
+	[ST_U_INH_F]= {
+		.in_event_mask = X(E_COMPL),
+		.out_state_mask = X(ST_U_INH_F_REC),
+		.name = "SID-UPDATE (Inh, FACCH)",
+		.action = dtx_fsm_u_inh_f,
 	},
 	/* SID-UPDATE: Inhibited not allowed (only for AMR HR) */
 	[ST_U_NOINH]= {
@@ -314,24 +380,40 @@
 	},
 	/* SID-FIRST Inhibition recursion in progress:
 	   Inhibit itself was already sent, now have to send the voice that caused it */
-	[ST_F1_INH_REC]= {
-		.in_event_mask = X(E_COMPL),
+	[ST_F1_INH_V_REC]= {
+		.in_event_mask = X(E_COMPL) | X(E_VOICE),
 		.out_state_mask = X(ST_VOICE),
-		.name = "SID-FIRST (Inh, Rec)",
-		.action = dtx_fsm_f1_inh_rec,
+		.name = "SID-FIRST (Inh, SPEECH, Rec)",
+		.action = dtx_fsm_f1_inh_v_rec,
+	},
+	/* SID-FIRST Inhibition recursion in progress:
+	   Inhibit itself was already sent, now have to send the data that caused it */
+	[ST_F1_INH_F_REC]= {
+		.in_event_mask = X(E_COMPL) | X(E_FACCH),
+		.out_state_mask = X(ST_FACCH),
+		.name = "SID-FIRST (Inh, FACCH, Rec)",
+		.action = dtx_fsm_f1_inh_f_rec,
 	},
 	/* SID-UPDATE Inhibition recursion in progress:
 	   Inhibit itself was already sent, now have to send the voice that caused it */
-	[ST_U_INH_REC]= {
-		.in_event_mask = X(E_COMPL),
+	[ST_U_INH_V_REC]= {
+		.in_event_mask = X(E_COMPL) | X(E_VOICE),
 		.out_state_mask = X(ST_VOICE),
-		.name = "SID-UPDATE (Inh, Rec)",
-		.action = dtx_fsm_u_inh_rec,
+		.name = "SID-UPDATE (Inh, SPEECH, Rec)",
+		.action = dtx_fsm_u_inh_v_rec,
+	},
+	/* SID-UPDATE Inhibition recursion in progress:
+	   Inhibit itself was already sent, now have to send the data that caused it */
+	[ST_U_INH_F_REC]= {
+		.in_event_mask = X(E_COMPL) | X(E_FACCH),
+		.out_state_mask = X(ST_FACCH),
+		.name = "SID-UPDATE (Inh, FACCH, Rec)",
+		.action = dtx_fsm_u_inh_f_rec,
 	},
 	/* Silence period with periodic comfort noise data updates */
 	[ST_SID_U]= {
 		.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_INHIB) | X(E_SID_U) | X(E_SID_F),
-		.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH) | X(ST_U_NOINH),
+		.out_state_mask = X(ST_ONSET_F) | X(ST_VOICE) | X(ST_U_INH_V) | X(ST_U_INH_F) | X(ST_U_NOINH),
 		.name = "SID-UPDATE (AMR/HR)",
 		.action = dtx_fsm_sid_upd,
 	},
@@ -365,8 +447,7 @@
 		.name = "ONSET (FACCH, Rec)",
 		.action = dtx_fsm_onset_f_rec,
 	},
-	/* FACCH sending state: no SPEECH was observed before so once we're done
-	   FSM should get back to silent period via SID-FIRST */
+	/* FACCH sending state */
 	[ST_FACCH]= {
 		.in_event_mask = X(E_FACCH) | X(E_VOICE) | X(E_COMPL) | X(E_SID_U) | X(E_SID_F),
 		.out_state_mask = X(ST_VOICE) | X(ST_SID_F1),
diff --git a/src/common/msg_utils.c b/src/common/msg_utils.c
index 062f5e3..f936c98 100644
--- a/src/common/msg_utils.c
+++ b/src/common/msg_utils.c
@@ -137,7 +137,7 @@
 		       size_t length, uint32_t fn, int update)
 {
 	size_t amr = (update < 0) ? 0 : 2,
-		copy_len = OSMO_MIN(length + 1,
+		copy_len = OSMO_MIN(length,
 				ARRAY_SIZE(lchan->tch.dtx.cache) - amr);
 
 	lchan->tch.dtx.len = copy_len + amr;
@@ -230,7 +230,7 @@
 
 	if (osmo_amr_is_speech(ft)) {
 		/* AMR HR - SID-FIRST_P1 Inhibition */
-		if (marker && dtx_is_first_p1(lchan))
+		if (marker && lchan->tch.dtx.dl_amr_fsm->state == ST_VOICE)
 			return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
 						      E_INHIB, (void *)lchan);
 
@@ -261,7 +261,8 @@
 			   as FIRST regardless of actually decoded type */
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, false);
 			return osmo_fsm_inst_dispatch(lchan->tch.dtx.dl_amr_fsm,
-						      E_SID_F, (void *)lchan);
+						      sti ? E_SID_U : E_SID_F,
+						      (void *)lchan);
 		} else if (lchan->tch.dtx.dl_amr_fsm->state != ST_FACCH)
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, sti);
 		if (lchan->tch.dtx.dl_amr_fsm->state == ST_SID_F2)
@@ -319,12 +320,24 @@
 		   already: we rely here on the order of RTS arrival from L1 - we
 		   expect that PH-DATA.req ALWAYS comes before PH-TCH.req for the
 		   same FN */
-		if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
-			/* FACCH interruption is over */
-			dtx_dispatch(lchan, E_COMPL);
-			return false;
-		} else
-			lchan->tch.dtx.fn = fn;
+		if(lchan->type == GSM_LCHAN_TCH_H) {
+			if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY &&
+			    lchan->tch.dtx.fn != LCHAN_FN_WAIT) {
+				/* FACCH interruption is over */
+				dtx_dispatch(lchan, E_COMPL);
+				return false;
+			} else if(lchan->tch.dtx.fn == LCHAN_FN_DUMMY) {
+				lchan->tch.dtx.fn = LCHAN_FN_WAIT;
+			} else
+				lchan->tch.dtx.fn = fn;
+		} else if(lchan->type == GSM_LCHAN_TCH_F) {
+			if (lchan->tch.dtx.fn != LCHAN_FN_DUMMY) {
+				/* FACCH interruption is over */
+				dtx_dispatch(lchan, E_COMPL);
+				return false;
+			} else
+				lchan->tch.dtx.fn = fn;
+		}
 		/* this FN was already used for FACCH or ONSET message so we just
 		   prepare things for next one */
 		return true;
@@ -401,9 +414,14 @@
 	if (!dtx_dl_amr_enabled(lchan))
 		return false;
 
-	if (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH ||
-	    lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_REC ||
-	    lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH ||
+	if (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_V_REC ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F_REC ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_V_REC ||
+	    lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F_REC ||
 	    lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F ||
 	    lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_V ||
 	    lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F_REC ||
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index e1dcecf..5977aa9 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -410,7 +410,9 @@
 			memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
 			       lchan->tch.dtx.facch, msgb_l2len(msg));
 		else if (dtx_dl_amr_enabled(lchan) &&
-			 lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) {
+			 ((lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) ||
+			 (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F) ||
+			 (lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F))) {
 			if (sapi == GsmL1_Sapi_FacchF) {
 				sapi = GsmL1_Sapi_TchF;
 			}
@@ -424,9 +426,16 @@
 				/* cache FACCH data */
 				memcpy(lchan->tch.dtx.facch, msg->l2h,
 				       msgb_l2len(msg));
-				/* prepare ONSET message */
-				l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
-					GsmL1_TchPlType_Amr_Onset;
+				/* prepare ONSET or INH message */
+				if(lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_Onset;
+				else if(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_SidUpdateInH;
+				else if(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_SidFirstInH;
 				/* ignored CMR/CMI pair */
 				l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0;
 				l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0;
diff --git a/src/osmo-bts-litecell15/tch.c b/src/osmo-bts-litecell15/tch.c
index 4b22b64..ffc1eb3 100644
--- a/src/osmo-bts-litecell15/tch.c
+++ b/src/osmo-bts-litecell15/tch.c
@@ -311,12 +311,12 @@
 			rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
 					     ft);
 			return 0;
-		case ST_F1_INH:
+		case ST_F1_INH_V:
 			*payload_type = GsmL1_TchPlType_Amr_SidFirstInH;
 			*len = 3;
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
 			return 1;
-		case ST_U_INH:
+		case ST_U_INH_V:
 			*payload_type = GsmL1_TchPlType_Amr_SidUpdateInH;
 			*len = 3;
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index ef965d4..c021368 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -405,7 +405,9 @@
 			memcpy(l1p->u.phDataReq.msgUnitParam.u8Buffer,
 			       lchan->tch.dtx.facch, msgb_l2len(msg));
 		else if (dtx_dl_amr_enabled(lchan) &&
-			 lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) {
+			 ((lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F) ||
+			 (lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F) ||
+			 (lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F))) {
 			if (sapi == GsmL1_Sapi_FacchF) {
 				sapi = GsmL1_Sapi_TchF;
 			}
@@ -419,9 +421,16 @@
 				/* cache FACCH data */
 				memcpy(lchan->tch.dtx.facch, msg->l2h,
 				       msgb_l2len(msg));
-				/* prepare ONSET message */
-				l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
-					GsmL1_TchPlType_Amr_Onset;
+				/* prepare ONSET or INH message */
+				if(lchan->tch.dtx.dl_amr_fsm->state == ST_ONSET_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_Onset;
+				else if(lchan->tch.dtx.dl_amr_fsm->state == ST_U_INH_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_SidUpdateInH;
+				else if(lchan->tch.dtx.dl_amr_fsm->state == ST_F1_INH_F)
+					l1p->u.phDataReq.msgUnitParam.u8Buffer[0] =
+								GsmL1_TchPlType_Amr_SidFirstInH;
 				/* ignored CMR/CMI pair */
 				l1p->u.phDataReq.msgUnitParam.u8Buffer[1] = 0;
 				l1p->u.phDataReq.msgUnitParam.u8Buffer[2] = 0;
diff --git a/src/osmo-bts-sysmo/tch.c b/src/osmo-bts-sysmo/tch.c
index 8eb419b..55c4049 100644
--- a/src/osmo-bts-sysmo/tch.c
+++ b/src/osmo-bts-sysmo/tch.c
@@ -409,12 +409,12 @@
 			rtppayload_to_l1_amr(l1_payload + 2, rtp_pl, rtp_pl_len,
 					     ft);
 			return 0;
-		case ST_F1_INH:
+		case ST_F1_INH_V:
 			*payload_type = GsmL1_TchPlType_Amr_SidFirstInH;
 			*len = 3;
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);
 			return 1;
-		case ST_U_INH:
+		case ST_U_INH_V:
 			*payload_type = GsmL1_TchPlType_Amr_SidUpdateInH;
 			*len = 3;
 			dtx_cache_payload(lchan, rtp_pl, rtp_pl_len, fn, 0);

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia811305e15541f2376005df736bd610e8b0d2f69
Gerrit-PatchSet: 3
Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Owner: jfdionne <jf.dionne at nutaq.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>
Gerrit-Reviewer: jfdionne <jf.dionne at nutaq.com>


More information about the gerrit-log mailing list