diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2012-07-23 18:20:36 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2012-07-23 18:25:43 +0200 |
commit | 7f5352c17bf08cbeba44849978ee984832f3e510 (patch) | |
tree | 2ecd1124ece7f2d7e416d1b82aaae882a0be36cb | |
parent | bc65586917eed2ac5a6ac00551b4f35935d0426c (diff) |
Fix: gprs_rlcmac_trigger_downlink_assignment() selects correct channel
In order to select correct channel (PCH or PACCH), a tbf pointer is set
in case of PACCH. The tbf pointer points to TBF whose PACCH is used.
-rw-r--r-- | src/gprs_bssgp_pcu.cpp | 12 | ||||
-rw-r--r-- | src/gprs_rlcmac.h | 4 | ||||
-rw-r--r-- | src/gprs_rlcmac_data.cpp | 23 |
3 files changed, 19 insertions, 20 deletions
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 217acdb9..d4a65574 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -141,7 +141,7 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) if (!tbf->ms_class && ms_class) tbf->ms_class = ms_class; tbf_update(tbf); - gprs_rlcmac_trigger_downlink_assignment(tbf, 1, NULL); + gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); } else { /* the TBF exists, so we must write it in the queue * we prepend lifetime in front of PDU */ @@ -173,18 +173,24 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) } } else { uint8_t trx, ts, use_trx, first_ts, ta, ss; + struct gprs_rlcmac_tbf *old_tbf; /* check for uplink data, so we copy our informations */ - if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF))) { + tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); + if (tbf && tbf->contention_resolution_done + && (tbf->state != GPRS_RLCMAC_FINISHED + || tbf->ul_ack_state != GPRS_RLCMAC_UL_ACK_WAIT_ACK)) { use_trx = tbf->trx; first_ts = tbf->first_ts; ta = tbf->ta; ss = 0; + old_tbf = tbf; } else { use_trx = -1; first_ts = -1; ta = 0; /* FIXME: initial TA */ ss = 1; /* PCH assignment only allows one timeslot */ + old_tbf = NULL; } // Create new TBF (any TRX) @@ -216,7 +222,7 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) * we don't use old_downlink, so the possible uplink is used * to trigger downlink assignment. if there is no uplink, * AGCH is used. */ - gprs_rlcmac_trigger_downlink_assignment(tbf, 0, imsi); + gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); } return 0; diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 8a8351d6..41fd2067 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -287,8 +287,8 @@ struct msgb *gprs_rlcmac_send_packet_uplink_assignment( struct msgb *gprs_rlcmac_send_packet_downlink_assignment( struct gprs_rlcmac_tbf *tbf, uint32_t fn); -void gprs_rlcmac_trigger_downlink_assignment(gprs_rlcmac_tbf *tbf, - uint8_t old_downlink, char *imsi); +void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_tbf *tbf, + struct gprs_rlcmac_tbf *old_tbf, char *imsi); int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final, uint8_t ssn, uint8_t *rbb); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 2a4c7b1a..e2549d41 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -315,7 +315,7 @@ void tbf_timer_cb(void *_tbf) switch (tbf->T) { #ifdef DEBUG_DL_ASS_IDLE case 1234: - gprs_rlcmac_trigger_downlink_assignment(tbf, 0, debug_imsi); + gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); break; #endif case 0: /* assignment */ @@ -1380,7 +1380,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final, "because another LLC PDU has arrived in between\n"); memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset RLC states */ tbf_update(tbf); - gprs_rlcmac_trigger_downlink_assignment(tbf, 1, NULL); + gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); return 0; } @@ -1406,7 +1406,7 @@ struct msgb *gprs_rlcmac_send_packet_downlink_assignment( /* be sure to check first, if contention resolution is done, * otherwise we cannot send the assignment yet */ if (!tbf->contention_resolution_done) { - LOGP(DRLCMAC, LOGL_NOTICE, "Cannot assign DL TBF now, " + LOGP(DRLCMAC, LOGL_DEBUG, "Cannot assign DL TBF now, " "because contention resolution is not " "finished.\n"); return NULL; @@ -1472,11 +1472,9 @@ static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll, } /* depending on the current TBF, we assign on PACCH or AGCH */ -void gprs_rlcmac_trigger_downlink_assignment(gprs_rlcmac_tbf *tbf, - uint8_t old_downlink, char *imsi) +void gprs_rlcmac_trigger_downlink_assignment(struct gprs_rlcmac_tbf *tbf, + struct gprs_rlcmac_tbf *old_tbf, char *imsi) { - gprs_rlcmac_tbf *old_tbf; - #ifdef DEBUG_DL_ASS_IDLE strncpy(debug_imsi, imsi); LOGP(DRLCMAC, LOGL_ERROR, "**** DEBUGGING DOWNLINK ASSIGNMENT ****\n"); @@ -1486,12 +1484,7 @@ void gprs_rlcmac_trigger_downlink_assignment(gprs_rlcmac_tbf *tbf, tbf_timer_stop(tbf); /* check for downlink tbf: */ - if (old_downlink) - old_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_DL_TBF); - else - old_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); - if (old_tbf && (old_tbf->state != GPRS_RLCMAC_FINISHED || - old_tbf->ul_ack_state != GPRS_RLCMAC_UL_ACK_WAIT_ACK)) { + if (old_tbf) { #ifdef DEBUG_DL_ASS_IDLE LOGP(DRLCMAC, LOGL_ERROR, "We must wait for current TBF to be " "released.\n"); @@ -1500,8 +1493,8 @@ void gprs_rlcmac_trigger_downlink_assignment(gprs_rlcmac_tbf *tbf, #else LOGP(DRLCMAC, LOGL_DEBUG, "Send dowlink assignment on " "PACCH, because %s TBF=%d exists for TLLI=0x%08x\n", - (old_tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - old_tbf->tfi, old_tbf->tlli); + (old_tbf->direction == GPRS_RLCMAC_UL_TBF) + ? "UL" : "DL", old_tbf->tfi, old_tbf->tlli); old_tbf->dl_ass_state = GPRS_RLCMAC_DL_ASS_SEND_ASS; /* use TA from old TBF */ tbf->ta = old_tbf->ta; |