aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2021-08-31 14:09:42 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2021-08-31 14:36:02 +0200
commit3bbb3cc1f23a74987b2fc993fbc38e8c05c6ac08 (patch)
tree307adc5935a68f06a4c231eaa3ab4a88fca5ddbd
parenta89a23881f26ea16b53a1736b2e617b3bf831965 (diff)
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
-rw-r--r--src/bts.cpp36
-rw-r--r--src/pcu_l1_if.cpp5
2 files changed, 26 insertions, 15 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 12a1b04b..62870db5 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -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)
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 5aa88494..4530e1a5 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -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;