diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Makefile.am | 2 | ||||
-rw-r--r-- | src/common/bts.c | 2 | ||||
-rw-r--r-- | src/common/bts_shutdown_fsm.c | 6 | ||||
-rw-r--r-- | src/common/bts_trx.c | 30 | ||||
-rw-r--r-- | src/common/l1sap.c | 2 | ||||
-rw-r--r-- | src/common/nm_bb_transc_fsm.c | 222 | ||||
-rw-r--r-- | src/common/nm_radio_carrier_fsm.c | 230 | ||||
-rw-r--r-- | src/common/oml.c | 22 | ||||
-rw-r--r-- | src/common/pcu_sock.c | 10 | ||||
-rw-r--r-- | src/common/phy_link.c | 12 | ||||
-rw-r--r-- | src/common/rsl.c | 4 | ||||
-rw-r--r-- | src/common/vty.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/l1_if.c | 18 | ||||
-rw-r--r-- | src/osmo-bts-litecell15/oml.c | 44 | ||||
-rw-r--r-- | src/osmo-bts-oc2g/calib_file.c | 6 | ||||
-rw-r--r-- | src/osmo-bts-oc2g/l1_if.c | 21 | ||||
-rw-r--r-- | src/osmo-bts-oc2g/oml.c | 43 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_if.c | 15 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_oml.c | 38 | ||||
-rw-r--r-- | src/osmo-bts-omldummy/bts_model.c | 24 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/l1_if.c | 18 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/oml.c | 44 | ||||
-rw-r--r-- | src/osmo-bts-trx/l1_if.c | 45 | ||||
-rw-r--r-- | src/osmo-bts-trx/trx_provision_fsm.c | 4 | ||||
-rw-r--r-- | src/osmo-bts-virtual/bts_model.c | 24 |
25 files changed, 674 insertions, 214 deletions
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: |