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