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>