aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-05-01 15:43:22 +0000
committerHarald Welte <laforge@gnumonks.org>2009-05-01 15:43:22 +0000
commitb463060db9dccecf0608ec8ef1dae27640b4e403 (patch)
treee56a98e27f232de973bb18c7e5af220ec66f2c1a /src
parent6dafb7ba37c2c70fb8c9e142977950ef226dcf38 (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.
Diffstat (limited to 'src')
-rw-r--r--src/bsc_hack.c68
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;