bts: Fix crash of receiving data during the release process

Release/Free the lapdm resources _after_ the channel has
been fully released. Do not forward data unless the lchan
is in the active state.

Reading this code again, there is probably a memory leak for
everytime the PCU will re-connect to the BTS.

 (gdb) p lchan->state
 $4 = LCHAN_S_REL_REQ
 (gdb) bt
 #0  lapd_dl_flush_hist (dl=0x40454894) at lapd_core.c:164
 #1  0x44873b54 in lapd_rx_u (lctx=0xbe9bd5a8, msg=0x92f90) at lapd_core.c:1040
 #2  lapd_ph_data_ind (msg=0x92f90, lctx=0xbe9bd5a8) at lapd_core.c:1644
 #3  0x44876d50 in l2_ph_data_ind (link_id=<optimized out>, chan_nr=<optimized out>,
     le=<optimized out>, msg=0x92f90) at lapdm.c:637
 #4  lapdm_phsap_up (oph=<optimized out>, le=<optimized out>) at lapdm.c:707
 #5  0x0000c504 in handle_ph_data_ind (l1p_msg=0x97358, data_ind=0x97420, fl1=<optimized out>)
     at l1_if.c:774
 #6  l1if_handle_ind (fl1=<optimized out>, msg=0x97358) at l1_if.c:892
This commit is contained in:
Holger Hans Peter Freyther 2013-11-01 18:22:43 +01:00
parent f56d56c439
commit 2800b347e9
1 changed files with 13 additions and 2 deletions

View File

@ -497,6 +497,12 @@ int rsl_tx_rf_rel_ack(struct gsm_lchan *lchan)
LOGP(DRSL, LOGL_NOTICE, "%s Tx RF CHAN REL ACK\n", gsm_lchan_name(lchan));
/*
* Free the LAPDm resources now that the BTS
* has released all the resources.
*/
lapdm_channel_exit(&lchan->lapdm_ch);
msg = rsl_msgb_alloc(sizeof(struct abis_rsl_dchan_hdr));
if (!msg)
return -ENOMEM;
@ -800,8 +806,6 @@ static int rsl_rx_rf_chan_rel(struct gsm_lchan *lchan)
lchan->rel_act_kind = LCHAN_REL_ACT_RSL;
rc = bts_model_rsl_chan_rel(lchan);
lapdm_channel_exit(&lchan->lapdm_ch);
return rc;
}
@ -1570,6 +1574,13 @@ int lapdm_rll_tx_cb(struct msgb *msg, struct lapdm_entity *le, void *ctx)
struct gsm_lchan *lchan = ctx;
struct abis_rsl_common_hdr *rh = msgb_l2(msg);
if (lchan->state != LCHAN_S_ACTIVE) {
LOGP(DRSL, LOGL_INFO, "%s(%s) is not active . Dropping message.\n",
gsm_lchan_name(lchan), gsm_lchans_name(lchan->state));
msgb_free(msg);
return 0;
}
msg->trx = lchan->ts->trx;
/* check if this is a measurement report from SACCH which needs special