Fix crash with dyn TS when using direct pcu

It seems there may be a race conditon where lower layers (direct PCU)
send UL blocks to us while the PDCH was already disabled (due to a call
entering on a dynamic TS).
As the PDCH is disabled, the ULC is NULL and shouldn't be used before
being enabled again.

Related: OS#5222
Change-Id: I4b8931f0cc7cfc787a1cc35196295402524b15c3
This commit is contained in:
Pau Espin 2021-08-31 14:09:42 +02:00
parent a89a23881f
commit 3bbb3cc1f2
2 changed files with 26 additions and 15 deletions

View File

@ -1159,25 +1159,31 @@ void bts_update_tbf_ta(struct gprs_rlcmac_bts *bts, const char *p, uint32_t fn,
uint8_t trx_no, uint8_t ts, int8_t ta, bool is_rach)
{
struct gprs_rlcmac_pdch *pdch = &bts->trx[trx_no].pdch[ts];
struct pdch_ulc_node *poll = pdch_ulc_get_node(pdch->ulc, fn);
struct pdch_ulc_node *poll;
struct gprs_rlcmac_ul_tbf *tbf;
if (!pdch->is_enabled())
goto no_tbf;
poll = pdch_ulc_get_node(pdch->ulc, fn);
if (!poll || poll->type !=PDCH_ULC_NODE_TBF_POLL ||
poll->tbf_poll.poll_tbf->direction != GPRS_RLCMAC_UL_TBF)
LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to "
"unknown UL TBF on TRX = %d, TS = %d, FN = %d\n",
p, ta, trx_no, ts, fn);
else {
tbf = as_ul_tbf(poll->tbf_poll.poll_tbf);
/* we need to distinguish TA information provided by L1
* from PH-DATA-IND and PHY-RA-IND so that we can properly
* update TA for given TBF
*/
if (is_rach)
set_tbf_ta(tbf, (uint8_t)ta);
else
update_tbf_ta(tbf, ta);
goto no_tbf;
}
tbf = as_ul_tbf(poll->tbf_poll.poll_tbf);
/* we need to distinguish TA information provided by L1
* from PH-DATA-IND and PHY-RA-IND so that we can properly
* update TA for given TBF
*/
if (is_rach)
set_tbf_ta(tbf, (uint8_t)ta);
else
update_tbf_ta(tbf, ta);
return;
no_tbf:
LOGP(DL1IF, LOGL_DEBUG, "[%s] update TA = %u ignored due to "
"unknown UL TBF on TRX = %d, TS = %d, FN = %d\n",
p, ta, trx_no, ts, fn);
}
void bts_trx_init(struct gprs_rlcmac_trx *trx, struct gprs_rlcmac_bts *bts, uint8_t trx_no)

View File

@ -281,6 +281,11 @@ int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *
{
int rc;
if (!pdch->is_enabled()) {
LOGPDCH(pdch, DL1IF, LOGL_INFO, "Received DATA.ind (PDTCH) on disabled TS\n");
return -EINVAL;
}
rc = pdch->rcv_block(data, len, fn, meas);
pdch_ulc_expire_fn(pdch->ulc, fn);
return rc;