bts: Add some simple dependency between different BTS

E.g. for the sysmoBTS2050 we have the requirement that the first
board connects before the second due clocking. The easiest point
to enforce this is the BSC. Add a simple bitmask based system to
allow to express dependencies for IP based systems.
This commit is contained in:
Holger Hans Peter Freyther 2014-12-17 14:46:17 +01:00
parent 27ca0436ac
commit c22930e24b
5 changed files with 136 additions and 0 deletions

View File

@ -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 */

View File

@ -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;
};

View File

@ -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);

View File

@ -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],

View File

@ -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;
}