<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/24850">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  pespin: Looks good to me, but someone else must approve
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">hodec2: [1/2] implement automatic choice between FULL and SUBSET measurements<br><br>Cosmetic preparation for enabling automatic choice between FULL and<br>SUBSET measurements depending on DTX in handover decision 2.<br><br>Change the internal API to pass separate enums for the choices {RXLEV,<br>RXQUAL}, {UL, DL} and {FULL, SUB}.<br><br>Change-Id: I283e03126a6bc1f5f1b35f9801e841053edd2947<br>---<br>M include/osmocom/bsc/meas_rep.h<br>M src/osmo-bsc/handover_decision.c<br>M src/osmo-bsc/handover_decision_2.c<br>M src/osmo-bsc/meas_rep.c<br>4 files changed, 82 insertions(+), 26 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/meas_rep.h b/include/osmocom/bsc/meas_rep.h</span><br><span>index 54e0519..5cfeb98 100644</span><br><span>--- a/include/osmocom/bsc/meas_rep.h</span><br><span>+++ b/include/osmocom/bsc/meas_rep.h</span><br><span>@@ -51,14 +51,32 @@</span><br><span>         struct gsm_meas_rep_cell cell[6];</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+enum tdma_meas_field {</span><br><span style="color: hsl(120, 100%, 40%);">+   TDMA_MEAS_FIELD_RXLEV = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+    TDMA_MEAS_FIELD_RXQUAL = 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%);">+enum tdma_meas_dir {</span><br><span style="color: hsl(120, 100%, 40%);">+       TDMA_MEAS_DIR_UL = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ TDMA_MEAS_DIR_DL = 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%);">+/* (function choose_meas_rep_field() depends on FULL and SUB being 0 and 1, but doesn't care about AUTO's value) */</span><br><span style="color: hsl(120, 100%, 40%);">+enum tdma_meas_set {</span><br><span style="color: hsl(120, 100%, 40%);">+        TDMA_MEAS_SET_FULL = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+       TDMA_MEAS_SET_SUB = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+        TDMA_MEAS_SET_AUTO,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* obtain an average over the last 'num' fields in the meas reps */</span><br><span> int get_meas_rep_avg(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-              enum meas_rep_field field, unsigned int num);</span><br><span style="color: hsl(120, 100%, 40%);">+                 enum tdma_meas_field field, enum tdma_meas_dir dir, enum tdma_meas_set set,</span><br><span style="color: hsl(120, 100%, 40%);">+                   unsigned int num);</span><br><span> </span><br><span> /* Check if N out of M last values for FIELD are >= bd */</span><br><span> int meas_rep_n_out_of_m_be(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                        enum meas_rep_field field,</span><br><span style="color: hsl(0, 100%, 40%);">-                      unsigned int n, unsigned int m, int be);</span><br><span style="color: hsl(120, 100%, 40%);">+                         enum tdma_meas_field field, enum tdma_meas_dir dir, enum tdma_meas_set set,</span><br><span style="color: hsl(120, 100%, 40%);">+                           unsigned int n, unsigned int m, int be);</span><br><span> </span><br><span> unsigned int calc_initial_idx(unsigned int array_size,</span><br><span>                          unsigned int meas_rep_idx,</span><br><span>diff --git a/src/osmo-bsc/handover_decision.c b/src/osmo-bsc/handover_decision.c</span><br><span>index 1eeb277..220fa1c 100644</span><br><span>--- a/src/osmo-bsc/handover_decision.c</span><br><span>+++ b/src/osmo-bsc/handover_decision.c</span><br><span>@@ -214,7 +214,7 @@</span><br><span> static void on_measurement_report(struct gsm_meas_rep *mr)</span><br><span> {</span><br><span>       struct gsm_bts *bts = mr->lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-      enum meas_rep_field dlev, dqual;</span><br><span style="color: hsl(120, 100%, 40%);">+      enum tdma_meas_set meas_set;</span><br><span>         int av_rxlev;</span><br><span>        unsigned int pwr_interval;</span><br><span> </span><br><span>@@ -231,24 +231,18 @@</span><br><span>               return;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (mr->flags & MEAS_REP_F_DL_DTX) {</span><br><span style="color: hsl(0, 100%, 40%);">-             dlev = MEAS_REP_DL_RXLEV_SUB;</span><br><span style="color: hsl(0, 100%, 40%);">-           dqual = MEAS_REP_DL_RXQUAL_SUB;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                dlev = MEAS_REP_DL_RXLEV_FULL;</span><br><span style="color: hsl(0, 100%, 40%);">-          dqual = MEAS_REP_DL_RXQUAL_FULL;</span><br><span style="color: hsl(0, 100%, 40%);">-        }</span><br><span style="color: hsl(120, 100%, 40%);">+     meas_set = (mr->flags & MEAS_REP_F_DL_DTX) ? TDMA_MEAS_SET_SUB : TDMA_MEAS_SET_FULL;</span><br><span> </span><br><span>      /* parse actual neighbor cell info */</span><br><span>        if (mr->num_cell > 0 && mr->num_cell < 7)</span><br><span>                process_meas_neigh(mr);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     av_rxlev = get_meas_rep_avg(mr->lchan, dlev,</span><br><span style="color: hsl(120, 100%, 40%);">+       av_rxlev = get_meas_rep_avg(mr->lchan, TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL, meas_set,</span><br><span>                                     ho_get_hodec1_rxlev_avg_win(bts->ho));</span><br><span> </span><br><span>    /* Interference HO */</span><br><span>        if (rxlev2dbm(av_rxlev) > -85 &&</span><br><span style="color: hsl(0, 100%, 40%);">-         meas_rep_n_out_of_m_be(mr->lchan, dqual, 3, 4, 5)) {</span><br><span style="color: hsl(120, 100%, 40%);">+       meas_rep_n_out_of_m_be(mr->lchan, TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL, meas_set, 3, 4, 5)) {</span><br><span>             LOGPC(DHO, LOGL_INFO, "HO cause: Interference HO av_rxlev=%d dBm\n",</span><br><span>                     rxlev2dbm(av_rxlev));</span><br><span>          attempt_handover(mr);</span><br><span>@@ -256,7 +250,7 @@</span><br><span>  }</span><br><span> </span><br><span>        /* Bad Quality */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (meas_rep_n_out_of_m_be(mr->lchan, dqual, 3, 4, 5)) {</span><br><span style="color: hsl(120, 100%, 40%);">+   if (meas_rep_n_out_of_m_be(mr->lchan, TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL, meas_set, 3, 4, 5)) {</span><br><span>             LOGPC(DHO, LOGL_INFO, "HO cause: Bad Quality av_rxlev=%d dBm\n", rxlev2dbm(av_rxlev));</span><br><span>             attempt_handover(mr);</span><br><span>                return;</span><br><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index d778876..67208fe 100644</span><br><span>--- a/src/osmo-bsc/handover_decision_2.c</span><br><span>+++ b/src/osmo-bsc/handover_decision_2.c</span><br><span>@@ -244,18 +244,16 @@</span><br><span> static int current_rxlev(struct gsm_lchan *lchan)</span><br><span> {</span><br><span>       struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-     return get_meas_rep_avg(lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                          ho_get_hodec2_full_tdma(bts->ho) ?</span><br><span style="color: hsl(0, 100%, 40%);">-                                   MEAS_REP_DL_RXLEV_FULL : MEAS_REP_DL_RXLEV_SUB,</span><br><span style="color: hsl(120, 100%, 40%);">+       return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL,</span><br><span style="color: hsl(120, 100%, 40%);">+                               ho_get_hodec2_full_tdma(bts->ho) ? TDMA_MEAS_SET_FULL : TDMA_MEAS_SET_SUB,</span><br><span>                                ho_get_hodec2_rxlev_avg_win(bts->ho));</span><br><span> }</span><br><span> </span><br><span> static int current_rxqual(struct gsm_lchan *lchan)</span><br><span> {</span><br><span>        struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span style="color: hsl(0, 100%, 40%);">-     return get_meas_rep_avg(lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                          ho_get_hodec2_full_tdma(bts->ho) ?</span><br><span style="color: hsl(0, 100%, 40%);">-                                   MEAS_REP_DL_RXQUAL_FULL : MEAS_REP_DL_RXQUAL_SUB,</span><br><span style="color: hsl(120, 100%, 40%);">+     return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL,</span><br><span style="color: hsl(120, 100%, 40%);">+                              ho_get_hodec2_full_tdma(bts->ho) ? TDMA_MEAS_SET_FULL : TDMA_MEAS_SET_SUB,</span><br><span>                                ho_get_hodec2_rxqual_avg_win(bts->ho));</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/meas_rep.c b/src/osmo-bsc/meas_rep.c</span><br><span>index 32c689d..97c30ac 100644</span><br><span>--- a/src/osmo-bsc/meas_rep.c</span><br><span>+++ b/src/osmo-bsc/meas_rep.c</span><br><span>@@ -80,9 +80,47 @@</span><br><span>    return idx;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* obtain an average over the last 'num' fields in the meas reps */</span><br><span style="color: hsl(120, 100%, 40%);">+static inline enum meas_rep_field choose_meas_rep_field(enum tdma_meas_field field, enum tdma_meas_dir dir,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  enum tdma_meas_set set)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_static_assert(TDMA_MEAS_FIELD_RXLEV >= 0 && TDMA_MEAS_FIELD_RXLEV <= 1</span><br><span style="color: hsl(120, 100%, 40%);">+                        && TDMA_MEAS_FIELD_RXQUAL >= 0 && TDMA_MEAS_FIELD_RXQUAL <= 1</span><br><span style="color: hsl(120, 100%, 40%);">+                           && TDMA_MEAS_DIR_UL >= 0 && TDMA_MEAS_DIR_UL <= 1</span><br><span style="color: hsl(120, 100%, 40%);">+                       && TDMA_MEAS_DIR_DL >= 0 && TDMA_MEAS_DIR_DL <= 1</span><br><span style="color: hsl(120, 100%, 40%);">+                       && TDMA_MEAS_SET_FULL >= 0 && TDMA_MEAS_SET_FULL <= 1</span><br><span style="color: hsl(120, 100%, 40%);">+                           && TDMA_MEAS_SET_SUB >= 0 && TDMA_MEAS_SET_SUB <= 1,</span><br><span style="color: hsl(120, 100%, 40%);">+                    choose_meas_rep_field__mux_macro_input_ranges);</span><br><span style="color: hsl(120, 100%, 40%);">+#define MUX(FIELD, DIR, SET) ((FIELD) + ((DIR) << 1) + ((SET) << 2))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (MUX(field, dir, set)) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case MUX(TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_UL, TDMA_MEAS_SET_FULL):</span><br><span style="color: hsl(120, 100%, 40%);">+                return MEAS_REP_UL_RXLEV_FULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MUX(TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_UL, TDMA_MEAS_SET_SUB):</span><br><span style="color: hsl(120, 100%, 40%);">+         return MEAS_REP_UL_RXLEV_SUB;</span><br><span style="color: hsl(120, 100%, 40%);">+ case MUX(TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL, TDMA_MEAS_SET_FULL):</span><br><span style="color: hsl(120, 100%, 40%);">+                return MEAS_REP_DL_RXLEV_FULL;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MUX(TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL, TDMA_MEAS_SET_SUB):</span><br><span style="color: hsl(120, 100%, 40%);">+         return MEAS_REP_DL_RXLEV_SUB;</span><br><span style="color: hsl(120, 100%, 40%);">+ case MUX(TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_UL, TDMA_MEAS_SET_FULL):</span><br><span style="color: hsl(120, 100%, 40%);">+               return MEAS_REP_UL_RXQUAL_FULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       case MUX(TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_UL, TDMA_MEAS_SET_SUB):</span><br><span style="color: hsl(120, 100%, 40%);">+                return MEAS_REP_UL_RXQUAL_SUB;</span><br><span style="color: hsl(120, 100%, 40%);">+        case MUX(TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL, TDMA_MEAS_SET_FULL):</span><br><span style="color: hsl(120, 100%, 40%);">+               return MEAS_REP_DL_RXQUAL_FULL;</span><br><span style="color: hsl(120, 100%, 40%);">+       case MUX(TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL, TDMA_MEAS_SET_SUB):</span><br><span style="color: hsl(120, 100%, 40%);">+                return MEAS_REP_DL_RXQUAL_SUB;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              OSMO_ASSERT(false);</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%);">+#undef MUX</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%);">+/* obtain an average over the last 'num' fields in the meas reps. For 'field', pass either DL_RXLEV or DL_RXQUAL, and</span><br><span style="color: hsl(120, 100%, 40%);">+ * by tdma_meas_set, choose between full, subset or automatic choice of set. */</span><br><span> int get_meas_rep_avg(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                  enum meas_rep_field field, unsigned int num)</span><br><span style="color: hsl(120, 100%, 40%);">+                  enum tdma_meas_field field, enum tdma_meas_dir dir, enum tdma_meas_set set,</span><br><span style="color: hsl(120, 100%, 40%);">+                   unsigned int num)</span><br><span> {</span><br><span>  unsigned int i, idx;</span><br><span>         int avg = 0, valid_num = 0;</span><br><span>@@ -98,7 +136,11 @@</span><br><span> </span><br><span>        for (i = 0; i < num; i++) {</span><br><span>               int j = (idx+i) % ARRAY_SIZE(lchan->meas_rep);</span><br><span style="color: hsl(0, 100%, 40%);">-               int val = get_field(&lchan->meas_rep[j], field);</span><br><span style="color: hsl(120, 100%, 40%);">+               enum meas_rep_field use_field;</span><br><span style="color: hsl(120, 100%, 40%);">+                int val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            use_field = choose_meas_rep_field(field, dir, set);</span><br><span style="color: hsl(120, 100%, 40%);">+           val = get_field(&lchan->meas_rep[j], use_field);</span><br><span> </span><br><span>          if (val >= 0) {</span><br><span>                   avg += val;</span><br><span>@@ -114,8 +156,8 @@</span><br><span> </span><br><span> /* Check if N out of M last values for FIELD are >= bd */</span><br><span> int meas_rep_n_out_of_m_be(const struct gsm_lchan *lchan,</span><br><span style="color: hsl(0, 100%, 40%);">-                      enum meas_rep_field field,</span><br><span style="color: hsl(0, 100%, 40%);">-                      unsigned int n, unsigned int m, int be)</span><br><span style="color: hsl(120, 100%, 40%);">+                          enum tdma_meas_field field, enum tdma_meas_dir dir, enum tdma_meas_set set,</span><br><span style="color: hsl(120, 100%, 40%);">+                           unsigned int n, unsigned int m, int be)</span><br><span> {</span><br><span>      unsigned int i, idx;</span><br><span>         int count = 0;</span><br><span>@@ -125,7 +167,11 @@</span><br><span> </span><br><span>    for (i = 0; i < m; i++) {</span><br><span>                 int j = (idx + i) % ARRAY_SIZE(lchan->meas_rep);</span><br><span style="color: hsl(0, 100%, 40%);">-             int val = get_field(&lchan->meas_rep[j], field);</span><br><span style="color: hsl(120, 100%, 40%);">+               enum meas_rep_field use_field;</span><br><span style="color: hsl(120, 100%, 40%);">+                int val;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            use_field = choose_meas_rep_field(field, dir, set);</span><br><span style="color: hsl(120, 100%, 40%);">+           val = get_field(&lchan->meas_rep[j], use_field);</span><br><span> </span><br><span>          if (val >= be) /* implies that val < 0 will not count */</span><br><span>                       count++;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/24850">change 24850</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-bsc/+/24850"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I283e03126a6bc1f5f1b35f9801e841053edd2947 </div>
<div style="display:none"> Gerrit-Change-Number: 24850 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: fixeria <vyanitskiy@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>