laforge has submitted this change. ( https://gerrit.osmocom.org/c/osmo-bts/+/21185 )
Change subject: l1sap: add repeated uplink SACCH ...................................................................... l1sap: add repeated uplink SACCH 3GPP TS 44.006, section 11 describes a method how the uplink SACCH transmission can be repeated to increase transmission reliability. Change-Id: I7e4cc33cc010866e41e3b594351a7f7bf93e08ac Related: OS#4795, SYS#5114 --- M include/osmo-bts/gsm_data.h M include/osmo-bts/scheduler.h M src/common/l1sap.c M src/osmo-bts-trx/sched_lchan_xcch.c 4 files changed, 80 insertions(+), 0 deletions(-) Approvals: Jenkins Builder: Verified fixeria: Looks good to me, but someone else must approve Hoernchen: 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 b5b616e..64102f5 100644 --- a/include/osmo-bts/gsm_data.h +++ b/include/osmo-bts/gsm_data.h @@ -326,6 +326,7 @@ struct abis_rsl_osmo_rep_acch_cap repeated_acch_capability; bool repeated_dl_facch_active; + bool repeated_ul_sacch_active; /* Message buffer to store DL-SACCH repeation candidate */ struct msgb *rep_sacch; diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h index 6bb0b9b..6f05756 100644 --- a/include/osmo-bts/scheduler.h +++ b/include/osmo-bts/scheduler.h @@ -87,6 +87,7 @@ ubit_t *dl_bursts; /* burst buffer for TX */ enum trx_burst_type dl_burst_type; /* GMSK or 8PSK burst type */ sbit_t *ul_bursts; /* burst buffer for RX */ + sbit_t *ul_bursts_prev;/* previous burst buffer for RX (repeated SACCH) */ uint32_t ul_first_fn; /* fn of first burst */ uint8_t ul_mask; /* mask of received bursts */ diff --git a/src/common/l1sap.c b/src/common/l1sap.c index 05adbb1..1785e66 100644 --- a/src/common/l1sap.c +++ b/src/common/l1sap.c @@ -1131,6 +1131,8 @@ p = msgb_put(msg, GSM_MACBLOCK_LEN); /* L1-header, if not set/modified by layer 1 */ p[0] = lchan->ms_power_ctrl.current; + if (lchan->repeated_ul_sacch_active) + p[0] |= 0x40; /* See also: 3GPP TS 44.004, section 7.1 */ p[1] = lchan->rqd_ta; le = &lchan->lapdm_ch.lapdm_acch; if (lchan->repeated_acch_capability.dl_sacch) @@ -1394,6 +1396,34 @@ return check_for_first_ciphrd(lchan, data, len); } +/* Decide if repeated UL-SACCH should be applied or not. If the BER level, of + * the received SACCH blocks rises above a certain threshold UL-SACCH + * repetition is enabled */ +static void repeated_ul_sacch_active_decision(struct gsm_lchan *lchan, + uint16_t ber10k) +{ + uint16_t upper = 0; + uint16_t lower = 0; + + if (!lchan->repeated_acch_capability.ul_sacch) + return; + + /* convert from RXQUAL value to ber10k vale, + * see also GSM 05.08, section 8.2.4 */ + static const uint16_t ber10k_by_rxqual_upper[] = + { 0, 26, 51, 100, 190, 380, 760, 1500 }; + static const uint16_t ber10k_by_rxqual_lower[] = + { 0, 10, 10, 30, 64, 130, 270, 540 }; + upper = ber10k_by_rxqual_upper[lchan->repeated_acch_capability.rxqual]; + lower = ber10k_by_rxqual_lower[lchan->repeated_acch_capability.rxqual]; + + /* If upper/rxqual == 0, then repeated UL-SACCH is always on */ + if (ber10k >= upper) + lchan->repeated_ul_sacch_active = true; + else if (ber10k <= lower) + lchan->repeated_ul_sacch_active = false; +} + /* DATA received from bts model */ static int l1sap_ph_data_ind(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap, struct ph_data_param *data_ind) @@ -1472,6 +1502,9 @@ return 0; } + if (L1SAP_IS_LINK_SACCH(link_id)) + repeated_ul_sacch_active_decision(lchan, data_ind->ber10k); + /* bad frame */ if (len == 0) { if (L1SAP_IS_LINK_SACCH(link_id)) { diff --git a/src/osmo-bts-trx/sched_lchan_xcch.c b/src/osmo-bts-trx/sched_lchan_xcch.c index b96bc0b..90f481a 100644 --- a/src/osmo-bts-trx/sched_lchan_xcch.c +++ b/src/osmo-bts-trx/sched_lchan_xcch.c @@ -34,6 +34,17 @@ #include <sched_utils.h> +/* Add two arrays of sbits */ +static void add_sbits(sbit_t * current, const sbit_t * previous) +{ + unsigned int i; + for (i = 0; i < 464; i++) { + *current = (*current) / 2 + (*previous) / 2; + current++; + previous++; + } +} + /*! \brief a single (SDCCH/SACCH) burst was received by the PHY, process it */ int rx_data_fn(struct l1sched_trx *l1t, enum trx_chan_type chan, uint8_t bid, const struct trx_ul_burst_ind *bi) @@ -49,6 +60,8 @@ int n_bits_total = 0; uint16_t ber10k; int rc; + struct gsm_lchan *lchan = chan_state->lchan; + bool rep_sacch = L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id) && lchan->repeated_ul_sacch_active; /* If handover RACH detection is turned on, treat this burst as an Access Burst. * Handle NOPE.ind as usually to ensure proper Uplink measurement reporting. */ @@ -65,6 +78,14 @@ return -ENOMEM; } + /* UL-SACCH requires additional memory to keep a copy of each previous + * burst set. */ + if (L1SAP_IS_LINK_SACCH(trx_chan_desc[chan].link_id) && !chan_state->ul_bursts_prev) { + chan_state->ul_bursts_prev = talloc_zero_size(tall_bts_ctx, 464); + if (!chan_state->ul_bursts_prev) + return -ENOMEM; + } + /* clear burst & store frame number of first burst */ if (bid == 0) { memset(*bursts_p, 0, 464); @@ -115,10 +136,34 @@ "Received bad data (%u/%u)\n", bi->fn % l1ts->mf_period, l1ts->mf_period); l2_len = 0; + + /* When SACCH Repetition is active, we may try to decode the + * current SACCH block by including the information from the + * information from the previous SACCH block. See also: + * 3GPP TS 44.006, section 11.2 */ + if (rep_sacch) { + add_sbits(*bursts_p, chan_state->ul_bursts_prev); + rc = gsm0503_xcch_decode(l2, *bursts_p, &n_errors, &n_bits_total); + if (rc) { + LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn, + "Combining current SACCH block with previous SACCH block also yields bad data (%u/%u)\n", + bi->fn % l1ts->mf_period, l1ts->mf_period); + } else { + LOGL1S(DL1P, LOGL_DEBUG, l1t, bi->tn, chan, bi->fn, + "Combining current SACCH block with previous SACCH block yields good data (%u/%u)\n", + bi->fn % l1ts->mf_period, l1ts->mf_period); + l2_len = GSM_MACBLOCK_LEN; + } + } } else l2_len = GSM_MACBLOCK_LEN; ber10k = compute_ber10k(n_bits_total, n_errors); + + /* Keep a copy to ease decoding in the next repetition pass */ + if (rep_sacch) + memcpy(chan_state->ul_bursts_prev, *bursts_p, 464); + return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn, chan, l2, l2_len, meas_avg.rssi, meas_avg.toa256, -- To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/21185 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Change-Id: I7e4cc33cc010866e41e3b594351a7f7bf93e08ac Gerrit-Change-Number: 21185 Gerrit-PatchSet: 5 Gerrit-Owner: dexter <pma...@sysmocom.de> Gerrit-Reviewer: Hoernchen <ew...@sysmocom.de> Gerrit-Reviewer: Jenkins Builder Gerrit-Reviewer: fixeria <vyanits...@sysmocom.de> Gerrit-Reviewer: laforge <lafo...@osmocom.org> Gerrit-Reviewer: tnt <t...@246tnt.com> Gerrit-MessageType: merged