Change in osmo-bts[master]: l1sap: add repeated downlink FACCH

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

laforge gerrit-no-reply at lists.osmocom.org
Tue Dec 1 12:01:29 UTC 2020


laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/21014 )

Change subject: l1sap: add repeated downlink FACCH
......................................................................

l1sap: add repeated downlink FACCH

3GPP TS 44.006, section 10 describes a method how the downlink
FACCH transmission can be repeated to increase transmission
reliability.

Change-Id: I72f0cf7eaaef9f80fc35e752c90ae0e2d24d0c75
Depends: libosmocore I6dda239e9cd7033297bed1deb5eb1d9f87b8433f
Related: OS#4796 SYS#5114
---
M include/osmo-bts/gsm_data.h
M include/osmo-bts/l1sap.h
M src/common/bts.c
M src/common/l1sap.c
M src/common/rsl.c
M src/osmo-bts-trx/main.c
6 files changed, 170 insertions(+), 7 deletions(-)

Approvals:
  Jenkins Builder: Verified
  pespin: Looks good to me, but someone else must approve
  fixeria: Looks good to me, but someone else must approve
  laforge: Looks good to me, approved



diff --git a/include/osmo-bts/gsm_data.h b/include/osmo-bts/gsm_data.h
index 7670508..47a6db8 100644
--- a/include/osmo-bts/gsm_data.h
+++ b/include/osmo-bts/gsm_data.h
@@ -156,6 +156,11 @@
 	LCHAN_REL_ACT_REACT, /* remove once auto-activation hack is removed from opstart_compl() */
 };
 
+struct gsm_rep_facch {
+	struct msgb *msg;
+	uint32_t fn;
+};
+
 struct gsm_lchan {
 	/* The TS that we're part of */
 	struct gsm_bts_trx_ts *ts;
@@ -272,6 +277,10 @@
 		} dtx;
 		uint8_t last_cmr;
 		uint32_t last_fn;
+
+		/* SLOT #0 and #1 to store FACCH for repetition */
+		struct gsm_rep_facch rep_facch[2];
+
 	} tch;
 
 	/* 3GPP TS 48.058 § 9.3.37: [0; 255] ok, -1 means invalid*/
@@ -314,6 +323,9 @@
 
 	/* ECU (Error Concealment Unit) state */
 	struct osmo_ecu_state *ecu_state;
+
+	struct abis_rsl_osmo_rep_acch_cap repeated_acch_capability;
+	bool repeated_dl_facch_active;
 };
 
 static inline uint8_t lchan_get_ta(const struct gsm_lchan *lchan)
diff --git a/include/osmo-bts/l1sap.h b/include/osmo-bts/l1sap.h
index 1fcf78c..85fe548 100644
--- a/include/osmo-bts/l1sap.h
+++ b/include/osmo-bts/l1sap.h
@@ -144,4 +144,7 @@
 
 int is_ccch_for_agch(struct gsm_bts_trx *trx, uint32_t fn);
 
+void repeated_dl_facch_active_decision(struct gsm_lchan *lchan,
+				       const uint8_t *l3, size_t l3_len);
+
 #endif /* L1SAP_H */
diff --git a/src/common/bts.c b/src/common/bts.c
index 6c25cbd..a1f9101 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -457,6 +457,11 @@
 	t200_ms_acch[DL_SAPI0] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
 	t200_ms_acch[DL_SAPI3] = bts->t200_ms[T200_SACCH_SDCCH] + fn_advance_ms;
 
+	if (lchan->repeated_acch_capability.dl_facch_all && (lchan->type == GSM_LCHAN_TCH_F || lchan->type == GSM_LCHAN_TCH_H)) {
+		t200_ms_acch[DL_SAPI0] *= 2;
+		t200_ms_acch[DL_SAPI3] *= 2;
+	}
+
 	switch (lchan->type) {
 	case GSM_LCHAN_SDCCH:
 		t200_ms_dcch[DL_SAPI0] = bts->t200_ms[T200_SDCCH] + fn_advance_ms;
diff --git a/src/common/l1sap.c b/src/common/l1sap.c
index cfe7ebb..4398f2a 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -908,6 +908,112 @@
 	}
 }
 
+/* Common dequeueing function */
+static inline struct msgb *lapdm_phsap_dequeue_msg(struct lapdm_entity *le)
+{
+	struct osmo_phsap_prim pp;
+	if (lapdm_phsap_dequeue_prim(le, &pp) < 0)
+		return NULL;
+	return pp.oph.msg;
+}
+
+/* Special dequeueing function with FACCH repetition (3GPP TS 44.006, section 10) */
+static inline struct msgb *lapdm_phsap_dequeue_msg_facch(struct gsm_lchan *lchan, struct lapdm_entity *le, uint32_t fn)
+{
+	struct osmo_phsap_prim pp;
+	struct msgb *msg;
+
+	/* Note: The repeated version of the FACCH block must be scheduled 8 or 9 bursts after the original
+	 * transmission. see 3GPP TS 44.006, section 10.2 for a more detailed explaination. */
+	if (lchan->tch.rep_facch[0].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[0].fn) >= 8) {
+		/* Re-use stored FACCH message buffer from SLOT #0 for repetition. */
+		msg = lchan->tch.rep_facch[0].msg;
+		lchan->tch.rep_facch[0].msg = NULL;
+	} else if (lchan->tch.rep_facch[1].msg && GSM_TDMA_FN_SUB(fn, lchan->tch.rep_facch[1].fn) >= 8) {
+		/* Re-use stored FACCH message buffer from SLOT #1 for repetition. */
+		msg = lchan->tch.rep_facch[1].msg;
+		lchan->tch.rep_facch[1].msg = NULL;
+	} else {
+		/* Fetch new FACCH from queue ... */
+		if (lapdm_phsap_dequeue_prim(le, &pp) < 0)
+			return NULL;
+		msg = pp.oph.msg;
+
+		/* Check if the LAPDm frame is a command frame,
+		 * see also: 3GPP TS 04.06 section 3.2 and 3.3.2.
+		 * If the MS explicitly indicated that repeated ACCH is
+		 * supported, than all FACCH frames may be repeated
+		 * see also: 3GPP TS 44.006, section 10.3). */
+		if (!(lchan->repeated_acch_capability.dl_facch_all || msg->data[0] & 0x02))
+			return msg;
+
+		/* ... and store the message buffer for repetition. */
+		if (lchan->tch.rep_facch[0].msg == NULL) {
+			lchan->tch.rep_facch[0].msg = msgb_copy(msg, "rep_facch_0");
+			lchan->tch.rep_facch[0].fn = fn;
+		} else if (lchan->tch.rep_facch[1].msg == NULL) {
+			lchan->tch.rep_facch[1].msg = msgb_copy(msg, "rep_facch_1");
+			lchan->tch.rep_facch[1].fn = fn;
+		} else {
+			/* By definition 3GPP TS 05.02 does not allow more than two (for TCH/H only one) FACCH blocks
+			 * to be transmitted simultaniously. */
+			OSMO_ASSERT(false);
+		}
+	}
+
+	return msg;
+}
+
+/* Decide if repeated FACCH should be applied or not. If RXQUAL level, that the
+ * MS reports is high enough, FACCH repetition is not needed. */
+void repeated_dl_facch_active_decision(struct gsm_lchan *lchan, const uint8_t *l3,
+				       size_t l3_len)
+{
+	const struct gsm48_meas_res *meas_res;
+	uint8_t upper;
+	uint8_t lower;
+
+	if (!lchan->repeated_acch_capability.dl_facch_cmd
+	    && !lchan->repeated_acch_capability.dl_facch_all)
+		return;
+
+	/* Threshold disabled (always on) */
+	if (lchan->repeated_acch_capability.rxqual == 0) {
+		lchan->repeated_dl_facch_active = true;
+		return;
+	}
+
+	/* When the MS sets the SRR bit in the UL-SACCH L1 header
+	 * (repeated SACCH requested) then it makes sense to enable
+	 * FACCH repetition too. */
+	if ((lchan->meas.l1_info[0] >> 1) & 1) {
+		lchan->repeated_dl_facch_active = true;
+		return;
+	}
+
+	/* Parse MS measurement results */
+	if (l3_len <= sizeof(struct gsm48_meas_res *) + 2)
+		return;
+	if (l3[0] != GSM48_PDISC_RR)
+		return;
+	if (l3[1] != GSM48_MT_RR_MEAS_REP)
+		return;
+	l3 += 2;
+	meas_res = (struct gsm48_meas_res *)l3;
+
+	/* If the RXQUAL level at the MS drops under a certain threshold
+	 * we enable FACCH repetition. */
+	upper = lchan->repeated_acch_capability.rxqual;
+	if (upper > 2)
+		lower = lchan->repeated_acch_capability.rxqual - 2;
+	else
+		lower = 0;
+	if (meas_res->rxqual_sub >= upper)
+		lchan->repeated_dl_facch_active = true;
+	else if (meas_res->rxqual_sub <= lower)
+		lchan->repeated_dl_facch_active = false;
+}
+
 /* PH-RTS-IND prim received from bts model */
 static int l1sap_ph_rts_ind(struct gsm_bts_trx *trx,
 	struct osmo_phsap_prim *l1sap, struct ph_data_param *rts_ind)
