<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21979">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: fix candidate choices in congestion check<br><br>Fix flaws in picking a candidate for congestion resolution, shown in<br>recently added tests.<br><br>- For TCH/H->TCH/F upgrading, do not favor moving to a weaker neighbor<br>  cell.<br><br>- When comparing dynamic timeslots on the same cell, favor a dynamic<br>  timeslot that frees an entire dyn TS even though the target rxlev<br>  differs.<br><br>Do not separate the passes for inter-cell and intra-cell candidates:<br>before, the inter-cell pass would already pick a candidate and start<br>handover, even though the subsequent intra-cell pass would have revealed<br>a better candidate. Join the intra-cell considerations into<br>pick_better_lchan_to_move().<br><br>The intra-cell pass was separate, because it would find the *weakest*<br>current rxlev, to give a TCH/H to TCH/F upgrade to the currently weakest<br>lchan.<br><br>Instead of the separate pass for weakest rxlev, in addition to the<br>target cell's rxlev, also consider the rxlev *change* in<br>pick_better_lchan_to_move(): For candidates that do not change the rxlev<br>(usually those that stay in the same cell) and that upgrade to TCH/F,<br>favor a candidate with weaker current rxlev.<br><br>Completely revisit the conditions in pick_better_lchan_to_move() to<br>yield the desired prioritization of candidate preferences.<br><br>In three handover tests, remove the "FAIL" comments and adjust to now<br>expect the actually desired behavior.<br><br>Related: SYS#5032<br>Change-Id: I2704899c85c35dfd4eba43468452483f40016ca2<br>---<br>M src/osmo-bsc/handover_decision_2.c<br>M tests/handover/test_amr_tch_h_to_f_congestion_two_cells.ho_vty<br>M tests/handover/test_congestion_intra_vs_inter_cell.ho_vty<br>M tests/handover/test_dyn_ts_favor_moving_half_used_tch_h.ho_vty<br>4 files changed, 81 insertions(+), 169 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index eb72e11..1ab92f5 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>@@ -1384,11 +1384,6 @@</span><br><span>     return count;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static bool is_intra_cell(const struct ho_candidate *c)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  return c->bts && (c->lchan->ts->trx->bts == c->bts);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static bool is_upgrade_to_tchf(const struct ho_candidate *c, uint8_t for_requirement)</span><br><span> {</span><br><span>        return c->lchan</span><br><span>@@ -1399,46 +1394,78 @@</span><br><span> /* Given two candidates, pick the one that should rather be moved during handover.</span><br><span>  * Return the better candidate in out-parameters best_cand and best_avg_db.</span><br><span>  */</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ho_candidate *pick_better_lchan_to_move(bool want_highest_db,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                   struct ho_candidate *a,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                 struct ho_candidate *b)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ho_candidate *pick_better_lchan_to_move(struct ho_candidate *a,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                struct ho_candidate *b,</span><br><span style="color: hsl(120, 100%, 40%);">+                                               uint8_t for_requirement)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     int a_rxlev;</span><br><span style="color: hsl(0, 100%, 40%);">-    int b_rxlev;</span><br><span style="color: hsl(120, 100%, 40%);">+  int a_rxlev_change;</span><br><span style="color: hsl(120, 100%, 40%);">+   int b_rxlev_change;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ho_candidate *ret = a;</span><br><span> </span><br><span>    if (!a)</span><br><span>              return b;</span><br><span>    if (!b)</span><br><span>              return a;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   a_rxlev = a->rxlev_target + a->rxlev_afs_bias;</span><br><span style="color: hsl(0, 100%, 40%);">-    b_rxlev = b->rxlev_target + b->rxlev_afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+  a_rxlev_change = a->rxlev_target - a->rxlev_current;</span><br><span style="color: hsl(120, 100%, 40%);">+    b_rxlev_change = b->rxlev_target - b->rxlev_current;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  if (want_highest_db && a_rxlev < b_rxlev)</span><br><span style="color: hsl(0, 100%, 40%);">-            return b;</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!want_highest_db && a_rxlev > b_rxlev)</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Typically, a congestion related handover reduces RXLEV. If there is a candidate that actually improves RXLEV,</span><br><span style="color: hsl(120, 100%, 40%);">+       * prefer that, because it pre-empts a likely handover due to measurement results later.  Also favor unchanged</span><br><span style="color: hsl(120, 100%, 40%);">+         * RXLEV over a loss of RXLEV (favor staying within the same cell over moving to a worse cell). */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a_rxlev_change >= 0 && a_rxlev_change > b_rxlev_change)</span><br><span style="color: hsl(120, 100%, 40%);">+             return a;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (b_rxlev_change >= 0 && b_rxlev_change > a_rxlev_change)</span><br><span>            return b;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   /* The two lchans have identical ratings, prefer picking a dynamic timeslot: free PDCH and allow more timeslot</span><br><span style="color: hsl(0, 100%, 40%);">-   * type flexibility for further congestion resolution. */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (lchan_is_on_dynamic_ts(b->lchan)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              /* If both are dynamic, prefer one that completely (or to a higher degree) frees its timeslot. */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (lchan_is_on_dynamic_ts(a->lchan)</span><br><span style="color: hsl(0, 100%, 40%);">-             && ts_usage_count(a->lchan->ts) < ts_usage_count(b->lchan->ts))</span><br><span style="color: hsl(120, 100%, 40%);">+    if (a_rxlev_change < 0 && b_rxlev_change < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         /* For handover that reduces RXLEV, favor the highest resulting RXLEV, AFS bias applied. */</span><br><span style="color: hsl(120, 100%, 40%);">+           int a_rxlev = a->rxlev_target + a->rxlev_afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+              int b_rxlev = b->rxlev_target + b->rxlev_afs_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (a_rxlev > b_rxlev)</span><br><span>                    return a;</span><br><span style="color: hsl(0, 100%, 40%);">-               /* If both equally satisfy these preferences, it does not matter which one is picked.</span><br><span style="color: hsl(0, 100%, 40%);">-            * Give slight preference to moving later dyn TS, so that a free dyn TS may group with following static</span><br><span style="color: hsl(0, 100%, 40%);">-          * PDCH, though this depends on how the user configured the TS -- not harmful to do so anyway. */</span><br><span style="color: hsl(0, 100%, 40%);">-               return b;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (b_rxlev > a_rxlev)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return b;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* There is no target RXLEV difference between the two candidates. Let other factors influence the</span><br><span style="color: hsl(120, 100%, 40%);">+             * choice. */</span><br><span>        }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   return a;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Prefer picking a dynamic timeslot: free PDCH and allow more timeslot type flexibility for further</span><br><span style="color: hsl(120, 100%, 40%);">+   * congestion resolution. */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (lchan_is_on_dynamic_ts(b->lchan)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            unsigned int ac, bc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (!lchan_is_on_dynamic_ts(a->lchan))</span><br><span style="color: hsl(120, 100%, 40%);">+                     return b;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Both are dynamic timeslots. Prefer one that completely (or to a higher degree) frees its</span><br><span style="color: hsl(120, 100%, 40%);">+            * timeslot. */</span><br><span style="color: hsl(120, 100%, 40%);">+               ac = ts_usage_count(a->lchan->ts);</span><br><span style="color: hsl(120, 100%, 40%);">+              bc = ts_usage_count(b->lchan->ts);</span><br><span style="color: hsl(120, 100%, 40%);">+              if (bc < ac)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return b;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ac < bc)</span><br><span style="color: hsl(120, 100%, 40%);">+                       return a;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* (If both are dynamic timeslots, favor moving the later dynamic timeslot. That is a vague preference</span><br><span style="color: hsl(120, 100%, 40%);">+                 * for later dynamic TS to become PDCH and join up with plain PDCH that follow it -- not actually clear</span><br><span style="color: hsl(120, 100%, 40%);">+                * whether that helps, and depends on user's TS config. No harm done either way.) */</span><br><span style="color: hsl(120, 100%, 40%);">+              ret = b;</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%);">+   /* When upgrading TCH/H to TCH/F, favor moving a TCH/H with lower current rxlev, because presumably that</span><br><span style="color: hsl(120, 100%, 40%);">+       * one benefits more from a higher bandwidth. */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (is_upgrade_to_tchf(a, for_requirement) && is_upgrade_to_tchf(b, for_requirement)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (b->rxlev_current < a->rxlev_current)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return b;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (a->rxlev_current < b->rxlev_current)</span><br><span style="color: hsl(120, 100%, 40%);">+                     return a;</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%);">+   return ret;</span><br><span> }</span><br><span> </span><br><span> static struct ho_candidate *pick_best_candidate(struct ho_candidate *clist, int clist_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              bool want_highest_db,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           bool omit_intra_cell_upgrade_to_tchf,</span><br><span style="color: hsl(0, 100%, 40%);">-                                           bool only_intra_cell_upgrade_to_tchf,</span><br><span>                                                uint8_t for_requirement)</span><br><span> {</span><br><span>        struct ho_candidate *result = NULL;</span><br><span>@@ -1446,8 +1473,6 @@</span><br><span> </span><br><span>      for (i = 0; i < clist_len; i++) {</span><br><span>                 struct ho_candidate *c = &clist[i];</span><br><span style="color: hsl(0, 100%, 40%);">-         bool intra_cell;</span><br><span style="color: hsl(0, 100%, 40%);">-                bool upgrade_to_tch_f;</span><br><span> </span><br><span>           /* For multiple passes of congestion resolution, already handovered candidates are marked by lchan =</span><br><span>                  * NULL. (though at the time of writing, multiple passes of congestion resolution are DISABLED.) */</span><br><span>@@ -1461,23 +1486,13 @@</span><br><span>                if (!(c->requirements & for_requirement))</span><br><span>                     continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           intra_cell = is_intra_cell(c);</span><br><span style="color: hsl(0, 100%, 40%);">-          upgrade_to_tch_f = is_upgrade_to_tchf(c, for_requirement);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-              if (only_intra_cell_upgrade_to_tchf</span><br><span style="color: hsl(0, 100%, 40%);">-                 && !(intra_cell && upgrade_to_tch_f))</span><br><span style="color: hsl(0, 100%, 40%);">-                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-               if (omit_intra_cell_upgrade_to_tchf</span><br><span style="color: hsl(0, 100%, 40%);">-                 && (intra_cell && upgrade_to_tch_f))</span><br><span style="color: hsl(0, 100%, 40%);">-                        continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>            /* improve AHS */</span><br><span style="color: hsl(0, 100%, 40%);">-               if (upgrade_to_tch_f)</span><br><span style="color: hsl(120, 100%, 40%);">+         if (is_upgrade_to_tchf(c, for_requirement))</span><br><span>                  c->rxlev_afs_bias = ho_get_hodec2_afs_bias_rxlev(c->bts->ho);</span><br><span>               else</span><br><span>                         c->rxlev_afs_bias = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           result = pick_better_lchan_to_move(want_highest_db, result, c);</span><br><span style="color: hsl(120, 100%, 40%);">+               result = pick_better_lchan_to_move(result, c, for_requirement);</span><br><span>      }</span><br><span> </span><br><span>        return result;</span><br><span>@@ -1643,11 +1658,7 @@</span><br><span>      /* TODO: attempt inter-BSC HO if no local cells qualify, and rely on the remote BSS to</span><br><span>        * deny receiving the handover if it also considers itself congested. Maybe do that only</span><br><span>      * when the cell is absolutely full, i.e. not only min-free-slots. (x) */</span><br><span style="color: hsl(0, 100%, 40%);">-       best_cand = pick_best_candidate(clist, candidates,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      /* want_highest_db */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     /* omit_intra_cell_upgrade_to_tchf */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     /* only_intra_cell_upgrade_to_tchf */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    REQUIREMENT_B_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+  best_cand = pick_best_candidate(clist, candidates, REQUIREMENT_B_MASK);</span><br><span>      if (best_cand) {</span><br><span>             any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_DEBUG, "Best candidate: RX level %d%s\n",</span><br><span>@@ -1676,54 +1687,12 @@</span><br><span>     }</span><br><span> </span><br><span> #if 0</span><br><span style="color: hsl(0, 100%, 40%);">-next_b2:</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-    /* For upgrading TCH/H to TCH/F within the same cell, we want to pick the *lowest* average rxlev: for staying</span><br><span style="color: hsl(0, 100%, 40%);">-    * within the same cell, give the MS with the worst service more bandwidth. When staying within the same cell,</span><br><span style="color: hsl(0, 100%, 40%);">-   * the target avg rxlev is identical to the source lchan rxlev, so it is fine to use the same avg rxlev value,</span><br><span style="color: hsl(0, 100%, 40%);">-   * but simply pick the lowest one.</span><br><span style="color: hsl(0, 100%, 40%);">-       * Upgrading TCH/H channels obviously only applies when TCH/H is actually congested. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (tchh_congestion > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             best_cand = pick_best_candidate(clist, candidates,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              /* want_highest_db */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            /* omit_intra_cell_upgrade_to_tchf */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            /* only_intra_cell_upgrade_to_tchf */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             REQUIREMENT_B_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (best_cand) {</span><br><span style="color: hsl(0, 100%, 40%);">-                any_ho = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPHOCAND(best_cand, LOGL_INFO, "Worst candidate: RX level %d from TCH/H -> TCH/F%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          best_cand->rxlev_afs_bias ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span style="color: hsl(0, 100%, 40%);">-              trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_B_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-                /* if there is still congestion, mark lchan as deleted</span><br><span style="color: hsl(0, 100%, 40%);">-           * and redo this process */</span><br><span style="color: hsl(0, 100%, 40%);">-             tchh_congestion--;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (tchh_congestion > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   delete_lchan = best_cand->lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-                     best_cand = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                       goto next_b2;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-          /* must exit here, because triggering handover/assignment</span><br><span style="color: hsl(0, 100%, 40%);">-                * will cause change in requirements. more check for this</span><br><span style="color: hsl(0, 100%, 40%);">-                * bts is performed in the next iteration.</span><br><span style="color: hsl(0, 100%, 40%);">-               */</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-               goto exit;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span> next_c1:</span><br><span> #endif</span><br><span>         /* Select best candidate that balances congestion.</span><br><span>    * Again no remote BSS.</span><br><span>       * Again no TCH/H -> F upgrades within the same cell. */</span><br><span style="color: hsl(0, 100%, 40%);">-     best_cand = pick_best_candidate(clist, candidates,</span><br><span style="color: hsl(0, 100%, 40%);">-                                      /* want_highest_db */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     /* omit_intra_cell_upgrade_to_tchf */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                     /* only_intra_cell_upgrade_to_tchf */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                    REQUIREMENT_C_MASK);</span><br><span style="color: hsl(120, 100%, 40%);">+  best_cand = pick_best_candidate(clist, candidates, REQUIREMENT_C_MASK);</span><br><span>      if (best_cand) {</span><br><span>             any_ho = 1;</span><br><span>          LOGPHOCAND(best_cand, LOGL_INFO, "Best candidate: RX level %d%s\n",</span><br><span>@@ -1754,46 +1723,6 @@</span><br><span>       LOGPHOBTS(bts, LOGL_DEBUG, "Did not find a best candidate that fulfills requirement C"</span><br><span>               " (omitting change from AHS to AFS)\n");</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-next_c2:</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Look for upgrading TCH/H to TCH/F within the same cell, which balances congestion, again upgrade the TCH/H</span><br><span style="color: hsl(0, 100%, 40%);">-    * lchan that has the worst reception: */</span><br><span style="color: hsl(0, 100%, 40%);">-       if (tchh_congestion > 0)</span><br><span style="color: hsl(0, 100%, 40%);">-             best_cand = pick_best_candidate(clist, candidates,</span><br><span style="color: hsl(0, 100%, 40%);">-                                              /* want_highest_db */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            /* omit_intra_cell_upgrade_to_tchf */ false,</span><br><span style="color: hsl(0, 100%, 40%);">-                                            /* only_intra_cell_upgrade_to_tchf */ true,</span><br><span style="color: hsl(0, 100%, 40%);">-                                             REQUIREMENT_C_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-    /* perform handover, if there is a candidate */</span><br><span style="color: hsl(0, 100%, 40%);">- if (best_cand) {</span><br><span style="color: hsl(0, 100%, 40%);">-                any_ho = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGPHOCAND(best_cand, LOGL_INFO, "Worst candidate: RX level %d from TCH/H -> TCH/F%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      rxlev2dbm(best_cand->rxlev_target),</span><br><span style="color: hsl(0, 100%, 40%);">-                          best_cand->rxlev_afs_bias ? " (applied AHS -> AFS rxlev bias)" : "");</span><br><span style="color: hsl(0, 100%, 40%);">-              trigger_ho(best_cand, best_cand->requirements & REQUIREMENT_C_MASK);</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-                /* if there is still congestion, mark lchan as deleted</span><br><span style="color: hsl(0, 100%, 40%);">-           * and redo this process */</span><br><span style="color: hsl(0, 100%, 40%);">-             tchh_congestion--;</span><br><span style="color: hsl(0, 100%, 40%);">-              if (tchh_congestion > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   delete_lchan = best_cand->lchan;</span><br><span style="color: hsl(0, 100%, 40%);">-                     best_cand = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-                       goto next_c2;</span><br><span style="color: hsl(0, 100%, 40%);">-           }</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-          /* must exit here, because triggering handover/assignment</span><br><span style="color: hsl(0, 100%, 40%);">-                * will cause change in requirements. more check for this</span><br><span style="color: hsl(0, 100%, 40%);">-                * bts is performed in the next iteration.</span><br><span style="color: hsl(0, 100%, 40%);">-               */</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-               goto exit;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-       LOGPHOBTS(bts, LOGL_DEBUG, "Did not find a worst candidate that fulfills requirement C,"</span><br><span style="color: hsl(0, 100%, 40%);">-                " selecting candidates that change from AHS to AFS only\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> exit:</span><br><span>    /* free array */</span><br><span>     talloc_free(clist);</span><br><span>diff --git a/tests/handover/test_amr_tch_h_to_f_congestion_two_cells.ho_vty b/tests/handover/test_amr_tch_h_to_f_congestion_two_cells.ho_vty</span><br><span>index eaaeabd..7cbcd4b 100644</span><br><span>--- a/tests/handover/test_amr_tch_h_to_f_congestion_two_cells.ho_vty</span><br><span>+++ b/tests/handover/test_amr_tch_h_to_f_congestion_two_cells.ho_vty</span><br><span>@@ -12,12 +12,6 @@</span><br><span> meas-rep repeat 10 lchan 1 0 4 0 rxlev 30 rxqual 0 ta 0 neighbors 20</span><br><span> expect-no-chan</span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL: bts 1 has better rxlev, so the call should stay in bts 1. Instead, a handover to bts 0 happens.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 1 0 4 0 to lchan 0 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * - - - - - - *</span><br><span style="color: hsl(0, 100%, 40%);">-# the fail continues: later the better rxqual does *another* ho back to the original cell</span><br><span style="color: hsl(0, 100%, 40%);">-meas-rep lchan 0 0 1 0 rxlev 20 rxqual 0 ta 0 neighbors 30</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 1 0 to lchan 1 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 1 0 4 0 to lchan 1 0 1 0</span><br><span> expect-ts-use trx 0 0 states * - - - - - - *</span><br><span> expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span>diff --git a/tests/handover/test_congestion_intra_vs_inter_cell.ho_vty b/tests/handover/test_congestion_intra_vs_inter_cell.ho_vty</span><br><span>index f0f8e2a..d93f56c 100644</span><br><span>--- a/tests/handover/test_congestion_intra_vs_inter_cell.ho_vty</span><br><span>+++ b/tests/handover/test_congestion_intra_vs_inter_cell.ho_vty</span><br><span>@@ -12,11 +12,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! should favor upgrading the weaker TS 6.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 5 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - - TCH/H- *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 6 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - TCH/H- - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>@@ -29,10 +27,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 5 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - - TCH/H- *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 5 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - - TCH/H- *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>@@ -45,11 +42,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! should favor upgrading the weaker TS 5.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 6 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - TCH/H- - *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 5 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - - TCH/H- *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>@@ -62,10 +57,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 5 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - - TCH/H- *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 5 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - - TCH/H- *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>@@ -78,11 +72,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! should favor upgrading the weaker TS 5.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 6 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - TCH/H- - *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 5 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - - TCH/H- *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>@@ -95,11 +87,9 @@</span><br><span> expect-no-chan</span><br><span> </span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! moving to a weaker neighbor, should move to TCH/F in current cell instead.</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL! should favor upgrading the weaker TS 6.</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 5 0 to lchan 1 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0 states * - - - - - TCH/H- *</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 1 0 states * TCH/F - - - - - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 6 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0 states * TCH/F - - - TCH/H- - *</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 1 0 states * - - - - - - *</span><br><span> </span><br><span> # clear measurements for next run</span><br><span> set-ts-use trx 0 0 states * - - - - - - *</span><br><span>diff --git a/tests/handover/test_dyn_ts_favor_moving_half_used_tch_h.ho_vty b/tests/handover/test_dyn_ts_favor_moving_half_used_tch_h.ho_vty</span><br><span>index 9d88c86..794bbef 100644</span><br><span>--- a/tests/handover/test_dyn_ts_favor_moving_half_used_tch_h.ho_vty</span><br><span>+++ b/tests/handover/test_dyn_ts_favor_moving_half_used_tch_h.ho_vty</span><br><span>@@ -41,6 +41,5 @@</span><br><span> meas-rep lchan 0 0 4 0 rxlev 32 rxqual 0 ta 0</span><br><span> meas-rep lchan 0 0 4 1 rxlev 31 rxqual 0 ta 0</span><br><span> congestion-check</span><br><span style="color: hsl(0, 100%, 40%);">-# FAIL: should still pick lchan 0 0 3 0!</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ho from lchan 0 0 4 1 to lchan 0 0 1 0</span><br><span style="color: hsl(0, 100%, 40%);">-expect-ts-use trx 0 0     states *    TCH/F TCH/HH TCH/H- TCH/H- pdch - -</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ho from lchan 0 0 3 0 to lchan 0 0 1 0</span><br><span style="color: hsl(120, 100%, 40%);">+expect-ts-use trx 0 0     states *    TCH/F TCH/HH pdch TCH/HH pdch - -</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/osmo-bsc/+/21979">change 21979</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/+/21979"/><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: I2704899c85c35dfd4eba43468452483f40016ca2 </div>
<div style="display:none"> Gerrit-Change-Number: 21979 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </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: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>