diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-11-24 17:28:49 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-11-26 20:57:24 +0100 |
commit | 86dc355a3328ad2305d8bd0b1fb6684509352289 (patch) | |
tree | af71b93de9d6aa090b2e5b7530125823d97244da | |
parent | bc155706516dd63d1fbe3d87601df2f7606a1162 (diff) |
tbf: Split the handling of DL ACK/NACK into two separate parts
Split the handling of the final ack and the handling of frames
that is moving frames.
-rw-r--r-- | src/tbf.cpp | 126 | ||||
-rw-r--r-- | src/tbf.h | 2 |
2 files changed, 69 insertions, 59 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp index bb13de78..4fefab63 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1361,70 +1361,70 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ack(uint32_t fn) return msg; } -int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) +int gprs_rlcmac_tbf::update_window(const uint8_t ssn, const uint8_t *rbb) { - uint16_t mod_sns = m_sns - 1; - uint16_t mod_sns_half = (m_sns >> 1) - 1; - int i; /* must be signed */ int16_t dist; /* must be signed */ - uint16_t bsn; - struct msgb *msg; uint16_t lost = 0, received = 0; + const uint16_t mod_sns = m_sns - 1; + const uint16_t mod_sns_half = (m_sns >> 1) - 1; + char show_rbb[65]; + char show_v_b[RLC_MAX_SNS + 1]; + + Decoding::extract_rbb(rbb, show_rbb); + /* show received array in debug (bit 64..1) */ + LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" + "(BSN=%d) 1=ACK o=NACK\n", (ssn - 64) & mod_sns, + show_rbb, (ssn - 1) & mod_sns); + + /* apply received array to receive state (SSN-64..SSN-1) */ + /* calculate distance of ssn from V(S) */ + dist = (dir.dl.v_s - ssn) & mod_sns; + /* check if distance is less than distance V(A)..V(S) */ + if (dist >= ((dir.dl.v_s - dir.dl.v_a) & mod_sns)) { + /* this might happpen, if the downlink assignment + * was not received by ms and the ack refers + * to previous TBF + * FIXME: we should implement polling for + * control ack!*/ + LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " + "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); + return 1; /* indicate to free TBF */ + } - LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); + dir.dl.v_b.update(bts, show_rbb, ssn, dir.dl.v_a, + mod_sns, mod_sns_half, &lost, &received); - if (!final) { - char show_rbb[65]; - char show_v_b[RLC_MAX_SNS + 1]; - - Decoding::extract_rbb(rbb, show_rbb); - /* show received array in debug (bit 64..1) */ - LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" - "(BSN=%d) 1=ACK o=NACK\n", (ssn - 64) & mod_sns, - show_rbb, (ssn - 1) & mod_sns); - - /* apply received array to receive state (SSN-64..SSN-1) */ - /* calculate distance of ssn from V(S) */ - dist = (dir.dl.v_s - ssn) & mod_sns; - /* check if distance is less than distance V(A)..V(S) */ - if (dist >= ((dir.dl.v_s - dir.dl.v_a) & mod_sns)) { - /* this might happpen, if the downlink assignment - * was not received by ms and the ack refers - * to previous TBF - * FIXME: we should implement polling for - * control ack!*/ - LOGP(DRLCMACDL, LOGL_NOTICE, "- ack range is out of " - "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); - return 1; /* indicate to free TBF */ - } + /* report lost and received packets */ + gprs_rlcmac_received_lost(this, received, lost); - dir.dl.v_b.update(bts, show_rbb, ssn, dir.dl.v_a, - mod_sns, mod_sns_half, - &lost, &received); - - /* report lost and received packets */ - gprs_rlcmac_received_lost(this, received, lost); - - /* raise V(A), if possible */ - dir.dl.v_a += dir.dl.v_b.move_window(dir.dl.v_a, dir.dl.v_s, - mod_sns, mod_sns_half) & mod_sns; - - /* show receive state array in debug (V(A)..V(S)-1) */ - dir.dl.v_b.state(show_v_b, dir.dl.v_a, dir.dl.v_s, - mod_sns, mod_sns_half); - LOGP(DRLCMACDL, LOGL_DEBUG, "- V(B): (V(A)=%d)\"%s\"" - "(V(S)-1=%d) A=Acked N=Nacked U=Unacked " - "X=Resend-Unacked\n", dir.dl.v_a, show_v_b, - (dir.dl.v_s - 1) & mod_sns); - - if (state_is(GPRS_RLCMAC_FINISHED) - && dir.dl.v_s == dir.dl.v_a) { - LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " - "all blocks, but without final ack " - "inidcation (don't worry)\n"); - } - return 0; + /* raise V(A), if possible */ + dir.dl.v_a += dir.dl.v_b.move_window(dir.dl.v_a, dir.dl.v_s, + mod_sns, mod_sns_half) & mod_sns; + + /* show receive state array in debug (V(A)..V(S)-1) */ + dir.dl.v_b.state(show_v_b, dir.dl.v_a, dir.dl.v_s, + mod_sns, mod_sns_half); + LOGP(DRLCMACDL, LOGL_DEBUG, "- V(B): (V(A)=%d)\"%s\"" + "(V(S)-1=%d) A=Acked N=Nacked U=Unacked " + "X=Resend-Unacked\n", dir.dl.v_a, show_v_b, + (dir.dl.v_s - 1) & mod_sns); + + if (state_is(GPRS_RLCMAC_FINISHED) && dir.dl.v_s == dir.dl.v_a) { + LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " + "all blocks, but without final ack " + "inidcation (don't worry)\n"); } + return 0; +} + + +int gprs_rlcmac_tbf::maybe_start_new_window() +{ + const uint16_t mod_sns = m_sns - 1; + const uint16_t mod_sns_half = (m_sns >> 1) - 1; + uint16_t bsn; + struct msgb *msg; + uint16_t lost = 0, received = 0; LOGP(DRLCMACDL, LOGL_DEBUG, "- Final ACK received.\n"); /* range V(A)..V(S)-1 */ @@ -1441,8 +1441,7 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) msg = llc_dequeue(gprs_bssgp_pcu_current_bctx()); if (!msg) { /* no message, start T3193, change state to RELEASE */ - LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we " - "release.\n"); + LOGP(DRLCMACDL, LOGL_DEBUG, "- No new message, so we release.\n"); /* start T3193 */ tbf_timer_start(this, 3193, bts_data()->t3193_msec / 1000, @@ -1458,6 +1457,15 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) return 0; } +int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final_ack, uint8_t ssn, uint8_t *rbb) +{ + LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); + + if (!final_ack) + return update_window(ssn, rbb); + return maybe_start_new_window(); +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) { @@ -234,6 +234,8 @@ struct gprs_rlcmac_tbf { char m_imsi[16]; protected: + int update_window(const uint8_t ssn, const uint8_t *rbb); + int maybe_start_new_window(); void reuse_tbf(const uint8_t *data, const uint16_t len); gprs_rlcmac_bts *bts_data() const; bool dl_window_stalled() const; |