@@ -921,7 +1027,7 @@
 	uint8_t *p = NULL;
 	uint8_t *si;
 	struct lapdm_entity *le;
-	struct osmo_phsap_prim pp;
+	struct msgb *pp_msg;
 	bool dtxd_facch = false;
 	int rc;
 	int is_ag_res;
@@ -989,13 +1095,17 @@
 			p[0] = lchan->ms_power_ctrl.current;
 			p[1] = lchan->rqd_ta;
 			le = &lchan->lapdm_ch.lapdm_acch;
+			pp_msg = lapdm_phsap_dequeue_msg(le);
 		} else {
 			if (lchan->ts->trx->bts->dtxd)
 				dtxd_facch = true;
 			le = &lchan->lapdm_ch.lapdm_dcch;
+			if (lchan->repeated_dl_facch_active && lchan->rsl_cmode != RSL_CMOD_SPD_SIGN)
+				pp_msg = lapdm_phsap_dequeue_msg_facch(lchan, le, fn);
+			else
+				pp_msg = lapdm_phsap_dequeue_msg(le);
 		}
-		rc = lapdm_phsap_dequeue_prim(le, &pp);
-		if (rc < 0) {
+		if (!pp_msg) {
 			if (L1SAP_IS_LINK_SACCH(link_id)) {
 				/* No SACCH data from LAPDM pending, send SACCH filling */
 				uint8_t *si = lchan_sacch_get(lchan);
@@ -1020,16 +1130,16 @@
 		} else {
 			/* The +2 is empty space where the DSP inserts the L1 hdr */
 			if (L1SAP_IS_LINK_SACCH(link_id))
-				memcpy(p + 2, pp.oph.msg->data + 2, GSM_MACBLOCK_LEN - 2);
+				memcpy(p + 2, pp_msg->data + 2, GSM_MACBLOCK_LEN - 2);
 			else {
 				p = msgb_put(msg, GSM_MACBLOCK_LEN);
-				memcpy(p, pp.oph.msg->data, GSM_MACBLOCK_LEN);
+				memcpy(p, pp_msg->data, GSM_MACBLOCK_LEN);
 				/* check if it is a RR CIPH MODE CMD. if yes, enable RX ciphering */
-				check_for_ciph_cmd(pp.oph.msg, lchan, chan_nr);
+				check_for_ciph_cmd(pp_msg, lchan, chan_nr);
 				if (dtxd_facch)
 					dtx_dispatch(lchan, E_FACCH);
 			}
-			msgb_free(pp.oph.msg);
+			msgb_free(pp_msg);
 		}
 	} else if (L1SAP_IS_CHAN_AGCH_PCH(chan_nr)) {
 		p = msgb_put(msg, GSM_MACBLOCK_LEN);
diff --git a/src/common/rsl.c b/src/common/rsl.c
index a0c1fb2..14a0dcc 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -823,6 +823,13 @@
 	 */
 	lapdm_channel_exit(&lchan->lapdm_ch);
 
+	/* Also ensure that there are no leftovers from repeated FACCH
+	 * that might cause memory leakage. */
+	msgb_free(lchan->tch.rep_facch[0].msg);
+	msgb_free(lchan->tch.rep_facch[1].msg);
+	lchan->tch.rep_facch[0].msg = NULL;
+	lchan->tch.rep_facch[1].msg = NULL;
+
 	return tx_rf_rel_ack(lchan, chan_nr);
 }
 
@@ -1085,6 +1092,26 @@
 	}
 }
 
