diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index cb64c4cfb..52b20a8b9 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -447,6 +447,8 @@ struct gsm_abis_mo { bool get_attr_rep_received; bool set_attr_sent; bool set_attr_ack_received; + bool rsl_connect_sent; + bool rsl_connect_ack_received; bool force_rf_lock; }; diff --git a/include/osmocom/bsc/nm_common_fsm.h b/include/osmocom/bsc/nm_common_fsm.h index 1d56220be..b41d24a60 100644 --- a/include/osmocom/bsc/nm_common_fsm.h +++ b/include/osmocom/bsc/nm_common_fsm.h @@ -40,6 +40,8 @@ enum nm_fsm_events { NM_EV_OML_DOWN, NM_EV_FORCE_LOCK, /* Only supported by RadioCarrier so far */ NM_EV_FEATURE_NEGOTIATED, /* Sent by BTS to NSVC MO */ + NM_EV_RSL_CONNECT_ACK, /* Sent by BTS to BBTRANSC MO */ + NM_EV_RSL_CONNECT_NACK, /* Sent by BTS to BBTRANSC MO */ }; extern const struct value_string nm_fsm_event_names[]; diff --git a/src/osmo-bsc/abis_nm.c b/src/osmo-bsc/abis_nm.c index b151f36e6..938f45d13 100644 --- a/src/osmo-bsc/abis_nm.c +++ b/src/osmo-bsc/abis_nm.c @@ -2966,6 +2966,7 @@ static int abis_nm_rx_ipacc(struct msgb *msg) signal.foh = foh; osmo_signal_dispatch(SS_NM, S_NM_IPACC_NACK, &signal); break; + case NM_MT_IPACC_RSL_CONNECT_ACK: case NM_MT_IPACC_SET_NVATTR_ACK: case NM_MT_IPACC_SET_ATTR_ACK: signal.bts = bts; diff --git a/src/osmo-bsc/bts_ipaccess_nanobts.c b/src/osmo-bsc/bts_ipaccess_nanobts.c index 0af5a2874..316594465 100644 --- a/src/osmo-bsc/bts_ipaccess_nanobts.c +++ b/src/osmo-bsc/bts_ipaccess_nanobts.c @@ -443,12 +443,56 @@ static void nm_rx_ipacc_set_attr_ack(struct ipacc_ack_signal_data *sig_data) } } +static void nm_rx_ipacc_rsl_connect_ack(struct ipacc_ack_signal_data *sig_data) +{ + struct gsm_bts *bts = sig_data->bts; + struct abis_om_fom_hdr *foh = sig_data->foh; + struct gsm_bts_trx *trx; + + if (foh->obj_class != NM_OC_BASEB_TRANSC) { + LOGPFOH(DNM, LOGL_ERROR, foh, "IPACC RSL Connect ACK received on incorrect object class %d!\n", foh->obj_class); + return; + } + + trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_CONNECT_ACK, NULL); +} + static void nm_rx_ipacc_ack(struct ipacc_ack_signal_data *sig_data) { switch (sig_data->foh->msg_type) { case NM_MT_IPACC_SET_ATTR_ACK: nm_rx_ipacc_set_attr_ack(sig_data); break; + case NM_MT_IPACC_RSL_CONNECT_ACK: + nm_rx_ipacc_rsl_connect_ack(sig_data); + break; + default: + break; + } +} + +static void nm_rx_ipacc_rsl_connect_nack(struct ipacc_ack_signal_data *sig_data) +{ + struct gsm_bts *bts = sig_data->bts; + struct abis_om_fom_hdr *foh = sig_data->foh; + struct gsm_bts_trx *trx; + + if (foh->obj_class != NM_OC_BASEB_TRANSC) { + LOGPFOH(DNM, LOGL_ERROR, foh, "IPACC RSL Connect NACK received on incorrect object class %d!\n", foh->obj_class); + return; + } + + trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr); + osmo_fsm_inst_dispatch(trx->bb_transc.mo.fi, NM_EV_RSL_CONNECT_NACK, NULL); +} + +static void nm_rx_ipacc_nack(struct ipacc_ack_signal_data *sig_data) +{ + switch (sig_data->foh->msg_type) { + case NM_MT_IPACC_RSL_CONNECT_ACK: + nm_rx_ipacc_rsl_connect_nack(sig_data); + break; default: break; } @@ -487,6 +531,9 @@ static int bts_ipa_nm_sig_cb(unsigned int subsys, unsigned int signal, case S_NM_IPACC_ACK: nm_rx_ipacc_ack(signal_data); return 0; + case S_NM_IPACC_NACK: + nm_rx_ipacc_nack(signal_data); + return 0; default: break; } diff --git a/src/osmo-bsc/nm_bb_transc_fsm.c b/src/osmo-bsc/nm_bb_transc_fsm.c index bf2469145..3a8786bfe 100644 --- a/src/osmo-bsc/nm_bb_transc_fsm.c +++ b/src/osmo-bsc/nm_bb_transc_fsm.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,8 @@ static void st_op_disabled_notinstalled_on_enter(struct osmo_fsm_inst *fi, uint3 bb_transc->mo.get_attr_sent = false; bb_transc->mo.get_attr_rep_received = false; bb_transc->mo.adm_unlock_sent = false; + bb_transc->mo.rsl_connect_sent = false; + bb_transc->mo.rsl_connect_ack_received = false; bb_transc->mo.opstart_sent = false; } @@ -125,14 +128,22 @@ static void configure_loop(struct gsm_bts_bb_trx *bb_transc, const struct gsm_nm NM_STATE_UNLOCKED); } + /* Provision BTS with RSL IP addr & port to connect to: */ if (allow_opstart && state->administrative == NM_STATE_UNLOCKED && - !bb_transc->mo.opstart_sent) { - bb_transc->mo.opstart_sent = true; - abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC, trx->bts->bts_nr, trx->nr, 0xff); - /* TRX software is active, tell it to initiate RSL Link */ + !bb_transc->mo.rsl_connect_sent && !bb_transc->mo.rsl_connect_ack_received) { + bb_transc->mo.rsl_connect_sent = true; abis_nm_ipaccess_rsl_connect(trx, trx->bts->ip_access.rsl_ip, 3003, trx->rsl_tei_primary); } + + /* OPSTART after receiving RSL CONNECT ACK. We cannot delay until the + * RSL/IPA socket is connected to us because nanoBTS only attempts + * connection after receiving an OPSTART: */ + if (allow_opstart && state->administrative == NM_STATE_UNLOCKED && + bb_transc->mo.rsl_connect_ack_received && !bb_transc->mo.opstart_sent) { + bb_transc->mo.opstart_sent = true; + abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC, trx->bts->bts_nr, trx->nr, 0xff); + } } static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state) @@ -150,6 +161,7 @@ static void st_op_disabled_dependency_on_enter(struct osmo_fsm_inst *fi, uint32_ static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, void *data) { struct gsm_bts_bb_trx *bb_transc = (struct gsm_bts_bb_trx *)fi->priv; + struct gsm_bts_trx *trx = gsm_bts_bb_trx_get_trx(bb_transc); struct nm_statechg_signal_data *nsd; const struct gsm_nm_state *new_state; @@ -159,6 +171,14 @@ static void st_op_disabled_dependency(struct osmo_fsm_inst *fi, uint32_t event, bb_transc->mo.get_attr_sent = false; configure_loop(bb_transc, &bb_transc->mo.nm_state, false); return; + case NM_EV_RSL_CONNECT_ACK: + bb_transc->mo.rsl_connect_ack_received = true; + bb_transc->mo.rsl_connect_sent = false; + configure_loop(bb_transc, &bb_transc->mo.nm_state, false); + break; + case NM_EV_RSL_CONNECT_NACK: + ipaccess_drop_oml_deferred(trx->bts); + break; case NM_EV_STATE_CHG_REP: nsd = (struct nm_statechg_signal_data *)data; new_state = &nsd->new_state; @@ -207,6 +227,14 @@ static void st_op_disabled_offline(struct osmo_fsm_inst *fi, uint32_t event, voi bb_transc->mo.get_attr_sent = false; configure_loop(bb_transc, &bb_transc->mo.nm_state, true); return; + case NM_EV_RSL_CONNECT_ACK: + bb_transc->mo.rsl_connect_ack_received = true; + bb_transc->mo.rsl_connect_sent = false; + configure_loop(bb_transc, &bb_transc->mo.nm_state, true); + break; + case NM_EV_RSL_CONNECT_NACK: + ipaccess_drop_oml_deferred(trx->bts); + break; case NM_EV_STATE_CHG_REP: nsd = (struct nm_statechg_signal_data *)data; new_state = &nsd->new_state; @@ -251,8 +279,10 @@ static void st_op_enabled_on_enter(struct osmo_fsm_inst *fi, uint32_t prev_state reused as soon as we move back to Disabled */ bb_transc->mo.get_attr_sent = false; bb_transc->mo.get_attr_rep_received = false; - bb_transc->mo.opstart_sent = false; bb_transc->mo.adm_unlock_sent = false; + bb_transc->mo.rsl_connect_ack_received = false; + bb_transc->mo.rsl_connect_sent = false; + bb_transc->mo.opstart_sent = false; nm_bb_transc_fsm_becomes_enabled(bb_transc); } @@ -330,7 +360,9 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = { [NM_BB_TRANSC_ST_OP_DISABLED_DEPENDENCY] = { .in_event_mask = X(NM_EV_STATE_CHG_REP) | - X(NM_EV_GET_ATTR_REP), + X(NM_EV_GET_ATTR_REP) | + X(NM_EV_RSL_CONNECT_ACK) | + X(NM_EV_RSL_CONNECT_NACK), .out_state_mask = X(NM_BB_TRANSC_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BB_TRANSC_ST_OP_DISABLED_OFFLINE) | @@ -342,7 +374,9 @@ static struct osmo_fsm_state nm_bb_transc_fsm_states[] = { [NM_BB_TRANSC_ST_OP_DISABLED_OFFLINE] = { .in_event_mask = X(NM_EV_STATE_CHG_REP) | - X(NM_EV_GET_ATTR_REP), + X(NM_EV_GET_ATTR_REP) | + X(NM_EV_RSL_CONNECT_ACK) | + X(NM_EV_RSL_CONNECT_NACK), .out_state_mask = X(NM_BB_TRANSC_ST_OP_DISABLED_NOTINSTALLED) | X(NM_BB_TRANSC_ST_OP_DISABLED_DEPENDENCY) | diff --git a/src/osmo-bsc/nm_common_fsm.c b/src/osmo-bsc/nm_common_fsm.c index b0902b171..2bf38ac31 100644 --- a/src/osmo-bsc/nm_common_fsm.c +++ b/src/osmo-bsc/nm_common_fsm.c @@ -33,6 +33,8 @@ const struct value_string nm_fsm_event_names[] = { { NM_EV_OML_DOWN, "OML_DOWN" }, { NM_EV_FORCE_LOCK, "FORCE_LOCK_CHG" }, { NM_EV_FEATURE_NEGOTIATED, "FEATURE_NEGOTIATED" }, + { NM_EV_RSL_CONNECT_ACK, "RSL_CONNECT_ACK" }, + { NM_EV_RSL_CONNECT_NACK, "RSL_CONNECT_NACK" }, { 0, NULL } };