diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index fc02f58de..792f56fd8 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -531,6 +531,7 @@ struct gsm_bts { struct gsm_nm_state nm_state; } site_mgr; + int neigh_list_manual_mode; /* parameters from which we build SYSTEM INFORMATION */ struct { struct gsm48_rach_control rach_control; diff --git a/openbsc/src/bsc_vty.c b/openbsc/src/bsc_vty.c index e5cc3a871..97093016e 100644 --- a/openbsc/src/bsc_vty.c +++ b/openbsc/src/bsc_vty.c @@ -488,6 +488,16 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts) if (bts->paging.free_chans_need >= 0) 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) { + 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); + } + } + config_write_bts_gprs(vty, bts); llist_for_each_entry(trx, &bts->trx_list, list) @@ -2116,6 +2126,50 @@ DEFUN(cfg_bts_si_static, cfg_bts_si_static_cmd, return CMD_SUCCESS; } +DEFUN(cfg_bts_neigh_mode, cfg_bts_neigh_mode_cmd, + "neighbor-list mode (automatic|manual)", + "Neighbor List\n" "Mode of Neighbor List generation\n" + "Automatically from all BTS in this OpenBSC\n" "Manual\n") +{ + struct gsm_bts *bts = vty->index; + + if (!strcmp(argv[0], "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; + + return CMD_SUCCESS; +} + +DEFUN(cfg_bts_neigh, cfg_bts_neigh_cmd, + "neighbor-list (add|del) arfcn <0-1024>", + "Neighbor List\n" "Add to manual neighbor list\n" + "Delete from manual neighbor list\n" "ARFCN of neighbor\n" + "ARFCN of neighbor\n") +{ + struct gsm_bts *bts = vty->index; + struct bitvec *bv = &bts->si_common.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" @@ -2614,6 +2668,8 @@ int bsc_vty_init(void) install_element(BTS_NODE, &cfg_bts_pag_free_cmd); install_element(BTS_NODE, &cfg_bts_si_mode_cmd); 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_trx_cmd); install_node(&trx_node, dummy_config_write); diff --git a/openbsc/src/gsm_data.c b/openbsc/src/gsm_data.c index 705c10742..5ae525899 100644 --- a/openbsc/src/gsm_data.c +++ b/openbsc/src/gsm_data.c @@ -207,6 +207,8 @@ struct gsm_bts *gsm_bts_alloc(struct gsm_network *net, enum gsm_bts_type type, bts->num_trx = 0; INIT_LLIST_HEAD(&bts->trx_list); bts->ms_max_power = 15; /* dBm */ + + bts->neigh_list_manual_mode = 0; bts->si_common.cell_sel_par.cell_resel_hyst = 2; /* 4 dB */ bts->si_common.cell_sel_par.rxlev_acc_min = 0; bts->si_common.neigh_list.data = bts->si_common.data.neigh_list; diff --git a/openbsc/src/system_information.c b/openbsc/src/system_information.c index 4f31c6b5d..5079d81b7 100644 --- a/openbsc/src/system_information.c +++ b/openbsc/src/system_information.c @@ -207,11 +207,14 @@ static int generate_bcch_chan_list(u_int8_t *chan_list, struct gsm_bts *bts) /* Zero-initialize the bit-vector */ memset(bv->data, 0, bv->data_len); - /* 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) - continue; - bitvec_set_bit_pos(bv, cur_bts->c0->arfcn, 1); + /* Generate list of neighbor cells if we are in automatic mode */ + if (bts->neigh_list_manual_mode == 0) { + /* 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) + continue; + bitvec_set_bit_pos(bv, cur_bts->c0->arfcn, 1); + } } /* then we generate a GSM 04.08 frequency list from the bitvec */