aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-05-09 17:46:22 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-05-10 04:53:53 +0200
commit91aa68f762218906e45be4817c6ea54b480da5e1 (patch)
tree7d13ae5e8733aa0d6a342e51faa67967363dea1c
parent83e3280ebec77454a7ed6ddc66cb1cfdff036f45 (diff)
dyn TS: init only when both RSL and the Channel OM are established
Recent Icf6e25ff068e8a2600562d52726ead65e864ec02 changed the dyn_ts_init() hook from bootstrap_rsl() to the Channel OPSTART ACK, but this is not sufficient. Now RBS2k never calls dyn_ts_init(), and we may need to wait for RSL: Dyn TS should actually be initialized only when *both* OML opstart and RSL link are established. To that end, introduce a generalized API to query OML and RSL status and to trigger a timeslot init at the appropriate time. Add gsm_ts_check_init() to be called both when RSL and OML opstart are established: trigger gsm_ts_init() only when both are given. Add gsm_bts_trx_ts->initialized flag to mark whether initialization has already taken place. Add gsm_bts_mark_all_ts_uninitialized() to conveniently clear this flag for all TS in a BTS. Add gsm_bts_model.oml_is_ts_ready() callback so that each BTS implementation can return the OML status of a timeslot in its own OML implementation. Actually, currently all BTS models that need this init mechanism store the TS' OML status in ts->mo.nm_state. While we would in practice correctly init dyn TS by just looking at ts->mo.nm_state, semantically, the decision whether the TS is ready is up to the BTS models' specific OML implementations. From bootstrap_rsl(), call gsm_ts_check_init(), in case the TS OML Opstart has happened before RSL is established -- applies to all BTS models. For all BTS models: - call gsm_{bts,trx}_mark_all_ts_uninitialized() when OM is torn down, to make sure the TS init mechanism will work a second time. For all BTS models supporting dyn TS, i.e. osmo-bts, nanobts and RBS2k: - implement oml_is_ts_ready(). - call gsm_ts_check_init() when a Channel OM is taken into operation. Any BTS models that don't set oml_is_ts_ready() will see a ts init as soon as RSL is bootstrapped (incidentally, the old dyn TS behavior before recent Icf6e25ff068e8a2600562d52726ead65e864ec02). This firstly fixes dyn TS for RBS2k by re-adding the initial switch to PDCH, and furthermore does so only after both OML TS opstart and RSL are through. This fixes the ttcn3-bsc-tests around dyn TS, since for the osmo-bts-virtual, the RSL is established only after OML opstart on the TS, which was broken by Icf6e25ff068e8a2600562d52726ead65e864ec02. Nokia Site and Siemens BS11 practically do not require this init mechanism, since all that happens there so far is dyn TS init, and these BTS models do not support dyn TS of any kind. A future patch may add oml_is_ts_ready(). Related: OS#3205 Change-Id: I99f29d2ba079f6f4b77f0af12d9784588d2f56b3
-rw-r--r--include/osmocom/bsc/gsm_data.h7
-rw-r--r--src/libbsc/abis_om2000.c4
-rw-r--r--src/libbsc/abis_rsl.c37
-rw-r--r--src/libbsc/bsc_init.c4
-rw-r--r--src/libbsc/bts_ericsson_rbs2000.c8
-rw-r--r--src/libbsc/bts_ipaccess_nanobts.c10
-rw-r--r--src/libbsc/bts_nokia_site.c4
-rw-r--r--src/libbsc/bts_siemens_bs11.c2
8 files changed, 73 insertions, 3 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index f113904d7..29b97f0f3 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -459,6 +459,8 @@ enum {
/* One Timeslot in a TRX */
struct gsm_bts_trx_ts {
struct gsm_bts_trx *trx;
+ bool initialized;
+
/* number of this timeslot at the TRX */
uint8_t nr;
@@ -605,6 +607,7 @@ struct gsm_bts_model {
int (*start)(struct gsm_network *net);
int (*oml_rcvmsg)(struct msgb *msg);
char * (*oml_status)(const struct gsm_bts *bts);
+ bool (*oml_is_ts_ready)(const struct gsm_bts_trx_ts *ts);
void (*e1line_bind_ops)(struct e1inp_line *line);
@@ -1387,4 +1390,8 @@ void gsm_bts_set_radio_link_timeout(struct gsm_bts *bts, int value);
bool classmark_is_r99(struct gsm_classmark *cm);
+void gsm_ts_check_init(struct gsm_bts_trx_ts *ts);
+void gsm_trx_mark_all_ts_uninitialized(struct gsm_bts_trx *trx);
+void gsm_bts_mark_all_ts_uninitialized(struct gsm_bts *bts);
+
#endif /* _GSM_DATA_H */
diff --git a/src/libbsc/abis_om2000.c b/src/libbsc/abis_om2000.c
index 6057bc647..d533ea198 100644
--- a/src/libbsc/abis_om2000.c
+++ b/src/libbsc/abis_om2000.c
@@ -2737,8 +2737,10 @@ void abis_om2k_trx_init(struct gsm_bts_trx *trx)
bts->nr, 255, trx->nr);
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
- om2k_mo_init(&trx->ts[i].rbs2000.om2k_mo, OM2K_MO_CLS_TS,
+ struct gsm_bts_trx_ts *ts = &trx->ts[i];
+ om2k_mo_init(&ts->rbs2000.om2k_mo, OM2K_MO_CLS_TS,
bts->nr, trx->nr, i);
+ gsm_ts_check_init(ts);
}
}
diff --git a/src/libbsc/abis_rsl.c b/src/libbsc/abis_rsl.c
index b36e49687..e6d0cea96 100644
--- a/src/libbsc/abis_rsl.c
+++ b/src/libbsc/abis_rsl.c
@@ -3017,3 +3017,40 @@ int rsl_direct_rf_release(struct gsm_lchan *lchan)
/* Now release it */
return rsl_rf_chan_release(lchan, 0, SACCH_NONE);
}
+
+/* Initial timeslot actions when a timeslot first comes into operation. */
+static bool gsm_ts_init(struct gsm_bts_trx_ts *ts)
+{
+ dyn_ts_init(ts);
+ return true;
+}
+
+/* Trigger initial timeslot actions iff both OML and RSL are setup. */
+void gsm_ts_check_init(struct gsm_bts_trx_ts *ts)
+{
+ struct gsm_bts *bts = ts->trx->bts;
+ if (bts->model->oml_is_ts_ready
+ && !bts->model->oml_is_ts_ready(ts))
+ return;
+ if (!ts->trx->rsl_link)
+ return;
+ if (ts->initialized)
+ return;
+ ts->initialized = gsm_ts_init(ts);
+}
+
+void gsm_trx_mark_all_ts_uninitialized(struct gsm_bts_trx *trx)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[i];
+ ts->initialized = false;
+ }
+}
+
+void gsm_bts_mark_all_ts_uninitialized(struct gsm_bts *bts)
+{
+ struct gsm_bts_trx *trx;
+ llist_for_each_entry(trx, &bts->trx_list, list)
+ gsm_trx_mark_all_ts_uninitialized(trx);
+}
diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c
index 92b8c27ff..5b157c57f 100644
--- a/src/libbsc/bsc_init.c
+++ b/src/libbsc/bsc_init.c
@@ -353,7 +353,9 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
}
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
- generate_ma_for_ts(&trx->ts[i]);
+ struct gsm_bts_trx_ts *ts = &trx->ts[i];
+ generate_ma_for_ts(ts);
+ gsm_ts_check_init(ts);
}
}
diff --git a/src/libbsc/bts_ericsson_rbs2000.c b/src/libbsc/bts_ericsson_rbs2000.c
index 20b498a52..9c8b90ee2 100644
--- a/src/libbsc/bts_ericsson_rbs2000.c
+++ b/src/libbsc/bts_ericsson_rbs2000.c
@@ -52,6 +52,8 @@ static void bootstrap_om_trx(struct gsm_bts_trx *trx)
static int shutdown_om(struct gsm_bts *bts)
{
+ gsm_bts_mark_all_ts_uninitialized(bts);
+
/* FIXME */
return 0;
}
@@ -172,11 +174,17 @@ static void bts_model_rbs2k_e1line_bind_ops(struct e1inp_line *line)
e1inp_line_bind_ops(line, &bts_isdn_e1inp_line_ops);
}
+static bool bts_model_rbs2k_is_ts_ready(const struct gsm_bts_trx_ts *ts)
+{
+ return ts && ts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
+}
+
static struct gsm_bts_model model_rbs2k = {
.type = GSM_BTS_TYPE_RBS2000,
.name = "rbs2000",
.start = bts_model_rbs2k_start,
.oml_rcvmsg = &abis_om2k_rcvmsg,
+ .oml_is_ts_ready = bts_model_rbs2k_is_ts_ready,
.config_write_bts = &config_write_bts,
.e1line_bind_ops = &bts_model_rbs2k_e1line_bind_ops,
};
diff --git a/src/libbsc/bts_ipaccess_nanobts.c b/src/libbsc/bts_ipaccess_nanobts.c
index 3eb7e0e4d..d5b3b21af 100644
--- a/src/libbsc/bts_ipaccess_nanobts.c
+++ b/src/libbsc/bts_ipaccess_nanobts.c
@@ -56,12 +56,18 @@ static char *get_oml_status(const struct gsm_bts *bts)
return "disconnected";
}
+static bool oml_is_ts_ready(const struct gsm_bts_trx_ts *ts)
+{
+ return ts && ts->mo.nm_state.operational == NM_OPSTATE_ENABLED;
+}
+
struct gsm_bts_model bts_model_nanobts = {
.type = GSM_BTS_TYPE_NANOBTS,
.name = "nanobts",
.start = bts_model_nanobts_start,
.oml_rcvmsg = &abis_nm_rcvmsg,
.oml_status = &get_oml_status,
+ .oml_is_ts_ready = oml_is_ts_ready,
.e1line_bind_ops = bts_model_nanobts_e1line_bind_ops,
.nm_att_tlvdef = {
.def = {
@@ -320,7 +326,7 @@ static void nm_rx_opstart_ack_chan(struct abis_om_fom_hdr *foh)
return;
}
- dyn_ts_init(ts);
+ gsm_ts_check_init(ts);
}
static void nm_rx_opstart_ack(struct abis_om_fom_hdr *foh)
@@ -426,6 +432,8 @@ void ipaccess_drop_oml(struct gsm_bts *bts)
llist_for_each_entry(trx, &bts->trx_list, list)
ipaccess_drop_rsl(trx);
+ gsm_bts_mark_all_ts_uninitialized(bts);
+
bts->ip_access.flags = 0;
/*
diff --git a/src/libbsc/bts_nokia_site.c b/src/libbsc/bts_nokia_site.c
index 67281bbf1..4a24c3931 100644
--- a/src/libbsc/bts_nokia_site.c
+++ b/src/libbsc/bts_nokia_site.c
@@ -55,6 +55,8 @@ static void bootstrap_om_bts(struct gsm_bts *bts)
{
LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);
+ gsm_bts_mark_all_ts_uninitialized(bts);
+
if (!bts->nokia.skip_reset) {
if (!bts->nokia.did_reset)
abis_nm_reset(bts, 1);
@@ -66,6 +68,8 @@ static void bootstrap_om_trx(struct gsm_bts_trx *trx)
{
LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for TRX %u/%u\n",
trx->bts->nr, trx->nr);
+
+ gsm_trx_mark_all_ts_uninitialized(trx);
}
static int shutdown_om(struct gsm_bts *bts)
diff --git a/src/libbsc/bts_siemens_bs11.c b/src/libbsc/bts_siemens_bs11.c
index 5701e47a8..2d2351702 100644
--- a/src/libbsc/bts_siemens_bs11.c
+++ b/src/libbsc/bts_siemens_bs11.c
@@ -536,6 +536,8 @@ static int shutdown_om(struct gsm_bts *bts)
/* Reset BTS Site manager resource */
abis_nm_bs11_reset_resource(bts);
+ gsm_bts_mark_all_ts_uninitialized(bts);
+
return 0;
}