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