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.
diff --git a/src/bsc_hack.c b/src/bsc_hack.c
index fb76233..37cdaff 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 @@
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 @@
}
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 @@
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 @@
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 @@
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;