<p>fixeria has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bts/+/15807">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">osmo-bts-trx/scheduler: refactor Uplink measurement processing<br><br>So far we used to store the sums of ToA, RSSI, and C/I measurements<br>in the logical channel state, and after decoding of a block, we did<br>calculate the average. This approach works fine for xCCH and PDTCH,<br>but when it comes to block-diagonal interleaving (which is used on<br>TCH/F and TCH/H channels), the results are incorrect.<br><br>Instead of calculating the sum of measurements on the fly, let's<br>push them onto a stack (the measurement history), and optionally<br>keep the last N measurements in there after decoding of a block.<br><br>The proposed approach will allow us to reduce the code duplication<br>and get much more accurate Uplink measurement reports. However,<br>there is a spoon of tar: records of the measurement history are<br>getting allocated on heap every time we receive an Uplink burst.<br><br>These frequent allocations may introduce a negative impact on the<br>overall performance level, but we can use a talloc pool to reduce<br>possible delays and potential fragmentation.<br><br>Change-Id: I6bc511223069f66b49109d3267bee7bd89585713<br>---<br>M include/osmo-bts/scheduler.h<br>M src/osmo-bts-trx/scheduler_trx.c<br>2 files changed, 145 insertions(+), 78 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/07/15807/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 3100a1d..e6ec37d 100644</span><br><span>--- a/include/osmo-bts/scheduler.h</span><br><span>+++ b/include/osmo-bts/scheduler.h</span><br><span>@@ -69,6 +69,15 @@</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 attached to a burst */</span><br><span style="color: hsl(120, 100%, 40%);">+struct l1sched_meas_set {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head list; /* Link to the measurement history */</span><br><span style="color: hsl(120, 100%, 40%);">+</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> /* scheduler */</span><br><span>@@ -79,14 +88,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>@@ -121,6 +122,10 @@</span><br><span> </span><br><span> /* measurements */</span><br><span> struct {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head hist; /* History of measurements (see l1sched_meas_set) */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num; /* Number of measurements in history */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* FIXME: keep all measurements in the history (see above) */</span><br><span> uint8_t clock; /* cyclic clock counter */</span><br><span> int8_t rssi[32]; /* last RSSI values */</span><br><span> int rssi_count; /* received RSSI values */</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 8662a14..d37dd51 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>@@ -887,6 +887,77 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Add a set of measurements to the head of the history. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void l1sched_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%);">+ struct l1sched_meas_set *set;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* TODO: unfortunately, we cannot use chan_state as the context :/</span><br><span style="color: hsl(120, 100%, 40%);">+ * TODO: should we use a talloc pool for such allocations? */</span><br><span style="color: hsl(120, 100%, 40%);">+ set = talloc(tall_bts_ctx, struct l1sched_meas_set);</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(set != NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ set->toa256 = bi->toa256;</span><br><span style="color: hsl(120, 100%, 40%);">+ set->rssi = bi->rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Optional fields */</span><br><span style="color: hsl(120, 100%, 40%);">+ set->ci_cb = (bi->flags & TRX_BI_F_CI_CB) ? bi->ci_cb : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_add(&set->list, &chan_state->meas.hist);</span><br><span style="color: hsl(120, 100%, 40%);">+ chan_state->meas.num++;</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%);">+/* Average a given number of measurements from the history,</span><br><span style="color: hsl(120, 100%, 40%);">+ * store the results in a caller-allocated set. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void l1sched_meas_average(const struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_meas_set *result,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_meas_set *set;</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%);">+ int rssi_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* There shall be at least one set */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(chan_state->meas.num > 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Prevent division by zero */</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(num > 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* There can be less records in the history */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (chan_state->meas.num < num)</span><br><span style="color: hsl(120, 100%, 40%);">+ num = chan_state->meas.num;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Calculate the sum of measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_for_each_entry(set, &chan_state->meas.hist, list) {</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%);">+ rssi_sum += set->rssi;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (--num == 0)</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 average */</span><br><span style="color: hsl(120, 100%, 40%);">+ result->toa256 = toa256_sum / num;</span><br><span style="color: hsl(120, 100%, 40%);">+ result->ci_cb = ci_cb_sum / num;</span><br><span style="color: hsl(120, 100%, 40%);">+ result->rssi = rssi_sum / num;</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%);">+/* Reduce amount of measurements in the history to a given number. */</span><br><span style="color: hsl(120, 100%, 40%);">+static void l1sched_meas_squeeze(struct l1sched_chan_state *chan_state,</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int num)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct llist_head *hist = &chan_state->meas.hist;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_meas_set *set;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (!llist_empty(hist) && chan_state->meas.num-- > num) {</span><br><span style="color: hsl(120, 100%, 40%);">+ set = llist_last_entry(hist, struct l1sched_meas_set, list);</span><br><span style="color: hsl(120, 100%, 40%);">+ llist_del(&set->list);</span><br><span style="color: hsl(120, 100%, 40%);">+ talloc_free(set);</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%);">+</span><br><span> /*! \brief a single (SDCCH/SACCH) burst was received by the PHY, process it */</span><br><span> int rx_data_fn(struct l1sched_trx *l1t, enum trx_chan_type chan,</span><br><span> uint8_t bid, const struct trx_ul_burst_ind *bi)</span><br><span>@@ -896,15 +967,9 @@</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_set;</span><br><span> int n_errors, n_bits_total;</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>@@ -920,6 +985,8 @@</span><br><span> *bursts_p = talloc_zero_size(tall_bts_ctx, 464);</span><br><span> if (!*bursts_p)</span><br><span> return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* HACK: also initialize the measurement history */</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&chan_state->meas.hist);</span><br><span> }</span><br><span> </span><br><span> /* clear burst & store frame number of first burst */</span><br><span>@@ -927,26 +994,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%);">+ /* store the measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_push(chan_state, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* update the 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 style="color: hsl(0, 100%, 40%);">-</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> </span><br><span> /* copy burst to buffer of 4 bursts */</span><br><span> burst = *bursts_p + bid * 116;</span><br><span>@@ -987,19 +1041,21 @@</span><br><span> } else</span><br><span> l2_len = GSM_MACBLOCK_LEN;</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%);">+ l1sched_meas_average(chan_state, &meas_set, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Nothing to store for the next block */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_squeeze(chan_state, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send uplink measurement information to L2 */</span><br><span> l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,</span><br><span> trx_chan_desc[chan].chan_nr | bi->tn,</span><br><span> n_errors, n_bits_total,</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 = *ci_cb_num ? (*ci_cb_sum / *ci_cb_num) : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.rssi, meas_set.toa256);</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_set.rssi, meas_set.toa256,</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.ci_cb, ber10k,</span><br><span> PRES_INFO_UNKNOWN);</span><br><span> }</span><br><span> </span><br><span>@@ -1012,15 +1068,9 @@</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[EGPRS_0503_MAX_BYTES];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct l1sched_meas_set meas_set;</span><br><span> int n_errors, n_bursts_bits, n_bits_total;</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>@@ -1033,6 +1083,8 @@</span><br><span> GSM0503_EGPRS_BURSTS_NBITS);</span><br><span> if (!*bursts_p)</span><br><span> return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* HACK: also initialize the measurement history */</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&chan_state->meas.hist);</span><br><span> }</span><br><span> </span><br><span> /* clear burst */</span><br><span>@@ -1040,26 +1092,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%);">+ /* store the measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_push(chan_state, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* update the 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 style="color: hsl(0, 100%, 40%);">-</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> </span><br><span> /* copy burst to buffer of 4 bursts */</span><br><span> if (bi->burst_len == EGPRS_BURST_LEN) {</span><br><span>@@ -1100,13 +1139,16 @@</span><br><span> &n_errors, &n_bits_total);</span><br><span> }</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%);">+ l1sched_meas_average(chan_state, &meas_set, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Nothing to store for the next block */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_squeeze(chan_state, 0);</span><br><span> </span><br><span> /* Send uplink measurement information to L2 */</span><br><span> l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,</span><br><span> trx_chan_desc[chan].chan_nr | bi->tn,</span><br><span> n_errors, n_bits_total,</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(120, 100%, 40%);">+ meas_set.rssi, meas_set.toa256);</span><br><span> </span><br><span> if (rc <= 0) {</span><br><span> LOGL1S(DL1P, LOGL_DEBUG, l1t, bi->tn, chan, bi->fn,</span><br><span>@@ -1115,13 +1157,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_set.rssi, meas_set.toa256,</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.ci_cb, ber10k,</span><br><span> PRES_INFO_BOTH);</span><br><span> }</span><br><span> </span><br><span>@@ -1137,6 +1177,7 @@</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%);">+ struct l1sched_meas_set meas_set;</span><br><span> int rc, amr = 0;</span><br><span> int n_errors, n_bits_total;</span><br><span> bool bfi_flag = false;</span><br><span>@@ -1155,6 +1196,8 @@</span><br><span> *bursts_p = talloc_zero_size(tall_bts_ctx, 928);</span><br><span> if (!*bursts_p)</span><br><span> return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* HACK: also initialize the measurement history */</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&chan_state->meas.hist);</span><br><span> }</span><br><span> </span><br><span> /* clear burst */</span><br><span>@@ -1164,6 +1207,9 @@</span><br><span> *first_fn = bi->fn;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* store the measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_push(chan_state, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* update mask */</span><br><span> *mask |= (1 << bid);</span><br><span> </span><br><span>@@ -1225,11 +1271,16 @@</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 8 bursts */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_average(chan_state, &meas_set, 8);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Keep measurements of the last 4 bursts */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_squeeze(chan_state, 4);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send uplink measurement information to L2 */</span><br><span> l1if_process_meas_res(l1t->trx, bi->tn, *first_fn,</span><br><span> trx_chan_desc[chan].chan_nr | bi->tn,</span><br><span> n_errors, n_bits_total,</span><br><span style="color: hsl(0, 100%, 40%);">- bi->rssi, bi->toa256);</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.rssi, meas_set.toa256);</span><br><span> </span><br><span> /* Check if the frame is bad */</span><br><span> if (rc < 0) {</span><br><span>@@ -1257,10 +1308,9 @@</span><br><span> /* FIXME: this calculation is wrong */</span><br><span> (bi->fn + GSM_HYPERFRAME - 7) % GSM_HYPERFRAME, 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_set.rssi, meas_set.toa256,</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.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>@@ -1332,6 +1382,7 @@</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%);">+ struct l1sched_meas_set meas_set;</span><br><span> int rc, amr = 0;</span><br><span> int n_errors, n_bits_total;</span><br><span> bool bfi_flag = false;</span><br><span>@@ -1355,6 +1406,8 @@</span><br><span> *bursts_p = talloc_zero_size(tall_bts_ctx, 696);</span><br><span> if (!*bursts_p)</span><br><span> return -ENOMEM;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* HACK: also initialize the measurement history */</span><br><span style="color: hsl(120, 100%, 40%);">+ INIT_LLIST_HEAD(&chan_state->meas.hist);</span><br><span> }</span><br><span> </span><br><span> /* clear burst */</span><br><span>@@ -1364,6 +1417,9 @@</span><br><span> *first_fn = bi->fn;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* store the measurements */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_push(chan_state, bi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* update mask */</span><br><span> *mask |= (1 << bid);</span><br><span> </span><br><span>@@ -1436,11 +1492,18 @@</span><br><span> memcpy(*bursts_p, *bursts_p + 232, 232);</span><br><span> memcpy(*bursts_p + 232, *bursts_p + 464, 232);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* Average measurements of either the last 4 bursts (speech),</span><br><span style="color: hsl(120, 100%, 40%);">+ * or the last 6 bursts (in case if FACCH/H was received). */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_average(chan_state, &meas_set, rc == GSM_MACBLOCK_LEN ? 6 : 4);</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Keep measurements of the last 2 bursts */</span><br><span style="color: hsl(120, 100%, 40%);">+ l1sched_meas_squeeze(chan_state, 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* Send uplink measurement information to L2 */</span><br><span> l1if_process_meas_res(l1t->trx, bi->tn,</span><br><span> *first_fn /* FIXME: this is wrong */,</span><br><span> trx_chan_desc[chan].chan_nr | bi->tn,</span><br><span style="color: hsl(0, 100%, 40%);">- n_errors, n_bits_total, bi->rssi, bi->toa256);</span><br><span style="color: hsl(120, 100%, 40%);">+ n_errors, n_bits_total,</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.rssi, meas_set.toa256);</span><br><span> </span><br><span> /* Check if the frame is bad */</span><br><span> if (rc < 0) {</span><br><span>@@ -1469,10 +1532,9 @@</span><br><span> /* FIXME: what the hell is this?!? */</span><br><span> (bi->fn + GSM_HYPERFRAME - 10 - ((bi->fn % 26) >= 19)) % GSM_HYPERFRAME, 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_set.rssi, meas_set.toa256,</span><br><span style="color: hsl(120, 100%, 40%);">+ meas_set.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></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bts/+/15807">change 15807</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/+/15807"/><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: I6bc511223069f66b49109d3267bee7bd89585713 </div>
<div style="display:none"> Gerrit-Change-Number: 15807 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: fixeria <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>