<p>dexter has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/12624">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">bsc_vty: add features to shun specific lchans<br><br>In some test and debug situations it is useful to have the ability to<br>lock certain lchans in a way that the BSC can not allocate them. One<br>application might be to simulate an exhaustion of all TCH/H channels in<br>order to force the BSC to take one of the available TCH/F.<br><br>Lets add a command to the vty which alloes us to mark certain lchans as<br>shunned and check that condition while doing the channel allocation<br><br>Change-Id: I397e68e26d6a1727890353fa34f4897b54795866<br>Related: OS#3503<br>---<br>M include/osmocom/bsc/gsm_data.h<br>M src/osmo-bsc/bsc_vty.c<br>M src/osmo-bsc/lchan_fsm.c<br>M src/osmo-bsc/lchan_select.c<br>4 files changed, 72 insertions(+), 19 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/24/12624/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h</span><br><span>index 9f7ce8d..22d80df 100644</span><br><span>--- a/include/osmocom/bsc/gsm_data.h</span><br><span>+++ b/include/osmocom/bsc/gsm_data.h</span><br><span>@@ -613,6 +613,10 @@</span><br><span> struct gsm48_req_ref *rqd_ref;</span><br><span> </span><br><span> struct gsm_subscriber_connection *conn;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Debug feature: When set to true via VTY, the channel allocator will</span><br><span style="color: hsl(120, 100%, 40%);">+ * not use this lchan. */</span><br><span style="color: hsl(120, 100%, 40%);">+ bool shun;</span><br><span> };</span><br><span> </span><br><span> /* One Timeslot in a TRX */</span><br><span>diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c</span><br><span>index 791aebe..ed93dcb 100644</span><br><span>--- a/src/osmo-bsc/bsc_vty.c</span><br><span>+++ b/src/osmo-bsc/bsc_vty.c</span><br><span>@@ -1372,10 +1372,11 @@</span><br><span> lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,</span><br><span> lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);</span><br><span> vty_out_dyn_ts_details(vty, lchan->ts);</span><br><span style="color: hsl(0, 100%, 40%);">- vty_out(vty, " Connection: %u, State: %s%s%s%s",</span><br><span style="color: hsl(120, 100%, 40%);">+ vty_out(vty, " Connection: %u, State: %s%s%s%s%s",</span><br><span> lchan->conn ? 1: 0, lchan_state_name(lchan),</span><br><span> lchan->fi && lchan->fi->state == LCHAN_ST_BORKEN ? " Error reason: " : "",</span><br><span> lchan->fi && lchan->fi->state == LCHAN_ST_BORKEN ? lchan->last_error : "",</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->shun ? " (shunned)" : "",</span><br><span> VTY_NEWLINE);</span><br><span> vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",</span><br><span> lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red</span><br><span>@@ -1430,22 +1431,24 @@</span><br><span> gsm_pchan_name(lchan->ts->pchan_on_init));</span><br><span> vty_out_dyn_ts_status(vty, lchan->ts);</span><br><span> vty_out(vty, ", Lchan %u, Type %s, State %s - "</span><br><span style="color: hsl(0, 100%, 40%);">- "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",</span><br><span style="color: hsl(120, 100%, 40%);">+ "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s%s",</span><br><span> lchan->nr,</span><br><span> gsm_lchant_name(lchan->type), lchan_state_name(lchan),</span><br><span> mr->ms_l1.pwr,</span><br><span> rxlev2dbm(mr->dl.full.rx_lev),</span><br><span> rxlev2dbm(mr->ul.full.rx_lev),</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->shun ? " (shunned)" : "",</span><br><span> VTY_NEWLINE);</span><br><span> }</span><br><span> </span><br><span> </span><br><span> static int dump_lchan_trx_ts(struct gsm_bts_trx_ts *ts, struct vty *vty,</span><br><span style="color: hsl(0, 100%, 40%);">- void (*dump_cb)(struct vty *, struct gsm_lchan *))</span><br><span style="color: hsl(120, 100%, 40%);">+ void (*dump_cb)(struct vty *, struct gsm_lchan *),</span><br><span style="color: hsl(120, 100%, 40%);">+ bool all)</span><br><span> {</span><br><span> struct gsm_lchan *lchan;</span><br><span> ts_for_each_lchan(lchan, ts) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan_state_is(lchan, LCHAN_ST_UNUSED))</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan_state_is(lchan, LCHAN_ST_UNUSED) && all == false)</span><br><span> continue;</span><br><span> dump_cb(vty, lchan);</span><br><span> }</span><br><span>@@ -1454,33 +1457,36 @@</span><br><span> }</span><br><span> </span><br><span> static int dump_lchan_trx(struct gsm_bts_trx *trx, struct vty *vty,</span><br><span style="color: hsl(0, 100%, 40%);">- void (*dump_cb)(struct vty *, struct gsm_lchan *))</span><br><span style="color: hsl(120, 100%, 40%);">+ void (*dump_cb)(struct vty *, struct gsm_lchan *),</span><br><span style="color: hsl(120, 100%, 40%);">+ bool all)</span><br><span> {</span><br><span> int ts_nr;</span><br><span> </span><br><span> for (ts_nr = 0; ts_nr < TRX_NR_TS; ts_nr++) {</span><br><span> struct gsm_bts_trx_ts *ts = &trx->ts[ts_nr];</span><br><span style="color: hsl(0, 100%, 40%);">- dump_lchan_trx_ts(ts, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_lchan_trx_ts(ts, vty, dump_cb, all);</span><br><span> }</span><br><span> </span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span> static int dump_lchan_bts(struct gsm_bts *bts, struct vty *vty,</span><br><span style="color: hsl(0, 100%, 40%);">- void (*dump_cb)(struct vty *, struct gsm_lchan *))</span><br><span style="color: hsl(120, 100%, 40%);">+ void (*dump_cb)(struct vty *, struct gsm_lchan *),</span><br><span style="color: hsl(120, 100%, 40%);">+ bool all)</span><br><span> {</span><br><span> int trx_nr;</span><br><span> </span><br><span> for (trx_nr = 0; trx_nr < bts->num_trx; trx_nr++) {</span><br><span> struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, trx_nr);</span><br><span style="color: hsl(0, 100%, 40%);">- dump_lchan_trx(trx, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_lchan_trx(trx, vty, dump_cb, all);</span><br><span> }</span><br><span> </span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span> static int lchan_summary(struct vty *vty, int argc, const char **argv,</span><br><span style="color: hsl(0, 100%, 40%);">- void (*dump_cb)(struct vty *, struct gsm_lchan *))</span><br><span style="color: hsl(120, 100%, 40%);">+ void (*dump_cb)(struct vty *, struct gsm_lchan *),</span><br><span style="color: hsl(120, 100%, 40%);">+ bool all)</span><br><span> {</span><br><span> struct gsm_network *net = gsmnet_from_vty(vty);</span><br><span> struct gsm_bts *bts = NULL;</span><br><span>@@ -1500,7 +1506,7 @@</span><br><span> bts = gsm_bts_num(net, bts_nr);</span><br><span> </span><br><span> if (argc == 1)</span><br><span style="color: hsl(0, 100%, 40%);">- return dump_lchan_bts(bts, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ return dump_lchan_bts(bts, vty, dump_cb, all);</span><br><span> }</span><br><span> if (argc >= 2) {</span><br><span> trx_nr = atoi(argv[1]);</span><br><span>@@ -1512,7 +1518,7 @@</span><br><span> trx = gsm_bts_trx_num(bts, trx_nr);</span><br><span> </span><br><span> if (argc == 2)</span><br><span style="color: hsl(0, 100%, 40%);">- return dump_lchan_trx(trx, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ return dump_lchan_trx(trx, vty, dump_cb, all);</span><br><span> }</span><br><span> if (argc >= 3) {</span><br><span> ts_nr = atoi(argv[2]);</span><br><span>@@ -1524,7 +1530,7 @@</span><br><span> ts = &trx->ts[ts_nr];</span><br><span> </span><br><span> if (argc == 3)</span><br><span style="color: hsl(0, 100%, 40%);">- return dump_lchan_trx_ts(ts, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ return dump_lchan_trx_ts(ts, vty, dump_cb, all);</span><br><span> }</span><br><span> if (argc >= 4) {</span><br><span> lchan_nr = atoi(argv[3]);</span><br><span>@@ -1541,7 +1547,7 @@</span><br><span> </span><br><span> for (bts_nr = 0; bts_nr < net->num_bts; bts_nr++) {</span><br><span> bts = gsm_bts_num(net, bts_nr);</span><br><span style="color: hsl(0, 100%, 40%);">- dump_lchan_bts(bts, vty, dump_cb);</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_lchan_bts(bts, vty, dump_cb, all);</span><br><span> }</span><br><span> </span><br><span> return CMD_SUCCESS;</span><br><span>@@ -1554,17 +1560,27 @@</span><br><span> SHOW_STR "Display information about a logical channel\n"</span><br><span> BTS_TRX_TS_LCHAN_STR)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return lchan_summary(vty, argc, argv, lchan_dump_full_vty);</span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan_summary(vty, argc, argv, lchan_dump_full_vty, true);</span><br><span> }</span><br><span> </span><br><span> DEFUN(show_lchan_summary,</span><br><span> show_lchan_summary_cmd,</span><br><span> "show lchan summary [<0-255>] [<0-255>] [<0-7>] [<0-7>]",</span><br><span> SHOW_STR "Display information about a logical channel\n"</span><br><span style="color: hsl(0, 100%, 40%);">- "Short summary\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Short summary (in use lchans)\n"</span><br><span> BTS_TRX_TS_LCHAN_STR)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- return lchan_summary(vty, argc, argv, lchan_dump_short_vty);</span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan_summary(vty, argc, argv, lchan_dump_short_vty, 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%);">+DEFUN(show_lchan_all,</span><br><span style="color: hsl(120, 100%, 40%);">+ show_lchan_all_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "show lchan all [<0-255>] [<0-255>] [<0-7>] [<0-7>]",</span><br><span style="color: hsl(120, 100%, 40%);">+ SHOW_STR "Display information about a logical channel\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Short summary (all lchans)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_TRX_TS_LCHAN_STR)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return lchan_summary(vty, argc, argv, lchan_dump_short_vty, true);</span><br><span> }</span><br><span> </span><br><span> static void dump_one_subscr_conn(struct vty *vty, const struct gsm_subscriber_connection *conn)</span><br><span>@@ -4774,6 +4790,34 @@</span><br><span> return CMD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/* Debug command to temporarily disable certain timeslots in order to force</span><br><span style="color: hsl(120, 100%, 40%);">+ * the channel allocator to pick one specific or from a group of specific</span><br><span style="color: hsl(120, 100%, 40%);">+ * timeslots. */</span><br><span style="color: hsl(120, 100%, 40%);">+DEFUN(ts_shun, ts_shun_cmd,</span><br><span style="color: hsl(120, 100%, 40%);">+ "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (shun|allow)",</span><br><span style="color: hsl(120, 100%, 40%);">+ BTS_NR_TRX_TS_SS_STR2</span><br><span style="color: hsl(120, 100%, 40%);">+ "Avoid channel allocation on timeslot (for debugging)\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Allow channel allocation on timeslot (take back shunning, for debugging)\n")</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts_trx_ts *ts;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_lchan *lchan;</span><br><span style="color: hsl(120, 100%, 40%);">+ int ss_nr = atoi(argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+ ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ts)</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan = &ts->lchan[ss_nr];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!lchan)</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_WARNING;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp(argv[4], "shun"))</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->shun = true;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->shun = false;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CMD_SUCCESS;</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> DEFUN(lchan_mdcx, lchan_mdcx_cmd,</span><br><span> "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",</span><br><span> BTS_NR_TRX_TS_SS_STR2</span><br><span>@@ -5085,6 +5129,7 @@</span><br><span> install_element_ve(&show_ts_cmd);</span><br><span> install_element_ve(&show_lchan_cmd);</span><br><span> install_element_ve(&show_lchan_summary_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element_ve(&show_lchan_all_cmd);</span><br><span> </span><br><span> install_element_ve(&show_subscr_conn_cmd);</span><br><span> </span><br><span>@@ -5249,6 +5294,8 @@</span><br><span> install_element(ENABLE_NODE, &pdch_act_cmd);</span><br><span> install_element(ENABLE_NODE, &lchan_act_cmd);</span><br><span> install_element(ENABLE_NODE, &lchan_mdcx_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+ install_element(ENABLE_NODE, &ts_shun_cmd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> install_element(ENABLE_NODE, &handover_subscr_conn_cmd);</span><br><span> install_element(ENABLE_NODE, &assignment_subscr_conn_cmd);</span><br><span> install_element(ENABLE_NODE, &smscb_cmd_cmd);</span><br><span>diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c</span><br><span>index f344cf9..c3b0017 100644</span><br><span>--- a/src/osmo-bsc/lchan_fsm.c</span><br><span>+++ b/src/osmo-bsc/lchan_fsm.c</span><br><span>@@ -400,6 +400,7 @@</span><br><span> .meas_rep_last_seen_nr = 255,</span><br><span> </span><br><span> .last_error = lchan->last_error,</span><br><span style="color: hsl(120, 100%, 40%);">+ .shun = lchan->shun,</span><br><span> };</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c</span><br><span>index eac0adf..4edf748 100644</span><br><span>--- a/src/osmo-bsc/lchan_select.c</span><br><span>+++ b/src/osmo-bsc/lchan_select.c</span><br><span>@@ -80,16 +80,17 @@</span><br><span> </span><br><span> /* TS is (going to be) in desired pchan mode. Go ahead and check for an available lchan. */</span><br><span> ts_as_pchan_for_each_lchan(lchan, ts, as_pchan) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (lchan->fi->state == LCHAN_ST_UNUSED) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lchan->fi->state == LCHAN_ST_UNUSED && lchan->shun == false) {</span><br><span> LOGPLCHANALLOC("%s ss=%d is available%s\n",</span><br><span> gsm_ts_and_pchan_name(ts), lchan->nr,</span><br><span> ts->pchan_is != as_pchan ? " after dyn PCHAN change" : "");</span><br><span> return lchan;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPLCHANALLOC("%s ss=%d in type=%s,state=%s not suitable\n",</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPLCHANALLOC("%s ss=%d in type=%s,state=%s %s\n",</span><br><span> gsm_ts_and_pchan_name(ts), lchan->nr,</span><br><span> gsm_lchant_name(lchan->type),</span><br><span style="color: hsl(0, 100%, 40%);">- osmo_fsm_inst_state_name(lchan->fi));</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fsm_inst_state_name(lchan->fi), lchan->shun ? "shunned" : "not suitable");</span><br><span> }</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12624">change 12624</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/12624"/><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: I397e68e26d6a1727890353fa34f4897b54795866 </div>
<div style="display:none"> Gerrit-Change-Number: 12624 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>