aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-11-24 17:28:49 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-11-26 20:57:24 +0100
commit86dc355a3328ad2305d8bd0b1fb6684509352289 (patch)
treeaf71b93de9d6aa090b2e5b7530125823d97244da
parentbc155706516dd63d1fbe3d87601df2f7606a1162 (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.cpp126
-rw-r--r--src/tbf.h2
2 files changed, 69 insertions, 59 deletions
diff --git a/src/tbf.cpp b/src/tbf.cpp
index bb13de7..4fefab6 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++) {
diff --git a/src/tbf.h b/src/tbf.h
index e512ba5..6f5c48e 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -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;