From df6b4f52e05e699b9a96a920973bff6241b5a853 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 24 Nov 2013 17:05:48 +0100 Subject: [PATCH] tbf/rlc: Move the parsing of RBB to Decoding, move window marking out Move the parsing of the bitbmap out of the TBF code into Decoding. Move the updating of the V_B into the V_B class. Add some comments about handling the mod_sns, mod_sns_half parameters by using template code. --- src/decoding.cpp | 14 ++++++++++++++ src/decoding.h | 2 ++ src/rlc.cpp | 29 +++++++++++++++++++++++++++++ src/rlc.h | 8 ++++++++ src/tbf.cpp | 34 ++++++++-------------------------- 5 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/decoding.cpp b/src/decoding.cpp index e7ec99ab..0f70872a 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -83,3 +83,17 @@ uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) return 0; } +/** + * show_rbb needs to be an array with 65 elements + */ +void Decoding::extract_rbb(const uint8_t *rbb, char *show_rbb) +{ + for (int i = 63; i >= 0; i--) { + uint8_t bit; + + bit = (rbb[i >> 3] >> (7 - (i&7))) & 1; + show_rbb[i] = bit ? '1' : 'o'; + } + + show_rbb[64] = '\0'; +} diff --git a/src/decoding.h b/src/decoding.h index 0590eb40..31be0320 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -28,4 +28,6 @@ public: static int tlli_from_ul_data(const uint8_t *data, uint8_t len, uint32_t *tlli); static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap); + + static void extract_rbb(const uint8_t *rbb, char *extracted_rbb); }; diff --git a/src/rlc.cpp b/src/rlc.cpp index f6b13623..d33e2067 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -17,6 +17,8 @@ */ #include "tbf.h" +#include "bts.h" +#include "gprs_debug.h" extern "C" { #include @@ -68,3 +70,30 @@ int gprs_rlc_v_b::mark_for_resend(const uint16_t v_a, const uint16_t v_s, return resend; } + +void gprs_rlc_v_b::update(BTS *bts, char *show_rbb, uint8_t ssn, + const uint16_t v_a, + const uint16_t mod_sns, const uint16_t mod_sns_half, + uint16_t *lost, uint16_t *received) +{ + uint16_t bsn; + int i; + + /* SSN - 1 is in range V(A)..V(S)-1 */ + for (i = 63, bsn = (ssn - 1) & mod_sns; + i >= 0 && bsn != ((v_a - 1) & mod_sns); + i--, bsn = (bsn - 1) & mod_sns) { + + if (show_rbb[i] == '1') { + LOGP(DRLCMACDL, LOGL_DEBUG, "- got ack for BSN=%d\n", bsn); + if (!is_acked(bsn & mod_sns_half)) + *received += 1; + mark_acked(bsn & mod_sns_half); + } else { + LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); + mark_nacked(bsn & mod_sns_half); + bts->rlc_nacked(); + *lost += 1; + } + } +} diff --git a/src/rlc.h b/src/rlc.h index 6edfb921..6905e2bd 100644 --- a/src/rlc.h +++ b/src/rlc.h @@ -25,6 +25,7 @@ #define RLC_MAX_WS 64 /* max window size */ #define RLC_MAX_LEN 54 /* CS-4 including spare bits */ +class BTS; struct gprs_rlc_data { uint8_t *prepare(size_t block_data_length); @@ -43,11 +44,18 @@ struct gprs_rlc { gprs_rlc_data blocks[RLC_MAX_SNS/2]; }; +/** + * TODO: for GPRS/EDGE maybe make sns a template parameter + * so we create specialized versions... + */ struct gprs_rlc_v_b { int resend_needed(const uint16_t acked, const uint16_t sent, const uint16_t mod_sns, const uint16_t mod_sns_half); int mark_for_resend(const uint16_t acked, const uint16_t sent, const uint16_t mod_sns, const uint16_t mod_sns_half); + void update(BTS *bts, char *show_rbb, uint8_t ssn, const uint16_t v_a, + const uint16_t mod_sns, const uint16_t mod_sns_half, + uint16_t *lost, uint16_t *received); /* Check for an individual frame */ bool is_unacked(int index) const; diff --git a/src/tbf.cpp b/src/tbf.cpp index 2ec020ee..c83ca966 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1363,12 +1363,11 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ack(uint32_t fn) int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) { - char show_rbb[65], show_v_b[RLC_MAX_SNS + 1]; + char show_v_b[RLC_MAX_SNS + 1]; 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 */ - uint8_t bit; uint16_t bsn; struct msgb *msg; uint16_t lost = 0, received = 0; @@ -1376,12 +1375,9 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) LOGP(DRLCMACDL, LOGL_DEBUG, "%s downlink acknowledge\n", tbf_name(this)); if (!final) { + char show_rbb[65]; + Decoding::extract_rbb(rbb, show_rbb); /* show received array in debug (bit 64..1) */ - for (i = 63; i >= 0; i--) { - bit = (rbb[i >> 3] >> (7 - (i&7))) & 1; - show_rbb[i] = (bit) ? '1' : 'o'; - } - show_rbb[64] = '\0'; 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); @@ -1400,25 +1396,11 @@ int gprs_rlcmac_tbf::snd_dl_ack(uint8_t final, uint8_t ssn, uint8_t *rbb) "V(A)..V(S) range %s Free TBF!\n", tbf_name(this)); return 1; /* indicate to free TBF */ } - /* SSN - 1 is in range V(A)..V(S)-1 */ - for (i = 63, bsn = (ssn - 1) & mod_sns; - i >= 0 && bsn != ((dir.dl.v_a - 1) & mod_sns); - i--, bsn = (bsn - 1) & mod_sns) { - bit = (rbb[i >> 3] >> (7 - (i&7))) & 1; - if (bit) { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got " - "ack for BSN=%d\n", bsn); - if (!dir.dl.v_b.is_acked(bsn & mod_sns_half)) - received++; - dir.dl.v_b.mark_acked(bsn & mod_sns_half); - } else { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got " - "NACK for BSN=%d\n", bsn); - dir.dl.v_b.mark_nacked(bsn & mod_sns_half); - bts->rlc_nacked(); - 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);