aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-11-24 17:05:48 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-11-26 20:57:24 +0100
commitdf6b4f52e05e699b9a96a920973bff6241b5a853 (patch)
tree433c1d5a236191f6ed4cb500054447ffae0712f6
parent9eb8ace2608980f6c5e68610210fc6dd921b41ff (diff)
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.
-rw-r--r--src/decoding.cpp14
-rw-r--r--src/decoding.h2
-rw-r--r--src/rlc.cpp29
-rw-r--r--src/rlc.h8
-rw-r--r--src/tbf.cpp34
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 <osmocom/core/utils.h>
@@ -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);