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