aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2019-01-22 10:18:20 +0100
committerPhilipp Maier <pmaier@sysmocom.de>2019-01-22 12:29:06 +0100
commit180980a377e13016cded1656e32b67d018414568 (patch)
treea67083a98a2ea8a2a01f8c2577e202f55307e987
parent59fe9c0dc8b7e47a94bbba3296a1326d94f75288 (diff)
bsc_vty: add features to disable specific lchans via vty
In some test and debug situations it is useful to have the ability to lock certain lchans in a way that the BSC can not allocate them. One application might be to simulate an exhaustion of all TCH/H channels in order to force the BSC to take one of the available TCH/F. Lets add a command to the vty which alloes us to mark certain lchans as disabled and check that condition while doing the channel allocation Change-Id: I397e68e26d6a1727890353fa34f4897b54795866 Related: OS#3503
-rw-r--r--include/osmocom/bsc/gsm_data.h4
-rw-r--r--src/osmo-bsc/bsc_vty.c36
-rw-r--r--src/osmo-bsc/lchan_fsm.c1
-rw-r--r--src/osmo-bsc/lchan_select.c7
4 files changed, 43 insertions, 5 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 9f7ce8d0b..a17f67e68 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -613,6 +613,10 @@ struct gsm_lchan {
struct gsm48_req_ref *rqd_ref;
struct gsm_subscriber_connection *conn;
+
+ /* Debug feature: When set to true via VTY, the channel allocator will
+ * not use this lchan. */
+ bool disabled;
};
/* One Timeslot in a TRX */
diff --git a/src/osmo-bsc/bsc_vty.c b/src/osmo-bsc/bsc_vty.c
index 31e1c719a..82b12e0aa 100644
--- a/src/osmo-bsc/bsc_vty.c
+++ b/src/osmo-bsc/bsc_vty.c
@@ -1372,10 +1372,11 @@ static void lchan_dump_full_vty(struct vty *vty, struct gsm_lchan *lchan)
lchan->ts->trx->bts->nr, lchan->ts->trx->nr, lchan->ts->nr,
lchan->nr, gsm_lchant_name(lchan->type), VTY_NEWLINE);
vty_out_dyn_ts_details(vty, lchan->ts);
- vty_out(vty, " Connection: %u, State: %s%s%s%s",
+ vty_out(vty, " Connection: %u, State: %s%s%s%s%s",
lchan->conn ? 1: 0, lchan_state_name(lchan),
lchan->fi && lchan->fi->state == LCHAN_ST_BORKEN ? " Error reason: " : "",
lchan->fi && lchan->fi->state == LCHAN_ST_BORKEN ? lchan->last_error : "",
+ lchan->disabled ? " (disabled)" : "",
VTY_NEWLINE);
vty_out(vty, " BS Power: %u dBm, MS Power: %u dBm%s",
lchan->ts->trx->nominal_power - lchan->ts->trx->max_power_red
@@ -1430,12 +1431,13 @@ static void lchan_dump_short_vty(struct vty *vty, struct gsm_lchan *lchan)
gsm_pchan_name(lchan->ts->pchan_on_init));
vty_out_dyn_ts_status(vty, lchan->ts);
vty_out(vty, ", Lchan %u, Type %s, State %s - "
- "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s",
+ "L1 MS Power: %u dBm RXL-FULL-dl: %4d dBm RXL-FULL-ul: %4d dBm%s%s",
lchan->nr,
gsm_lchant_name(lchan->type), lchan_state_name(lchan),
mr->ms_l1.pwr,
rxlev2dbm(mr->dl.full.rx_lev),
rxlev2dbm(mr->ul.full.rx_lev),
+ lchan->disabled ? " (disabled)" : "",
VTY_NEWLINE);
}
@@ -4788,6 +4790,34 @@ DEFUN(lchan_act, lchan_act_cmd,
return CMD_SUCCESS;
}
+/* Debug command to temporarily disable certain timeslots in order to force
+ * the channel allocator to pick one specific or from a group of specific
+ * timeslots. */
+DEFUN_HIDDEN(ts_disable, ts_disable_cmd,
+ "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> (disable|enable)",
+ BTS_NR_TRX_TS_SS_STR2
+ "Disable channel allocation on this timeslot (for debugging)\n"
+ "Enable channel allocation on this timeslot (for debugging)\n")
+{
+ struct gsm_bts_trx_ts *ts;
+ struct gsm_lchan *lchan;
+ int ss_nr = atoi(argv[3]);
+ ts = vty_get_ts(vty, argv[0], argv[1], argv[2]);
+ if (!ts)
+ return CMD_WARNING;
+ lchan = &ts->lchan[ss_nr];
+ if (!lchan)
+ return CMD_WARNING;
+
+ if (!strcmp(argv[4], "disable"))
+ lchan->disabled = true;
+ else
+ lchan->disabled = false;
+
+ return CMD_SUCCESS;
+}
+
+
DEFUN(lchan_mdcx, lchan_mdcx_cmd,
"bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7> mdcx A.B.C.D <0-65535>",
BTS_NR_TRX_TS_SS_STR2
@@ -5264,6 +5294,8 @@ int bsc_vty_init(struct gsm_network *network)
install_element(ENABLE_NODE, &pdch_act_cmd);
install_element(ENABLE_NODE, &lchan_act_cmd);
install_element(ENABLE_NODE, &lchan_mdcx_cmd);
+ install_element(ENABLE_NODE, &ts_disable_cmd);
+
install_element(ENABLE_NODE, &handover_subscr_conn_cmd);
install_element(ENABLE_NODE, &assignment_subscr_conn_cmd);
install_element(ENABLE_NODE, &smscb_cmd_cmd);
diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c
index f344cf990..109aedfb7 100644
--- a/src/osmo-bsc/lchan_fsm.c
+++ b/src/osmo-bsc/lchan_fsm.c
@@ -400,6 +400,7 @@ static void lchan_reset(struct gsm_lchan *lchan)
.meas_rep_last_seen_nr = 255,
.last_error = lchan->last_error,
+ .disabled = lchan->disabled,
};
}
diff --git a/src/osmo-bsc/lchan_select.c b/src/osmo-bsc/lchan_select.c
index 0f4dd6527..36e7b5c31 100644
--- a/src/osmo-bsc/lchan_select.c
+++ b/src/osmo-bsc/lchan_select.c
@@ -80,16 +80,17 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
/* TS is (going to be) in desired pchan mode. Go ahead and check for an available lchan. */
ts_as_pchan_for_each_lchan(lchan, ts, as_pchan) {
- if (lchan->fi->state == LCHAN_ST_UNUSED) {
+ if (lchan->fi->state == LCHAN_ST_UNUSED && lchan->disabled == false) {
LOGPLCHANALLOC("%s ss=%d is available%s\n",
gsm_ts_and_pchan_name(ts), lchan->nr,
ts->pchan_is != as_pchan ? " after dyn PCHAN change" : "");
return lchan;
}
- LOGPLCHANALLOC("%s ss=%d in type=%s,state=%s not suitable\n",
+ LOGPLCHANALLOC("%s ss=%d in type=%s,state=%s %s\n",
gsm_ts_and_pchan_name(ts), lchan->nr,
gsm_lchant_name(lchan->type),
- osmo_fsm_inst_state_name(lchan->fi));
+ osmo_fsm_inst_state_name(lchan->fi),
+ lchan->disabled ? "disabled" : "not suitable");
}
}