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/.
fixeria gerrit-no-reply at lists.osmocom.orgfixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-bts/+/18973 ) Change subject: osmo-bts-trx/scheduler: refactor UL burst measurement processing ...................................................................... osmo-bts-trx/scheduler: refactor UL burst measurement processing Currently the UL measurements (RSSI, ToA256, C/I) of the burst that concludes a block are passed up to the higher layers. This means that the measurement values of the other bursts are skipped. Let's keep record of all UL measurements and average the values before we pass them up to the higher layers. Use a simple ring buffer to store the measurement history (up to 8 unique entries for now). Remove *_num/*_sum variables from l1sched_chan_state. Change-Id: I2b02b51fea5664f161382a4ddc63dbf14ffc9ac5 Related: OS#3032, OS#2978 --- M include/osmo-bts/scheduler.h M src/osmo-bts-trx/sched_lchan_pdtch.c M src/osmo-bts-trx/sched_lchan_tchf.c M src/osmo-bts-trx/sched_lchan_tchh.c M src/osmo-bts-trx/sched_lchan_xcch.c M src/osmo-bts-trx/scheduler_trx.c 6 files changed, 148 insertions(+), 85 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-bts refs/changes/73/18973/1 diff --git a/include/osmo-bts/scheduler.h b/include/osmo-bts/scheduler.h index bc2fb69..5eac9f2 100644 --- a/include/osmo-bts/scheduler.h +++ b/include/osmo-bts/scheduler.h @@ -70,6 +70,13 @@ TRX_BURST_8PSK, }; +/* A set of measurements belonging to one Uplink burst */ +struct l1sched_meas_set { + int16_t toa256; /* Timing of Arrival (1/256 of a symbol) */ + int16_t ci_cb; /* Carrier-to-Interference (cB) */ + float rssi; /* RSSI (dBm) */ +}; + /* States each channel on a multiframe */ struct l1sched_chan_state { /* Pointer to the associated logical channel state from gsm_data_shared. @@ -85,14 +92,6 @@ uint32_t ul_first_fn; /* fn of first burst */ uint8_t ul_mask; /* mask of received bursts */ - /* measurements */ - uint8_t rssi_num; /* number of RSSI values */ - float rssi_sum; /* sum of RSSI values */ - uint8_t toa_num; /* number of TOA values */ - int32_t toa256_sum; /* sum of TOA values (1/256 symbol) */ - uint8_t ci_cb_num; /* number of C/I values */ - int32_t ci_cb_sum; /* sum of C/I values (in centiBels) */ - /* loss detection */ uint8_t lost_frames; /* how many L2 frames were lost */ uint32_t last_tdma_fn; /* last processed TDMA frame number */ @@ -127,7 +126,11 @@ uint8_t dl_encr_key[MAX_A5_KEY_LEN]; /* measurements */ - /* TODO: measurement history (ring buffer) will be added here */ + struct { + /* Simple ring buffer (up to 8 unique measurements) */ + struct l1sched_meas_set buf[8]; + unsigned int idx; + } meas; /* handover */ bool ho_rach_detect; /* if rach detection is on */ @@ -269,4 +272,20 @@ /*! Handle an UL burst received by PHY */ int trx_sched_ul_burst(struct l1sched_trx *l1t, struct trx_ul_burst_ind *bi); +/* Averaging mode for trx_sched_meas_avg() */ +enum sched_meas_avg_mode { + /* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */ + SCHED_MEAS_AVG_M_QUAD, + /* last 8 bursts (default for TCH/F and FACCH/F) */ + SCHED_MEAS_AVG_M_OCTO, + /* last 6 bursts (default for FACCH/H) */ + SCHED_MEAS_AVG_M_SIX, +}; + +void trx_sched_meas_push(struct l1sched_chan_state *chan_state, + const struct trx_ul_burst_ind *bi); +void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, + struct l1sched_meas_set *avg, + enum sched_meas_avg_mode mode); + #endif /* TRX_SCHEDULER_H */ diff --git a/src/osmo-bts-trx/sched_lchan_pdtch.c b/src/osmo-bts-trx/sched_lchan_pdtch.c index 259d336..28a45f5 100644 --- a/src/osmo-bts-trx/sched_lchan_pdtch.c +++ b/src/osmo-bts-trx/sched_lchan_pdtch.c @@ -46,17 +46,11 @@ sbit_t *burst, **bursts_p = &chan_state->ul_bursts; uint32_t *first_fn = &chan_state->ul_first_fn; uint8_t *mask = &chan_state->ul_mask; - float *rssi_sum = &chan_state->rssi_sum; - uint8_t *rssi_num = &chan_state->rssi_num; - int32_t *toa256_sum = &chan_state->toa256_sum; - uint8_t *toa_num = &chan_state->toa_num; - int32_t *ci_cb_sum = &chan_state->ci_cb_sum; - uint8_t *ci_cb_num = &chan_state->ci_cb_num; + struct l1sched_meas_set meas_avg; uint8_t l2[EGPRS_0503_MAX_BYTES]; int n_errors = 0; int n_bursts_bits = 0; int n_bits_total = 0; - int16_t lqual_cb; uint16_t ber10k; int rc; @@ -76,26 +70,13 @@ memset(*bursts_p, 0, GSM0503_EGPRS_BURSTS_NBITS); *mask = 0x0; *first_fn = bi->fn; - *rssi_sum = 0; - *rssi_num = 0; - *toa256_sum = 0; - *toa_num = 0; - *ci_cb_sum = 0; - *ci_cb_num = 0; } - /* update mask + rssi */ + /* update mask */ *mask |= (1 << bid); - *rssi_sum += bi->rssi; - (*rssi_num)++; - *toa256_sum += bi->toa256; - (*toa_num)++; - /* C/I: Carrier-to-Interference ratio (in centiBels) */ - if (bi->flags & TRX_BI_F_CI_CB) { - *ci_cb_sum += bi->ci_cb; - (*ci_cb_num)++; - } + /* store measurements */ + trx_sched_meas_push(chan_state, bi); /* copy burst to buffer of 4 bursts */ if (bi->burst_len == EGPRS_BURST_LEN) { @@ -114,6 +95,9 @@ if (bid != 3) return 0; + /* average measurements of the last 4 bursts */ + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_QUAD); + /* check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { LOGL1S(DL1P, LOGL_DEBUG, l1t, bi->tn, chan, bi->fn, @@ -143,13 +127,11 @@ return 0; } - lqual_cb = *ci_cb_num ? (*ci_cb_sum / *ci_cb_num) : 0; ber10k = compute_ber10k(n_bits_total, n_errors); return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn, chan, l2, rc, - *rssi_sum / *rssi_num, - *toa256_sum / *toa_num, - lqual_cb, ber10k, + meas_avg.rssi, meas_avg.toa256, + meas_avg.ci_cb, ber10k, PRES_INFO_BOTH); } diff --git a/src/osmo-bts-trx/sched_lchan_tchf.c b/src/osmo-bts-trx/sched_lchan_tchf.c index d289620..099088e 100644 --- a/src/osmo-bts-trx/sched_lchan_tchf.c +++ b/src/osmo-bts-trx/sched_lchan_tchf.c @@ -56,6 +56,8 @@ uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; uint8_t tch_data[128]; /* just to be safe */ + enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_OCTO; + struct l1sched_meas_set meas_avg; int rc, amr = 0; int n_errors = 0; int n_bits_total = 0; @@ -89,6 +91,9 @@ /* update mask */ *mask |= (1 << bid); + /* store measurements */ + trx_sched_meas_push(chan_state, bi); + /* copy burst to end of buffer of 8 bursts */ burst = *bursts_p + bid * 116 + 464; if (bi->burst_len > 0) { @@ -194,6 +199,10 @@ } memcpy(*bursts_p, *bursts_p + 464, 464); + /* average measurements of the last N (depends on mode) bursts + * TODO: properly handle measurements in DTX mode */ + trx_sched_meas_avg(chan_state, &meas_avg, meas_avg_mode); + /* Check if the frame is bad */ if (rc < 0) { LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn, @@ -219,10 +228,9 @@ fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_F); _sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, chan, tch_data + amr, GSM_MACBLOCK_LEN, - /* FIXME: AVG RSSI and ToA256 */ - bi->rssi, bi->toa256, - 0 /* FIXME: AVG C/I */, - ber10k, PRES_INFO_UNKNOWN); + meas_avg.rssi, meas_avg.toa256, + meas_avg.ci_cb, ber10k, + PRES_INFO_UNKNOWN); bfi: if (rsl_cmode == RSL_CMOD_SPD_SPEECH) { /* indicate bad frame */ @@ -277,8 +285,10 @@ /* TCH or BFI */ compose_l1sap: fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_F); - return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan, - tch_data, rc, bi->toa256, ber10k, bi->rssi, is_sub); + return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan, tch_data, rc, + /* FIXME: what should we use for BFI here? */ + bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k, + bfi_flag ? bi->rssi : meas_avg.rssi, is_sub); } /* common section for generation of TCH bursts (TCH/H and TCH/F). @@ -293,9 +303,6 @@ uint8_t rsl_cmode = chan_state->rsl_cmode; uint8_t tch_mode = chan_state->tch_mode; struct osmo_phsap_prim *l1sap; - int32_t *toa256_sum = &chan_state->toa256_sum; - uint8_t *toa_num = &chan_state->toa_num; - int16_t toa256; /* handle loss detection of received TCH frames */ if (rsl_cmode == RSL_CMOD_SPD_SPEECH @@ -343,14 +350,9 @@ } if (len) { - if (*toa_num == 0) - toa256 = 0; - else - toa256 = *toa256_sum / *toa_num; - - /* Note: RSSI is set to 0 to indicate to the higher + /* Note: RSSI/ToA256 is set to 0 to indicate to the higher * layers that this is a faked tch_ind */ - _sched_compose_tch_ind(l1t, tn, fn, chan, tch_data, len, toa256, 10000, 0, 0); + _sched_compose_tch_ind(l1t, tn, fn, chan, tch_data, len, 0, 10000, 0, 0); } } diff --git a/src/osmo-bts-trx/sched_lchan_tchh.c b/src/osmo-bts-trx/sched_lchan_tchh.c index 0281342..43f24b3 100644 --- a/src/osmo-bts-trx/sched_lchan_tchh.c +++ b/src/osmo-bts-trx/sched_lchan_tchh.c @@ -65,6 +65,8 @@ * Even FN ending at: 10,11,19,20,2,3 */ int fn_is_odd = (((bi->fn + 26 - 10) % 26) >> 2) & 1; + enum sched_meas_avg_mode meas_avg_mode = SCHED_MEAS_AVG_M_QUAD; + struct l1sched_meas_set meas_avg; unsigned int fn_begin; uint16_t ber10k; uint8_t is_sub = 0; @@ -94,6 +96,9 @@ /* update mask */ *mask |= (1 << bid); + /* store measurements */ + trx_sched_meas_push(chan_state, bi); + /* copy burst to end of buffer of 6 bursts */ burst = *bursts_p + bid * 116 + 464; if (bi->burst_len > 0) { @@ -208,6 +213,11 @@ memcpy(*bursts_p + 232, *bursts_p + 464, 232); ber10k = compute_ber10k(n_bits_total, n_errors); + /* average measurements of the last N (depends on mode) bursts + * TODO: properly handle measurements in DTX mode */ + if (rc == GSM_MACBLOCK_LEN) + meas_avg_mode = SCHED_MEAS_AVG_M_SIX; + trx_sched_meas_avg(chan_state, &meas_avg, meas_avg_mode); /* Check if the frame is bad */ if (rc < 0) { @@ -238,10 +248,9 @@ fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_FACCH_H1); _sched_compose_ph_data_ind(l1t, bi->tn, fn_begin, chan, tch_data + amr, GSM_MACBLOCK_LEN, - /* FIXME: AVG both RSSI and ToA */ - bi->rssi, bi->toa256, - 0 /* FIXME: AVG C/I */, - ber10k, PRES_INFO_UNKNOWN); + meas_avg.rssi, meas_avg.toa256, + meas_avg.ci_cb, ber10k, + PRES_INFO_UNKNOWN); bfi: /* FIXME: a FACCH/H frame replaces two speech frames, * so we actually need to send two bad frame indications! */ @@ -301,8 +310,10 @@ fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_H0); else fn_begin = gsm0502_fn_remap(bi->fn, FN_REMAP_TCH_H1); - return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan, - tch_data, rc, bi->toa256, ber10k, bi->rssi, is_sub); + return _sched_compose_tch_ind(l1t, bi->tn, fn_begin, chan, tch_data, rc, + /* FIXME: what should we use for BFI here? */ + bfi_flag ? bi->toa256 : meas_avg.toa256, ber10k, + bfi_flag ? bi->rssi : meas_avg.rssi, is_sub); } /* common section for generation of TCH bursts (TCH/H and TCH/F). diff --git a/src/osmo-bts-trx/sched_lchan_xcch.c b/src/osmo-bts-trx/sched_lchan_xcch.c index e2670d8..b96bc0b 100644 --- a/src/osmo-bts-trx/sched_lchan_xcch.c +++ b/src/osmo-bts-trx/sched_lchan_xcch.c @@ -43,16 +43,10 @@ sbit_t *burst, **bursts_p = &chan_state->ul_bursts; uint32_t *first_fn = &chan_state->ul_first_fn; uint8_t *mask = &chan_state->ul_mask; - float *rssi_sum = &chan_state->rssi_sum; - uint8_t *rssi_num = &chan_state->rssi_num; - int32_t *toa256_sum = &chan_state->toa256_sum; - uint8_t *toa_num = &chan_state->toa_num; - int32_t *ci_cb_sum = &chan_state->ci_cb_sum; - uint8_t *ci_cb_num = &chan_state->ci_cb_num; uint8_t l2[GSM_MACBLOCK_LEN], l2_len; + struct l1sched_meas_set meas_avg; int n_errors = 0; int n_bits_total = 0; - int16_t lqual_cb; uint16_t ber10k; int rc; @@ -76,26 +70,13 @@ memset(*bursts_p, 0, 464); *mask = 0x0; *first_fn = bi->fn; - *rssi_sum = 0; - *rssi_num = 0; - *toa256_sum = 0; - *toa_num = 0; - *ci_cb_sum = 0; - *ci_cb_num = 0; } - /* update mask + RSSI */ + /* update mask */ *mask |= (1 << bid); - *rssi_sum += bi->rssi; - (*rssi_num)++; - *toa256_sum += bi->toa256; - (*toa_num)++; - /* C/I: Carrier-to-Interference ratio (in centiBels) */ - if (bi->flags & TRX_BI_F_CI_CB) { - *ci_cb_sum += bi->ci_cb; - (*ci_cb_num)++; - } + /* store measurements */ + trx_sched_meas_push(chan_state, bi); /* Copy burst to buffer of 4 bursts. If the burst indication contains * no data, ensure that the buffer does not stay uninitialized */ @@ -110,6 +91,9 @@ if (bid != 3) return 0; + /* average measurements of the last 4 bursts */ + trx_sched_meas_avg(chan_state, &meas_avg, SCHED_MEAS_AVG_M_QUAD); + /* check for complete set of bursts */ if ((*mask & 0xf) != 0xf) { LOGL1S(DL1P, LOGL_NOTICE, l1t, bi->tn, chan, bi->fn, @@ -134,13 +118,11 @@ } else l2_len = GSM_MACBLOCK_LEN; - lqual_cb = *ci_cb_num ? (*ci_cb_sum / *ci_cb_num) : 0; ber10k = compute_ber10k(n_bits_total, n_errors); return _sched_compose_ph_data_ind(l1t, bi->tn, *first_fn, chan, l2, l2_len, - *rssi_sum / *rssi_num, - *toa256_sum / *toa_num, - lqual_cb, ber10k, + meas_avg.rssi, meas_avg.toa256, + meas_avg.ci_cb, ber10k, PRES_INFO_UNKNOWN); } diff --git a/src/osmo-bts-trx/scheduler_trx.c b/src/osmo-bts-trx/scheduler_trx.c index d4a38b6..acb7907 100644 --- a/src/osmo-bts-trx/scheduler_trx.c +++ b/src/osmo-bts-trx/scheduler_trx.c @@ -368,3 +368,70 @@ else trx_if_cmd_nohandover(l1h, tn, ss); } + +/* Add a set of UL burst measurements to the history */ +void trx_sched_meas_push(struct l1sched_chan_state *chan_state, + const struct trx_ul_burst_ind *bi) +{ + unsigned int hist_size = ARRAY_SIZE(chan_state->meas.buf); + unsigned int current = chan_state->meas.idx; + + chan_state->meas.buf[current] = (struct l1sched_meas_set) { + .ci_cb = (bi->flags & TRX_BI_F_CI_CB) ? bi->ci_cb : 0, + .toa256 = bi->toa256, + .rssi = bi->rssi, + }; + + chan_state->meas.idx = (current + 1) % hist_size; +} + +/* Calculate the AVG of n measurements from the history */ +void trx_sched_meas_avg(const struct l1sched_chan_state *chan_state, + struct l1sched_meas_set *avg, + enum sched_meas_avg_mode mode) +{ + unsigned int hist_size = ARRAY_SIZE(chan_state->meas.buf); + unsigned int current = chan_state->meas.idx; + const struct l1sched_meas_set *set; + unsigned int shift, pos, i, n; + + float rssi_sum = 0; + int toa256_sum = 0; + int ci_cb_sum = 0; + + switch (mode) { + /* last 4 bursts (default for xCCH, TCH/H, PTCCH and PDTCH) */ + case SCHED_MEAS_AVG_M_QUAD: + n = 4; shift = n; + break; + /* last 8 bursts (default for TCH/F and FACCH/F) */ + case SCHED_MEAS_AVG_M_OCTO: + n = 8; shift = n; + break; + /* last 6 bursts (default for FACCH/H) */ + case SCHED_MEAS_AVG_M_SIX: + n = 6; shift = n; + break; + } + + /* Calculate the sum of n entries starting from pos */ + for (i = 0; i < n; i++) { + pos = (current + hist_size - shift + i) % hist_size; + set = &chan_state->meas.buf[pos]; + + rssi_sum += set->rssi; + toa256_sum += set->toa256; + ci_cb_sum += set->ci_cb; + } + + /* Calculate the average for each value */ + *avg = (struct l1sched_meas_set) { + .rssi = (rssi_sum / n), + .toa256 = (toa256_sum / n), + .ci_cb = (ci_cb_sum / n), + }; + + LOGP(DL1C, LOGL_DEBUG, "Measurement AVG (num=%u, shift=%u): " + "RSSI %f, ToA256 %d, C/I %d cB\n", n, shift, + avg->rssi, avg->toa256, avg->ci_cb); +} -- To view, visit https://gerrit.osmocom.org/c/osmo-bts/+/18973 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-bts Gerrit-Branch: master Gerrit-Change-Id: I2b02b51fea5664f161382a4ddc63dbf14ffc9ac5 Gerrit-Change-Number: 18973 Gerrit-PatchSet: 1 Gerrit-Owner: fixeria <vyanitskiy at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200622/5d9c5818/attachment.htm>