aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Kluchnikov <kluchnikovi@gmail.com>2014-02-20 11:23:10 +0400
committerIvan Kluchnikov <kluchnikovi@gmail.com>2014-02-20 11:23:10 +0400
commit73255e8b62db40b32cd754d3aced14ca1590d35a (patch)
tree421432bbdf4aedabccf2eaa5d7850f2d772e2ca0
parent3247ffec30724ed65514b967d9e3fee57c8b73c0 (diff)
rsl: Implement handling of rsl Delete Ind messagekluchnikov/rsl-delete-ind
If bsc receives Delete_Ind message from bts, bsc should release allocated channel, which was specified in dropped imm_assign message.
-rw-r--r--openbsc/src/libbsc/abis_rsl.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/openbsc/src/libbsc/abis_rsl.c b/openbsc/src/libbsc/abis_rsl.c
index f53ba8434..773090a1b 100644
--- a/openbsc/src/libbsc/abis_rsl.c
+++ b/openbsc/src/libbsc/abis_rsl.c
@@ -1539,6 +1539,40 @@ static int rsl_rx_ccch_load(struct msgb *msg)
return 0;
}
+/* CCCH is overloaded, IMM_ASSIGN was dropped */
+static int rsl_rx_delete_ind(struct gsm_bts_trx *trx, struct msgb *msg)
+{
+ struct abis_rsl_dchan_hdr *rqd_hdr = msgb_l2(msg);
+ struct gsm48_imm_ass *ia;
+ struct gsm_lchan *lchan;
+ struct gsm_bts_trx *cur_trx;
+ uint8_t chan_nr;
+ uint16_t arfcn;
+
+ /* bts didn't send IMM_ASSIGN, so we should release allocated channel */
+ if (msgb_l2len(msg) != MACBLOCK_SIZE + 6)
+ return -EIO;
+
+ ia = (struct gsm48_imm_ass *) (rqd_hdr->data + 2);
+
+ if (ia->msg_type == GSM48_MT_RR_IMM_ASS) {
+ chan_nr = ia->chan_desc.chan_nr;
+ arfcn = ia->chan_desc.h0.arfcn_high;
+ arfcn = (arfcn << 8) | ia->chan_desc.h0.arfcn_low;
+ cur_trx = gsm_bts_trx_by_arfcn(trx->bts, arfcn);
+ if (!cur_trx)
+ return -EINVAL;
+ lchan = lchan_lookup(cur_trx, chan_nr);
+ if (!lchan)
+ return -EINVAL;
+ if (lchan->state != LCHAN_S_ACTIVE)
+ return -EINVAL;
+ rsl_direct_rf_release(lchan);
+ }
+
+ return 0;
+}
+
static int abis_rsl_rx_cchan(struct msgb *msg)
{
struct e1inp_sign_link *sign_link = msg->dst;
@@ -1557,7 +1591,9 @@ static int abis_rsl_rx_cchan(struct msgb *msg)
rc = rsl_rx_ccch_load(msg);
break;
case RSL_MT_DELETE_IND:
- /* CCCH overloaded, IMM_ASSIGN was dropped */
+ /* CCCH is overloaded, IMM_ASSIGN was dropped */
+ rc = rsl_rx_delete_ind(sign_link->trx, msg);
+ break;
case RSL_MT_CBCH_LOAD_IND:
/* current load on the CBCH */
LOGP(DRSL, LOGL_NOTICE, "Unimplemented Abis RSL TRX message "