<p>Neels Hofmeyr has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10108">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">vty: 'handover any': pick more random chans, use lchan_select_by_type()<br><br>The 'handover any' VTY command is only useful for testing. It is even more<br>useful if it doesn't always pick the first used lchan but produces more random<br>handovers.<br><br>The algorithm takes a random number as input, iterates over used lchans once,<br>and if the random number is larger, takes modulo of the nr of used lchans<br>counted. A second iteration will then produce a match.<br><br>Instead of figuring out the lchan type logic in bsc_vty.c, just use<br>lchan_select_by_type();<br><br>Change-Id: I50b70e02d665b967e401db65581e110bc83101e7<br>---<br>M src/osmo-bsc/bsc_vty.c<br>1 file changed, 43 insertions(+), 47 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/08/10108/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c</span><br><span>index f5454ec..83ca2e5 100644</span><br><span>--- a/src/osmo-bsc/bsc_vty.c</span><br><span>+++ b/src/osmo-bsc/bsc_vty.c</span><br><span>@@ -68,6 +68,7 @@</span><br><span> #include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/timeslot_fsm.h></span><br><span> #include <osmocom/bsc/lchan_fsm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/bsc/lchan_select.h></span><br><span> #include <osmocom/bsc/gsm_timers.h></span><br><span> #include <osmocom/bsc/mgw_endpoint_fsm.h></span><br><span> </span><br><span>@@ -1605,36 +1606,48 @@</span><br><span>  return ho_or_as(vty, argv, argc);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static struct gsm_lchan *find_used_voice_lchan(struct vty *vty)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct gsm_lchan *find_used_voice_lchan(struct vty *vty, int random_idx)</span><br><span> {</span><br><span>      struct gsm_bts *bts;</span><br><span>         struct gsm_network *network = gsmnet_from_vty(vty);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- llist_for_each_entry(bts, &network->bts_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-            struct gsm_bts_trx *trx;</span><br><span style="color: hsl(120, 100%, 40%);">+      while (1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           int count = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                llist_for_each_entry(bts, &network->bts_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  struct gsm_bts_trx *trx;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-            llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        int i;</span><br><span style="color: hsl(0, 100%, 40%);">-                  for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct gsm_bts_trx_ts *ts = &trx->ts[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                      llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(120, 100%, 40%);">+                              int i;</span><br><span style="color: hsl(120, 100%, 40%);">+                                for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     struct gsm_bts_trx_ts *ts = &trx->ts[i];</span><br><span style="color: hsl(120, 100%, 40%);">+                                       struct gsm_lchan *lchan;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                            if (ts->fi->state != TS_ST_IN_USE)</span><br><span style="color: hsl(0, 100%, 40%);">-                                        continue;</span><br><span style="color: hsl(120, 100%, 40%);">+                                     if (ts->fi->state != TS_ST_IN_USE)</span><br><span style="color: hsl(120, 100%, 40%);">+                                              continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                           ts_for_each_lchan(lchan, ts) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED)</span><br><span style="color: hsl(0, 100%, 40%);">-                                     && (lchan->type == GSM_LCHAN_TCH_F</span><br><span style="color: hsl(0, 100%, 40%);">-                                               || lchan->type == GSM_LCHAN_TCH_H)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ts_for_each_lchan(lchan, ts) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                if (lchan_state_is(lchan, LCHAN_ST_ESTABLISHED)</span><br><span style="color: hsl(120, 100%, 40%);">+                                                   && (lchan->type == GSM_LCHAN_TCH_F</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     || lchan->type == GSM_LCHAN_TCH_H)) {</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                                            vty_out(vty, "Found voice call: %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        gsm_lchan_name(lchan), VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                                            lchan_dump_full_vty(vty, lchan);</span><br><span style="color: hsl(0, 100%, 40%);">-                                                return lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 if (count == random_idx) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                                            vty_out(vty, "Found voice call: %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                      gsm_lchan_name(lchan),</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                        VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                         lchan_dump_full_vty(vty, lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+                                                              return lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                                                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     count ++;</span><br><span style="color: hsl(120, 100%, 40%);">+                                             }</span><br><span>                                    }</span><br><span>                            }</span><br><span>                    }</span><br><span>            }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!count)</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                /* there are used lchans, but random_idx is > count. Iterate again. */</span><br><span style="color: hsl(120, 100%, 40%);">+             random_idx %= count;</span><br><span>         }</span><br><span> </span><br><span>        vty_out(vty, "Cannot find any ongoing voice calls%s", VTY_NEWLINE);</span><br><span>@@ -1642,7 +1655,7 @@</span><br><span> }</span><br><span> </span><br><span> static struct gsm_bts *find_other_bts_with_free_slots(struct vty *vty, struct gsm_bts *not_this_bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                enum gsm_phys_chan_config free_type)</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  enum gsm_chan_t free_type)</span><br><span> {</span><br><span>        struct gsm_bts *bts;</span><br><span>         struct gsm_network *network = gsmnet_from_vty(vty);</span><br><span>@@ -1654,30 +1667,14 @@</span><br><span>                        continue;</span><br><span> </span><br><span>                llist_for_each_entry(trx, &bts->trx_list, list) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        int i;</span><br><span style="color: hsl(0, 100%, 40%);">-                  /* FIXME: use lchan_select_by_type() instead */</span><br><span style="color: hsl(0, 100%, 40%);">-                 for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-                               struct gsm_bts_trx_ts *ts = &trx->ts[i];</span><br><span style="color: hsl(0, 100%, 40%);">-                         struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+                      struct gsm_lchan *lchan = lchan_select_by_type(bts, free_type);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (!lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+                           continue;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                           /* skip administratively deactivated timeslots */</span><br><span style="color: hsl(0, 100%, 40%);">-                               if (!nm_is_running(&ts->mo.nm_state))</span><br><span style="color: hsl(0, 100%, 40%);">-                                    continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                               if (ts->pchan_is != free_type)</span><br><span style="color: hsl(0, 100%, 40%);">-                                       continue;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                               ts_for_each_lchan(lchan, ts) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                  if (lchan->fi->state != LCHAN_ST_UNUSED)</span><br><span style="color: hsl(0, 100%, 40%);">-                                          continue;</span><br><span style="color: hsl(0, 100%, 40%);">-                                       vty_out(vty, "Found unused %s slot: %s%s",</span><br><span style="color: hsl(0, 100%, 40%);">-                                            gsm_pchan_name(free_type),</span><br><span style="color: hsl(0, 100%, 40%);">-                                              gsm_lchan_name(lchan),</span><br><span style="color: hsl(0, 100%, 40%);">-                                          VTY_NEWLINE);</span><br><span style="color: hsl(0, 100%, 40%);">-                                   lchan_dump_full_vty(vty, lchan);</span><br><span style="color: hsl(0, 100%, 40%);">-                                        return bts;</span><br><span style="color: hsl(0, 100%, 40%);">-                             }</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(120, 100%, 40%);">+                     vty_out(vty, "Found unused %s slot: %s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+                          gsm_lchant_name(free_type), gsm_lchan_name(lchan), VTY_NEWLINE);</span><br><span style="color: hsl(120, 100%, 40%);">+                      lchan_dump_full_vty(vty, lchan);</span><br><span style="color: hsl(120, 100%, 40%);">+                      return bts;</span><br><span>          }</span><br><span>    }</span><br><span>    vty_out(vty, "Cannot find any BTS (other than BTS %u) with free %s lchan%s",</span><br><span>@@ -1694,12 +1691,11 @@</span><br><span>     struct gsm_lchan *from_lchan;</span><br><span>        struct gsm_bts *to_bts;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     from_lchan = find_used_voice_lchan(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+      from_lchan = find_used_voice_lchan(vty, random());</span><br><span>   if (!from_lchan)</span><br><span>             return CMD_WARNING;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts,</span><br><span style="color: hsl(0, 100%, 40%);">-                                         from_lchan->ts->pchan_is);</span><br><span style="color: hsl(120, 100%, 40%);">+      to_bts = find_other_bts_with_free_slots(vty, from_lchan->ts->trx->bts, from_lchan->type);</span><br><span>        if (!to_bts)</span><br><span>                 return CMD_WARNING;</span><br><span> </span><br><span>@@ -1714,7 +1710,7 @@</span><br><span> {</span><br><span>         struct gsm_lchan *from_lchan;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       from_lchan = find_used_voice_lchan(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+      from_lchan = find_used_voice_lchan(vty, random());</span><br><span>   if (!from_lchan)</span><br><span>             return CMD_WARNING;</span><br><span> </span><br><span>@@ -1732,7 +1728,7 @@</span><br><span> {</span><br><span>         struct gsm_lchan *from_lchan;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-       from_lchan = find_used_voice_lchan(vty);</span><br><span style="color: hsl(120, 100%, 40%);">+      from_lchan = find_used_voice_lchan(vty, random());</span><br><span>   if (!from_lchan)</span><br><span>             return CMD_WARNING;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10108">change 10108</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/10108"/><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-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I50b70e02d665b967e401db65581e110bc83101e7 </div>
<div style="display:none"> Gerrit-Change-Number: 10108 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>