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.
This commit is contained in:
parent
9eb8ace260
commit
df6b4f52e0
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
29
src/rlc.cpp
29
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
34
src/tbf.cpp
34
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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue