diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index aee359219..cd1209303 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -172,6 +172,7 @@ enum gsm_lchan_state { LCHAN_S_NONE, /* channel is not active */ LCHAN_S_ACT_REQ, /* channel activatin requested */ LCHAN_S_ACTIVE, /* channel is active and operational */ + LCHAN_S_REL_REQ, /* channel release has been requested */ LCHAN_S_INACTIVE, /* channel is set inactive */ }; diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index 667313b0a..6f13b4b30 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -921,6 +921,9 @@ int rsl_release_request(struct gsm_lchan *lchan, u_int8_t link_id) rh->link_id = link_id; msgb_tv_put(msg, RSL_IE_RELEASE_MODE, 0); /* normal release */ + lchan->state = LCHAN_S_REL_REQ; + /* FIXME: start some timer in case we don't receive a REL ACK ? */ + msg->trx = lchan->ts->trx; return abis_rsl_sendmsg(msg); @@ -936,6 +939,9 @@ static int rsl_rx_chan_act_ack(struct msgb *msg) if (rslh->ie_chan != RSL_IE_CHAN_NR) return -EINVAL; + if (msg->lchan->state != LCHAN_S_ACT_REQ) + LOGP(DRSL, LOGL_NOTICE, "%s CHAN ACT ACK, but state %u\n", + gsm_lchan_name(msg->lchan), msg->lchan->state); msg->lchan->state = LCHAN_S_ACTIVE; dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_ACK, msg->lchan); @@ -1056,8 +1062,11 @@ static int rsl_rx_meas_res(struct msgb *msg) /* check if this channel is actually active */ /* FIXME: maybe this check should be way more generic/centralized */ - if (msg->lchan->state != LCHAN_S_ACTIVE) + if (msg->lchan->state != LCHAN_S_ACTIVE) { + LOGP(DRSL, LOGL_NOTICE, "%s: MEAS RES for inactive channel\n", + gsm_lchan_name(msg->lchan)); return 0; + } memset(mr, 0, sizeof(*mr)); mr->lchan = msg->lchan; @@ -1161,6 +1170,9 @@ static int abis_rsl_rx_dchan(struct msgb *msg) break; case RSL_MT_RF_CHAN_REL_ACK: DEBUGP(DRSL, "%s RF CHANNEL RELEASE ACK\n", ts_name); + if (msg->lchan->state != LCHAN_S_REL_REQ) + LOGP(DRSL, LOGL_NOTICE, "%s CHAN REL ACK but state=%u\n", + gsm_lchan_name(msg->lchan), msg->lchan->state); msg->lchan->state = LCHAN_S_NONE; lchan_free(msg->lchan); break; @@ -1298,6 +1310,9 @@ static int rsl_rx_chan_rqd(struct msgb *msg) return -ENOMEM; } + if (lchan->state != LCHAN_S_NONE) + LOGP(DRSL, LOGL_NOTICE, "%s lchan_alloc() returned channel " + "in state %u\n", gsm_lchan_name(lchan), lchan->state); lchan->state = LCHAN_S_ACT_REQ; ts_number = lchan->ts->nr;