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