<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/9777">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">Add min/max/std-dev measurement reporting for TOA256<br><br>This patch adds extended processing of the high-resolution TOA256<br>measurement values.  It adds reporting of the following values<br>for each RSL MEAS REP for uplink measurements:<br>* minimum TOA256 value during reporting period<br>* maximum TOA256 value during reporting period<br>* standard deviation of  TOA256 value during reporting period<br><br>Change-Id: Iea4a4781481f77c6163d82dcd71a844a5be87bf2<br>---<br>M include/osmo-bts/gsm_data_shared.h<br>M src/common/measurement.c<br>M src/common/rsl.c<br>M tests/meas/meas_test.c<br>M tests/meas/meas_test.ok<br>5 files changed, 348 insertions(+), 9 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmo-bts/gsm_data_shared.h b/include/osmo-bts/gsm_data_shared.h</span><br><span>index f4fb766..e15abfe 100644</span><br><span>--- a/include/osmo-bts/gsm_data_shared.h</span><br><span>+++ b/include/osmo-bts/gsm_data_shared.h</span><br><span>@@ -127,6 +127,7 @@</span><br><span> #define MAX_NUM_UL_MEAS     104</span><br><span> #define LC_UL_M_F_L1_VALID       (1 << 0)</span><br><span> #define LC_UL_M_F_RES_VALID   (1 << 1)</span><br><span style="color: hsl(120, 100%, 40%);">+#define LC_UL_M_F_OSMO_EXT_VALID (1 << 2)</span><br><span> </span><br><span> struct bts_ul_meas {</span><br><span>  /* BER in units of 0.01%: 10.000 == 100% ber, 0 == 0% ber */</span><br><span>@@ -257,6 +258,15 @@</span><br><span>          uint8_t l1_info[2];</span><br><span>          struct gsm_meas_rep_unidir ul_res;</span><br><span>           int16_t ms_toa256;</span><br><span style="color: hsl(120, 100%, 40%);">+            /* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */</span><br><span style="color: hsl(120, 100%, 40%);">+          struct {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* minimum value of toa256 during measurement period */</span><br><span style="color: hsl(120, 100%, 40%);">+                       int16_t toa256_min;</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* maximum value of toa256 during measurement period */</span><br><span style="color: hsl(120, 100%, 40%);">+                       int16_t toa256_max;</span><br><span style="color: hsl(120, 100%, 40%);">+                   /* standard deviation of toa256 value during measurement period */</span><br><span style="color: hsl(120, 100%, 40%);">+                    uint16_t toa256_std_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+              } ext;</span><br><span>       } meas;</span><br><span>      struct {</span><br><span>             struct amr_multirate_conf amr_mr;</span><br><span>@@ -317,6 +327,11 @@</span><br><span>     } ecu_state;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static inline uint8_t lchan_get_ta(const struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return lchan->meas.l1_info[1];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern const struct value_string lchan_ciph_state_names[];</span><br><span> static inline const char *lchan_ciph_state_name(uint8_t state) {</span><br><span>     return get_value_string(lchan_ciph_state_names, state);</span><br><span>diff --git a/src/common/measurement.c b/src/common/measurement.c</span><br><span>index ba7494a..01f1e5d 100644</span><br><span>--- a/src/common/measurement.c</span><br><span>+++ b/src/common/measurement.c</span><br><span>@@ -3,6 +3,7 @@</span><br><span> #include <errno.h></span><br><span> </span><br><span> #include <osmocom/gsm/gsm_utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span> </span><br><span> #include <osmo-bts/gsm_data.h></span><br><span> #include <osmo-bts/logging.h></span><br><span>@@ -335,6 +336,64 @@</span><br><span>  return 7;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* if we clip the TOA value to 12 bits, i.e. toa256=3200,</span><br><span style="color: hsl(120, 100%, 40%);">+ *  -> the maximum deviation can be 2*3200 = 6400</span><br><span style="color: hsl(120, 100%, 40%);">+ *  -> the maximum squared deviation can be 6400^2 = 40960000</span><br><span style="color: hsl(120, 100%, 40%);">+ *  -> the maximum sum of squared deviations can be 104*40960000 = 4259840000</span><br><span style="color: hsl(120, 100%, 40%);">+ *     and hence fit into uint32_t</span><br><span style="color: hsl(120, 100%, 40%);">+ *  -> once the value is divided by 104, it's again below 40960000</span><br><span style="color: hsl(120, 100%, 40%);">+ *     leaving 6 MSBs of freedom, i.e. we could extend by 64, resulting in 2621440000</span><br><span style="color: hsl(120, 100%, 40%);">+ *  -> as a result, the standard deviation could be communicated with up to six bits</span><br><span style="color: hsl(120, 100%, 40%);">+ *     of fractional fixed-point number.</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%);">+/* compute Osmocom extended measurements for the given lchan */</span><br><span style="color: hsl(120, 100%, 40%);">+static void lchan_meas_compute_extended(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ /* we assume that lchan_meas_check_compute() has already computed the mean value</span><br><span style="color: hsl(120, 100%, 40%);">+       * and we can compute the min/max/variance/stddev from this */</span><br><span style="color: hsl(120, 100%, 40%);">+        int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* each measurement is an int32_t, so the squared difference value must fit in 32bits */</span><br><span style="color: hsl(120, 100%, 40%);">+      /* the sum of the squared values (each up to 32bit) can very easily exceed 32 bits */</span><br><span style="color: hsl(120, 100%, 40%);">+ u_int64_t sq_diff_sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* initialize min/max values with their counterpart */</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan->meas.ext.toa256_min = INT16_MAX;</span><br><span style="color: hsl(120, 100%, 40%);">+    lchan->meas.ext.toa256_max = INT16_MIN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_ASSERT(lchan->meas.num_ul_meas);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* all computations are done on the relative arrival time of the burst, relative to the</span><br><span style="color: hsl(120, 100%, 40%);">+        * beginning of its slot. This is of course excluding the TA value that the MS has already</span><br><span style="color: hsl(120, 100%, 40%);">+     * compensated/pre-empted its transmission */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* step 1: compute the sum of the squared difference of each value to mean */</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < lchan->meas.num_ul_meas; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+         struct bts_ul_meas *m = &lchan->meas.uplink[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                int32_t diff = (int32_t)m->ta_offs_256bits - (int32_t)lchan->meas.ms_toa256;</span><br><span style="color: hsl(120, 100%, 40%);">+            /* diff can now be any value of +65535 to -65535, so we can safely square it,</span><br><span style="color: hsl(120, 100%, 40%);">+          * but only in unsigned math.  As squaring looses the sign, we can simply drop</span><br><span style="color: hsl(120, 100%, 40%);">+                 * it before squaring, too. */</span><br><span style="color: hsl(120, 100%, 40%);">+                uint32_t diff_abs = labs(diff);</span><br><span style="color: hsl(120, 100%, 40%);">+               uint32_t diff_squared = diff_abs * diff_abs;</span><br><span style="color: hsl(120, 100%, 40%);">+          sq_diff_sum += diff_squared;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                /* also use this loop iteration to compute min/max values */</span><br><span style="color: hsl(120, 100%, 40%);">+          if (m->ta_offs_256bits > lchan->meas.ext.toa256_max)</span><br><span style="color: hsl(120, 100%, 40%);">+                 lchan->meas.ext.toa256_max = m->ta_offs_256bits;</span><br><span style="color: hsl(120, 100%, 40%);">+                if (m->ta_offs_256bits < lchan->meas.ext.toa256_min)</span><br><span style="color: hsl(120, 100%, 40%);">+                 lchan->meas.ext.toa256_min = m->ta_offs_256bits;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     /* step 2: compute the variance (mean of sum of squared differences) */</span><br><span style="color: hsl(120, 100%, 40%);">+       sq_diff_sum = sq_diff_sum / lchan->meas.num_ul_meas;</span><br><span style="color: hsl(120, 100%, 40%);">+       /* as the individual summed values can each not exceed 2^32, and we're</span><br><span style="color: hsl(120, 100%, 40%);">+     * dividing by the number of summands, the resulting value can also not exceed 2^32 */</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(sq_diff_sum <= UINT32_MAX);</span><br><span style="color: hsl(120, 100%, 40%);">+    /* step 3: compute the standard deviation from the variance */</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan->meas.ext.toa256_std_dev = osmo_isqrt32(sq_diff_sum);</span><br><span style="color: hsl(120, 100%, 40%);">+        lchan->meas.flags |= LC_UL_M_F_OSMO_EXT_VALID;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)</span><br><span> {</span><br><span>    struct gsm_meas_rep_unidir *mru;</span><br><span>@@ -410,8 +469,10 @@</span><br><span>             mru->sub.rx_qual, num_meas_sub, lchan->meas.num_ul_meas);</span><br><span> </span><br><span>   lchan->meas.flags |= LC_UL_M_F_RES_VALID;</span><br><span style="color: hsl(0, 100%, 40%);">-    lchan->meas.num_ul_meas = 0;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+   lchan_meas_compute_extended(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->meas.num_ul_meas = 0;</span><br><span>      /* send a signal indicating computation is complete */</span><br><span> </span><br><span>   return 1;</span><br><span>diff --git a/src/common/rsl.c b/src/common/rsl.c</span><br><span>index 5d30ca7..8bbf73c 100644</span><br><span>--- a/src/common/rsl.c</span><br><span>+++ b/src/common/rsl.c</span><br><span>@@ -2536,6 +2536,13 @@</span><br><span>      return (lchan->ms_t_offs >= 0) || (lchan->p_offs >= 0);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bts_supp_meas_info {</span><br><span style="color: hsl(120, 100%, 40%);">+        int16_t toa256_mean;</span><br><span style="color: hsl(120, 100%, 40%);">+  int16_t toa256_min;</span><br><span style="color: hsl(120, 100%, 40%);">+   int16_t toa256_max;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t toa256_std_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((packed));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* 8.4.8 MEASUREMENT RESult */</span><br><span> static int rsl_tx_meas_res(struct gsm_lchan *lchan, uint8_t *l3, int l3_len, const struct lapdm_entity *le)</span><br><span> {</span><br><span>@@ -2573,16 +2580,23 @@</span><br><span>                                               meas_res);</span><br><span>   lchan->tch.dtx.dl_active = false;</span><br><span>         if (ie_len >= 3) {</span><br><span style="color: hsl(0, 100%, 40%);">-           if (bts->supp_meas_toa256) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (bts->supp_meas_toa256 && lchan->meas.flags & LC_UL_M_F_OSMO_EXT_VALID) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        struct osmo_bts_supp_meas_info *smi;</span><br><span style="color: hsl(120, 100%, 40%);">+                  smi = (struct osmo_bts_supp_meas_info *) &meas_res[ie_len];</span><br><span style="color: hsl(120, 100%, 40%);">+                       ie_len += sizeof(struct osmo_bts_supp_meas_info);</span><br><span>                    /* append signed 16bit value containing MS timing offset in 1/256th symbols</span><br><span>                   * in the vendor-specific "Supplementary Measurement Information" part of</span><br><span style="color: hsl(0, 100%, 40%);">-                      * the uplink measurements IE.  This is the current offset *relative* to the</span><br><span style="color: hsl(0, 100%, 40%);">-                     * TA which the MS has already applied.  So if you want to know the total</span><br><span style="color: hsl(0, 100%, 40%);">-                        * propagation time between MS and BTS, you need to add the actual TA value</span><br><span style="color: hsl(0, 100%, 40%);">-                      * used (from L1_INFO below, in full symbols) plus the ms_toa256 value</span><br><span style="color: hsl(0, 100%, 40%);">-                   * in 1/256 symbol periods. */</span><br><span style="color: hsl(0, 100%, 40%);">-                  meas_res[ie_len++] = lchan->meas.ms_toa256 >> 8;</span><br><span style="color: hsl(0, 100%, 40%);">-                       meas_res[ie_len++] = lchan->meas.ms_toa256 & 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+                      * the uplink measurements IE.  The lchan->meas.ext members are the current</span><br><span style="color: hsl(120, 100%, 40%);">+                         * offset *relative* to the TA which the MS has already applied.  As we want</span><br><span style="color: hsl(120, 100%, 40%);">+                   * to know the total propagation time between MS and BTS, we need to add</span><br><span style="color: hsl(120, 100%, 40%);">+                       * the actual TA value applied by the MS plus the respective toa256 value in</span><br><span style="color: hsl(120, 100%, 40%);">+                   * 1/256 symbol periods. */</span><br><span style="color: hsl(120, 100%, 40%);">+                   int16_t ta256 = lchan_get_ta(lchan) * 256;</span><br><span style="color: hsl(120, 100%, 40%);">+                    smi->toa256_mean = htons(ta256 + lchan->meas.ms_toa256);</span><br><span style="color: hsl(120, 100%, 40%);">+                        smi->toa256_min = htons(ta256 + lchan->meas.ext.toa256_min);</span><br><span style="color: hsl(120, 100%, 40%);">+                    smi->toa256_max = htons(ta256 + lchan->meas.ext.toa256_max);</span><br><span style="color: hsl(120, 100%, 40%);">+                    smi->toa256_std_dev = htons(lchan->meas.ext.toa256_std_dev);</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.flags &= ~LC_UL_M_F_OSMO_EXT_VALID;</span><br><span>               }</span><br><span>            msgb_tlv_put(msg, RSL_IE_UPLINK_MEAS, ie_len, meas_res);</span><br><span>             lchan->meas.flags &= ~LC_UL_M_F_RES_VALID;</span><br><span>diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c</span><br><span>index cbc673f..e889345 100644</span><br><span>--- a/tests/meas/meas_test.c</span><br><span>+++ b/tests/meas/meas_test.c</span><br><span>@@ -3,6 +3,7 @@</span><br><span> </span><br><span> #include <osmocom/core/talloc.h></span><br><span> #include <osmocom/core/application.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm_utils.h></span><br><span> </span><br><span> #include <osmo-bts/gsm_data.h></span><br><span> #include <osmo-bts/logging.h></span><br><span>@@ -62,6 +63,214 @@</span><br><span>     OSMO_ASSERT(tsmap_result == tsmap);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#define ULM(ber, ta, neg_rssi) \</span><br><span style="color: hsl(120, 100%, 40%);">+        { .ber10k = (ber), .ta_offs_256bits = (ta), .c_i = 1.0, .is_sub = 0, .inv_rssi = (neg_rssi) }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct meas_testcase {</span><br><span style="color: hsl(120, 100%, 40%);">+       const char *name;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* input data */</span><br><span style="color: hsl(120, 100%, 40%);">+      const struct bts_ul_meas *ulm;</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int ulm_count;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t final_fn;</span><br><span style="color: hsl(120, 100%, 40%);">+    /* results */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct {</span><br><span style="color: hsl(120, 100%, 40%);">+              int success;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t rx_lev_full;</span><br><span style="color: hsl(120, 100%, 40%);">+          uint8_t rx_qual_full;</span><br><span style="color: hsl(120, 100%, 40%);">+         int16_t toa256_mean;</span><br><span style="color: hsl(120, 100%, 40%);">+          int16_t toa256_min;</span><br><span style="color: hsl(120, 100%, 40%);">+           int16_t toa256_max;</span><br><span style="color: hsl(120, 100%, 40%);">+           uint16_t toa256_std_dev;</span><br><span style="color: hsl(120, 100%, 40%);">+      } res;</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%);">+static struct bts_ul_meas ulm1[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+    ULM(0, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+        ULM(0, 256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, -256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct meas_testcase mtc1 = {</span><br><span style="color: hsl(120, 100%, 40%);">+     .name = "TOA256 Min-Max negative/positive",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm1,</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm_count = ARRAY_SIZE(ulm1),</span><br><span style="color: hsl(120, 100%, 40%);">+        .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+       .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+         .rx_lev_full = 110-90,</span><br><span style="color: hsl(120, 100%, 40%);">+                .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_mean = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+             .toa256_max = 256,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_min = -256,</span><br><span style="color: hsl(120, 100%, 40%);">+           .toa256_std_dev = 209,</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm2[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 258, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 254, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 258, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 254, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+      ULM(0, 256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct meas_testcase mtc2 = {</span><br><span style="color: hsl(120, 100%, 40%);">+      .name = "TOA256 small jitter around 256",</span><br><span style="color: hsl(120, 100%, 40%);">+   .ulm = ulm2,</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm_count = ARRAY_SIZE(ulm2),</span><br><span style="color: hsl(120, 100%, 40%);">+        .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+       .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+         .rx_lev_full = 110-90,</span><br><span style="color: hsl(120, 100%, 40%);">+                .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_mean = 256,</span><br><span style="color: hsl(120, 100%, 40%);">+           .toa256_max = 258,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_min = 254,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_std_dev = 1,</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 style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm3[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        ULM(0, 0, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+        ULM(0, 0, 80),</span><br><span style="color: hsl(120, 100%, 40%);">+        ULM(0, 0, 80),</span><br><span style="color: hsl(120, 100%, 40%);">+        ULM(0, 0, 100),</span><br><span style="color: hsl(120, 100%, 40%);">+       ULM(0, 0, 100),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct meas_testcase mtc3 = {</span><br><span style="color: hsl(120, 100%, 40%);">+       .name = "RxLEv averaging",</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm = ulm3,</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm_count = ARRAY_SIZE(ulm3),</span><br><span style="color: hsl(120, 100%, 40%);">+        .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+       .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+         .rx_lev_full = 110-90,</span><br><span style="color: hsl(120, 100%, 40%);">+                .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_mean = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+             .toa256_max = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+              .toa256_min = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+              .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm4[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct meas_testcase mtc4 = {</span><br><span style="color: hsl(120, 100%, 40%);">+        .name = "Empty measurements",</span><br><span style="color: hsl(120, 100%, 40%);">+       .ulm = ulm4,</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm_count = ARRAY_SIZE(ulm4),</span><br><span style="color: hsl(120, 100%, 40%);">+        .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+       .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .success = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+         .rx_lev_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+             .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_mean = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+             .toa256_max = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+              .toa256_min = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+              .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+static struct bts_ul_meas ulm5[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        /* one 104 multiframe can at max contain 26 blocks (TCH/F),</span><br><span style="color: hsl(120, 100%, 40%);">+    * each of which can at maximum be 64 bits in advance (TA range) */</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+   ULM(0, 64*256, 90),</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct meas_testcase mtc5 = {</span><br><span style="color: hsl(120, 100%, 40%);">+   .name = "TOA256 26 blocks with max TOA256",</span><br><span style="color: hsl(120, 100%, 40%);">+ .ulm = ulm5,</span><br><span style="color: hsl(120, 100%, 40%);">+  .ulm_count = ARRAY_SIZE(ulm5),</span><br><span style="color: hsl(120, 100%, 40%);">+        .final_fn = 25,</span><br><span style="color: hsl(120, 100%, 40%);">+       .res = {</span><br><span style="color: hsl(120, 100%, 40%);">+              .success = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+         .rx_lev_full = 110-90,</span><br><span style="color: hsl(120, 100%, 40%);">+                .rx_qual_full = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+            .toa256_mean = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+                .toa256_max = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+         .toa256_min = 64*256,</span><br><span style="color: hsl(120, 100%, 40%);">+         .toa256_std_dev = 0,</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 style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void reset_lchan_meas(struct gsm_lchan *lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan->state = LCHAN_S_ACTIVE;</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(&lchan->meas, 0, sizeof(lchan->meas));</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%);">+static void test_meas_compute(const struct meas_testcase *mtc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gsm_lchan *lchan = &trx->ts[1].lchan[0];</span><br><span style="color: hsl(120, 100%, 40%);">+        unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int fn = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\nMeasurement Compute Test %s\n", mtc->name);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  lchan->ts->pchan = GSM_PCHAN_TCH_F;</span><br><span style="color: hsl(120, 100%, 40%);">+     reset_lchan_meas(lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* feed uplink measurements into the code */</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < mtc->ulm_count; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          lchan_new_ul_meas(lchan, (struct bts_ul_meas *) &mtc->ulm[i], fn);</span><br><span style="color: hsl(120, 100%, 40%);">+             fn += 1;</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%);">+   /* compute the results */</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_ASSERT(lchan_meas_check_compute(lchan, mtc->final_fn) == mtc->res.success);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!mtc->res.success) {</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_ASSERT(!(lchan->meas.flags & LC_UL_M_F_RES_VALID));</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(lchan->meas.flags & (LC_UL_M_F_RES_VALID|LC_UL_M_F_OSMO_EXT_VALID));</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("meas.ext.toa256_min      | %6d | %6d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ext.toa256_min, mtc->res.toa256_min);</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("meas.ext.toa256_max      | %6d | %6d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ext.toa256_max, mtc->res.toa256_max);</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("meas.ms_toa256           | %6d | %6d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ms_toa256, mtc->res.toa256_mean);</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("meas.ext.toa256_std_dev  | %6u | %6u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ext.toa256_std_dev, mtc->res.toa256_std_dev);</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("meas.ul_res.full.rx_lev  | %6u | %6u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ul_res.full.rx_lev, mtc->res.rx_lev_full);</span><br><span style="color: hsl(120, 100%, 40%);">+          printf("meas.ul_res.full.rx_qual | %6u | %6u\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    lchan->meas.ul_res.full.rx_qual, mtc->res.rx_qual_full);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if ((lchan->meas.ext.toa256_min != mtc->res.toa256_min) ||</span><br><span style="color: hsl(120, 100%, 40%);">+                  (lchan->meas.ext.toa256_max != mtc->res.toa256_max) ||</span><br><span style="color: hsl(120, 100%, 40%);">+                  (lchan->meas.ms_toa256 != mtc->res.toa256_mean) ||</span><br><span style="color: hsl(120, 100%, 40%);">+              (lchan->meas.ext.toa256_std_dev != mtc->res.toa256_std_dev) ||</span><br><span style="color: hsl(120, 100%, 40%);">+                  (lchan->meas.ul_res.full.rx_lev != mtc->res.rx_lev_full)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 fprintf(stderr, "%s: Unexpected measurement result!\n", mtc->name);</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 style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span>     void *tall_bts_ctx;</span><br><span>@@ -111,6 +320,12 @@</span><br><span>   test_fn_sample(test_fn_tch_h_ts_6_ss0_ss1, ARRAY_SIZE(test_fn_tch_h_ts_6_ss0_ss1), GSM_PCHAN_TCH_H, (1 << 6));</span><br><span>         test_fn_sample(test_fn_tch_h_ts_7_ss0_ss1, ARRAY_SIZE(test_fn_tch_h_ts_7_ss0_ss1), GSM_PCHAN_TCH_H, (1 << 7));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+      test_meas_compute(&mtc1);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc2);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc3);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc4);</span><br><span style="color: hsl(120, 100%, 40%);">+ test_meas_compute(&mtc5);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      printf("Success\n");</span><br><span> </span><br><span>   return 0;</span><br><span>diff --git a/tests/meas/meas_test.ok b/tests/meas/meas_test.ok</span><br><span>index 6dbda54..026899d 100644</span><br><span>--- a/tests/meas/meas_test.ok</span><br><span>+++ b/tests/meas/meas_test.ok</span><br><span>@@ -539,4 +539,38 @@</span><br><span> Testing: ts[7]->lchan[1], fn=15079=>015079/11/25/34/23, fn%104=103, rc=1, delta=13</span><br><span> Testing: ts[7]->lchan[0], fn=15170=>015170/11/12/23/14, fn%104=90, rc=1, delta=91</span><br><span> Testing: ts[7]->lchan[1], fn=15183=>015183/11/25/36/27, fn%104=103, rc=1, delta=13</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test TOA256 Min-Max negative/positive</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min      |   -256 |   -256</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max      |    256 |    256</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256           |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev  |    209 |    209</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev  |     20 |     20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test TOA256 small jitter around 256</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min      |    254 |    254</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max      |    258 |    258</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256           |    256 |    256</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev  |      1 |      1</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev  |     20 |     20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test RxLEv averaging</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min      |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max      |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256           |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev  |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev  |     20 |     20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test Empty measurements</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+Measurement Compute Test TOA256 26 blocks with max TOA256</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_min      |  16384 |  16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_max      |  16384 |  16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ms_toa256           |  16384 |  16384</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ext.toa256_std_dev  |      0 |      0</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_lev  |     20 |     20</span><br><span style="color: hsl(120, 100%, 40%);">+meas.ul_res.full.rx_qual |      0 |      0</span><br><span> Success</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/9777">change 9777</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/9777"/><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-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Iea4a4781481f77c6163d82dcd71a844a5be87bf2 </div>
<div style="display:none"> Gerrit-Change-Number: 9777 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>