<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/24850">View Change</a></p><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, 77 insertions(+), 26 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmo-bsc refs/changes/50/24850/1</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..77af365 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,31 @@</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,</span><br><span style="color: hsl(120, 100%, 40%);">+        TDMA_MEAS_FIELD_RXQUAL,</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,</span><br><span style="color: hsl(120, 100%, 40%);">+     TDMA_MEAS_DIR_DL,</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_set {</span><br><span style="color: hsl(120, 100%, 40%);">+ TDMA_MEAS_SET_FULL,</span><br><span style="color: hsl(120, 100%, 40%);">+   TDMA_MEAS_SET_SUB,</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 0966583..c3674ff 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..0ddf349 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,43 @@</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%);">+    const enum meas_rep_field map[2][2][2] = {</span><br><span style="color: hsl(120, 100%, 40%);">+            [TDMA_MEAS_FIELD_RXLEV] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                   [TDMA_MEAS_DIR_UL] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_FULL] = MEAS_REP_UL_RXLEV_FULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_SUB] = MEAS_REP_UL_RXLEV_SUB,</span><br><span style="color: hsl(120, 100%, 40%);">+                  },</span><br><span style="color: hsl(120, 100%, 40%);">+                    [TDMA_MEAS_DIR_DL] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_FULL] = MEAS_REP_DL_RXLEV_FULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_SUB] = MEAS_REP_DL_RXLEV_SUB,</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%);">+            [TDMA_MEAS_FIELD_RXQUAL] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                  [TDMA_MEAS_DIR_UL] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_FULL] = MEAS_REP_UL_RXQUAL_FULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                               [TDMA_MEAS_SET_SUB] = MEAS_REP_UL_RXQUAL_SUB,</span><br><span style="color: hsl(120, 100%, 40%);">+                 },</span><br><span style="color: hsl(120, 100%, 40%);">+                    [TDMA_MEAS_DIR_DL] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                                [TDMA_MEAS_SET_FULL] = MEAS_REP_DL_RXQUAL_FULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                               [TDMA_MEAS_SET_SUB] = MEAS_REP_DL_RXQUAL_SUB,</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%);">+  OSMO_ASSERT(field == TDMA_MEAS_FIELD_RXQUAL || field == TDMA_MEAS_FIELD_RXLEV);</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(dir == TDMA_MEAS_DIR_UL || dir == TDMA_MEAS_DIR_DL);</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_ASSERT(set == TDMA_MEAS_SET_FULL || set == TDMA_MEAS_SET_SUB);</span><br><span style="color: hsl(120, 100%, 40%);">+   return map[field][dir][set];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 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 +132,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 +152,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 +163,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: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>