aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-01-11 23:44:56 +0100
committerHarald Welte <laforge@gnumonks.org>2011-01-11 23:48:52 +0100
commit32c0962b100b5dd066b1a55e584baadd22fbe443 (patch)
treeac236f5c5d4119e59d16371cb338e6ed8ef33391
parent9b5f1d7b4399932ac83c0f1f14b192a25db8cf53 (diff)
[BSC] Allow manual override of neighbor cell list
So far, OpenBSC simply assumed that all BTS's configured in openbsc.cfg are neighbors of each other. While this is true for small site installations, it is definitely not true in most real world cases. We now have the following new commands at the 'configure bts' level: 'neighbor-list mode (auto|manual)' for selecting the mode 'neighbor-list (add|del) arfcn <0-1024>' for adding/deleting ARFCN in manual mode
-rw-r--r--openbsc/include/openbsc/gsm_data.h1
-rw-r--r--openbsc/src/bsc_vty.c56
-rw-r--r--openbsc/src/gsm_data.c2
-rw-r--r--openbsc/src/system_information.c13
4 files changed, 67 insertions, 5 deletions
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 */