From 9fa0cce100d25585f5a1baff3353cd54a5a58d5f Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Fri, 1 Jul 2011 18:09:34 +0200 Subject: [PATCH] fix BTS initialization order The sequence is as follows: 0) start osmo-bts 1) start connection attempts to BTS 2) issue L1-RESET.req 3) receive L1-RESET.conf 4) issue RF-ACTIVATE.req 5) receive RF-ACTIVATE.conf 6) receive attributes for TRX 7) receive opstart for TRX 8) issue MPH-INIT.req [...] The important point here is: We don't want the BSC to set TRX attributes or do TRX opstart before our RF related hardware is initialized. --- include/osmo-bts/bts.h | 2 +- src/common/abis.c | 9 +++++++-- src/common/bts.c | 24 ++++++++++++++---------- src/common/oml.c | 9 ++++----- src/osmo-bts-sysmo/l1_if.c | 38 +++++++++++++++++++++++++++++++++++--- src/osmo-bts-sysmo/main.c | 2 +- src/osmo-bts-sysmo/oml.c | 15 ++++++++++++--- 7 files changed, 74 insertions(+), 25 deletions(-) diff --git a/include/osmo-bts/bts.h b/include/osmo-bts/bts.h index 1a5a7fd68..92be011c4 100644 --- a/include/osmo-bts/bts.h +++ b/include/osmo-bts/bts.h @@ -6,7 +6,7 @@ extern void *tall_bts_ctx; int bts_init(struct gsm_bts *bts); -void bts_shutdown(struct gsm_bts *bts); +void bts_shutdown(struct gsm_bts *bts, const char *reason); struct gsm_bts *create_bts(uint8_t num_trx, char *id); int create_ms(struct gsm_bts_trx *trx, int maskc, uint8_t *maskv_tx, diff --git a/src/common/abis.c b/src/common/abis.c index c1e1c4f30..7a08e188f 100644 --- a/src/common/abis.c +++ b/src/common/abis.c @@ -74,6 +74,11 @@ int abis_oml_sendmsg(struct msgb *msg) abis_push_ipa(msg, 0xff); + if (!bts->oml_link) { + msgb_free(msg); + return 0; + } + return abis_tx((struct ipabis_link *) bts->oml_link, msg); } @@ -516,9 +521,9 @@ void abis_close(struct ipabis_link *link) /* for now, we simply terminate the program and re-spawn */ if (link->bts) - bts_shutdown(link->bts); + bts_shutdown(link->bts, "Abis close / OML"); else if (link->trx) - bts_shutdown(link->trx->bts); + bts_shutdown(link->trx->bts, "Abis close / RSL"); else exit(43); } diff --git a/src/common/bts.c b/src/common/bts.c index 19a3e4305..e34639729 100644 --- a/src/common/bts.c +++ b/src/common/bts.c @@ -53,6 +53,9 @@ int bts_init(struct gsm_bts *bts) /* FIXME: make those parameters configurable */ btsb->paging_state = paging_init(btsb, 200, 0); + /* set BTS to dependency */ + oml_mo_state_chg(&bts->mo, -1, NM_AVSTATE_DEPENDENCY); + return bts_model_init(bts); } @@ -65,10 +68,13 @@ static struct osmo_timer_list shutdown_timer = { .cb = &shutdown_timer_cb, }; -void bts_shutdown(struct gsm_bts *bts) +void bts_shutdown(struct gsm_bts *bts, const char *reason) { struct gsm_bts_trx *trx; + LOGP(DOML, LOGL_INFO, "Shutting down BTS %u, Reason %s\n", + bts->nr, reason); + llist_for_each_entry(trx, &bts->trx_list, list) bts_model_trx_deact_rf(trx); @@ -302,27 +308,25 @@ void destroy_bts(struct osmocom_bts *bts) int bts_link_estab(struct gsm_bts *bts) { int i, j; - uint8_t radio_state; LOGP(DSUM, LOGL_INFO, "Main link established, sending Status'.\n"); - oml_mo_state_chg(&bts->site_mgr.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - oml_mo_state_chg(&bts->mo, NM_OPSTATE_ENABLED, NM_AVSTATE_DEPENDENCY); + /* BTS and SITE MGR are EAABLED, BTS is DEPENDENCY */ + oml_tx_state_changed(&bts->site_mgr.mo); + oml_tx_state_changed(&bts->mo); + /* All other objects start off-line until the BTS Model code says otherwise */ for (i = 0; i < bts->num_trx; i++) { struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, i); struct ipabis_link *link = (struct ipabis_link *) trx->rsl_link; - radio_state = (link && link->state == LINK_STATE_CONNECT) ? NM_OPSTATE_ENABLED : NM_OPSTATE_DISABLED; - oml_mo_state_chg(&trx->mo, radio_state, NM_AVSTATE_OK); - oml_mo_tx_sw_act_rep(&trx->mo); - oml_mo_state_chg(&trx->bb_transc.mo, NM_OPSTATE_ENABLED, NM_AVSTATE_OK); - oml_mo_tx_sw_act_rep(&trx->bb_transc.mo); + oml_tx_state_changed(&trx->mo); + oml_tx_state_changed(&trx->bb_transc.mo); for (j = 0; j < ARRAY_SIZE(trx->ts); j++) { struct gsm_bts_trx_ts *ts = &trx->ts[j]; - oml_mo_state_chg(&ts->mo, NM_OPSTATE_DISABLED, NM_AVSTATE_DEPENDENCY); + oml_tx_state_changed(&ts->mo); } } diff --git a/src/common/oml.c b/src/common/oml.c index 26363321b..ca19490ad 100644 --- a/src/common/oml.c +++ b/src/common/oml.c @@ -207,8 +207,7 @@ char *gsm_abis_mo_name(const struct gsm_abis_mo *mo) } /* 8.8.1 sending State Changed Event Report */ -int oml_tx_state_changed(struct gsm_abis_mo *mo, - uint8_t op_state, uint8_t avail_status) +int oml_tx_state_changed(struct gsm_abis_mo *mo) { struct msgb *nmsg; @@ -219,10 +218,10 @@ int oml_tx_state_changed(struct gsm_abis_mo *mo, return -ENOMEM; /* 9.4.38 Operational State */ - msgb_tv_put(nmsg, NM_ATT_OPER_STATE, op_state); + msgb_tv_put(nmsg, NM_ATT_OPER_STATE, mo->nm_state.operational); /* 9.4.7 Availability Status */ - msgb_tl16v_put(nmsg, NM_ATT_AVAIL_STATUS, 1, &avail_status); + msgb_tl16v_put(nmsg, NM_ATT_AVAIL_STATUS, 1, &mo->nm_state.availability); return oml_mo_send_msg(mo, nmsg, NM_MT_STATECHG_EVENT_REP); } @@ -249,7 +248,7 @@ int oml_mo_state_chg(struct gsm_abis_mo *mo, int op_state, int avail_state) } /* send state change report */ - rc = oml_tx_state_changed(mo, op_state, avail_state); + rc = oml_tx_state_changed(mo); } return rc; } diff --git a/src/osmo-bts-sysmo/l1_if.c b/src/osmo-bts-sysmo/l1_if.c index 2206cbc4d..d4cb7fdbb 100644 --- a/src/osmo-bts-sysmo/l1_if.c +++ b/src/osmo-bts-sysmo/l1_if.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -111,7 +112,7 @@ int l1if_req_compl(struct femtol1_hdl *fl1h, struct msgb *msg, wlc->is_sys_prim = 0; wlc->conf_prim_id = femtobts_l1prim_req2conf[l1p->id]; wqueue = &fl1h->write_q[MQ_L1_WRITE]; - timeout_secs = 10; + timeout_secs = 30; } else { FemtoBts_Prim_t *sysp = msgb_sysprim(msg); @@ -592,8 +593,11 @@ int sysinfo_has_changed(struct gsm_bts *bts, int si) static int activate_rf_compl_cb(struct msgb *resp, void *data) { FemtoBts_Prim_t *sysp = msgb_sysprim(resp); + struct femtol1_hdl *fl1h = data; + struct gsm_bts_trx *trx = fl1h->priv; GsmL1_Status_t status; int on = 0; + unsigned int i; if (sysp->id == FemtoBts_PrimId_ActivateRfCnf) on = 1; @@ -606,11 +610,32 @@ static int activate_rf_compl_cb(struct msgb *resp, void *data) LOGP(DL1C, LOGL_INFO, "Rx RF-%sACT.conf (status=%s)\n", on ? "" : "DE", get_value_string(femtobts_l1status_names, status)); + + if (on) { + if (status != GsmL1_Status_Success) { + LOGP(DL1C, LOGL_FATAL, "RF-ACT.conf with status %s\n", + get_value_string(femtobts_l1status_names, status)); + bts_shutdown(trx->bts, "RF-ACT failure"); + } + /* 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); + + 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); + } + talloc_free(resp); return 0; } +/* activate or de-activate the entire RF-Frontend */ int l1if_activate_rf(struct femtol1_hdl *hdl, int on) { struct msgb *msg = sysp_msgb_alloc(); @@ -629,6 +654,7 @@ int l1if_activate_rf(struct femtol1_hdl *hdl, int on) static int reset_compl_cb(struct msgb *resp, void *data) { struct femtol1_hdl *fl1h = data; + struct gsm_bts_trx *trx = fl1h->priv; FemtoBts_Prim_t *sysp = msgb_sysprim(resp); GsmL1_Status_t status = sysp->u.layer1ResetCnf.status; @@ -638,8 +664,14 @@ static int reset_compl_cb(struct msgb *resp, void *data) talloc_free(resp); /* If we're coming out of reset .. */ - if (status == GsmL1_Status_Success) - l1if_activate_rf(fl1h, 1); + if (status != GsmL1_Status_Success) { + LOGP(DL1C, LOGL_FATAL, "L1-RESET.conf with status %s\n", + get_value_string(femtobts_l1status_names, status)); + bts_shutdown(trx->bts, "L1-RESET failure"); + } + + /* otherwise, request activation of RF board */ + l1if_activate_rf(fl1h, 1); return 0; } diff --git a/src/osmo-bts-sysmo/main.c b/src/osmo-bts-sysmo/main.c index cf6aeae91..07ed8dcbb 100644 --- a/src/osmo-bts-sysmo/main.c +++ b/src/osmo-bts-sysmo/main.c @@ -170,7 +170,7 @@ static void signal_handler(int signal) switch (signal) { case SIGINT: //osmo_signal_dispatch(SS_GLOBAL, S_GLOBAL_SHUTDOWN, NULL); - bts_shutdown(bts); + bts_shutdown(bts, "SIGINT"); break; case SIGABRT: case SIGUSR1: diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index c765c595f..9c471a895 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -195,9 +195,17 @@ static int trx_init_compl_cb(struct msgb *l1_msg, void *data) GsmL1_Prim_t *l1p = msgb_l1prim(l1_msg); GsmL1_MphInitCnf_t *ic = &l1p->u.mphInitCnf; + LOGP(DL1C, LOGL_INFO, "Rx MPH-INIT.conf (status=%s)\n", + get_value_string(femtobts_l1status_names, ic->status)); + /* store layer1 handle */ - if (ic->status == GsmL1_Status_Success) - fl1h->hLayer1 = ic->hLayer1; + if (ic->status != GsmL1_Status_Success) { + LOGP(DL1C, LOGL_FATAL, "Rx MPH-INIT.conf status=%s\n", + get_value_string(femtobts_l1status_names, ic->status)); + bts_shutdown(trx->bts, "MPH-INIT failure"); + } + + fl1h->hLayer1 = ic->hLayer1; return opstart_compl_cb(l1_msg, &trx->mo); } @@ -585,8 +593,9 @@ int bts_model_opstart(struct gsm_bts *bts, struct gsm_abis_mo *mo, case NM_OC_BTS: case NM_OC_SITE_MANAGER: case NM_OC_BASEB_TRANSC: - mo->nm_state.operational = NM_OPSTATE_ENABLED; + oml_mo_state_chg(mo, NM_OPSTATE_ENABLED, -1); rc = oml_mo_opstart_ack(mo); + break; default: rc = oml_mo_opstart_nack(mo, NM_NACK_OBJCLASS_NOTSUPP); }