mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
synced 2025-10-23 08:12:01 +00:00
Allow configuration of SI5 neighbor list != SI2 neighbor list
This introducecs the new VTY command "neighbor-list mode manual-si5" in combination with "si5 neighbor-list (add|del) arfcn <0-1024>", which allows you to (optionally) have neighbor channel lists that differ in SI5 and in SI2.
This commit is contained in:
@@ -491,6 +491,12 @@ struct gsm_bts_gprs_nsvc {
|
||||
struct gsm_nm_state nm_state;
|
||||
};
|
||||
|
||||
enum neigh_list_manual_mode {
|
||||
NL_MODE_AUTOMATIC = 0,
|
||||
NL_MODE_MANUAL = 1,
|
||||
NL_MODE_MANUAL_SI5SEP = 2, /* SI2 and SI5 have separate neighbor lists */
|
||||
};
|
||||
|
||||
/* One BTS */
|
||||
struct gsm_bts {
|
||||
/* list header in net->bts_list */
|
||||
@@ -542,7 +548,7 @@ struct gsm_bts {
|
||||
struct gsm_nm_state nm_state;
|
||||
} site_mgr;
|
||||
|
||||
int neigh_list_manual_mode;
|
||||
enum neigh_list_manual_mode neigh_list_manual_mode;
|
||||
/* parameters from which we build SYSTEM INFORMATION */
|
||||
struct {
|
||||
struct gsm48_rach_control rach_control;
|
||||
@@ -553,10 +559,13 @@ struct gsm_bts {
|
||||
struct gsm48_control_channel_descr chan_desc;
|
||||
struct bitvec neigh_list;
|
||||
struct bitvec cell_alloc;
|
||||
struct bitvec si5_neigh_list;
|
||||
struct {
|
||||
/* bitmask large enough for all possible ARFCN's */
|
||||
u_int8_t neigh_list[1024/8];
|
||||
u_int8_t cell_alloc[1024/8];
|
||||
/* If the user wants a different neighbor list in SI5 than in SI2 */
|
||||
u_int8_t si5_neigh_list[1024/8];
|
||||
} data;
|
||||
} si_common;
|
||||
|
||||
|
@@ -76,6 +76,13 @@ static const struct value_string gprs_bssgp_cfg_strs[] = {
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
static const struct value_string bts_neigh_mode_strs[] = {
|
||||
{ NL_MODE_AUTOMATIC, "automatic" },
|
||||
{ NL_MODE_MANUAL, "manual" },
|
||||
{ NL_MODE_MANUAL_SI5SEP, "manual-si5" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
struct cmd_node net_node = {
|
||||
GSMNET_NODE,
|
||||
"%s(network)#",
|
||||
@@ -495,14 +502,21 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
|
||||
vty_out(vty, " paging free %d%s", bts->paging.free_chans_need, VTY_NEWLINE);
|
||||
|
||||
vty_out(vty, " neighbor-list mode %s%s",
|
||||
bts->neigh_list_manual_mode ? "manual" : "automatic", VTY_NEWLINE);
|
||||
if (bts->neigh_list_manual_mode) {
|
||||
get_value_string(bts_neigh_mode_strs, bts->neigh_list_manual_mode), VTY_NEWLINE);
|
||||
if (bts->neigh_list_manual_mode != NL_MODE_AUTOMATIC) {
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (bitvec_get_bit_pos(&bts->si_common.neigh_list, i))
|
||||
vty_out(vty, " neighbor-list add arfcn %u%s",
|
||||
i, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
if (bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP) {
|
||||
for (i = 0; i < 1024; i++) {
|
||||
if (bitvec_get_bit_pos(&bts->si_common.si5_neigh_list, i))
|
||||
vty_out(vty, " si5 neighbor-list add arfcn %u%s",
|
||||
i, VTY_NEWLINE);
|
||||
}
|
||||
}
|
||||
|
||||
config_write_bts_gprs(vty, bts);
|
||||
|
||||
@@ -2136,21 +2150,28 @@ DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd,
|
||||
}
|
||||
|
||||
DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd,
|
||||
"neighbor-list mode (automatic|manual)",
|
||||
"neighbor-list mode (automatic|manual|manual-si5)",
|
||||
"Neighbor List\n" "Mode of Neighbor List generation\n"
|
||||
"Automatically from all BTS in this OpenBSC\n" "Manual\n")
|
||||
"Automatically from all BTS in this OpenBSC\n" "Manual\n"
|
||||
"Manual with different lists for SI2 and SI5\n")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
int mode = get_string_value(bts_neigh_mode_strs, argv[0]);
|
||||
|
||||
if (!strcmp(argv[0], "manual")) {
|
||||
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));
|
||||
bts->neigh_list_manual_mode = 1;
|
||||
} else
|
||||
bts->neigh_list_manual_mode = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bts->neigh_list_manual_mode = mode;
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@@ -2179,6 +2200,29 @@ DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(cfg_bts_si5_neigh, cfg_bts_si5_neigh_cmd,
|
||||
"si5 neighbor-list (add|del) arfcn <0-1024>",
|
||||
"SI5 Neighbor List\n" "Add to manual SI5 neighbor list\n"
|
||||
"Delete from SI5 manual neighbor list\n" "ARFCN of neighbor\n"
|
||||
"ARFCN of neighbor\n")
|
||||
{
|
||||
struct gsm_bts *bts = vty->index;
|
||||
struct bitvec *bv = &bts->si_common.si5_neigh_list;
|
||||
uint16_t arfcn = atoi(argv[1]);
|
||||
|
||||
if (!bts->neigh_list_manual_mode) {
|
||||
vty_out(vty, "%% Cannot configure neighbor list in "
|
||||
"automatic mode%s", VTY_NEWLINE);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[0], "add"))
|
||||
bitvec_set_bit_pos(bv, arfcn, 1);
|
||||
else
|
||||
bitvec_set_bit_pos(bv, arfcn, 0);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
#define TRX_TEXT "Radio Transceiver\n"
|
||||
|
||||
@@ -2679,6 +2723,7 @@ int bsc_vty_init(void)
|
||||
install_element(BTS_NODE, &cfg_bts_si_static_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_neigh_mode_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_neigh_cmd);
|
||||
install_element(BTS_NODE, &cfg_bts_si5_neigh_cmd);
|
||||
|
||||
install_element(BTS_NODE, &cfg_trx_cmd);
|
||||
install_node(&trx_node, dummy_config_write);
|
||||
|
@@ -214,6 +214,9 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type,
|
||||
bts->si_common.neigh_list.data = bts->si_common.data.neigh_list;
|
||||
bts->si_common.neigh_list.data_len =
|
||||
sizeof(bts->si_common.data.neigh_list);
|
||||
bts->si_common.si5_neigh_list.data = bts->si_common.data.si5_neigh_list;
|
||||
bts->si_common.si5_neigh_list.data_len =
|
||||
sizeof(bts->si_common.data.si5_neigh_list);
|
||||
bts->si_common.cell_alloc.data = bts->si_common.data.cell_alloc;
|
||||
bts->si_common.cell_alloc.data_len =
|
||||
sizeof(bts->si_common.data.cell_alloc);
|
||||
|
@@ -199,16 +199,21 @@ static int generate_cell_chan_list(u_int8_t *chan_list, struct gsm_bts *bts)
|
||||
}
|
||||
|
||||
/* generate a cell channel list as per Section 10.5.2.1b of 04.08 */
|
||||
static int generate_bcch_chan_list(u_int8_t *chan_list, struct gsm_bts *bts)
|
||||
static int generate_bcch_chan_list(u_int8_t *chan_list, struct gsm_bts *bts, int si5)
|
||||
{
|
||||
struct gsm_bts *cur_bts;
|
||||
struct bitvec *bv = &bts->si_common.neigh_list;
|
||||
struct bitvec *bv;
|
||||
|
||||
if (si5 && bts->neigh_list_manual_mode == NL_MODE_MANUAL_SI5SEP)
|
||||
bv = &bts->si_common.si5_neigh_list;
|
||||
else
|
||||
bv = &bts->si_common.neigh_list;
|
||||
|
||||
/* Zero-initialize the bit-vector */
|
||||
memset(bv->data, 0, bv->data_len);
|
||||
|
||||
/* Generate list of neighbor cells if we are in automatic mode */
|
||||
if (bts->neigh_list_manual_mode == 0) {
|
||||
if (bts->neigh_list_manual_mode == NL_MODE_AUTOMATIC) {
|
||||
/* first we generate a bitvec of the BCCH ARFCN's in our BSC */
|
||||
llist_for_each_entry(cur_bts, &bts->network->bts_list, list) {
|
||||
if (cur_bts == bts)
|
||||
@@ -259,7 +264,7 @@ static int generate_si2(u_int8_t *output, struct gsm_bts *bts)
|
||||
si2->header.skip_indicator = 0;
|
||||
si2->header.system_information = GSM48_MT_RR_SYSINFO_2;
|
||||
|
||||
rc = generate_bcch_chan_list(si2->bcch_frequency_list, bts);
|
||||
rc = generate_bcch_chan_list(si2->bcch_frequency_list, bts, 0);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
@@ -376,7 +381,7 @@ static int generate_si5(u_int8_t *output, struct gsm_bts *bts)
|
||||
si5->rr_protocol_discriminator = GSM48_PDISC_RR;
|
||||
si5->skip_indicator = 0;
|
||||
si5->system_information = GSM48_MT_RR_SYSINFO_5;
|
||||
rc = generate_bcch_chan_list(si5->bcch_frequency_list, bts);
|
||||
rc = generate_bcch_chan_list(si5->bcch_frequency_list, bts, 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
|
Reference in New Issue
Block a user