diff options
author | Harald Welte <laforge@gnumonks.org> | 2009-05-01 15:43:22 +0000 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2009-05-01 15:43:22 +0000 |
commit | b463060db9dccecf0608ec8ef1dae27640b4e403 (patch) | |
tree | e56a98e27f232de973bb18c7e5af220ec66f2c1a | |
parent | 6dafb7ba37c2c70fb8c9e142977950ef226dcf38 (diff) |
Fix long-standing bug: nanoBTS now even works after cold boot (first time after power up).
The problem in the old logic was that we started talking to a given object
(e.g. radio carrier) one we received an administrative state change report. It
turns out we have to wait for the software activation report instead - and
everything suddenly works.
-rw-r--r-- | src/bsc_hack.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/bsc_hack.c b/src/bsc_hack.c index fb762337c..37cdaffd5 100644 --- a/src/bsc_hack.c +++ b/src/bsc_hack.c @@ -46,6 +46,7 @@ #include <openbsc/telnet_interface.h> #include <openbsc/paging.h> #include <openbsc/e1_input.h> +#include <openbsc/signal.h> /* global pointer to the gsm network data structure */ static struct gsm_network *gsmnet; @@ -359,6 +360,7 @@ static unsigned char nanobts_attr_e0[] = { 0x81, 0x0b, 0xbb, /* TCP PORT for RSL */ }; +/* Callback function to be called whenever we get a GSM 12.21 state change event */ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, struct gsm_nm_state *old_state, struct gsm_nm_state *new_state) { @@ -390,16 +392,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, } break; case NM_OC_RADIO_CARRIER: - trx = obj; - if (new_state->availability == 3) { - abis_nm_set_radio_attr(trx, nanobts_attr_radio, - sizeof(nanobts_attr_radio)); - abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER, - trx->bts->bts_nr, trx->nr, 0xff); - abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER, - trx->bts->bts_nr, trx->nr, 0xff, - NM_STATE_UNLOCKED); - } break; case NM_OC_CHANNEL: ts = obj; @@ -418,16 +410,6 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, break; case NM_OC_BASEB_TRANSC: trx = container_of(obj, struct gsm_bts_trx, bb_transc); - if (new_state->availability == 5) { - abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC, - trx->bts->bts_nr, trx->nr, 0xff, - nanobts_attr_e0, sizeof(nanobts_attr_e0)); - abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC, - trx->bts->bts_nr, trx->nr, 0xff); - abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC, - trx->bts->bts_nr, trx->nr, 0xff, - NM_STATE_UNLOCKED); - } break; } break; @@ -438,6 +420,50 @@ int nm_state_event(enum nm_evt evt, u_int8_t obj_class, void *obj, return 0; } +/* Callback function to be called every time we receive a 12.21 SW activated report */ +static int sw_activ_rep(struct msgb *mb) +{ + struct abis_om_fom_hdr *foh = msgb_l3(mb); + struct gsm_bts_trx *trx = mb->trx; + + switch (foh->obj_class) { + case NM_OC_BASEB_TRANSC: + /* TRX software is active, tell it to initiate RSL Link */ + abis_nm_ipaccess_msg(trx->bts, 0xe0, NM_OC_BASEB_TRANSC, + trx->bts->bts_nr, trx->nr, 0xff, + nanobts_attr_e0, sizeof(nanobts_attr_e0)); + abis_nm_opstart(trx->bts, NM_OC_BASEB_TRANSC, + trx->bts->bts_nr, trx->nr, 0xff); + abis_nm_chg_adm_state(trx->bts, NM_OC_BASEB_TRANSC, + trx->bts->bts_nr, trx->nr, 0xff, + NM_STATE_UNLOCKED); + break; + case NM_OC_RADIO_CARRIER: + abis_nm_set_radio_attr(trx, nanobts_attr_radio, + sizeof(nanobts_attr_radio)); + abis_nm_opstart(trx->bts, NM_OC_RADIO_CARRIER, + trx->bts->bts_nr, trx->nr, 0xff); + abis_nm_chg_adm_state(trx->bts, NM_OC_RADIO_CARRIER, + trx->bts->bts_nr, trx->nr, 0xff, + NM_STATE_UNLOCKED); + break; + } + return 0; +} + +/* Callback function to be called every time we receive a signal from NM */ +static int nm_sig_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + switch (signal) { + case S_NM_SW_ACTIV_REP: + return sw_activ_rep(signal_data); + default: + break; + } + return 0; +} + static void bootstrap_om_nanobts(struct gsm_bts *bts) { /* We don't do callback based bootstrapping, but event driven (see above) */ @@ -935,6 +961,8 @@ static int bootstrap_network(void) telnet_init(gsmnet, 4242); + register_signal_handler(SS_NM, nm_sig_cb, NULL); + /* E1 mISDN input setup */ if (BTS_TYPE == GSM_BTS_TYPE_BS11) { gsmnet->num_bts = 1; |