aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gsm_data.h5
-rw-r--r--openbsc/include/openbsc/gsm_data_shared.h3
-rw-r--r--openbsc/src/libbsc/bsc_vty.c63
-rw-r--r--openbsc/src/libbsc/bts_ipaccess_nanobts.c7
-rw-r--r--openbsc/src/libcommon/gsm_data.c58
5 files changed, 136 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index e237ea2a6..89db48b05 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/gsm_data.h
@@ -436,4 +436,9 @@ extern const struct value_string bts_type_descs[_NUM_GSM_BTS_TYPE+1];
int bsc_base_ctrl_cmds_install(void);
int msc_ctrl_cmds_install(void);
+/* dependency handling */
+void bts_depend_mark(struct gsm_bts *bts, int dep);
+void bts_depend_clear(struct gsm_bts *bts, int dep);
+int bts_depend_check(struct gsm_bts *bts);
+
#endif /* _GSM_DATA_H */
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 001a526bf..5d84969ae 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -720,6 +720,9 @@ struct gsm_bts {
/* supported codecs beside FR */
struct bts_codec_conf codec;
+
+ /* BTS dependencies bit field */
+ uint32_t depends_on[256/(8*4)];
#endif /* ROLE_BSC */
void *role;
};
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 08f9a8e50..d6d66c638 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -650,6 +650,23 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
vty_out(vty, " %sforce-combined-si%s",
bts->force_combined_si ? "" : "no ", VTY_NEWLINE);
+ for (i = 0; i < ARRAY_SIZE(bts->depends_on); ++i) {
+ int j;
+
+ if (bts->depends_on[i] == 0)
+ continue;
+
+ for (j = 0; j < sizeof(bts->depends_on[i]) * 8; ++j) {
+ int bts_nr;
+
+ if ((bts->depends_on[i] & (1<<j)) == 0)
+ continue;
+
+ bts_nr = (i * sizeof(bts->depends_on[i]) * 8) + j;
+ vty_out(vty, " depends-on-bts %d%s", bts_nr, VTY_NEWLINE);
+ }
+ }
+
config_write_bts_model(vty, bts);
}
@@ -2772,6 +2789,50 @@ DEFUN(cfg_bts_codec4, cfg_bts_codec4_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_bts_depends_on, cfg_bts_depends_on_cmd,
+ "depends-on-bts <0-255>",
+ "This BTS can only be started if another one is up\n" "BTS Number\n")
+{
+ struct gsm_bts *bts = vty->index;
+ struct gsm_bts *other_bts;
+ int dep = atoi(argv[0]);
+
+
+ if (!is_ipaccess_bts(bts)) {
+ vty_out(vty, "This feature is only available for IP systems.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ other_bts = gsm_bts_num(bts->network, dep);
+ if (!other_bts || !is_ipaccess_bts(other_bts)) {
+ vty_out(vty, "This feature is only available for IP systems.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (dep >= bts->nr) {
+ vty_out(vty, "%%Need to depend on an already declared unit.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ bts_depend_mark(bts, dep);
+ return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_no_depends_on, cfg_bts_no_depends_on_cmd,
+ "depeneds-on-bts <0-255>",
+ NO_STR "This BTS can only be started if another one is up\n"
+ "BTS Number\n")
+{
+ struct gsm_bts *bts = vty->index;
+ int dep = atoi(argv[0]);
+
+ bts_depend_clear(bts, dep);
+ return CMD_SUCCESS;
+}
+
#define TRX_TEXT "Radio Transceiver\n"
/* per TRX configuration */
@@ -3383,6 +3444,8 @@ int bsc_vty_init(const struct log_info *cat)
install_element(BTS_NODE, &cfg_bts_codec2_cmd);
install_element(BTS_NODE, &cfg_bts_codec3_cmd);
install_element(BTS_NODE, &cfg_bts_codec4_cmd);
+ install_element(BTS_NODE, &cfg_bts_depends_on_cmd);
+ install_element(BTS_NODE, &cfg_bts_no_depends_on_cmd);
install_element(BTS_NODE, &cfg_trx_cmd);
install_node(&trx_node, dummy_config_write);
diff --git a/openbsc/src/libbsc/bts_ipaccess_nanobts.c b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
index 9fa03bfe6..825a22e2a 100644
--- a/openbsc/src/libbsc/bts_ipaccess_nanobts.c
+++ b/openbsc/src/libbsc/bts_ipaccess_nanobts.c
@@ -590,6 +590,13 @@ ipaccess_sign_link_up(void *unit_data, struct e1inp_line *line,
/* remove old OML signal link for this BTS. */
ipaccess_drop_oml(bts);
+ if (!bts_depend_check(bts)) {
+ LOGP(DLINP, LOGL_NOTICE,
+ "Dependency not full-filled for %u/%u/%u\n",
+ dev->site_id, dev->bts_id, dev->trx_id);
+ return NULL;
+ }
+
/* create new OML link. */
sign_link = bts->oml_link =
e1inp_sign_link_create(&line->ts[E1INP_SIGN_OML - 1],
diff --git a/openbsc/src/libcommon/gsm_data.c b/openbsc/src/libcommon/gsm_data.c
index 03e9b85e2..73041fcec 100644
--- a/openbsc/src/libcommon/gsm_data.c
+++ b/openbsc/src/libcommon/gsm_data.c
@@ -364,3 +364,61 @@ int gsm_parse_reg(void *ctx, regex_t *reg, char **str, int argc, const char **ar
return ret;
}
+/* Assume there are only 256 possible bts */
+osmo_static_assert(sizeof(((struct gsm_bts *) 0)->nr) == 1, _bts_nr_is_256);
+static void depends_calc_index_bit(int bts_nr, int *idx, int *bit)
+{
+ *idx = bts_nr / (8 * 4);
+ *bit = bts_nr % (8 * 4);
+}
+
+void bts_depend_mark(struct gsm_bts *bts, int dep)
+{
+ int idx, bit;
+ depends_calc_index_bit(dep, &idx, &bit);
+
+ bts->depends_on[idx] |= 1 << bit;
+}
+
+void bts_depend_clear(struct gsm_bts *bts, int dep)
+{
+ int idx, bit;
+ depends_calc_index_bit(dep, &idx, &bit);
+
+ bts->depends_on[idx] &= ~(1 << bit);
+}
+
+static int bts_depend_is_depedency(struct gsm_bts *base, struct gsm_bts *other)
+{
+ int idx, bit;
+ depends_calc_index_bit(other->nr, &idx, &bit);
+
+ /* Check if there is a depends bit */
+ return (base->depends_on[idx] & (1 << bit)) > 0;
+}
+
+static int bts_is_online(struct gsm_bts *bts)
+{
+ /* TODO: support E1 BTS too */
+ if (!is_ipaccess_bts(bts))
+ return 1;
+
+ if (!bts->oml_link)
+ return 0;
+
+ return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
+}
+
+int bts_depend_check(struct gsm_bts *bts)
+{
+ struct gsm_bts *other_bts;
+
+ llist_for_each_entry(other_bts, &bts->network->bts_list, list) {
+ if (!bts_depend_is_depedency(bts, other_bts))
+ continue;
+ if (bts_is_online(other_bts))
+ continue;
+ return 0;
+ }
+ return 1;
+}