+/* Parse RSL_IE_OSMO_REP_ACCH_CAP */
+static void parse_repeated_acch_capability(struct gsm_lchan *lchan, struct tlv_parsed *tp)
+{
+	/* 3GPP TS 24.008, section 10.5.1.7 defines a Repeated ACCH Capability
+	 * bit that indicates if REPEATED FACCH/SACCH is supported or not.
+	 * Unfortunately there is not 3gpp spec that describes how this bit
+	 * should be communicated in the RSL CHANNEL ACTIVATION. For osmo-bts
+	 * we will use a propritary IE. */
+
+	memset(&lchan->repeated_acch_capability, 0, sizeof(lchan->repeated_acch_capability));
+
+	if (!TLVP_PRESENT(tp, RSL_IE_OSMO_REP_ACCH_CAP))
+		return;
+	if (TLVP_LEN(tp, RSL_IE_OSMO_REP_ACCH_CAP) != sizeof(lchan->repeated_acch_capability))
+		return;
+
+	memcpy(&lchan->repeated_acch_capability, TLVP_VAL(tp, RSL_IE_OSMO_REP_ACCH_CAP),
+	       sizeof(lchan->repeated_acch_capability));
+}
+
 /* 8.4.1 CHANnel ACTIVation is received */
 static int rsl_rx_chan_activ(struct msgb *msg)
 {
@@ -1327,6 +1354,8 @@
 	/* Remember to send an RSL ACK once the lchan is active */
 	lchan->rel_act_kind = LCHAN_REL_ACT_RSL;
 
+	parse_repeated_acch_capability(lchan, &tp);
+
 	/* actually activate the channel in the BTS */
 	rc = l1sap_chan_act(lchan->ts->trx, dch->chan_nr, &tp);
 	if (rc < 0)
@@ -1653,6 +1682,8 @@
 	/* 9.3.53 MultiRate Control */
 	/* 9.3.54 Supported Codec Types */
 
+	parse_repeated_acch_capability(lchan, &tp);
+
 	l1sap_chan_modify(lchan->ts->trx, dch->chan_nr);
 
 	/* FIXME: delay this until L1 says OK? */
@@ -3007,6 +3038,7 @@
 			return 0;
 		}
 
+		repeated_dl_facch_active_decision(lchan, msgb_l3(msg), msgb_l3len(msg));
 		rc = rsl_tx_meas_res(lchan, msgb_l3(msg), msgb_l3len(msg), le);
 		msgb_free(msg);
 		return rc;
diff --git a/src/osmo-bts-trx/main.c b/src/osmo-bts-trx/main.c
index 021c3c7..7e6dea9 100644
--- a/src/osmo-bts-trx/main.c
+++ b/src/osmo-bts-trx/main.c
@@ -144,6 +144,7 @@
 	osmo_bts_set_feature(bts->features, BTS_FEAT_SPEECH_H_AMR);
 	osmo_bts_set_feature(bts->features, BTS_FEAT_CBCH);
 	osmo_bts_set_feature(bts->features, BTS_FEAT_HOPPING);
+	osmo_bts_set_feature(bts->features, BTS_FEAT_ACCH_REP);
 
 	bts_internal_flag_set(bts, BTS_INTERNAL_FLAG_MEAS_PAYLOAD_COMB);
 

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/21014
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-bts
Gerrit-Branch: master
Gerrit-Change-Id: I72f0cf7eaaef9f80fc35e752c90ae0e2d24d0c75
Gerrit-Change-Number: 21014
Gerrit-PatchSet: 11
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: fixeria <vyanitskiy at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20201201/78fc0f11/attachment.htm>


More information about the gerrit-log mailing list