aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2020-09-25 18:55:55 +0200
committerlaforge <laforge@osmocom.org>2020-10-20 13:45:57 +0000
commit7810a917331b33b6cfab5259b5fb2df73b27b230 (patch)
treea463fa051fd97170f80f2aa4acf8d5c4ce61e56a
parentae6e3e8f8b2bd7b8235035fb324c373d61648cb5 (diff)
Introduce NM Radio Carrier and Baseband Transceiver FSMs
All the Operative State logic to manage a RadioCarrier//BBTransc NM objects is centralized in these FSM, where other parts of the code simply send events to it. This allows keeping state consistent and offloading logic from each bts backend, since they are only required to submit events now. The idea in the long run is to also replace other NM objects with similar FSMs. This improved logic fixes bug where PHY + RSL link became available before OPSTART and hence op state changed to Enabled before receiving any OPSTART message. Change-Id: Ifb249a821c4270918699b6375a72b3a618e8cfbe
-rw-r--r--include/osmo-bts/bts_trx.h12
-rw-r--r--include/osmo-bts/nm_common_fsm.h22
-rw-r--r--src/common/Makefile.am2
-rw-r--r--src/common/bts_trx.c42
-rw-r--r--src/common/nm_bb_transc_fsm.c211
-rw-r--r--src/common/nm_common_fsm.c5
-rw-r--r--src/common/nm_radio_carrier_fsm.c218
-rw-r--r--src/common/phy_link.c11
-rw-r--r--src/osmo-bts-litecell15/l1_if.c11
-rw-r--r--src/osmo-bts-litecell15/oml.c37
-rw-r--r--src/osmo-bts-oc2g/l1_if.c12
-rw-r--r--src/osmo-bts-oc2g/oml.c32
-rw-r--r--src/osmo-bts-octphy/l1_if.c14
-rw-r--r--src/osmo-bts-octphy/l1_oml.c33
-rw-r--r--src/osmo-bts-omldummy/bts_model.c23
-rw-r--r--src/osmo-bts-sysmo/l1_if.c11
-rw-r--r--src/osmo-bts-sysmo/oml.c37
-rw-r--r--src/osmo-bts-trx/l1_if.c36
-rw-r--r--src/osmo-bts-virtual/bts_model.c23
19 files changed, 632 insertions, 160 deletions
diff --git a/include/osmo-bts/bts_trx.h b/include/osmo-bts/bts_trx.h
index ce2d4d4a..08eaf659 100644
--- a/include/osmo-bts/bts_trx.h
+++ b/include/osmo-bts/bts_trx.h
@@ -2,6 +2,10 @@
#include <osmo-bts/gsm_data.h>
+struct gsm_bts_bb_trx {
+ struct gsm_abis_mo mo;
+};
+
/* One TRX in a BTS */
struct gsm_bts_trx {
/* list header in bts->trx_list */
@@ -16,10 +20,9 @@ struct gsm_bts_trx {
uint8_t rsl_tei;
struct e1inp_sign_link *rsl_link;
+ /* NM Radio Carrier and Baseband Transciever */
struct gsm_abis_mo mo;
- struct {
- struct gsm_abis_mo mo;
- } bb_transc;
+ struct gsm_bts_bb_trx bb_transc;
uint16_t arfcn;
int nominal_power; /* in dBm */
@@ -45,6 +48,9 @@ struct gsm_bts_trx {
struct gsm_bts_trx_ts ts[TRX_NR_TS];
};
+static inline struct gsm_bts_trx *gsm_bts_bb_trx_get_trx(struct gsm_bts_bb_trx *bb_transc) {
+ return (struct gsm_bts_trx *)container_of(bb_transc, struct gsm_bts_trx, bb_transc);
+}
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts);
int bts_trx_init(struct gsm_bts_trx *trx);
diff --git a/include/osmo-bts/nm_common_fsm.h b/include/osmo-bts/nm_common_fsm.h
index 93e4bde3..46717250 100644
--- a/include/osmo-bts/nm_common_fsm.h
+++ b/include/osmo-bts/nm_common_fsm.h
@@ -31,6 +31,12 @@ enum nm_fsm_events {
NM_EV_SW_ACT,
NM_EV_OPSTART_ACK,
NM_EV_OPSTART_NACK,
+ NM_EV_RSL_UP, /* RadioCarrier and BaseBand Transceiver only */
+ NM_EV_RSL_DOWN, /* RadioCarrier and BaseBand Transceiver only */
+ NM_EV_PHYLINK_UP, /* RadioCarrier and BaseBand Transceiver only */
+ NM_EV_PHYLINK_DOWN, /* RadioCarrier and BaseBand Transceiver only */
+ NM_EV_DISABLE, /* RadioCarrier and BaseBand Transceiver only */
+
};
extern const struct value_string nm_fsm_event_names[];
@@ -50,3 +56,19 @@ enum nm_bts_op_fsm_states {
NM_BTS_ST_OP_ENABLED,
};
extern struct osmo_fsm nm_bts_fsm;
+
+/* BaseBand Transceiver */
+enum nm_bb_transc_op_fsm_states {
+ NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED,
+ NM_BBTRANSC_ST_OP_DISABLED_OFFLINE,
+ NM_BBTRANSC_ST_OP_ENABLED,
+};
+extern struct osmo_fsm nm_bb_transc_fsm;
+
+/* Radio Carrier */
+enum nm_rcarrier_op_fsm_states {
+ NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED,
+ NM_RCARRIER_ST_OP_DISABLED_OFFLINE,
+ NM_RCARRIER_ST_OP_ENABLED,
+};
+extern struct osmo_fsm nm_rcarrier_fsm;
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 463797ef..71567857 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -40,6 +40,8 @@ libbts_a_SOURCES = \
nm_common_fsm.c \
nm_bts_sm_fsm.c \
nm_bts_fsm.c \
+ nm_bb_transc_fsm.c \
+ nm_radio_carrier_fsm.c \
$(NULL)
libl1sched_a_SOURCES = scheduler.c
diff --git a/src/common/bts_trx.c b/src/common/bts_trx.c
index 93e15c32..04c21c34 100644
--- a/src/common/bts_trx.c
+++ b/src/common/bts_trx.c
@@ -17,6 +17,8 @@
*
*/
+#include <osmocom/core/fsm.h>
+
#include <osmocom/gsm/abis_nm.h>
#include <osmo-bts/logging.h>
@@ -26,6 +28,20 @@
#include <osmo-bts/bts_model.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/phy_link.h>
+#include <osmo-bts/nm_common_fsm.h>
+
+static int gsm_bts_trx_talloc_destructor(struct gsm_bts_trx *trx)
+{
+ if (trx->bb_transc.mo.fi) {
+ osmo_fsm_inst_free(trx->bb_transc.mo.fi);
+ trx->bb_transc.mo.fi = NULL;
+ }
+ if (trx->mo.fi) {
+ osmo_fsm_inst_free(trx->mo.fi);
+ trx->mo.fi = NULL;
+ }
+ return 0;
+}
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
{
@@ -35,12 +51,20 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
if (!trx)
return NULL;
+ talloc_set_destructor(trx, gsm_bts_trx_talloc_destructor);
+
trx->bts = bts;
trx->nr = bts->num_trx++;
+ trx->mo.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
+ LOGL_INFO, NULL);
+ osmo_fsm_inst_update_id_f(trx->mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
bts->nr, trx->nr, 0xff);
+ trx->bb_transc.mo.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, &trx->bb_transc,
+ LOGL_INFO, NULL);
+ osmo_fsm_inst_update_id_f(trx->bb_transc.mo.fi, "bts%d-trx%d", bts->nr, trx->nr);
gsm_mo_init(&trx->bb_transc.mo, bts, NM_OC_BASEB_TRANSC,
bts->nr, trx->nr, 0xff);
@@ -161,7 +185,7 @@ int trx_link_estab(struct gsm_bts_trx *trx)
LOGPTRX(trx, DSUM, LOGL_INFO, "RSL link %s\n",
link ? "up" : "down");
- trx_operability_update(trx);
+ osmo_fsm_inst_dispatch(trx->mo.fi, link ? NM_EV_RSL_UP : NM_EV_RSL_DOWN, NULL);
if (link)
rc = rsl_tx_rf_res(trx);
@@ -177,22 +201,6 @@ int trx_link_estab(struct gsm_bts_trx *trx)
return 0;
}
-/* set the availability of the TRX based on internal state (RSL + phy link) */
-void trx_operability_update(struct gsm_bts_trx *trx)
-{
- enum abis_nm_op_state op_st;
- enum abis_nm_avail_state avail_st;
- struct phy_instance *pinst = trx_phy_instance(trx);
-
- op_st = (trx->rsl_link && phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED) ?
- NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED;
- avail_st = (op_st == NM_OPSTATE_ENABLED) ? NM_AVSTATE_OK : NM_AVSTATE_NOT_INSTALLED;
-
- LOGPTRX(trx, DSUM, LOGL_INFO, "Setting operative = %s\n", abis_nm_opstate_name(op_st));
- oml_mo_state_chg(&trx->mo, op_st, avail_st);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, avail_st);
-}
-
bool trx_ms_pwr_ctrl_is_osmo(const struct gsm_bts_trx *trx)
{
diff --git a/src/common/nm_bb_transc_fsm.c b/src/common/nm_bb_transc_fsm.c
new file mode 100644
index 00000000..b23ff531
--- /dev/null
+++ b/src/common/nm_bb_transc_fsm.c
@@ -0,0 +1,211 @@
+/* NM Radio Carrier FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
+
+#include <osmo-bts/logging.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_model.h>
+#include <osmo-bts/bts.h>
+#include <osmo-bts/rsl.h>
+#include <osmo-bts/nm_common_fsm.h>
+#include <osmo-bts/phy_link.h>
+
+#define X(s) (1 << (s))
+
+#define nm_bb_transc_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0)
+
+//////////////////////////
+// FSM STATE ACTIONS
+//////////////////////////
+
+static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
+ bb_transc->mo.opstart_success = false;
+ oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
+}
+
+static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
+
+ switch (event) {
+ case NM_EV_SW_ACT:
+ oml_mo_tx_sw_act_rep(&bb_transc->mo);
+ nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
+ return;
+ case NM_EV_RSL_UP:
+ return;
+ case NM_EV_RSL_DOWN:
+ return;
+ case NM_EV_PHYLINK_UP:
+ return;
+ case NM_EV_PHYLINK_DOWN:
+ return;
+ case NM_EV_DISABLE:
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
+static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
+ bb_transc->mo.opstart_success = false;
+ oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+}
+
+static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
+ struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc);
+ bool phy_state_connected;
+ bool rsl_link_connected;
+
+ switch (event) {
+ case NM_EV_OPSTART_ACK:
+ bb_transc->mo.opstart_success = true;
+ oml_mo_opstart_ack(&bb_transc->mo);
+ break; /* check statechg below */
+ case NM_EV_OPSTART_NACK:
+ bb_transc->mo.opstart_success = false;
+ oml_mo_opstart_nack(&bb_transc->mo, (int)(intptr_t)data);
+ return;
+ case NM_EV_RSL_UP:
+ break; /* check statechg below */
+ case NM_EV_RSL_DOWN:
+ return;
+ case NM_EV_PHYLINK_UP:
+ break; /* check statechg below */
+ case NM_EV_PHYLINK_DOWN:
+ return;
+ case NM_EV_DISABLE:
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+
+
+ if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
+ struct phy_instance *pinst = trx_phy_instance(trx);
+ phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
+ rsl_link_connected = !!trx->rsl_link;
+ } else {
+ phy_state_connected = true;
+ rsl_link_connected = true;
+ }
+
+ if (rsl_link_connected && phy_state_connected &&
+ bb_transc->mo.opstart_success) {
+ nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_ENABLED);
+ } else {
+ LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s\n",
+ rsl_link_connected ? "": " rsl",
+ phy_state_connected ? "": " phy",
+ bb_transc->mo.opstart_success ? "": " opstart");
+
+ }
+}
+
+static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv;
+ oml_mo_state_chg(&bb_transc->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
+}
+
+static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch (event) {
+ case NM_EV_RSL_DOWN:
+ break;
+ case NM_EV_PHYLINK_DOWN:
+ break;
+ case NM_EV_DISABLE:
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+
+ nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
+}
+
+static struct osmo_fsm_state nm_bb_transc_fsm_states[] = {
+ [NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED] = {
+ .in_event_mask =
+ X(NM_EV_SW_ACT) |
+ X(NM_EV_RSL_UP) |
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_UP) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE),
+ .name = "DISABLED_NOTINSTALLED",
+ .onenter = st_op_disabled_notinstalled_on_enter,
+ .action = st_op_disabled_notinstalled,
+ },
+ [NM_BBTRANSC_ST_OP_DISABLED_OFFLINE] = {
+ .in_event_mask =
+ X(NM_EV_OPSTART_ACK) |
+ X(NM_EV_OPSTART_NACK) |
+ X(NM_EV_RSL_UP) |
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_UP) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_BBTRANSC_ST_OP_ENABLED),
+ .name = "DISABLED_OFFLINE",
+ .onenter = st_op_disabled_offline_on_enter,
+ .action = st_op_disabled_offline,
+ },
+ [NM_BBTRANSC_ST_OP_ENABLED] = {
+ .in_event_mask =
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_BBTRANSC_ST_OP_DISABLED_OFFLINE),
+ .name = "ENABLED",
+ .onenter = st_op_enabled_on_enter,
+ .action = st_op_enabled,
+ },
+};
+
+struct osmo_fsm nm_bb_transc_fsm = {
+ .name = "NM_BBTRANSC_OP",
+ .states = nm_bb_transc_fsm_states,
+ .num_states = ARRAY_SIZE(nm_bb_transc_fsm_states),
+ .event_names = nm_fsm_event_names,
+ .log_subsys = DOML,
+};
+
+static __attribute__((constructor)) void nm_bb_transc_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&nm_bb_transc_fsm) == 0);
+}
diff --git a/src/common/nm_common_fsm.c b/src/common/nm_common_fsm.c
index 662a7602..88045699 100644
--- a/src/common/nm_common_fsm.c
+++ b/src/common/nm_common_fsm.c
@@ -27,5 +27,10 @@ const struct value_string nm_fsm_event_names[] = {
{ NM_EV_SW_ACT, "SW_ACT" },
{ NM_EV_OPSTART_ACK, "OPSTART_ACK" },
{ NM_EV_OPSTART_NACK, "OPSTART_NACK" },
+ { NM_EV_RSL_UP, "RSL_UP" },
+ { NM_EV_RSL_DOWN, "RSL_DOWN" },
+ { NM_EV_PHYLINK_UP, "PHYLINK_UP" },
+ { NM_EV_PHYLINK_DOWN, "PHYLINK_DOWN" },
+ { NM_EV_DISABLE, "DISABLE" },
{ 0, NULL }
};
diff --git a/src/common/nm_radio_carrier_fsm.c b/src/common/nm_radio_carrier_fsm.c
new file mode 100644
index 00000000..01849d1e
--- /dev/null
+++ b/src/common/nm_radio_carrier_fsm.c
@@ -0,0 +1,218 @@
+/* NM Radio Carrier FSM */
+
+/* (C) 2020 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <inttypes.h>
+
+#include <osmocom/core/fsm.h>
+#include <osmocom/core/tdef.h>
+#include <osmocom/gsm/protocol/gsm_12_21.h>
+
+#include <osmo-bts/logging.h>
+#include <osmo-bts/gsm_data.h>
+#include <osmo-bts/bts_model.h>
+#include <osmo-bts/bts.h>
+#include <osmo-bts/rsl.h>
+#include <osmo-bts/nm_common_fsm.h>
+#include <osmo-bts/phy_link.h>
+
+#define X(s) (1 << (s))
+
+#define nm_rcarrier_fsm_state_chg(fi, NEXT_STATE) \
+ osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0)
+
+//////////////////////////
+// FSM STATE ACTIONS
+//////////////////////////
+
+static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ trx->mo.opstart_success = false;
+ oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED);
+}
+
+static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv;
+
+ switch (event) {
+ case NM_EV_SW_ACT:
+ oml_mo_tx_sw_act_rep(&trx->mo);
+ nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_OFFLINE);
+ return;
+ case NM_EV_RSL_UP:
+ return;
+ case NM_EV_RSL_DOWN:
+ return;
+ case NM_EV_PHYLINK_UP:
+ return;
+ case NM_EV_PHYLINK_DOWN:
+ return;
+ case NM_EV_DISABLE:
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
+static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ trx->mo.opstart_success = false;
+ oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+}
+
+static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ bool phy_state_connected;
+ bool rsl_link_connected;
+
+ switch (event) {
+ case NM_EV_OPSTART_ACK:
+ trx->mo.opstart_success = true;
+ oml_mo_opstart_ack(&trx->mo);
+ break; /* check statechg below */
+ case NM_EV_OPSTART_NACK:
+ trx->mo.opstart_success = false;
+ oml_mo_opstart_nack(&trx->mo, (int)(intptr_t)data);
+ return;
+ case NM_EV_RSL_UP:
+ break; /* check statechg below */
+ case NM_EV_RSL_DOWN:
+ return;
+ case NM_EV_PHYLINK_UP:
+ break; /* check statechg below */
+ case NM_EV_PHYLINK_DOWN:
+ return;
+ case NM_EV_DISABLE:
+ return;
+ default:
+ OSMO_ASSERT(0);
+ }
+
+ if (trx->bts->variant != BTS_OSMO_OMLDUMMY) { /* In OMLDUMMY, phy=NULL */
+ struct phy_instance *pinst = trx_phy_instance(trx);
+ phy_state_connected = phy_link_state_get(pinst->phy_link) == PHY_LINK_CONNECTED;
+ rsl_link_connected = !!trx->rsl_link;
+ } else {
+ phy_state_connected = true;
+ rsl_link_connected = true;
+ }
+
+ if (rsl_link_connected && phy_state_connected &&
+ trx->mo.opstart_success) {
+ nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_ENABLED);
+ } else {
+ LOGPFSML(fi, LOGL_INFO, "Delay switch to operative state Enabled, wait for:%s%s%s\n",
+ rsl_link_connected ? "": " rsl",
+ phy_state_connected ? "": " phy",
+ trx->mo.opstart_success ? "": " opstart");
+
+ }
+}
+
+static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
+{
+ struct gsm_bts_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ uint8_t tn;
+ oml_mo_state_chg(&trx->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
+
+ /* Mark Dependency TS as Offline (ready to be Opstarted) */
+ for (tn = 0; tn < TRX_NR_TS; tn++) {
+ if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
+ trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
+ oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+ }
+ }
+}
+
+static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch (event) {
+ case NM_EV_RSL_DOWN:
+ break;
+ case NM_EV_PHYLINK_DOWN:
+ break;
+ case NM_EV_DISABLE:
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+
+ nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_OFFLINE);
+}
+
+static struct osmo_fsm_state nm_rcarrier_fsm_states[] = {
+ [NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED] = {
+ .in_event_mask =
+ X(NM_EV_SW_ACT) |
+ X(NM_EV_RSL_UP) |
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_UP) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_RCARRIER_ST_OP_DISABLED_OFFLINE),
+ .name = "DISABLED_NOTINSTALLED",
+ .onenter = st_op_disabled_notinstalled_on_enter,
+ .action = st_op_disabled_notinstalled,
+ },
+ [NM_RCARRIER_ST_OP_DISABLED_OFFLINE] = {
+ .in_event_mask =
+ X(NM_EV_OPSTART_ACK) |
+ X(NM_EV_OPSTART_NACK) |
+ X(NM_EV_RSL_UP) |
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_UP) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_RCARRIER_ST_OP_ENABLED),
+ .name = "DISABLED_OFFLINE",
+ .onenter = st_op_disabled_offline_on_enter,
+ .action = st_op_disabled_offline,
+ },
+ [NM_RCARRIER_ST_OP_ENABLED] = {
+ .in_event_mask =
+ X(NM_EV_RSL_DOWN) |
+ X(NM_EV_PHYLINK_DOWN),
+ .out_state_mask =
+ X(NM_RCARRIER_ST_OP_DISABLED_OFFLINE),
+ .name = "ENABLED",
+ .onenter = st_op_enabled_on_enter,
+ .action = st_op_enabled,
+ },
+};
+
+struct osmo_fsm nm_rcarrier_fsm = {
+ .name = "NM_RCARRIER_OP",
+ .states = nm_rcarrier_fsm_states,
+ .num_states = ARRAY_SIZE(nm_rcarrier_fsm_states),
+ .event_names = nm_fsm_event_names,
+ .log_subsys = DOML,
+};
+
+static __attribute__((constructor)) void nm_rcarrier_fsm_init(void)
+{
+ OSMO_ASSERT(osmo_fsm_register(&nm_rcarrier_fsm) == 0);
+}
diff --git a/src/common/phy_link.c b/src/common/phy_link.c
index 48ba283e..77d7aa62 100644
--- a/src/common/phy_link.c
+++ b/src/common/phy_link.c
@@ -2,6 +2,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/talloc.h>
+#include <osmocom/core/fsm.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/gsm_data.h>
@@ -9,6 +10,7 @@
#include <osmo-bts/oml.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/bts_model.h>
+#include <osmo-bts/nm_common_fsm.h>
static LLIST_HEAD(g_phy_links);
@@ -65,7 +67,14 @@ void phy_link_state_set(struct phy_link *plink, enum phy_link_state state)
if (!trx)
continue;
- trx_operability_update(trx);
+ osmo_fsm_inst_dispatch(trx->mo.fi,
+ state == PHY_LINK_CONNECTED ? NM_EV_PHYLINK_UP :
+ NM_EV_PHYLINK_DOWN,
+ NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi,
+ state == PHY_LINK_CONNECTED ? NM_EV_PHYLINK_UP :
+ NM_EV_PHYLINK_DOWN,
+ NULL);
}
}
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 23f7c3d5..94fd1653 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -54,6 +54,7 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
+#include <osmo-bts/nm_common_fsm.h>
#include <nrw/litecell15/litecell15.h>
#include <nrw/litecell15/gsml1prim.h>
@@ -1270,18 +1271,16 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
}
/* signal availability */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
} else {
if (bts_lc15->led_ctrl_mode == LC15_LED_CONTROL_BTS)
bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
}
msgb_free(resp);
diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c
index 03f787b0..d8109877 100644
--- a/src/osmo-bts-litecell15/oml.c
+++ b/src/osmo-bts-litecell15/oml.c
@@ -26,6 +26,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/fsm.h>
#include <nrw/litecell15/gsml1prim.h>
#include <nrw/litecell15/gsml1const.h>
@@ -270,31 +271,28 @@ static int opstart_compl(struct gsm_abis_mo *mo, struct msgb *l1_msg)
GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
GsmL1_Status_t status = prim_status(l1p);
struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
- uint8_t tn;
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx %s, status: %s\n",
get_value_string(lc15bts_l1prim_names, l1p->id),
get_value_string(lc15bts_l1status_names, status));
msgb_free(l1_msg);
- return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ (void*)(intptr_t)NM_NACK_CANT_PERFORM);
+ else
+ return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
}
msgb_free(l1_msg);
+ /* We already have a FSM for Radio Carrier, handle it there */
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+
/* Set to Operational State: Enabled */
oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- if (mo->obj_class == NM_OC_RADIO_CARRIER) {
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- }
-
/* ugly hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */
if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 &&
mo->obj_inst.ts_nr == 0) {
@@ -403,8 +401,9 @@ static int trx_init(struct gsm_bts_trx *trx)
ARRAY_SIZE(trx_rqd_attr))) {
/* HACK: spec says we need to decline, but openbsc
* doesn't deal with this very well */
- return oml_mo_opstart_ack(&trx->mo);
- //return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM);
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
/* Update TRX band */
@@ -1885,6 +1884,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj)
{
+ struct gsm_bts_bb_trx *bb_transc;
+ struct gsm_bts_trx *trx;
int rc;
switch (mo->obj_class) {
@@ -1895,12 +1896,16 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_RADIO_CARRIER:
- rc = trx_init(obj);
+ trx = (struct gsm_bts_trx *) obj;
+ rc = trx_init(trx);
+ break;
+ case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_CHANNEL:
rc = ts_opstart(obj);
break;
- case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-oc2g/l1_if.c b/src/osmo-bts-oc2g/l1_if.c
index 8e486744..4044f43d 100644
--- a/src/osmo-bts-oc2g/l1_if.c
+++ b/src/osmo-bts-oc2g/l1_if.c
@@ -37,6 +37,7 @@
#include <osmocom/core/select.h>
#include <osmocom/core/timer.h>
#include <osmocom/core/write_queue.h>
+#include <osmocom/core/fsm.h>
#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/lapdm.h>
@@ -55,6 +56,7 @@
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/cbch.h>
+#include <osmo-bts/nm_common_fsm.h>
#include <nrw/oc2g/oc2g.h>
#include <nrw/oc2g/gsml1prim.h>
@@ -1324,17 +1326,15 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
/* signal availability */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
} else {
bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
}
msgb_free(resp);
diff --git a/src/osmo-bts-oc2g/oml.c b/src/osmo-bts-oc2g/oml.c
index 15513d11..2efa577b 100644
--- a/src/osmo-bts-oc2g/oml.c
+++ b/src/osmo-bts-oc2g/oml.c
@@ -26,6 +26,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/fsm.h>
#include <nrw/oc2g/gsml1prim.h>
#include <nrw/oc2g/gsml1const.h>
@@ -270,31 +271,28 @@ static int opstart_compl(struct gsm_abis_mo *mo, struct msgb *l1_msg)
GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
GsmL1_Status_t status = prim_status(l1p);
struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
- uint8_t tn;
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx %s, status: %s\n",
get_value_string(oc2gbts_l1prim_names, l1p->id),
get_value_string(oc2gbts_l1status_names, status));
msgb_free(l1_msg);
- return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ (void*)(intptr_t)NM_NACK_CANT_PERFORM);
+ else
+ return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
}
msgb_free(l1_msg);
+ /* We already have a FSM for Radio Carrier, handle it there */
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+
/* Set to Operational State: Enabled */
oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- if (mo->obj_class == NM_OC_RADIO_CARRIER) {
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- }
-
/* ugly hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */
if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 &&
mo->obj_inst.ts_nr == 0) {
@@ -1894,6 +1892,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj)
{
+ struct gsm_bts_bb_trx *bb_transc;
+ struct gsm_bts_trx* trx;
int rc;
switch (mo->obj_class) {
@@ -1908,12 +1908,16 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK);
break;
case NM_OC_RADIO_CARRIER:
- rc = trx_init(obj);
+ trx = (struct gsm_bts_trx *) obj;
+ rc = trx_init(trx);
+ break;
+ case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_CHANNEL:
rc = ts_opstart(obj);
break;
- case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-octphy/l1_if.c b/src/osmo-bts-octphy/l1_if.c
index f20f21a5..c7e0b429 100644
--- a/src/osmo-bts-octphy/l1_if.c
+++ b/src/osmo-bts-octphy/l1_if.c
@@ -36,6 +36,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/socket.h>
+#include <osmocom/core/fsm.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/bts_model.h>
@@ -44,6 +45,7 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/handover.h>
#include <osmo-bts/bts.h>
+#include <osmo-bts/nm_common_fsm.h>
#include "l1_if.h"
#include "l1_oml.h"
@@ -311,19 +313,15 @@ int l1if_activate_rf(struct gsm_bts_trx *trx, int on)
int i;
if (on) {
/* signal availability */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED,
NM_AVSTATE_DEPENDENCY);
} else {
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED,
- NM_AVSTATE_OFF_LINE);
- oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED,
- NM_AVSTATE_OFF_LINE);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
}
return 0;
diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c
index 2062be3c..a72367c4 100644
--- a/src/osmo-bts-octphy/l1_oml.c
+++ b/src/osmo-bts-octphy/l1_oml.c
@@ -28,6 +28,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/fsm.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/logging.h>
@@ -187,22 +188,15 @@ extern uint8_t rach_detected_Other_g;
static int opstart_compl(struct gsm_abis_mo *mo)
{
struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
- uint8_t tn;
/* TODO: Send NACK in case of error! */
+ /* We already have a FSM for Radio Carrier, handle it there */
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+
/* Set to Operational State: Enabled */
oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- if (mo->obj_class == NM_OC_RADIO_CARRIER) {
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- }
-
/* hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */
if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 &&
mo->obj_inst.ts_nr == 7) {
@@ -1450,8 +1444,9 @@ static int trx_init(struct gsm_bts_trx *trx)
ARRAY_SIZE(trx_rqd_attr))) {
/* HACK: spec says we need to decline, but openbsc
* doesn't deal with this very well */
- return oml_mo_opstart_ack(&trx->mo);
- /* return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM); */
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
l1if_check_app_version(trx);
@@ -1763,8 +1758,10 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
/* callback from OML */
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
{
- int rc = -1;
+ struct gsm_bts_bb_trx *bb_transc;
+ struct gsm_bts_trx* trx;
struct gsm_bts_trx_ts *ts;
+ int rc;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -1774,13 +1771,17 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
rc = osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_RADIO_CARRIER:
- rc = trx_init(obj);
+ trx = (struct gsm_bts_trx*) obj;
+ rc = trx_init(trx);
+ break;
+ case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_CHANNEL:
ts = (struct gsm_bts_trx_ts*) obj;
rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL);
break;
- case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-omldummy/bts_model.c b/src/osmo-bts-omldummy/bts_model.c
index ad007ec5..06e13735 100644
--- a/src/osmo-bts-omldummy/bts_model.c
+++ b/src/osmo-bts-omldummy/bts_model.c
@@ -23,6 +23,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/codec/codec.h>
+#include <osmocom/core/fsm.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/phy_link.h>
@@ -75,15 +76,13 @@ static uint8_t vbts_set_bts(struct gsm_bts *bts)
uint8_t tn;
llist_for_each_entry(trx, &bts->trx_list, list) {
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
for (tn = 0; tn < TRX_NR_TS; tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
/* report availability of trx to the bts. this will trigger the rsl connection */
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
}
return 0;
}
@@ -123,8 +122,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
{
int rc;
+ struct gsm_bts_bb_trx *bb_transc;
struct gsm_bts_trx* trx;
- uint8_t tn;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -135,18 +134,12 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
break;
case NM_OC_RADIO_CARRIER:
trx = (struct gsm_bts_trx*) obj;
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- rc = oml_mo_opstart_ack(mo);
+ rc = osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
- case NM_OC_CHANNEL:
case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c
index 2e5e5b67..4d228bb6 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -51,6 +51,7 @@
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/tx_power.h>
+#include <osmo-bts/nm_common_fsm.h>
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1prim.h>
@@ -1240,17 +1241,15 @@ static int activate_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
bts_update_status(BTS_STATUS_RF_ACTIVE, 1);
/* signal availability */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
for (i = 0; i < ARRAY_SIZE(trx->ts); i++)
oml_mo_state_chg(&trx->ts[i].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
} else {
bts_update_status(BTS_STATUS_RF_ACTIVE, 0);
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
}
msgb_free(resp);
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index 7d9aa2aa..9a82647e 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -23,6 +23,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
+#include <osmocom/core/fsm.h>
#include <sysmocom/femtobts/gsml1prim.h>
#include <sysmocom/femtobts/gsml1const.h>
@@ -269,31 +270,28 @@ static int opstart_compl(struct gsm_abis_mo *mo, struct msgb *l1_msg)
GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg);
GsmL1_Status_t status = prim_status(l1p);
struct gsm_bts_trx *trx = gsm_bts_trx_num(mo->bts, mo->obj_inst.trx_nr);
- uint8_t tn;
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx %s, status: %s\n",
get_value_string(femtobts_l1prim_names, l1p->id),
get_value_string(femtobts_l1status_names, status));
msgb_free(l1_msg);
- return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ (void*)(intptr_t)NM_NACK_CANT_PERFORM);
+ else
+ return oml_mo_opstart_nack(mo, NM_NACK_CANT_PERFORM);
}
msgb_free(l1_msg);
+ /* We already have a FSM for Radio Carrier, handle it there */
+ if (mo->obj_class == NM_OC_RADIO_CARRIER)
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+
/* Set to Operational State: Enabled */
oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- if (mo->obj_class == NM_OC_RADIO_CARRIER) {
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- }
-
/* ugly hack to auto-activate all SAPIs for the BCCH/CCCH on TS0 */
if (mo->obj_class == NM_OC_CHANNEL && mo->obj_inst.trx_nr == 0 &&
mo->obj_inst.ts_nr == 0) {
@@ -407,8 +405,9 @@ static int trx_init(struct gsm_bts_trx *trx)
ARRAY_SIZE(trx_rqd_attr))) {
/* HACK: spec says we need to decline, but openbsc
* doesn't deal with this very well */
- return oml_mo_opstart_ack(&trx->mo);
- //return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM);
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
femto_band = sysmobts_select_femto_band(trx, trx->arfcn);
@@ -1771,6 +1770,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj)
{
+ struct gsm_bts_bb_trx *bb_transc;
+ struct gsm_bts_trx* trx;
int rc;
switch (mo->obj_class) {
@@ -1785,12 +1786,16 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
oml_mo_state_chg(&bts->gprs.nsvc[0].mo, -1, NM_AVSTATE_OK);
break;
case NM_OC_RADIO_CARRIER:
- rc = trx_init(obj);
+ trx = (struct gsm_bts_trx *) obj;
+ rc = trx_init(trx);
+ break;
+ case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
case NM_OC_CHANNEL:
rc = ts_opstart(obj);
break;
- case NM_OC_BASEB_TRANSC:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c
index 916f6a27..9c8069a3 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -97,11 +97,9 @@ static void check_transceiver_availability_trx(struct trx_l1h *l1h, int avail)
* transceiver */
if (avail) {
/* signal availability */
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
if (!pinst->u.osmotrx.sw_act_reported) {
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
pinst->u.osmotrx.sw_act_reported = true;
}
@@ -111,10 +109,8 @@ static void check_transceiver_availability_trx(struct trx_l1h *l1h, int avail)
NM_AVSTATE_DEPENDENCY :
NM_AVSTATE_NOT_INSTALLED);
} else {
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED,
- NM_AVSTATE_OFF_LINE);
- oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_DISABLED,
- NM_AVSTATE_OFF_LINE);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_DISABLE, NULL);
for (tn = 0; tn < TRX_NR_TS; tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED,
@@ -200,25 +196,17 @@ static int trx_init(struct gsm_bts_trx *trx)
struct phy_instance *pinst = trx_phy_instance(trx);
struct trx_l1h *l1h = pinst->u.osmotrx.hdl;
int rc;
- uint8_t tn;
rc = osmo_fsm_inst_dispatch(l1h->provision_fi, TRX_PROV_EV_CFG_ENABLE, (void*)(intptr_t)true);
if (rc != 0)
- return oml_mo_opstart_nack(&trx->mo, NM_NACK_CANT_PERFORM);
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_NACK,
+ (void*)(intptr_t)NM_NACK_CANT_PERFORM);
if (trx == trx->bts->c0)
lchan_init_lapdm(&trx->ts[0].lchan[CCCH_LCHAN]);
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
-
/* Send OPSTART ack */
- return oml_mo_opstart_ack(&trx->mo);
+ return osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
}
/* Deact RF on transceiver */
@@ -614,6 +602,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
void *obj)
{
+ struct gsm_bts_bb_trx *bb_transc;
+ struct gsm_bts_trx *trx;
int rc;
switch (mo->obj_class) {
@@ -625,10 +615,14 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
break;
case NM_OC_RADIO_CARRIER:
/* activate transceiver */
- rc = trx_init(obj);
+ trx = (struct gsm_bts_trx *) obj;
+ rc = trx_init(trx);
break;
- case NM_OC_CHANNEL:
case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ break;
+ case NM_OC_CHANNEL:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c
index 9ba632c7..c3a75f4c 100644
--- a/src/osmo-bts-virtual/bts_model.c
+++ b/src/osmo-bts-virtual/bts_model.c
@@ -23,6 +23,7 @@
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/codec/codec.h>
+#include <osmocom/core/fsm.h>
#include <osmo-bts/gsm_data.h>
#include <osmo-bts/phy_link.h>
@@ -85,15 +86,13 @@ static uint8_t vbts_set_bts(struct gsm_bts *bts)
uint8_t tn;
llist_for_each_entry(trx, &bts->trx_list, list) {
- oml_mo_state_chg(&trx->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OK);
- oml_mo_state_chg(&trx->bb_transc.mo, -1, NM_AVSTATE_OK);
for (tn = 0; tn < TRX_NR_TS; tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY);
/* report availability of trx to the bts. this will trigger the rsl connection */
- oml_mo_tx_sw_act_rep(&trx->mo);
- oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_SW_ACT, NULL);
}
return 0;
}
@@ -140,8 +139,8 @@ int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
{
int rc;
+ struct gsm_bts_bb_trx *bb_transc;
struct gsm_bts_trx* trx;
- uint8_t tn;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -152,18 +151,12 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
break;
case NM_OC_RADIO_CARRIER:
trx = (struct gsm_bts_trx*) obj;
- /* Mark Dependency TS as Offline (ready to be Opstarted) */
- for (tn = 0; tn < TRX_NR_TS; tn++) {
- if (trx->ts[tn].mo.nm_state.operational == NM_OPSTATE_DISABLED &&
- trx->ts[tn].mo.nm_state.availability == NM_AVSTATE_DEPENDENCY) {
- oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE);
- }
- }
- oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK);
- rc = oml_mo_opstart_ack(mo);
+ rc = osmo_fsm_inst_dispatch(trx->mo.fi, NM_EV_OPSTART_ACK, NULL);
break;
- case NM_OC_CHANNEL:
case NM_OC_BASEB_TRANSC:
+ bb_transc = (struct gsm_bts_bb_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(bb_transc->mo.fi, NM_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC: