<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>