tbf: Avoid keeping poll nodes in pdch_ulc of temporary control_ts used during PACCH assignment
When MS sends us the Packet Resource Request as RRBP from final UL ACK/NACK, we create a new TBF with a different set of allocated TS. However, we must send the Pkt UL Assignment with information of the new TBF using that same TS where we receive the Packet Resource Request, which happens to be the control TS of the previous/old TBF. The original control TS of the new TBF is kept in tbf->first_common_ts. Hence the code does gprs_rlcmac_pdch::rcv_resource_request(): """ ul_tbf->control_ts = ts_no; """ And later, when we receive a CTRL ACK answering the Pkt UL Assigment, we change the control TS of the new TBF back to the new one, by calling tbf_assign_control_ts(), which basically does: """ tbf->control_ts = tbf->first_common_ts; """ So, for instance we have a TBF which was allocated with tbf->control_ts=4 and hence is only attached to PDCH 4 (tbf->pdch[]), but for which is temporarily applied tbf->control_ts=7. Hence, when a poll is requested, it is done in control_ts, aka 7, which is not in the array of attached PDCH. The problem is of course if we never reach the point where the final control_ts is set, due to never receiving the CTRL ACK. If the TBF is freed (due to timer X2001) before receiving the CTRL ACK and hence tbf_assign_control_ts() is called, a crash may occur, because potentially a poll for the TBF is left in TS 7 because it's not a PDCH attached to the TBF and hence poll entries on that TS are not released, hence keeping a pointer to the freed TBF. Related: SYS#5647 Change-Id: I0c49f2695e0d932d956c01976c9458eebee63cd4
This commit is contained in:
parent
ffa2918bc5
commit
b9fede74ef
10
src/tbf.cpp
10
src/tbf.cpp
|
@ -243,6 +243,16 @@ static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf)
|
|||
{
|
||||
int ts;
|
||||
|
||||
/* During assignment (state=ASSIGN), tbf may be temporarily using
|
||||
* tbf->control_ts from a previous TBF/SBA to transmit the UL/DL
|
||||
* Assignment, which may not be necessarly be a TS where the current TBF
|
||||
* is attached to. Hence, we may have ULC pollings ongoing and we need
|
||||
* to make sure we drop all reserved nodes there: */
|
||||
if (tbf_state(tbf) == TBF_ST_ASSIGN &&
|
||||
tbf->control_ts != TBF_CONTROL_TS_UNSET && !tbf->pdch[tbf->control_ts])
|
||||
pdch_ulc_release_tbf(tbf->trx->pdch[tbf->control_ts].ulc, tbf);
|
||||
|
||||
/* Now simply detach from all attached PDCHs */
|
||||
for (ts = 0; ts < 8; ts++) {
|
||||
if (!tbf->pdch[ts])
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue