rlc/tbf: Move v_n into gprs_rlc_ul_window and adapt the tests
v_n is part of the UL window handling so move it inside the ul_window
This commit is contained in:
parent
f4a1ec6ce7
commit
7c3751b10b
|
@ -382,7 +382,7 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts,
|
|||
|
||||
char rbb[65];
|
||||
|
||||
tbf->dir.ul.window.update_rbb(&tbf->dir.ul.v_n, rbb);
|
||||
tbf->dir.ul.window.update_rbb(rbb);
|
||||
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s "
|
||||
"(final=%d)\n", tbf_name(tbf), final);
|
||||
|
|
12
src/rlc.cpp
12
src/rlc.cpp
|
@ -151,11 +151,11 @@ void gprs_rlc_v_n::reset()
|
|||
}
|
||||
|
||||
/* Update the receive block bitmap */
|
||||
void gprs_rlc_ul_window::update_rbb(const gprs_rlc_v_n *v_n, char *rbb)
|
||||
void gprs_rlc_ul_window::update_rbb(char *rbb)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i < ws(); i++) {
|
||||
if (v_n->is_received(ssn()-1-i))
|
||||
if (m_v_n.is_received(ssn()-1-i))
|
||||
rbb[ws()-1-i] = 'R';
|
||||
else
|
||||
rbb[ws()-1-i] = 'I';
|
||||
|
@ -163,7 +163,7 @@ void gprs_rlc_ul_window::update_rbb(const gprs_rlc_v_n *v_n, char *rbb)
|
|||
}
|
||||
|
||||
/* Raise V(R) to highest received sequence number not received. */
|
||||
void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn, gprs_rlc_v_n *v_n)
|
||||
void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn)
|
||||
{
|
||||
uint16_t offset_v_r;
|
||||
offset_v_r = (bsn + 1 - v_r()) & mod_sns();
|
||||
|
@ -171,7 +171,7 @@ void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn, gprs_rlc_v_n *v_n)
|
|||
if (offset_v_r < (sns() >> 1)) {
|
||||
while (offset_v_r--) {
|
||||
if (offset_v_r) /* all except the received block */
|
||||
v_n->mark_missing(v_r());
|
||||
m_v_n.mark_missing(v_r());
|
||||
raise_v_r_to(1);
|
||||
}
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- Raising V(R) to %d\n", v_r());
|
||||
|
@ -182,12 +182,12 @@ void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn, gprs_rlc_v_n *v_n)
|
|||
* Raise V(Q) if possible. This is looped until there is a gap
|
||||
* (non received block) or the window is empty.
|
||||
*/
|
||||
uint16_t gprs_rlc_ul_window::raise_v_q(gprs_rlc_v_n *v_n)
|
||||
uint16_t gprs_rlc_ul_window::raise_v_q()
|
||||
{
|
||||
uint16_t count = 0;
|
||||
|
||||
while (v_q() != v_r()) {
|
||||
if (!v_n->is_received(v_q()))
|
||||
if (!m_v_n.is_received(v_q()))
|
||||
break;
|
||||
LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising "
|
||||
"V(Q) to %d\n", v_q(), (v_q() + 1) & mod_sns());
|
||||
|
|
38
src/rlc.h
38
src/rlc.h
|
@ -81,6 +81,21 @@ struct gprs_rlc_dl_window {
|
|||
uint16_t m_v_a; /* ack state */
|
||||
};
|
||||
|
||||
struct gprs_rlc_v_n {
|
||||
void reset();
|
||||
|
||||
void mark_received(int bsn);
|
||||
void mark_missing(int bsn);
|
||||
|
||||
bool is_received(int bsn) const;
|
||||
|
||||
char state(int bsn) const;
|
||||
private:
|
||||
bool is_state(int bsn, const char state) const;
|
||||
void mark(int bsn, const char state);
|
||||
char m_v_n[RLC_MAX_SNS/2]; /* receive state array */
|
||||
};
|
||||
|
||||
struct gprs_rlc_ul_window {
|
||||
const uint16_t mod_sns() const;
|
||||
const uint16_t sns() const;
|
||||
|
@ -93,15 +108,17 @@ struct gprs_rlc_ul_window {
|
|||
|
||||
bool is_in_window(uint8_t bsn) const;
|
||||
|
||||
void update_rbb(const gprs_rlc_v_n *v_n, char *rbb);
|
||||
void update_rbb(char *rbb);
|
||||
void raise_v_r_to(int moves);
|
||||
void raise_v_r(const uint16_t bsn, gprs_rlc_v_n *v_n);
|
||||
uint16_t raise_v_q(gprs_rlc_v_n *v_n);
|
||||
void raise_v_r(const uint16_t bsn);
|
||||
uint16_t raise_v_q();
|
||||
|
||||
void raise_v_q(int);
|
||||
|
||||
uint16_t m_v_r; /* receive state */
|
||||
uint16_t m_v_q; /* receive window state */
|
||||
|
||||
gprs_rlc_v_n m_v_n;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -141,21 +158,6 @@ private:
|
|||
char m_v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
|
||||
};
|
||||
|
||||
struct gprs_rlc_v_n {
|
||||
void reset();
|
||||
|
||||
void mark_received(int bsn);
|
||||
void mark_missing(int bsn);
|
||||
|
||||
bool is_received(int bsn) const;
|
||||
|
||||
char state(int bsn) const;
|
||||
private:
|
||||
bool is_state(int bsn, const char state) const;
|
||||
void mark(int bsn, const char state);
|
||||
char m_v_n[RLC_MAX_SNS/2]; /* receive state array */
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
/* TS 04.60 10.2.2 */
|
||||
struct rlc_ul_header {
|
||||
|
|
|
@ -1606,14 +1606,14 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len
|
|||
rh->bsn, dir.ul.window.v_q(),
|
||||
(dir.ul.window.v_q() + ws - 1) & mod_sns);
|
||||
|
||||
dir.ul.v_n.mark_received(rh->bsn);
|
||||
dir.ul.window.raise_v_r(rh->bsn, &dir.ul.v_n);
|
||||
dir.ul.window.m_v_n.mark_received(rh->bsn);
|
||||
dir.ul.window.raise_v_r(rh->bsn);
|
||||
|
||||
/* Raise V(Q) if possible, and retrieve LLC frames from blocks.
|
||||
* This is looped until there is a gap (non received block) or
|
||||
* the window is empty.*/
|
||||
const uint16_t v_q_beg = dir.ul.window.v_q();
|
||||
const uint16_t count = dir.ul.window.raise_v_q(&dir.ul.v_n);
|
||||
const uint16_t count = dir.ul.window.raise_v_q();
|
||||
|
||||
/* Retrieve LLC frames from blocks that are ready */
|
||||
for (uint16_t i = 0; i < count; ++i) {
|
||||
|
|
|
@ -174,7 +174,6 @@ struct gprs_rlcmac_tbf {
|
|||
} dl;
|
||||
struct {
|
||||
gprs_rlc_ul_window window;
|
||||
gprs_rlc_v_n v_n;
|
||||
int32_t rx_counter; /* count all received blocks */
|
||||
uint8_t n3103; /* N3103 counter */
|
||||
uint8_t usf[8]; /* list USFs per PDCH (timeslot) */
|
||||
|
|
|
@ -193,24 +193,23 @@ static void test_rlc_dl_ul_basic()
|
|||
|
||||
{
|
||||
gprs_rlc_ul_window ul_win = { 0, };
|
||||
gprs_rlc_v_n v_n;
|
||||
int count;
|
||||
const char *rbb;
|
||||
char win_rbb[65];
|
||||
uint8_t bin_rbb[8];
|
||||
win_rbb[64] = '\0';
|
||||
|
||||
v_n.reset();
|
||||
ul_win.m_v_n.reset();
|
||||
|
||||
OSMO_ASSERT(ul_win.is_in_window(0));
|
||||
OSMO_ASSERT(ul_win.is_in_window(63));
|
||||
OSMO_ASSERT(!ul_win.is_in_window(64));
|
||||
|
||||
OSMO_ASSERT(!v_n.is_received(0));
|
||||
OSMO_ASSERT(!ul_win.m_v_n.is_received(0));
|
||||
|
||||
rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII";
|
||||
OSMO_ASSERT(ul_win.ssn() == 0);
|
||||
ul_win.update_rbb(&v_n, win_rbb);
|
||||
ul_win.update_rbb(win_rbb);
|
||||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
Encoding::encode_rbb(win_rbb, bin_rbb);
|
||||
printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
|
||||
|
@ -219,17 +218,17 @@ static void test_rlc_dl_ul_basic()
|
|||
|
||||
/* simulate to have received 0, 1 and 5 */
|
||||
OSMO_ASSERT(ul_win.is_in_window(0));
|
||||
v_n.mark_received(0);
|
||||
ul_win.raise_v_r(0, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
OSMO_ASSERT(v_n.is_received(0));
|
||||
ul_win.m_v_n.mark_received(0);
|
||||
ul_win.raise_v_r(0);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(ul_win.m_v_n.is_received(0));
|
||||
OSMO_ASSERT(ul_win.v_q() == 1);
|
||||
OSMO_ASSERT(ul_win.v_r() == 1);
|
||||
OSMO_ASSERT(count == 1);
|
||||
|
||||
rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
|
||||
OSMO_ASSERT(ul_win.ssn() == 1);
|
||||
ul_win.update_rbb(&v_n, win_rbb);
|
||||
ul_win.update_rbb(win_rbb);
|
||||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
Encoding::encode_rbb(win_rbb, bin_rbb);
|
||||
printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
|
||||
|
@ -237,17 +236,17 @@ static void test_rlc_dl_ul_basic()
|
|||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
|
||||
OSMO_ASSERT(ul_win.is_in_window(1));
|
||||
v_n.mark_received(1);
|
||||
ul_win.raise_v_r(1, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
OSMO_ASSERT(v_n.is_received(0));
|
||||
ul_win.m_v_n.mark_received(1);
|
||||
ul_win.raise_v_r(1);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(ul_win.m_v_n.is_received(0));
|
||||
OSMO_ASSERT(ul_win.v_q() == 2);
|
||||
OSMO_ASSERT(ul_win.v_r() == 2);
|
||||
OSMO_ASSERT(count == 1);
|
||||
|
||||
rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRR";
|
||||
OSMO_ASSERT(ul_win.ssn() == 2);
|
||||
ul_win.update_rbb(&v_n, win_rbb);
|
||||
ul_win.update_rbb(win_rbb);
|
||||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
Encoding::encode_rbb(win_rbb, bin_rbb);
|
||||
printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
|
||||
|
@ -255,17 +254,17 @@ static void test_rlc_dl_ul_basic()
|
|||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
|
||||
OSMO_ASSERT(ul_win.is_in_window(5));
|
||||
v_n.mark_received(5);
|
||||
ul_win.raise_v_r(5, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
OSMO_ASSERT(v_n.is_received(0));
|
||||
ul_win.m_v_n.mark_received(5);
|
||||
ul_win.raise_v_r(5);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(ul_win.m_v_n.is_received(0));
|
||||
OSMO_ASSERT(ul_win.v_q() == 2);
|
||||
OSMO_ASSERT(ul_win.v_r() == 6);
|
||||
OSMO_ASSERT(count == 0);
|
||||
|
||||
rbb = "IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIRRIIIR";
|
||||
OSMO_ASSERT(ul_win.ssn() == 6);
|
||||
ul_win.update_rbb(&v_n, win_rbb);
|
||||
ul_win.update_rbb(win_rbb);
|
||||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
Encoding::encode_rbb(win_rbb, bin_rbb);
|
||||
printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
|
||||
|
@ -274,18 +273,18 @@ static void test_rlc_dl_ul_basic()
|
|||
|
||||
OSMO_ASSERT(ul_win.is_in_window(65));
|
||||
OSMO_ASSERT(ul_win.is_in_window(2));
|
||||
OSMO_ASSERT(v_n.is_received(5));
|
||||
v_n.mark_received(65);
|
||||
ul_win.raise_v_r(65, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
OSMO_ASSERT(ul_win.m_v_n.is_received(5));
|
||||
ul_win.m_v_n.mark_received(65);
|
||||
ul_win.raise_v_r(65);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(count == 0);
|
||||
OSMO_ASSERT(v_n.is_received(5));
|
||||
OSMO_ASSERT(ul_win.m_v_n.is_received(5));
|
||||
OSMO_ASSERT(ul_win.v_q() == 2);
|
||||
OSMO_ASSERT(ul_win.v_r() == 66);
|
||||
|
||||
rbb = "IIIRIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIR";
|
||||
OSMO_ASSERT(ul_win.ssn() == 66);
|
||||
ul_win.update_rbb(&v_n, win_rbb);
|
||||
ul_win.update_rbb(win_rbb);
|
||||
OSMO_ASSERT_STR_EQ(win_rbb, rbb);
|
||||
Encoding::encode_rbb(win_rbb, bin_rbb);
|
||||
printf("rbb: %s\n", osmo_hexdump(bin_rbb, sizeof(bin_rbb)));
|
||||
|
@ -294,33 +293,33 @@ static void test_rlc_dl_ul_basic()
|
|||
|
||||
OSMO_ASSERT(ul_win.is_in_window(2));
|
||||
OSMO_ASSERT(!ul_win.is_in_window(66));
|
||||
v_n.mark_received(2);
|
||||
ul_win.raise_v_r(2, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
ul_win.m_v_n.mark_received(2);
|
||||
ul_win.raise_v_r(2);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(count == 1);
|
||||
OSMO_ASSERT(ul_win.v_q() == 3);
|
||||
OSMO_ASSERT(ul_win.v_r() == 66);
|
||||
|
||||
OSMO_ASSERT(ul_win.is_in_window(66));
|
||||
v_n.mark_received(66);
|
||||
ul_win.raise_v_r(66, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
ul_win.m_v_n.mark_received(66);
|
||||
ul_win.raise_v_r(66);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(count == 0);
|
||||
OSMO_ASSERT(ul_win.v_q() == 3);
|
||||
OSMO_ASSERT(ul_win.v_r() == 67);
|
||||
|
||||
for (int i = 3; i <= 67; ++i) {
|
||||
v_n.mark_received(i);
|
||||
ul_win.raise_v_r(i, &v_n);
|
||||
ul_win.raise_v_q(&v_n);
|
||||
ul_win.m_v_n.mark_received(i);
|
||||
ul_win.raise_v_r(i);
|
||||
ul_win.raise_v_q();
|
||||
}
|
||||
|
||||
OSMO_ASSERT(ul_win.v_q() == 68);
|
||||
OSMO_ASSERT(ul_win.v_r() == 68);
|
||||
|
||||
v_n.mark_received(68);
|
||||
ul_win.raise_v_r(68, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
ul_win.m_v_n.mark_received(68);
|
||||
ul_win.raise_v_r(68);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(ul_win.v_q() == 69);
|
||||
OSMO_ASSERT(ul_win.v_r() == 69);
|
||||
OSMO_ASSERT(count == 1);
|
||||
|
@ -328,9 +327,9 @@ static void test_rlc_dl_ul_basic()
|
|||
/* now test the wrapping */
|
||||
OSMO_ASSERT(ul_win.is_in_window(4));
|
||||
OSMO_ASSERT(!ul_win.is_in_window(5));
|
||||
v_n.mark_received(4);
|
||||
ul_win.raise_v_r(4, &v_n);
|
||||
count = ul_win.raise_v_q(&v_n);
|
||||
ul_win.m_v_n.mark_received(4);
|
||||
ul_win.raise_v_r(4);
|
||||
count = ul_win.raise_v_q();
|
||||
OSMO_ASSERT(count == 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue