diff options
author | Pau Espin Pedrol <pespin@sysmocom.de> | 2023-04-04 18:57:50 +0200 |
---|---|---|
committer | pespin <pespin@sysmocom.de> | 2023-04-06 10:28:22 +0000 |
commit | 633bbf174a9361d6de009910cec8c3ead1621d79 (patch) | |
tree | b9368e2d0ce4f29f882e166bb73dbf7fd952f827 | |
parent | 4190537d7d4414e2545d9808d922b90ed807675a (diff) |
Introduce NM FSM for GPRS NSE object
Related: OS#5994
Change-Id: I01eadc63214a2eb5e1bce455c7e5b62bd41905ea
-rw-r--r-- | include/osmo-bts/bts.h | 18 | ||||
-rw-r--r-- | include/osmo-bts/nm_common_fsm.h | 9 | ||||
-rw-r--r-- | src/common/Makefile.am | 1 | ||||
-rw-r--r-- | src/common/bts.c | 20 | ||||
-rw-r--r-- | src/common/nm_bts_sm_fsm.c | 1 | ||||
-rw-r--r-- | src/common/nm_gprs_nse_fsm.c | 278 | ||||
-rw-r--r-- | src/common/oml.c | 83 | ||||
-rw-r--r-- | src/osmo-bts-lc15/oml.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-oc2g/oml.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-octphy/l1_oml.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-omldummy/bts_model.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/oml.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-trx/l1_if.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-virtual/bts_model.c | 2 |
14 files changed, 368 insertions, 56 deletions
diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 2d0eec77..bbf5dc46 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -136,6 +136,13 @@ struct gsm_bts_sm { struct gsm_abis_mo mo; }; +/* GPRS NSE; ip.access specific NM Object */ +struct gsm_gprs_nse { + struct gsm_abis_mo mo; + uint16_t nsei; + uint8_t timer[7]; +}; + /* Struct that holds one OML-Address (Address of the BSC) */ struct bsc_oml_host { struct llist_head list; @@ -224,11 +231,7 @@ struct gsm_bts { /* Not entirely sure how ip.access specific this is */ struct { - struct { - struct gsm_abis_mo mo; - uint16_t nsei; - uint8_t timer[7]; - } nse; + struct gsm_gprs_nse nse; struct { struct gsm_abis_mo mo; uint16_t bvci; @@ -396,6 +399,11 @@ static inline struct gsm_bts *gsm_bts_sm_get_bts(struct gsm_bts_sm *site_mgr) { return (struct gsm_bts *)container_of(site_mgr, struct gsm_bts, site_mgr); } +static inline struct gsm_bts *gsm_gprs_nse_get_bts(struct gsm_gprs_nse *nse) +{ + return (struct gsm_bts *)container_of(nse, struct gsm_bts, gprs.nse); +} + struct gsm_bts *gsm_bts_alloc(void *talloc_ctx, uint8_t bts_num); struct gsm_bts *gsm_bts_num(const struct gsm_network *net, int num); diff --git a/include/osmo-bts/nm_common_fsm.h b/include/osmo-bts/nm_common_fsm.h index 22a4be09..9264eea5 100644 --- a/include/osmo-bts/nm_common_fsm.h +++ b/include/osmo-bts/nm_common_fsm.h @@ -94,3 +94,12 @@ enum nm_chan_op_fsm_states { NM_CHAN_ST_OP_ENABLED, }; extern struct osmo_fsm nm_chan_fsm; + +/* GPRS NSE */ +enum nm_gprs_nse_op_fsm_states { + NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED, + NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY, + NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE, + NM_GPRS_NSE_ST_OP_ENABLED, +}; +extern struct osmo_fsm nm_gprs_nse_fsm; diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 99f99242..cb5ff501 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -61,6 +61,7 @@ libbts_a_SOURCES = \ nm_bts_fsm.c \ nm_bb_transc_fsm.c \ nm_channel_fsm.c \ + nm_gprs_nse_fsm.c \ nm_radio_carrier_fsm.c \ probes.d \ $(NULL) diff --git a/src/common/bts.c b/src/common/bts.c index de27ad8f..051f41b7 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -251,26 +251,32 @@ struct gsm_bts *gsm_bts_alloc(void *ctx, uint8_t bts_num) LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(bts->shutdown_fi, "bts%d", bts->nr); + /* NM SITE_MGR */ bts->site_mgr.mo.fi = osmo_fsm_inst_alloc(&nm_bts_sm_fsm, bts, &bts->site_mgr, LOGL_INFO, "bts_sm"); gsm_mo_init(&bts->site_mgr.mo, bts, NM_OC_SITE_MANAGER, 0xff, 0xff, 0xff); + /* NM BTS */ bts->mo.fi = osmo_fsm_inst_alloc(&nm_bts_fsm, bts, bts, LOGL_INFO, NULL); osmo_fsm_inst_update_id_f(bts->mo.fi, "bts%d", bts->nr); gsm_mo_init(&bts->mo, bts, NM_OC_BTS, bts->nr, 0xff, 0xff); + /* NM GPRS NSE */ + bts->gprs.nse.mo.fi = osmo_fsm_inst_alloc(&nm_gprs_nse_fsm, bts, &bts->gprs.nse, + LOGL_INFO, NULL); + osmo_fsm_inst_update_id_f(bts->gprs.nse.mo.fi, "gprs_nse%d", bts->nr); + gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE, bts->nr, 0xff, 0xff); + memcpy(&bts->gprs.nse.timer, bts_nse_timer_default, + sizeof(bts->gprs.nse.timer)); + for (i = 0; i < ARRAY_SIZE(bts->gprs.nsvc); i++) { bts->gprs.nsvc[i].bts = bts; bts->gprs.nsvc[i].id = i; gsm_mo_init(&bts->gprs.nsvc[i].mo, bts, NM_OC_GPRS_NSVC, bts->nr, i, 0xff); } - memcpy(&bts->gprs.nse.timer, bts_nse_timer_default, - sizeof(bts->gprs.nse.timer)); - gsm_mo_init(&bts->gprs.nse.mo, bts, NM_OC_GPRS_NSE, - bts->nr, 0xff, 0xff); memcpy(&bts->gprs.cell.timer, bts_cell_timer_default, sizeof(bts->gprs.cell.timer)); gsm_mo_init(&bts->gprs.cell.mo, bts, NM_OC_GPRS_CELL, @@ -372,9 +378,9 @@ int bts_init(struct gsm_bts *bts) /* Start with the site manager */ oml_mo_state_init(&bts->site_mgr.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); oml_mo_state_init(&bts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); + oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED); /* set BTS attr to dependency */ - oml_mo_state_init(&bts->gprs.nse.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); oml_mo_state_init(&bts->gprs.cell.mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); oml_mo_state_init(&bts->gprs.nsvc[0].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); oml_mo_state_init(&bts->gprs.nsvc[1].mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); @@ -446,12 +452,12 @@ int bts_link_estab(struct gsm_bts *bts) LOGP(DOML, LOGL_INFO, "Main link established, sending NM Status.\n"); - /* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS is DEPENDENCY */ + /* BTS SITE MGR becomes Offline (tx SW ACT Report), BTS, NSE is DEPENDENCY */ osmo_fsm_inst_dispatch(bts->site_mgr.mo.fi, NM_EV_SW_ACT, NULL); osmo_fsm_inst_dispatch(bts->mo.fi, NM_EV_SW_ACT, NULL); + osmo_fsm_inst_dispatch(bts->gprs.nse.mo.fi, NM_EV_SW_ACT, NULL); /* those should all be in DEPENDENCY */ - oml_tx_state_changed(&bts->gprs.nse.mo); oml_tx_state_changed(&bts->gprs.cell.mo); oml_tx_state_changed(&bts->gprs.nsvc[0].mo); oml_tx_state_changed(&bts->gprs.nsvc[1].mo); diff --git a/src/common/nm_bts_sm_fsm.c b/src/common/nm_bts_sm_fsm.c index 4767f9c9..f775265e 100644 --- a/src/common/nm_bts_sm_fsm.c +++ b/src/common/nm_bts_sm_fsm.c @@ -45,6 +45,7 @@ static void ev_dispatch_children(struct gsm_bts_sm *site_mgr, uint32_t event) { struct gsm_bts *bts = gsm_bts_sm_get_bts(site_mgr); + osmo_fsm_inst_dispatch(bts->gprs.nse.mo.fi, event, NULL); osmo_fsm_inst_dispatch(bts->mo.fi, event, NULL); } diff --git a/src/common/nm_gprs_nse_fsm.c b/src/common/nm_gprs_nse_fsm.c new file mode 100644 index 00000000..b6588282 --- /dev/null +++ b/src/common/nm_gprs_nse_fsm.c @@ -0,0 +1,278 @@ +/* NM GPRS NSE FSM */ + +/* (C) 2023 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de> + * Author: Pau Espin Pedrol <pespin@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <errno.h> +#include <unistd.h> +#include <inttypes.h> + +#include <osmocom/core/fsm.h> +#include <osmocom/core/tdef.h> +#include <osmocom/gsm/protocol/gsm_12_21.h> + +#include <osmo-bts/logging.h> +#include <osmo-bts/gsm_data.h> +#include <osmo-bts/bts_model.h> +#include <osmo-bts/bts.h> +#include <osmo-bts/rsl.h> +#include <osmo-bts/nm_common_fsm.h> +#include <osmo-bts/phy_link.h> +#include <osmo-bts/cbch.h> + +#define X(s) (1 << (s)) + +#define nm_gprs_nse_fsm_state_chg(fi, NEXT_STATE) \ + osmo_fsm_inst_state_chg(fi, NEXT_STATE, 0, 0) + +static void ev_dispatch_children(struct gsm_gprs_nse *nse, uint32_t event) +{ + /* TODO: once we have FSMs for GPRS Cell and GPRS NSVC: */ +#if 0 + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + osmo_fsm_inst_dispatch(bts->gprs.cell.mo.fi, event, NULL); + if (bts->gprs.nsvc[0].fi) + osmo_fsm_inst_dispatch(bts->gprs.nsvc[0].fi, event, NULL); + if (bts->gprs.nsvc[1].fi) + osmo_fsm_inst_dispatch(bts->gprs.nsvc[1].fi, event, NULL); +#endif +} + +/* Can the NSE be enabled (OPSTARTed)? aka should it stay in "Disabled Dependency" state? */ +static bool nse_can_be_enabled(struct gsm_gprs_nse *nse) +{ + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + return bts->mo.nm_state.operational == NM_OPSTATE_ENABLED; +} + + +////////////////////////// +// FSM STATE ACTIONS +////////////////////////// + +static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + /* Reset state here: */ + + nse->mo.setattr_success = false; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_NOT_INSTALLED, NM_STATE_LOCKED); +} + +static void st_op_disabled_notinstalled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + + switch (event) { + case NM_EV_SW_ACT: + oml_mo_tx_sw_act_rep(&nse->mo); + if (nse_can_be_enabled(nse)) + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE); + else + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + nse->mo.setattr_success = false; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY, -1); +} + +static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, + &nse->mo, nse); + nse->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nse->mo.setattr_success) { + oml_mo_opstart_nack(&nse->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nse->mo, nse); + break; + case NM_EV_OPSTART_ACK: + nse->mo.opstart_success = true; + oml_mo_opstart_ack(&nse->mo); + nm_gprs_nse_fsm_state_chg(fi, NM_CHAN_ST_OP_ENABLED); + return; + case NM_EV_OPSTART_NACK: + nse->mo.opstart_success = false; + oml_mo_opstart_nack(&nse->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_disabled_offline_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + nse->mo.opstart_success = false; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_OFF_LINE, -1); +} + +static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data *setattr_data; + int rc; + + switch (event) { + case NM_EV_RX_SETATTR: + setattr_data = (struct nm_fsm_ev_setattr_data *)data; + rc = bts_model_apply_oml(bts, setattr_data->msg, &nse->mo, bts); + nse->mo.setattr_success = rc == 0; + oml_fom_ack_nack_copy_msg(setattr_data->msg, rc); + break; + case NM_EV_RX_OPSTART: + if (!nse->mo.setattr_success) { + oml_mo_opstart_nack(&nse->mo, NM_NACK_CANT_PERFORM); + return; + } + bts_model_opstart(bts, &nse->mo, bts); + break; + case NM_EV_OPSTART_ACK: + nse->mo.opstart_success = true; + oml_mo_opstart_ack(&nse->mo); + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_ENABLED); + break; /* check statechg below */ + case NM_EV_OPSTART_NACK: + nse->mo.opstart_success = false; + oml_mo_opstart_nack(&nse->mo, (int)(intptr_t)data); + return; + default: + OSMO_ASSERT(0); + } +} + +static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + oml_mo_state_chg(&nse->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); +} + +static void st_op_enabled(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ +} + +static void nm_gprs_nse_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *data) +{ + struct gsm_gprs_nse *nse = (struct gsm_gprs_nse *)fi->priv; + + switch (event) { + case NM_EV_SHUTDOWN_START: + /* Announce we start shutting down */ + oml_mo_state_chg(&nse->mo, -1, -1, NM_STATE_SHUTDOWN); + + /* Propagate event to children: */ + ev_dispatch_children(nse, event); + break; + case NM_EV_SHUTDOWN_FINISH: + /* Propagate event to children: */ + ev_dispatch_children(nse, event); + nm_gprs_nse_fsm_state_chg(fi, NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED); + break; + default: + OSMO_ASSERT(false); + } +} + +static struct osmo_fsm_state nm_gprs_nse_fsm_states[] = { + [NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED] = { + .in_event_mask = + X(NM_EV_SW_ACT), + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY) | + X(NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE), + .name = "DISABLED_NOTINSTALLED", + .onenter = st_op_disabled_notinstalled_on_enter, + .action = st_op_disabled_notinstalled, + }, + [NM_GPRS_NSE_ST_OP_DISABLED_DEPENDENCY] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_ACK) | /* backward compatibility, buggy BSC */ + X(NM_EV_OPSTART_NACK), /* backward compatibility, buggy BSC */ + .out_state_mask = + X(NM_CHAN_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_CHAN_ST_OP_DISABLED_OFFLINE) | + X(NM_CHAN_ST_OP_ENABLED), /* backward compatibility, buggy BSC */ + .name = "DISABLED_DEPENDENCY", + .onenter = st_op_disabled_dependency_on_enter, + .action = st_op_disabled_dependency, + }, + [NM_GPRS_NSE_ST_OP_DISABLED_OFFLINE] = { + .in_event_mask = + X(NM_EV_RX_SETATTR) | + X(NM_EV_RX_OPSTART) | + X(NM_EV_OPSTART_ACK) | + X(NM_EV_OPSTART_NACK), + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED) | + X(NM_GPRS_NSE_ST_OP_ENABLED), + .name = "DISABLED_OFFLINE", + .onenter = st_op_disabled_offline_on_enter, + .action = st_op_disabled_offline, + }, + [NM_GPRS_NSE_ST_OP_ENABLED] = { + .in_event_mask = 0, + .out_state_mask = + X(NM_GPRS_NSE_ST_OP_DISABLED_NOTINSTALLED), + .name = "ENABLED", + .onenter = st_op_enabled_on_enter, + .action = st_op_enabled, + }, +}; + +struct osmo_fsm nm_gprs_nse_fsm = { + .name = "NM_GPRS_NSE_OP", + .states = nm_gprs_nse_fsm_states, + .num_states = ARRAY_SIZE(nm_gprs_nse_fsm_states), + .event_names = nm_fsm_event_names, + .allstate_action = nm_gprs_nse_allstate, + .allstate_event_mask = X(NM_EV_SHUTDOWN_START) | + X(NM_EV_SHUTDOWN_FINISH), + .log_subsys = DOML, +}; + +static __attribute__((constructor)) void nm_gprs_nse_fsm_init(void) +{ + OSMO_ASSERT(osmo_fsm_register(&nm_gprs_nse_fsm) == 0); +} diff --git a/src/common/oml.c b/src/common/oml.c index a55ba445..5e8f0ad4 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -1096,7 +1096,7 @@ static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg) if (!mo->fi) { /* Some NM objets still don't have FSMs implemented, such as - * NM_OC_GPRS_NSE, NM_OC_GPRS_CELL or NM_OC_GPRS_NSVC. For those, don't go through FSM: + * NM_OC_GPRS_CELL or NM_OC_GPRS_NSVC. For those, don't go through FSM: */ return bts_model_opstart(bts, mo, obj); } @@ -1257,16 +1257,21 @@ static int down_fom(struct gsm_bts *bts, struct msgb *msg) * manufacturer related messages */ -static int oml_ipa_mo_set_attr_nse(void *obj, const struct tlv_parsed *tp) +static int oml_ipa_mo_set_attr_nse(void *obj, + const struct msgb *msg, + const struct tlv_parsed *tp) { - struct gsm_bts *bts = container_of(obj, struct gsm_bts, gprs.nse); + struct gsm_gprs_nse *nse = obj; + struct gsm_bts *bts = gsm_gprs_nse_get_bts(nse); + struct nm_fsm_ev_setattr_data ev_data; + int rc; if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_NSEI, 2)) - bts->gprs.nse.nsei = + nse->nsei = ntohs(tlvp_val16_unal(tp, NM_ATT_IPACC_NSEI)); if (TLVP_PRES_LEN(tp, NM_ATT_IPACC_NS_CFG, 7)) { - memcpy(&bts->gprs.nse.timer, + memcpy(&nse->timer, TLVP_VAL(tp, NM_ATT_IPACC_NS_CFG), 7); } @@ -1275,6 +1280,13 @@ static int oml_ipa_mo_set_attr_nse(void *obj, const struct tlv_parsed *tp) TLVP_VAL(tp, NM_ATT_IPACC_BSSGP_CFG), 11); } + ev_data = (struct nm_fsm_ev_setattr_data){ + .msg = msg, + }; + rc = osmo_fsm_inst_dispatch(nse->mo.fi, NM_EV_RX_SETATTR, &ev_data); + if (rc < 0) + return NM_NACK_CANT_PERFORM; + osmo_signal_dispatch(SS_GLOBAL, S_NEW_NSE_ATTR, bts); return 0; @@ -1420,28 +1432,6 @@ static int oml_ipa_mo_set_attr_nsvc(struct gsm_bts_gprs_nsvc *nsvc, return 0; } -static int oml_ipa_mo_set_attr(struct gsm_bts *bts, const struct gsm_abis_mo *mo, - void *obj, const struct tlv_parsed *tp) -{ - int rc; - - switch (mo->obj_class) { - case NM_OC_GPRS_NSE: - rc = oml_ipa_mo_set_attr_nse(obj, tp); - break; - case NM_OC_GPRS_CELL: - rc = oml_ipa_mo_set_attr_cell(obj, tp); - break; - case NM_OC_GPRS_NSVC: - rc = oml_ipa_mo_set_attr_nsvc(obj, tp); - break; - default: - rc = NM_NACK_OBJINST_UNKN; - } - - return rc; -} - static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg) { struct abis_om_fom_hdr *foh = msgb_l3(msg); @@ -1468,18 +1458,37 @@ static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg) if (!mo || !obj) return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN); - rc = oml_ipa_mo_set_attr(bts, mo, obj, &tp); - if (rc == 0) { - /* Success: replace old MO attributes with new */ - /* merge existing MO attributes with new attributes */ - tp_merged = osmo_tlvp_copy(mo->nm_attr, bts); - talloc_set_name_const(tp_merged, "oml_ipa_attr"); - osmo_tlvp_merge(tp_merged, &tp); - talloc_free(mo->nm_attr); - mo->nm_attr = tp_merged; + + switch (mo->obj_class) { + case NM_OC_GPRS_NSE: + rc = oml_ipa_mo_set_attr_nse(obj, msg, &tp); + break; + case NM_OC_GPRS_CELL: + rc = oml_ipa_mo_set_attr_cell(obj, &tp); + break; + case NM_OC_GPRS_NSVC: + rc = oml_ipa_mo_set_attr_nsvc(obj, &tp); + break; + default: + rc = NM_NACK_OBJINST_UNKN; } - return oml_fom_ack_nack(msg, rc); + if (rc != 0) + return oml_fom_ack_nack(msg, rc); + + /* Success: replace old MO attributes with new */ + /* merge existing MO attributes with new attributes */ + tp_merged = osmo_tlvp_copy(mo->nm_attr, bts); + talloc_set_name_const(tp_merged, "oml_ipa_attr"); + osmo_tlvp_merge(tp_merged, &tp); + talloc_free(mo->nm_attr); + mo->nm_attr = tp_merged; + + /* These are not yet handled through NM FSM: */ + if (mo->obj_class == NM_OC_GPRS_CELL || + mo->obj_class == NM_OC_GPRS_NSVC) + return oml_fom_ack_nack(msg, rc); + return rc; } static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg, diff --git a/src/osmo-bts-lc15/oml.c b/src/osmo-bts-lc15/oml.c index 1ba5337e..aec639da 100644 --- a/src/osmo-bts-lc15/oml.c +++ b/src/osmo-bts-lc15/oml.c @@ -1866,6 +1866,7 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, case NM_OC_SITE_MANAGER: case NM_OC_BTS: case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: @@ -1876,7 +1877,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, ts = (struct gsm_bts_trx_ts*) obj; rc = ts_opstart(ts); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); diff --git a/src/osmo-bts-oc2g/oml.c b/src/osmo-bts-oc2g/oml.c index b6791813..a3e09aa7 100644 --- a/src/osmo-bts-oc2g/oml.c +++ b/src/osmo-bts-oc2g/oml.c @@ -1871,6 +1871,7 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, case NM_OC_SITE_MANAGER: case NM_OC_BTS: case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: @@ -1881,7 +1882,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, ts = (struct gsm_bts_trx_ts*) obj; rc = ts_opstart(ts); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); diff --git a/src/osmo-bts-octphy/l1_oml.c b/src/osmo-bts-octphy/l1_oml.c index d0fd3b58..08d120bf 100644 --- a/src/osmo-bts-octphy/l1_oml.c +++ b/src/osmo-bts-octphy/l1_oml.c @@ -1770,6 +1770,7 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) case NM_OC_SITE_MANAGER: case NM_OC_BTS: case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: @@ -1780,7 +1781,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) ts = (struct gsm_bts_trx_ts*) obj; rc = ts_connect_as(ts, ts->pchan, pchan_act_compl_cb, NULL); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1, -1); diff --git a/src/osmo-bts-omldummy/bts_model.c b/src/osmo-bts-omldummy/bts_model.c index b9be5ff5..04c4ab98 100644 --- a/src/osmo-bts-omldummy/bts_model.c +++ b/src/osmo-bts-omldummy/bts_model.c @@ -128,9 +128,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) case NM_OC_BASEB_TRANSC: case NM_OC_RADIO_CARRIER: case NM_OC_CHANNEL: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 772e9f26..725ab093 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -1747,6 +1747,7 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, case NM_OC_SITE_MANAGER: case NM_OC_BTS: case NM_OC_BASEB_TRANSC: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: @@ -1757,7 +1758,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, ts = (struct gsm_bts_trx_ts*) obj; rc = ts_opstart(ts); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); diff --git a/src/osmo-bts-trx/l1_if.c b/src/osmo-bts-trx/l1_if.c index a135479f..bf8393c6 100644 --- a/src/osmo-bts-trx/l1_if.c +++ b/src/osmo-bts-trx/l1_if.c @@ -584,6 +584,7 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, case NM_OC_BTS: case NM_OC_BASEB_TRANSC: case NM_OC_CHANNEL: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; case NM_OC_RADIO_CARRIER: @@ -591,7 +592,6 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, trx = (struct gsm_bts_trx *) obj; rc = trx_init(trx); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); diff --git a/src/osmo-bts-virtual/bts_model.c b/src/osmo-bts-virtual/bts_model.c index b9f060ce..a69e1d8a 100644 --- a/src/osmo-bts-virtual/bts_model.c +++ b/src/osmo-bts-virtual/bts_model.c @@ -163,9 +163,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, void *obj) case NM_OC_RADIO_CARRIER: case NM_OC_BASEB_TRANSC: case NM_OC_CHANNEL: + case NM_OC_GPRS_NSE: rc = osmo_fsm_inst_dispatch(mo->fi, NM_EV_OPSTART_ACK, NULL); break; - case NM_OC_GPRS_NSE: case NM_OC_GPRS_CELL: case NM_OC_GPRS_NSVC: oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK, -1); |