bsc_ctrl_commands: change neighbor-list mode/arfcn via control interface

It is possible to change the neighbor-list mode via the VTY from
automatic mode to manual neighbor-list configuration. In the manual
mode, the user can add ARFCN values manually. This command can be found
under the bts node. Lets add pendant of this command on the control
interface as well.

Change-Id: Id97bc0d31a358db6221c385761773fb48670c921
Related: SYS#5641
This commit is contained in:
Philipp Maier 2021-10-27 17:28:49 +02:00 committed by laforge
parent 085a92584f
commit 3ca2ae1d0a
3 changed files with 160 additions and 0 deletions

View File

@ -68,6 +68,9 @@ TRX-specific commands are additionally prefixed with TRX number e. g.
|[bts.N.]handover2.penalty-time.failed-assignment|RW|No|<0-99999>,"default"|Time to suspend handover for a subscriber after a failed re-assignment within this cell.
|[bts.N.]handover2.retries|RW|No|<0-9>,"default"|Number of times to immediately retry a failed handover/assignment, before a penalty time is applied.
|handover2.congestion-check|RW|No|"disabled",<1-999>,"now"|Congestion check interval in seconds, "now" triggers immediate congestion check.
|bts.N.neighbor-list.mode|WO|No|"automatic","manual","manual-si5"|Mode of Neighbor List generation.
|bts.N.neighbor-list.add|WO|No|<0-1023>|Add to manual neighbor list.
|bts.N.neighbor-list.del|WO|No|<0-1023>|Delete from manual neighbor list.
|===
[[notif]]

View File

@ -668,6 +668,120 @@ static int set_bts_c0_power_red(struct ctrl_cmd *cmd, void *data)
CTRL_CMD_DEFINE(bts_c0_power_red, "c0-power-reduction");
static int verify_bts_neighbor_list_add_del(struct ctrl_cmd *cmd, const char *value, void *_data)
{
int arfcn;
if (osmo_str_to_int(&arfcn, value, 10, 0, 1023) < 0) {
cmd->reply = "Invalid ARFCN value";
return 1;
}
return 0;
}
static int set_bts_neighbor_list_add_del(struct ctrl_cmd *cmd, void *data, bool add)
{
struct gsm_bts *bts = cmd->node;
struct bitvec *bv = &bts->si_common.neigh_list;
int arfcn_int;
uint16_t arfcn;
enum gsm_band unused;
if (osmo_str_to_int(&arfcn_int, cmd->value, 10, 0, 1023) < 0) {
cmd->reply = "Failed to parse ARFCN value";
return CTRL_CMD_ERROR;
}
arfcn = (uint16_t) arfcn_int;
if (bts->neigh_list_manual_mode == NL_MODE_AUTOMATIC) {
cmd->reply = "Neighbor list not in manual mode";
return CTRL_CMD_ERROR;
}
if (gsm_arfcn2band_rc(arfcn, &unused) < 0) {
cmd->reply = "Invalid arfcn detected";
return CTRL_CMD_ERROR;
}
if (add)
bitvec_set_bit_pos(bv, arfcn, 1);
else
bitvec_set_bit_pos(bv, arfcn, 0);
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
static int verify_bts_neighbor_list_add(struct ctrl_cmd *cmd, const char *value, void *_data)
{
return verify_bts_neighbor_list_add_del(cmd, value, _data);
}
static int set_bts_neighbor_list_add(struct ctrl_cmd *cmd, void *data)
{
return set_bts_neighbor_list_add_del(cmd, data, true);
}
CTRL_CMD_DEFINE_WO(bts_neighbor_list_add, "neighbor-list add");
static int verify_bts_neighbor_list_del(struct ctrl_cmd *cmd, const char *value, void *_data)
{
return verify_bts_neighbor_list_add_del(cmd, value, _data);
}
static int set_bts_neighbor_list_del(struct ctrl_cmd *cmd, void *data)
{
return set_bts_neighbor_list_add_del(cmd, data, false);
}
CTRL_CMD_DEFINE_WO(bts_neighbor_list_del, "neighbor-list del");
static int verify_bts_neighbor_list_mode(struct ctrl_cmd *cmd, const char *value, void *_data)
{
if (!strcmp(value, "automatic"))
return 0;
if (!strcmp(value, "manual"))
return 0;
if (!strcmp(value, "manual-si5"))
return 0;
cmd->reply = "Invalid mode";
return 1;
}
static int set_bts_neighbor_list_mode(struct ctrl_cmd *cmd, void *data)
{
struct gsm_bts *bts = cmd->node;
int mode;
if (!strcmp(cmd->value, "automatic"))
mode = NL_MODE_AUTOMATIC;
else if (!strcmp(cmd->value, "manual"))
mode = NL_MODE_MANUAL;
else if (!strcmp(cmd->value, "manual-si5"))
mode = NL_MODE_MANUAL_SI5SEP;
switch (mode) {
case NL_MODE_MANUAL_SI5SEP:
case NL_MODE_MANUAL:
/* make sure we clear the current list when switching to
* manual mode */
if (bts->neigh_list_manual_mode == 0)
memset(&bts->si_common.data.neigh_list, 0, sizeof(bts->si_common.data.neigh_list));
break;
default:
break;
}
bts->neigh_list_manual_mode = mode;
cmd->reply = "OK";
return CTRL_CMD_REPLY;
}
CTRL_CMD_DEFINE_WO(bts_neighbor_list_mode, "neighbor-list mode");
int bsc_base_ctrl_cmds_install(void)
{
int rc = 0;
@ -692,6 +806,9 @@ int bsc_base_ctrl_cmds_install(void)
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rf_state);
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_rf_states);
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_c0_power_red);
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_add);
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_del);
rc |= ctrl_cmd_install(CTRL_NODE_BTS, &cmd_bts_neighbor_list_mode);
rc |= neighbor_ident_ctrl_init();

View File

@ -525,6 +525,46 @@ class TestCtrlBSC(TestCtrlBase):
self.assertEqual(r['var'], 'apply-config-file')
self.assertEqual(r['value'], 'OK')
def testNeighborList(self):
# Enter manual neighbor-list mode
r = self.do_set('bts.0.neighbor-list.mode', 'manual')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'SET_REPLY')
self.assertEqual(r['var'], 'bts.0.neighbor-list.mode')
self.assertEqual(r['value'], 'OK')
# Add an ARFCN
r = self.do_set('bts.0.neighbor-list.add', '123')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'SET_REPLY')
self.assertEqual(r['var'], 'bts.0.neighbor-list.add')
self.assertEqual(r['value'], 'OK')
# Delete the ARFCN again
r = self.do_set('bts.0.neighbor-list.del', '123')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'SET_REPLY')
self.assertEqual(r['var'], 'bts.0.neighbor-list.del')
self.assertEqual(r['value'], 'OK')
# Go back to automatic neighbor-list mode
r = self.do_set('bts.0.neighbor-list.mode', 'automatic')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'SET_REPLY')
self.assertEqual(r['var'], 'bts.0.neighbor-list.mode')
self.assertEqual(r['value'], 'OK')
# This must not work as we are in automatic neighbor-list mode
r = self.do_set('bts.0.neighbor-list.add', '123')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'ERROR')
self.assertEqual(r['error'], 'Neighbor list not in manual mode')
# Try an invalid neighbor-list mode
r = self.do_set('bts.0.neighbor-list.mode', 'qwertzuiop')
print('respose: ' + str(r))
self.assertEqual(r['mtype'], 'ERROR')
self.assertEqual(r['error'], 'Invalid mode')
class TestCtrlBSCNeighbor(TestCtrlBase):