aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/Makefile.am2
-rw-r--r--include/osmo-bts/bts_trx.h21
-rw-r--r--include/osmo-bts/nm_bb_transc_fsm.h45
-rw-r--r--include/osmo-bts/nm_radio_carrier_fsm.h45
-rw-r--r--src/common/Makefile.am2
-rw-r--r--src/common/bts.c2
-rw-r--r--src/common/bts_shutdown_fsm.c6
-rw-r--r--src/common/bts_trx.c30
-rw-r--r--src/common/l1sap.c2
-rw-r--r--src/common/nm_bb_transc_fsm.c222
-rw-r--r--src/common/nm_radio_carrier_fsm.c230
-rw-r--r--src/common/oml.c22
-rw-r--r--src/common/pcu_sock.c10
-rw-r--r--src/common/phy_link.c12
-rw-r--r--src/common/rsl.c4
-rw-r--r--src/common/vty.c2
-rw-r--r--src/osmo-bts-litecell15/l1_if.c18
-rw-r--r--src/osmo-bts-litecell15/oml.c44
-rw-r--r--src/osmo-bts-oc2g/calib_file.c6
-rw-r--r--src/osmo-bts-oc2g/l1_if.c21
-rw-r--r--src/osmo-bts-oc2g/oml.c43
-rw-r--r--src/osmo-bts-octphy/l1_if.c15
-rw-r--r--src/osmo-bts-octphy/l1_oml.c38
-rw-r--r--src/osmo-bts-omldummy/bts_model.c24
-rw-r--r--src/osmo-bts-sysmo/l1_if.c18
-rw-r--r--src/osmo-bts-sysmo/oml.c44
-rw-r--r--src/osmo-bts-trx/l1_if.c45
-rw-r--r--src/osmo-bts-trx/trx_provision_fsm.c4
-rw-r--r--src/osmo-bts-virtual/bts_model.c24
29 files changed, 783 insertions, 218 deletions
diff --git a/include/osmo-bts/Makefile.am b/include/osmo-bts/Makefile.am
index 8179f1ad..8f5a4517 100644
--- a/include/osmo-bts/Makefile.am
+++ b/include/osmo-bts/Makefile.am
@@ -29,4 +29,6 @@ noinst_HEADERS = \
ta_control.h \
nm_bts_sm_fsm.h \
nm_bts_fsm.h \
+ nm_bb_transc_fsm.h \
+ nm_radio_carrier_fsm.h \
$(NULL)
diff --git a/include/osmo-bts/bts_trx.h b/include/osmo-bts/bts_trx.h
index ce2d4d4a..aed2e734 100644
--- a/include/osmo-bts/bts_trx.h
+++ b/include/osmo-bts/bts_trx.h
@@ -2,6 +2,20 @@
#include <osmo-bts/gsm_data.h>
+struct nm_rcarrier {
+ /* NM Radio Carrier FSM */
+ struct osmo_fsm_inst *fi;
+ bool opstart_success; /* OPSTART went OK in lower layers and was acked */
+ struct gsm_abis_mo mo;
+};
+
+struct nm_bb_transc {
+ /* NM Baseband Transciever FSM */
+ struct osmo_fsm_inst *fi;
+ bool opstart_success; /* OPSTART went OK in lower layers and was acked */
+ struct gsm_abis_mo mo;
+};
+
/* One TRX in a BTS */
struct gsm_bts_trx {
/* list header in bts->trx_list */
@@ -16,10 +30,9 @@ struct gsm_bts_trx {
uint8_t rsl_tei;
struct e1inp_sign_link *rsl_link;
- struct gsm_abis_mo mo;
- struct {
- struct gsm_abis_mo mo;
- } bb_transc;
+ /* NM Radio Carrier and Baseband Transciever */
+ struct nm_rcarrier rc;
+ struct nm_bb_transc bb_transc;
uint16_t arfcn;
int nominal_power; /* in dBm */
diff --git a/include/osmo-bts/nm_bb_transc_fsm.h b/include/osmo-bts/nm_bb_transc_fsm.h
new file mode 100644
index 00000000..cd189a33
--- /dev/null
+++ b/include/osmo-bts/nm_bb_transc_fsm.h
@@ -0,0 +1,45 @@
+/* NM Baseband Transciever FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
+ GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
+
+/* (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/>.
+ *
+ */
+
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+enum nm_bb_transc_op_fsm_states {
+ NM_BBTRANSC_ST_OP_DISABLED_NOTINSTALLED,
+ NM_BBTRANSC_ST_OP_DISABLED_OFFLINE,
+ NM_BBTRANSC_ST_OP_ENABLED,
+};
+
+enum nm_bb_transc_op_fsm_events {
+ NM_BBTRANSC_EV_SW_ACT,
+ NM_BBTRANSC_EV_OPSTART_ACK,
+ NM_BBTRANSC_EV_OPSTART_NACK,
+ NM_BBTRANSC_EV_RSL_UP,
+ NM_BBTRANSC_EV_RSL_DOWN,
+ NM_BBTRANSC_EV_PHYLINK_UP,
+ NM_BBTRANSC_EV_PHYLINK_DOWN,
+ NM_BBTRANSC_EV_DISABLE,
+};
+
+extern struct osmo_fsm nm_bb_transc_fsm;
diff --git a/include/osmo-bts/nm_radio_carrier_fsm.h b/include/osmo-bts/nm_radio_carrier_fsm.h
new file mode 100644
index 00000000..206fcfe5
--- /dev/null
+++ b/include/osmo-bts/nm_radio_carrier_fsm.h
@@ -0,0 +1,45 @@
+/* NM Radio Carrier FSM. Following 3GPP TS 12.21 Figure 2/GSM 12.21:
+ GSM 12.21 Objects' Operational state and availability status behaviour during initialization */
+
+/* (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/>.
+ *
+ */
+
+#pragma once
+
+#include <osmocom/core/fsm.h>
+
+enum nm_rcarrier_op_fsm_states {
+ NM_RCARRIER_ST_OP_DISABLED_NOTINSTALLED,
+ NM_RCARRIER_ST_OP_DISABLED_OFFLINE,
+ NM_RCARRIER_ST_OP_ENABLED,
+};
+
+enum nm_rcarrier_op_fsm_events {
+ NM_RCARRIER_EV_SW_ACT,
+ NM_RCARRIER_EV_OPSTART_ACK,
+ NM_RCARRIER_EV_OPSTART_NACK,
+ NM_RCARRIER_EV_RSL_UP,
+ NM_RCARRIER_EV_RSL_DOWN,
+ NM_RCARRIER_EV_PHYLINK_UP,
+ NM_RCARRIER_EV_PHYLINK_DOWN,
+ NM_RCARRIER_EV_DISABLE,
+};
+
+extern struct osmo_fsm nm_rcarrier_fsm;
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 546e02a1..fa2d2885 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -39,6 +39,8 @@ libbts_a_SOURCES = \
ta_control.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.c b/src/common/bts.c
index 38ec5534..fdd1ede8 100644
--- a/src/common/bts.c
+++ b/src/common/bts.c
@@ -412,7 +412,7 @@ int bts_link_estab(struct gsm_bts *bts)
for (i = 0; i < bts->num_trx; i++) {
struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i);
- oml_tx_state_changed(&trx->mo);
+ oml_tx_state_changed(&trx->rc.mo);
oml_tx_state_changed(&trx->bb_transc.mo);
for (j = 0; j < ARRAY_SIZE(trx->ts); j++) {
diff --git a/src/common/bts_shutdown_fsm.c b/src/common/bts_shutdown_fsm.c
index 0ac30789..8d6fb39a 100644
--- a/src/common/bts_shutdown_fsm.c
+++ b/src/common/bts_shutdown_fsm.c
@@ -46,7 +46,7 @@ static unsigned int count_trx_operational(struct gsm_bts *bts) {
unsigned int count = 0;
struct gsm_bts_trx *trx;
llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED)
+ if (trx->rc.mo.nm_state.operational == NM_OPSTATE_ENABLED)
count++;
}
return count;
@@ -83,7 +83,7 @@ static void st_wait_ramp_down_compl_on_enter(struct osmo_fsm_inst *fi, uint32_t
struct gsm_bts_trx *trx;
llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED)
+ if (trx->rc.mo.nm_state.operational != NM_OPSTATE_ENABLED)
continue;
power_ramp_start(trx, to_mdB(BTS_SHUTDOWN_POWER_RAMP_TGT), 1, ramp_down_compl_cb);
}
@@ -101,7 +101,7 @@ static void st_wait_ramp_down_compl(struct osmo_fsm_inst *fi, uint32_t event, vo
src_trx = (struct gsm_bts_trx *)data;
llist_for_each_entry(trx, &bts->trx_list, list) {
- if (trx->mo.nm_state.operational == NM_OPSTATE_ENABLED &&
+ if (trx->rc.mo.nm_state.operational == NM_OPSTATE_ENABLED &&
trx->power_params.p_total_cur_mdBm > BTS_SHUTDOWN_POWER_RAMP_TGT)
remaining++;
}
diff --git a/src/common/bts_trx.c b/src/common/bts_trx.c
index 93e15c32..6ffae9ee 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,8 @@
#include <osmo-bts/bts_model.h>
#include <osmo-bts/rsl.h>
#include <osmo-bts/phy_link.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
{
@@ -38,9 +42,15 @@ struct gsm_bts_trx *gsm_bts_trx_alloc(struct gsm_bts *bts)
trx->bts = bts;
trx->nr = bts->num_trx++;
- gsm_mo_init(&trx->mo, bts, NM_OC_RADIO_CARRIER,
+ trx->rc.fi = osmo_fsm_inst_alloc(&nm_rcarrier_fsm, trx, trx,
+ LOGL_INFO, NULL);
+ osmo_fsm_inst_update_id_f(trx->rc.fi, "bts%d-trx%d", bts->nr, trx->nr);
+ gsm_mo_init(&trx->rc.mo, bts, NM_OC_RADIO_CARRIER,
bts->nr, trx->nr, 0xff);
+ trx->bb_transc.fi = osmo_fsm_inst_alloc(&nm_bb_transc_fsm, trx, trx,
+ LOGL_INFO, NULL);
+ osmo_fsm_inst_update_id_f(trx->bb_transc.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 +171,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->rc.fi, link ? NM_RCARRIER_EV_RSL_UP : NM_RCARRIER_EV_RSL_DOWN, NULL);
if (link)
rc = rsl_tx_rf_res(trx);
@@ -177,22 +187,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/l1sap.c b/src/common/l1sap.c
index ca1949a8..8306016b 100644
--- a/src/common/l1sap.c
+++ b/src/common/l1sap.c
@@ -1623,7 +1623,7 @@ int l1sap_up(struct gsm_bts_trx *trx, struct osmo_phsap_prim *l1sap)
default:
LOGP(DL1P, LOGL_NOTICE, "unknown prim %d op %d\n",
l1sap->oph.primitive, l1sap->oph.operation);
- oml_tx_failure_event_rep(&trx->mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
+ oml_tx_failure_event_rep(&trx->rc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
"unknown prim %d op %d",
l1sap->oph.primitive,
l1sap->oph.operation);
diff --git a/src/common/nm_bb_transc_fsm.c b/src/common/nm_bb_transc_fsm.c
new file mode 100644
index 00000000..1e92457a
--- /dev/null
+++ b/src/common/nm_bb_transc_fsm.c
@@ -0,0 +1,222 @@
+/* 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_bb_transc_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_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ trx->bb_transc.opstart_success = false;
+ oml_mo_state_chg(&trx->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_trx *trx = (struct gsm_bts_trx *)fi->priv;
+
+ switch (event) {
+ case NM_BBTRANSC_EV_SW_ACT:
+ oml_mo_tx_sw_act_rep(&trx->bb_transc.mo);
+ nm_bb_transc_fsm_state_chg(fi, NM_BBTRANSC_ST_OP_DISABLED_OFFLINE);
+ return;
+ case NM_BBTRANSC_EV_RSL_UP:
+ return;
+ case NM_BBTRANSC_EV_RSL_DOWN:
+ return;
+ case NM_BBTRANSC_EV_PHYLINK_UP:
+ return;
+ case NM_BBTRANSC_EV_PHYLINK_DOWN:
+ return;
+ case NM_BBTRANSC_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->bb_transc.opstart_success = false;
+ oml_mo_state_chg(&trx->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_trx *trx = (struct gsm_bts_trx *)fi->priv;
+ bool phy_state_connected;
+ bool rsl_link_connected;
+
+ switch (event) {
+ case NM_BBTRANSC_EV_OPSTART_ACK:
+ trx->bb_transc.opstart_success = true;
+ oml_mo_opstart_ack(&trx->bb_transc.mo);
+ break; /* check statechg below */
+ case NM_BBTRANSC_EV_OPSTART_NACK:
+ trx->bb_transc.opstart_success = false;
+ oml_mo_opstart_nack(&trx->bb_transc.mo, (int)(intptr_t)data);
+ return;
+ case NM_BBTRANSC_EV_RSL_UP:
+ break; /* check statechg below */
+ case NM_BBTRANSC_EV_RSL_DOWN:
+ return;
+ case NM_BBTRANSC_EV_PHYLINK_UP:
+ break; /* check statechg below */
+ case NM_BBTRANSC_EV_PHYLINK_DOWN:
+ return;
+ case NM_BBTRANSC_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->rc.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",
+ trx->rc.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;
+ oml_mo_state_chg(&trx->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_BBTRANSC_EV_RSL_DOWN:
+ break;
+ case NM_BBTRANSC_EV_PHYLINK_DOWN:
+ break;
+ case NM_BBTRANSC_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_BBTRANSC_EV_SW_ACT) |
+ X(NM_BBTRANSC_EV_RSL_UP) |
+ X(NM_BBTRANSC_EV_RSL_DOWN) |
+ X(NM_BBTRANSC_EV_PHYLINK_UP) |
+ X(NM_BBTRANSC_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_BBTRANSC_EV_OPSTART_ACK) |
+ X(NM_BBTRANSC_EV_OPSTART_NACK) |
+ X(NM_BBTRANSC_EV_RSL_UP) |
+ X(NM_BBTRANSC_EV_RSL_DOWN) |
+ X(NM_BBTRANSC_EV_PHYLINK_UP) |
+ X(NM_BBTRANSC_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_BBTRANSC_EV_RSL_DOWN) |
+ X(NM_BBTRANSC_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,
+ },
+};
+
+const struct value_string nm_bb_transc_fsm_event_names[] = {
+ { NM_BBTRANSC_EV_SW_ACT, "SW_ACT" },
+ { NM_BBTRANSC_EV_OPSTART_ACK, "OPSTART_ACK" },
+ { NM_BBTRANSC_EV_OPSTART_NACK, "OPSTART_NACK" },
+ { NM_BBTRANSC_EV_RSL_UP, "RSL_UP" },
+ { NM_BBTRANSC_EV_RSL_DOWN, "RSL_DOWN" },
+ { NM_BBTRANSC_EV_PHYLINK_UP, "PHYLINK_UP" },
+ { NM_BBTRANSC_EV_PHYLINK_DOWN, "PHYLINK_DOWN" },
+ { NM_BBTRANSC_EV_DISABLE, "DISABLE" },
+ { 0, NULL }
+};
+
+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_bb_transc_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_radio_carrier_fsm.c b/src/common/nm_radio_carrier_fsm.c
new file mode 100644
index 00000000..5facb5dc
--- /dev/null
+++ b/src/common/nm_radio_carrier_fsm.c
@@ -0,0 +1,230 @@
+/* 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_radio_carrier_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->rc.opstart_success = false;
+ oml_mo_state_chg(&trx->rc.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_RCARRIER_EV_SW_ACT:
+ oml_mo_tx_sw_act_rep(&trx->rc.mo);
+ nm_rcarrier_fsm_state_chg(fi, NM_RCARRIER_ST_OP_DISABLED_OFFLINE);
+ return;
+ case NM_RCARRIER_EV_RSL_UP:
+ return;
+ case NM_RCARRIER_EV_RSL_DOWN:
+ return;
+ case NM_RCARRIER_EV_PHYLINK_UP:
+ return;
+ case NM_RCARRIER_EV_PHYLINK_DOWN:
+ return;
+ case NM_RCARRIER_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->rc.opstart_success = false;
+ oml_mo_state_chg(&trx->rc.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_RCARRIER_EV_OPSTART_ACK:
+ trx->rc.opstart_success = true;
+ oml_mo_opstart_ack(&trx->rc.mo);
+ break; /* check statechg below */
+ case NM_RCARRIER_EV_OPSTART_NACK:
+ trx->rc.opstart_success = false;
+ oml_mo_opstart_nack(&trx->rc.mo, (int)(intptr_t)data);
+ return;
+ case NM_RCARRIER_EV_RSL_UP:
+ break; /* check statechg below */
+ case NM_RCARRIER_EV_RSL_DOWN:
+ return;
+ case NM_RCARRIER_EV_PHYLINK_UP:
+ break; /* check statechg below */
+ case NM_RCARRIER_EV_PHYLINK_DOWN:
+ return;
+ case NM_RCARRIER_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->rc.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->rc.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->rc.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_RCARRIER_EV_RSL_DOWN:
+ break;
+ case NM_RCARRIER_EV_PHYLINK_DOWN:
+ break;
+ case NM_RCARRIER_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_RCARRIER_EV_SW_ACT) |
+ X(NM_RCARRIER_EV_RSL_UP) |
+ X(NM_RCARRIER_EV_RSL_DOWN) |
+ X(NM_RCARRIER_EV_PHYLINK_UP) |
+ X(NM_RCARRIER_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_RCARRIER_EV_OPSTART_ACK) |
+ X(NM_RCARRIER_EV_OPSTART_NACK) |
+ X(NM_RCARRIER_EV_RSL_UP) |
+ X(NM_RCARRIER_EV_RSL_DOWN) |
+ X(NM_RCARRIER_EV_PHYLINK_UP) |
+ X(NM_RCARRIER_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_RCARRIER_EV_RSL_DOWN) |
+ X(NM_RCARRIER_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,
+ },
+};
+
+const struct value_string nm_rcarrier_fsm_event_names[] = {
+ { NM_RCARRIER_EV_SW_ACT, "SW_ACT" },
+ { NM_RCARRIER_EV_OPSTART_ACK, "OPSTART_ACK" },
+ { NM_RCARRIER_EV_OPSTART_NACK, "OPSTART_NACK" },
+ { NM_RCARRIER_EV_RSL_UP, "RSL_UP" },
+ { NM_RCARRIER_EV_RSL_DOWN, "RSL_DOWN" },
+ { NM_RCARRIER_EV_PHYLINK_UP, "PHYLINK_UP" },
+ { NM_RCARRIER_EV_PHYLINK_DOWN, "PHYLINK_DOWN" },
+ { NM_RCARRIER_EV_DISABLE, "DISABLE" },
+ { 0, NULL }
+};
+
+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_rcarrier_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/oml.c b/src/common/oml.c
index 0dd7ecb2..1a31f8e2 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -712,26 +712,26 @@ static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
if (rc < 0) {
- oml_tx_failure_event_rep(&trx->mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UNSUP_ATTR,
+ oml_tx_failure_event_rep(&trx->rc.mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UNSUP_ATTR,
"New value for Set Radio Attribute not"
" supported");
return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
}
/* merge existing BTS attributes with new attributes */
- tp_merged = osmo_tlvp_copy(trx->mo.nm_attr, trx->bts);
+ tp_merged = osmo_tlvp_copy(trx->rc.mo.nm_attr, trx->bts);
osmo_tlvp_merge(tp_merged, &tp);
/* Ask BTS driver to validate new merged attributes */
- rc = bts_model_check_oml(trx->bts, foh->msg_type, trx->mo.nm_attr, tp_merged, trx);
+ rc = bts_model_check_oml(trx->bts, foh->msg_type, trx->rc.mo.nm_attr, tp_merged, trx);
if (rc < 0) {
talloc_free(tp_merged);
return oml_fom_ack_nack(msg, -rc);
}
/* Success: replace old BTS attributes with new */
- talloc_free(trx->mo.nm_attr);
- trx->mo.nm_attr = tp_merged;
+ talloc_free(trx->rc.mo.nm_attr);
+ trx->rc.mo.nm_attr = tp_merged;
/* ... and actually still parse them */
@@ -1060,7 +1060,7 @@ static inline bool report_bts_number_incorrect(struct gsm_bts *bts, const struct
if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) {
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx)
- mo = &trx->mo;
+ mo = &trx->rc.mo;
oml_tx_failure_event_rep(mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG, form,
foh->obj_inst.bts_nr,
get_value_string(abis_nm_msgtype_names, foh->msg_type));
@@ -1082,7 +1082,7 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg)
if (msgb_l2len(msg) < sizeof(*foh)) {
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx)
- mo = &trx->mo;
+ mo = &trx->rc.mo;
oml_tx_failure_event_rep(mo, NM_SEVER_MAJOR, OSMO_EVT_MAJ_UKWN_MSG,
"Formatted O&M message too short");
return -EIO;
@@ -1138,7 +1138,7 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg)
default:
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx)
- mo = &trx->mo;
+ mo = &trx->rc.mo;
oml_tx_failure_event_rep(mo, NM_SEVER_MINOR, OSMO_EVT_MAJ_UKWN_MSG,
"unknown Formatted O&M msg_type 0x%02x", foh->msg_type);
ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL);
@@ -1427,7 +1427,7 @@ static int down_mom(struct gsm_bts *bts, struct msgb *msg)
default:
trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
if (trx)
- mo = &trx->mo;
+ mo = &trx->rc.mo;
oml_tx_failure_event_rep(mo, NM_SEVER_MINOR, OSMO_EVT_MAJ_UKWN_MSG,
"unknown Manufacturer O&M msg_type 0x%02x", foh->msg_type);
ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL);
@@ -1535,7 +1535,7 @@ gsm_objclass2mo(struct gsm_bts *bts, uint8_t obj_class,
return NULL;
}
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- mo = &trx->mo;
+ mo = &trx->rc.mo;
break;
case NM_OC_BASEB_TRANSC:
if (obj_inst->trx_nr >= bts->num_trx) {
@@ -1609,7 +1609,7 @@ gsm_objclass2obj(struct gsm_bts *bts, uint8_t obj_class,
return NULL;
}
trx = gsm_bts_trx_num(bts, obj_inst->trx_nr);
- obj = &trx->bb_transc;
+ obj = trx;
break;
case NM_OC_CHANNEL:
if (obj_inst->trx_nr >= bts->num_trx) {
diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c
index c922584c..45047ba5 100644
--- a/src/common/pcu_sock.c
+++ b/src/common/pcu_sock.c
@@ -146,7 +146,7 @@ static void info_ind_fill_fhp(struct gsm_pcu_if_info_trx_ts *ts_info,
llist_for_each_entry(trx, &bts->trx_list, list) {
/* Skip non-provisioned transceivers */
- if (trx->mo.nm_attr == NULL) {
+ if (trx->rc.mo.nm_attr == NULL) {
LOGPTRX(trx, DPCU, LOGL_NOTICE, "not (yet) provisioned\n");
continue;
}
@@ -200,11 +200,11 @@ static void info_ind_fill_trx(struct gsm_pcu_if_info_trx *trx_info,
trx_info->arfcn = trx->arfcn;
trx_info->hlayer1 = trx_get_hlayer1(trx);
- if (trx->mo.nm_state.operational != NM_OPSTATE_ENABLED ||
- trx->mo.nm_state.administrative != NM_STATE_UNLOCKED) {
+ if (trx->rc.mo.nm_state.operational != NM_OPSTATE_ENABLED ||
+ trx->rc.mo.nm_state.administrative != NM_STATE_UNLOCKED) {
LOGPTRX(trx, DPCU, LOGL_INFO, "unavailable for PCU (op=%s adm=%s)\n",
- abis_nm_opstate_name(trx->mo.nm_state.operational),
- abis_nm_admin_name(trx->mo.nm_state.administrative));
+ abis_nm_opstate_name(trx->rc.mo.nm_state.operational),
+ abis_nm_admin_name(trx->rc.mo.nm_state.administrative));
return;
}
diff --git a/src/common/phy_link.c b/src/common/phy_link.c
index 48ba283e..222868cd 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,8 @@
#include <osmo-bts/oml.h>
#include <osmo-bts/logging.h>
#include <osmo-bts/bts_model.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
static LLIST_HEAD(g_phy_links);
@@ -65,7 +68,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->rc.fi,
+ state == PHY_LINK_CONNECTED ? NM_RCARRIER_EV_PHYLINK_UP :
+ NM_RCARRIER_EV_PHYLINK_DOWN,
+ NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi,
+ state == PHY_LINK_CONNECTED ? NM_BBTRANSC_EV_PHYLINK_UP :
+ NM_BBTRANSC_EV_PHYLINK_DOWN,
+ NULL);
}
}
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 91e9f75c..a175a9cb 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -2125,7 +2125,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
OSMO_RTP_F_POLL);
if (!lchan->abis_ip.rtp_socket) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to create RTP/RTCP sockets\n");
- oml_tx_failure_event_rep(&lchan->ts->trx->mo,
+ oml_tx_failure_event_rep(&lchan->ts->trx->rc.mo,
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
"%s IPAC Failed to create RTP/RTCP sockets",
gsm_lchan_name(lchan));
@@ -2162,7 +2162,7 @@ static int rsl_rx_ipac_XXcx(struct msgb *msg)
rc = bind_rtp(bts, lchan->abis_ip.rtp_socket, ipstr);
if (rc < 0) {
LOGPLCHAN(lchan, DRTP, LOGL_ERROR, "IPAC Failed to bind RTP/RTCP sockets\n");
- oml_tx_failure_event_rep(&lchan->ts->trx->mo,
+ oml_tx_failure_event_rep(&lchan->ts->trx->rc.mo,
NM_SEVER_MINOR, OSMO_EVT_CRIT_RTP_TOUT,
"%s IPAC Failed to bind RTP/RTCP sockets",
gsm_lchan_name(lchan));
diff --git a/src/common/vty.c b/src/common/vty.c
index c3909793..afa97e2b 100644
--- a/src/common/vty.c
+++ b/src/common/vty.c
@@ -974,7 +974,7 @@ static void trx_dump_vty(struct vty *vty, const struct gsm_bts_trx *trx)
trx->nominal_power, trx->max_power_red,
trx->nominal_power - trx->max_power_red, VTY_NEWLINE);
vty_out(vty, " NM State: ");
- net_dump_nmstate(vty, &trx->mo.nm_state);
+ net_dump_nmstate(vty, &trx->rc.mo.nm_state);
vty_out(vty, " RSL State: %s%s", trx->rsl_link? "connected" : "disconnected", VTY_NEWLINE);
vty_out(vty, " Baseband Transceiver NM State: ");
net_dump_nmstate(vty, &trx->bb_transc.mo.nm_state);
diff --git a/src/osmo-bts-litecell15/l1_if.c b/src/osmo-bts-litecell15/l1_if.c
index 23f7c3d5..b61d963b 100644
--- a/src/osmo-bts-litecell15/l1_if.c
+++ b/src/osmo-bts-litecell15/l1_if.c
@@ -54,6 +54,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include <nrw/litecell15/litecell15.h>
#include <nrw/litecell15/gsml1prim.h>
@@ -1270,18 +1272,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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->rc.fi, NM_RCARRIER_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_DISABLE, NULL);
}
msgb_free(resp);
@@ -1362,14 +1362,14 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n",
get_value_string(lc15bts_l1status_names, status));
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 0);
} else {
int i;
LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
get_value_string(lc15bts_l1status_names, status));
bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 1);
osmo_static_assert(
ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute),
@@ -1634,7 +1634,7 @@ static void dsp_alive_timer_cb(void *data)
get_value_string(lc15bts_sysprim_names, sys_prim->id + 1), trx->nr);
if( fl1h->phy_inst->trx ){
- fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
+ fl1h->phy_inst->trx->rc.mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
}
}
diff --git a/src/osmo-bts-litecell15/oml.c b/src/osmo-bts-litecell15/oml.c
index 424a945d..a2d34609 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>
@@ -44,6 +45,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "lc15bts.h"
@@ -271,31 +274,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->rc.fi, NM_RCARRIER_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->rc.fi, NM_RCARRIER_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) {
@@ -365,13 +365,13 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
fl1h->hLayer1 = ic->hLayer1;
/* If the TRX was already locked the MphInit would have undone it */
- if (trx->mo.nm_state.administrative == NM_STATE_LOCKED)
+ if (trx->rc.mo.nm_state.administrative == NM_STATE_LOCKED)
trx_rf_lock(trx, 1, trx_mute_on_init_cb);
/* Begin to ramp up the power */
power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL);
- return opstart_compl(&trx->mo, l1_msg);
+ return opstart_compl(&trx->rc.mo, l1_msg);
}
int gsm_abis_mo_check_attr(const struct gsm_abis_mo *mo, const uint8_t *attr_ids,
@@ -400,12 +400,13 @@ static int trx_init(struct gsm_bts_trx *trx)
GsmL1_DeviceParam_t *dev_par;
int rc, lc15_band;
- if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,
+ if (!gsm_abis_mo_check_attr(&trx->rc.mo, trx_rqd_attr,
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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->rc.fi, NM_RCARRIER_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
/* Update TRX band */
@@ -1886,6 +1887,7 @@ 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_trx *trx;
int rc;
switch (mo->obj_class) {
@@ -1896,12 +1898,16 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
rc = osmo_fsm_inst_dispatch(bts->nm.fi, NM_BTS_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:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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/calib_file.c b/src/osmo-bts-oc2g/calib_file.c
index 22122ab3..81c0ebd2 100644
--- a/src/osmo-bts-oc2g/calib_file.c
+++ b/src/osmo-bts-oc2g/calib_file.c
@@ -134,7 +134,7 @@ static int calib_file_open(struct oc2gl1_hdl *fl1h,
st->fp = fopen(fname, "rb");
if (!st->fp) {
LOGP(DL1C, LOGL_FATAL, "Failed to open '%s' for calibration data.\n", fname);
- oml_tx_failure_event_rep(&fl1h->phy_inst->trx->mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
+ oml_tx_failure_event_rep(&fl1h->phy_inst->trx->rc.mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
"Failed to open '%s' for calibration data", fname);
return -1;
}
@@ -221,7 +221,7 @@ static int calib_file_send(struct oc2gl1_hdl *fl1h,
rc = calib_verify(fl1h, desc);
if (rc < 0) {
LOGP(DL1C, LOGL_FATAL, "Verify L1 calibration table %s -> failed (%d)\n", desc->fname, rc);
- oml_tx_failure_event_rep(&fl1h->phy_inst->trx->mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
+ oml_tx_failure_event_rep(&fl1h->phy_inst->trx->rc.mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
"Verify L1 calibration table %s -> failed (%d)", desc->fname, rc);
st->last_file_idx = get_next_calib_file_idx(fl1h, st->last_file_idx);
@@ -278,7 +278,7 @@ int calib_load(struct oc2gl1_hdl *fl1h)
if (!calib_path) {
LOGP(DL1C, LOGL_FATAL, "Calibration file path not specified\n");
- oml_tx_failure_event_rep(&fl1h->phy_inst->trx->mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
+ oml_tx_failure_event_rep(&fl1h->phy_inst->trx->rc.mo, NM_SEVER_MAJOR, OSMO_EVT_WARN_SW_WARN,
"Calibration file path not specified");
return -1;
}
diff --git a/src/osmo-bts-oc2g/l1_if.c b/src/osmo-bts-oc2g/l1_if.c
index 8e486744..d281dbb2 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,8 @@
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/cbch.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include <nrw/oc2g/oc2g.h>
#include <nrw/oc2g/gsml1prim.h>
@@ -1324,17 +1327,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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->rc.fi, NM_RCARRIER_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_DISABLE, NULL);
}
msgb_free(resp);
@@ -1408,14 +1409,14 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n",
get_value_string(oc2gbts_l1status_names, status));
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 0);
} else {
int i;
LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
get_value_string(oc2gbts_l1status_names, status));
bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 1);
osmo_static_assert(
ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute),
@@ -1698,9 +1699,9 @@ static void dsp_alive_timer_cb(void *data)
get_value_string(oc2gbts_sysprim_names, sys_prim->id + 1), trx->nr);
if( fl1h->phy_inst->trx ){
- fl1h->phy_inst->trx->mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
+ fl1h->phy_inst->trx->rc.mo.obj_inst.trx_nr = fl1h->phy_inst->trx->nr;
- alarm_sig_data.mo = &fl1h->phy_inst->trx->mo;
+ alarm_sig_data.mo = &fl1h->phy_inst->trx->rc.mo;
memcpy(alarm_sig_data.spare, &sys_prim->id, sizeof(unsigned int));
osmo_signal_dispatch(SS_NM, S_NM_OML_BTS_DSP_ALIVE_ALARM, &alarm_sig_data);
if (!alarm_sig_data.rc) {
diff --git a/src/osmo-bts-oc2g/oml.c b/src/osmo-bts-oc2g/oml.c
index 2cff758d..737afd31 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>
@@ -44,6 +45,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "oc2gbts.h"
@@ -271,31 +274,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->rc.fi, NM_RCARRIER_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->rc.fi, NM_RCARRIER_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) {
@@ -365,7 +365,7 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
fl1h->hLayer1 = ic->hLayer1;
/* If the TRX was already locked the MphInit would have undone it */
- if (trx->mo.nm_state.administrative == NM_STATE_LOCKED)
+ if (trx->rc.mo.nm_state.administrative == NM_STATE_LOCKED)
trx_rf_lock(trx, 1, trx_mute_on_init_cb);
/* apply initial values for Tx power backoff for 8-PSK */
@@ -387,7 +387,7 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
/* Begin to ramp up the power */
power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL);
- return opstart_compl(&trx->mo, l1_msg);
+ return opstart_compl(&trx->rc.mo, l1_msg);
}
int gsm_abis_mo_check_attr(const struct gsm_abis_mo *mo, const uint8_t *attr_ids,
@@ -416,12 +416,12 @@ static int trx_init(struct gsm_bts_trx *trx)
GsmL1_DeviceParam_t *dev_par;
int rc, oc2g_band;
- if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,
+ if (!gsm_abis_mo_check_attr(&trx->rc.mo, trx_rqd_attr,
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 oml_mo_opstart_ack(&trx->rc.mo);
+ //return oml_mo_opstart_nack(&trx->rc.mo, NM_NACK_CANT_PERFORM);
}
/* Update TRX band */
@@ -1895,6 +1895,7 @@ 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_trx* trx;
int rc;
switch (mo->obj_class) {
@@ -1909,12 +1910,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:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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 c03b4112..37a3e65c 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,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/handover.h>
#include <osmo-bts/bts.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "l1_oml.h"
@@ -311,19 +314,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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->rc.fi, NM_RCARRIER_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_DISABLE, NULL);
}
return 0;
diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c
index 8156c49a..f036fe95 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>
@@ -40,6 +41,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "l1_oml.h"
@@ -188,22 +191,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->rc.fi, NM_RCARRIER_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) {
@@ -1314,7 +1310,7 @@ static int trx_open_compl_cb(struct octphy_hdl *fl1h, struct msgb *resp, void *d
msgb_free(resp);
- opstart_compl(&trx->mo);
+ opstart_compl(&trx->rc.mo);
octphy_hw_get_pcb_info(fl1h);
octphy_hw_get_rf_port_info(fl1h, 0);
@@ -1447,12 +1443,13 @@ uint32_t trx_get_hlayer1(const struct gsm_bts_trx *trx)
static int trx_init(struct gsm_bts_trx *trx)
{
- if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,
+ if (!gsm_abis_mo_check_attr(&trx->rc.mo, trx_rqd_attr,
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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->rc.fi, NM_RCARRIER_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
l1if_check_app_version(trx);
@@ -1764,8 +1761,9 @@ 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_trx* trx;
struct gsm_bts_trx_ts *ts;
+ int rc;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -1775,13 +1773,17 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
rc = osmo_fsm_inst_dispatch(bts->nm.fi, NM_BTS_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:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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 dee671b5..60ab107f 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>
@@ -36,6 +37,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
/* TODO: check if dummy method is sufficient, else implement */
int bts_model_lchan_deactivate(struct gsm_lchan *lchan)
@@ -79,15 +82,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_SW_ACT, NULL);
}
return 0;
}
@@ -128,7 +129,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
{
int rc;
struct gsm_bts_trx* trx;
- uint8_t tn;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -139,18 +139,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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
break;
- case NM_OC_CHANNEL:
case NM_OC_BASEB_TRANSC:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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..e766cea0 100644
--- a/src/osmo-bts-sysmo/l1_if.c
+++ b/src/osmo-bts-sysmo/l1_if.c
@@ -51,6 +51,8 @@
#include <osmo-bts/msg_utils.h>
#include <osmo-bts/dtx_dl_amr_fsm.h>
#include <osmo-bts/tx_power.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include <sysmocom/femtobts/superfemto.h>
#include <sysmocom/femtobts/gsml1prim.h>
@@ -1240,17 +1242,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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->rc.fi, NM_RCARRIER_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_DISABLE, NULL);
}
msgb_free(resp);
@@ -1384,14 +1384,14 @@ static int mute_rf_compl_cb(struct gsm_bts_trx *trx, struct msgb *resp,
if (status != GsmL1_Status_Success) {
LOGP(DL1C, LOGL_ERROR, "Rx RF-MUTE.conf with status %s\n",
get_value_string(femtobts_l1status_names, status));
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 0);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 0);
} else {
int i;
LOGP(DL1C, LOGL_INFO, "Rx RF-MUTE.conf with status=%s\n",
get_value_string(femtobts_l1status_names, status));
bts_update_status(BTS_STATUS_RF_MUTE, fl1h->last_rf_mute[0]);
- oml_mo_rf_lock_chg(&trx->mo, fl1h->last_rf_mute, 1);
+ oml_mo_rf_lock_chg(&trx->rc.mo, fl1h->last_rf_mute, 1);
osmo_static_assert(
ARRAY_SIZE(trx->ts) >= ARRAY_SIZE(fl1h->last_rf_mute),
@@ -1424,7 +1424,7 @@ int l1if_mute_rf(struct femtol1_hdl *hdl, uint8_t mute[8], l1if_compl_cb *cb)
/* always acknowledge an un-MUTE (which is a no-op if MUTE is not supported */
if (!memcmp(mute, unmuted, ARRAY_SIZE(unmuted))) {
bts_update_status(BTS_STATUS_RF_MUTE, mute[0]);
- oml_mo_rf_lock_chg(&trx->mo, mute, 1);
+ oml_mo_rf_lock_chg(&trx->rc.mo, mute, 1);
for (i = 0; i < ARRAY_SIZE(unmuted); ++i)
mute_handle_ts(&trx->ts[i], mute[i]);
return 0;
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index 9bbf02f7..46dfa813 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>
@@ -41,6 +42,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "femtobts.h"
@@ -270,31 +273,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->rc.fi, NM_RCARRIER_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->rc.fi, NM_RCARRIER_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) {
@@ -367,14 +367,14 @@ static int trx_init_compl_cb(struct gsm_bts_trx *trx, struct msgb *l1_msg,
#if SUPERFEMTO_API_VERSION >= SUPERFEMTO_API(3,6,0)
/* If the TRX was already locked the MphInit would have undone it */
- if (trx->mo.nm_state.administrative == NM_STATE_LOCKED)
+ if (trx->rc.mo.nm_state.administrative == NM_STATE_LOCKED)
trx_rf_lock(trx, 1, trx_mute_on_init_cb);
#endif
/* Begin to ramp up the power */
power_ramp_start(trx, get_p_target_mdBm(trx, 0), 0, NULL);
- return opstart_compl(&trx->mo, l1_msg);
+ return opstart_compl(&trx->rc.mo, l1_msg);
}
int gsm_abis_mo_check_attr(const struct gsm_abis_mo *mo, const uint8_t *attr_ids,
@@ -404,12 +404,13 @@ static int trx_init(struct gsm_bts_trx *trx)
int femto_band;
int initial_mdBm = power_ramp_initial_power_mdBm(trx);
- if (!gsm_abis_mo_check_attr(&trx->mo, trx_rqd_attr,
+ if (!gsm_abis_mo_check_attr(&trx->rc.mo, trx_rqd_attr,
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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
+ //return osmo_fsm_inst_dispatch(trx->rc.fi, NM_RCARRIER_EV_OPSTART_NACK,
+ // (void*)(intptr_t)NM_NACK_CANT_PERFORM);
}
femto_band = sysmobts_select_femto_band(trx, trx->arfcn);
@@ -1772,6 +1773,7 @@ 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_trx* trx;
int rc;
switch (mo->obj_class) {
@@ -1786,12 +1788,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:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_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 03835a02..2c58c2f7 100644
--- a/src/osmo-bts-trx/l1_if.c
+++ b/src/osmo-bts-trx/l1_if.c
@@ -46,6 +46,8 @@
#include <osmo-bts/pcu_if.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "l1_if.h"
#include "trx_if.h"
@@ -98,11 +100,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_SW_ACT, NULL);
pinst->u.osmotrx.sw_act_reported = true;
}
@@ -112,10 +112,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->rc.fi, NM_RCARRIER_EV_DISABLE, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_DISABLE, NULL);
for (tn = 0; tn < TRX_NR_TS; tn++)
oml_mo_state_chg(&trx->ts[tn].mo, NM_OPSTATE_DISABLED,
@@ -172,7 +170,7 @@ void l1if_trx_set_nominal_power(struct gsm_bts_trx *trx, int nominal_power)
/* If TRX is not yet powered, delay ramping until it's ON */
if (!nom_pwr_changed || !pinst->phy_link->u.osmotrx.powered ||
- trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+ trx->rc.mo.nm_state.administrative == NM_STATE_UNLOCKED)
return;
/* We are already ON and we got new information about nominal power, so
@@ -201,25 +199,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->rc.fi, NM_RCARRIER_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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
}
/* Deact RF on transceiver */
@@ -287,7 +277,7 @@ static uint8_t trx_set_trx(struct gsm_bts_trx *trx)
is already running. Otherwise skip, power ramping will be started
after TRX is running */
if (plink->u.osmotrx.powered && l1h->config.forced_max_power_red == -1 &&
- trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+ trx->rc.mo.nm_state.administrative == NM_STATE_UNLOCKED)
power_ramp_start(pinst->trx, get_p_nominal_mdBm(pinst->trx), 0, NULL);
return 0;
@@ -615,6 +605,7 @@ 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_trx *trx;
int rc;
switch (mo->obj_class) {
@@ -626,10 +617,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:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_OPSTART_ACK, NULL);
+ break;
+ case NM_OC_CHANNEL:
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC:
@@ -645,8 +640,8 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo,
static void bts_model_chg_adm_state_ramp_compl_cb(struct gsm_bts_trx *trx)
{
LOGPTRX(trx, DL1C, LOGL_INFO, "power ramp due to ADM STATE change finished\n");
- trx->mo.procedure_pending = 0;
- if (trx->mo.nm_state.administrative == NM_STATE_LOCKED) {
+ trx->rc.mo.procedure_pending = 0;
+ if (trx->rc.mo.nm_state.administrative == NM_STATE_LOCKED) {
bts_model_trx_deact_rf(trx);
pcu_tx_info_ind();
}
diff --git a/src/osmo-bts-trx/trx_provision_fsm.c b/src/osmo-bts-trx/trx_provision_fsm.c
index e4721ba7..59f0d2fd 100644
--- a/src/osmo-bts-trx/trx_provision_fsm.c
+++ b/src/osmo-bts-trx/trx_provision_fsm.c
@@ -279,7 +279,7 @@ static void st_open_poweroff_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_st
l1h->config.trxd_hdr_ver_req = pinst->phy_link->u.osmotrx.trxd_hdr_ver_max;
/* Apply initial RFMUTE state */
- trx_if_cmd_rfmute(l1h, pinst->trx->mo.nm_state.administrative != NM_STATE_UNLOCKED);
+ trx_if_cmd_rfmute(l1h, pinst->trx->rc.mo.nm_state.administrative != NM_STATE_UNLOCKED);
}
static void st_open_poweroff(struct osmo_fsm_inst *fi, uint32_t event, void *data)
@@ -437,7 +437,7 @@ static void st_open_wait_power_cnf(struct osmo_fsm_inst *fi, uint32_t event, voi
/* Begin to ramp up the power on all TRX associated with this phy */
llist_for_each_entry(pinst, &plink->instances, list) {
- if (pinst->trx->mo.nm_state.administrative == NM_STATE_UNLOCKED)
+ if (pinst->trx->rc.mo.nm_state.administrative == NM_STATE_UNLOCKED)
l1if_trx_start_power_ramp(pinst->trx, NULL);
}
diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c
index 66240e26..c2d68cb7 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>
@@ -36,6 +37,8 @@
#include <osmo-bts/l1sap.h>
#include <osmo-bts/nm_bts_sm_fsm.h>
#include <osmo-bts/nm_bts_fsm.h>
+#include <osmo-bts/nm_radio_carrier_fsm.h>
+#include <osmo-bts/nm_bb_transc_fsm.h>
#include "virtual_um.h"
@@ -86,15 +89,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->rc.fi, NM_RCARRIER_EV_SW_ACT, NULL);
+ osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_SW_ACT, NULL);
}
return 0;
}
@@ -142,7 +143,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj)
{
int rc;
struct gsm_bts_trx* trx;
- uint8_t tn;
switch (mo->obj_class) {
case NM_OC_SITE_MANAGER:
@@ -153,18 +153,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->rc.fi, NM_RCARRIER_EV_OPSTART_ACK, NULL);
break;
- case NM_OC_CHANNEL:
case NM_OC_BASEB_TRANSC:
+ trx = (struct gsm_bts_trx *) obj;
+ rc = osmo_fsm_inst_dispatch(trx->bb_transc.fi, NM_BBTRANSC_EV_OPSTART_ACK, NULL);
+ break;
case NM_OC_GPRS_NSE:
case NM_OC_GPRS_CELL:
case NM_OC_GPRS_NSVC: