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
diff --git a/src/bts.cpp b/src/bts.cpp
index 12a1b04..62870db 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -1159,25 +1159,31 @@
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)
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 5aa8849..4530e1a 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -281,6 +281,11 @@
{
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;