tbf/rlc: Move raising of V(Q) into the ul window code

This commit is contained in:
Holger Hans Peter Freyther 2013-11-25 23:51:19 +01:00
parent cbb00ebd04
commit 7f3e662b34
3 changed files with 36 additions and 18 deletions

View File

@ -151,7 +151,7 @@ void gprs_rlc_v_n::reset()
}
/* Raise V(R) to highest received sequence number not received. */
void gprs_rlc_ul_window::raise(const uint16_t bsn, gprs_rlc_v_n *v_n)
void gprs_rlc_ul_window::raise_v_r(const uint16_t bsn, gprs_rlc_v_n *v_n)
{
uint16_t offset_v_r;
offset_v_r = (bsn + 1 - v_r()) & mod_sns();
@ -160,8 +160,29 @@ void gprs_rlc_ul_window::raise(const uint16_t bsn, gprs_rlc_v_n *v_n)
while (offset_v_r--) {
if (offset_v_r) /* all except the received block */
v_n->mark_missing(v_r() & mod_sns_half());
raise(1);
raise_v_r(1);
}
LOGP(DRLCMACUL, LOGL_DEBUG, "- Raising V(R) to %d\n", v_r());
}
}
/*
* 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 count = 0;
while (v_q() != v_r()) {
uint16_t index = v_q() & mod_sns_half();
if (!v_n->is_received(index))
break;
LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising "
"V(Q) to %d\n", v_q(), (v_q() + 1) & mod_sns());
raise_v_q(1);
count += 1;
}
return count;
}

View File

@ -87,10 +87,11 @@ struct gprs_rlc_ul_window {
bool is_in_window(uint8_t bsn) const;
void raise(int moves);
void raise(const uint16_t bsn, gprs_rlc_v_n *v_n);
void raise_v_r(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 increment_q(int);
void raise_v_q(int);
uint16_t m_v_r; /* receive state */
uint16_t m_v_q; /* receive window state */
@ -347,12 +348,12 @@ inline const uint16_t gprs_rlc_ul_window::v_q() const
return m_v_q;
}
inline void gprs_rlc_ul_window::raise(int moves)
inline void gprs_rlc_ul_window::raise_v_r(int moves)
{
m_v_r = (m_v_r + moves) & mod_sns();
}
inline void gprs_rlc_ul_window::increment_q(int incr)
inline void gprs_rlc_ul_window::raise_v_q(int incr)
{
m_v_q = (m_v_q + incr) & mod_sns();
}

View File

@ -1613,22 +1613,18 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len
(dir.ul.window.v_q() + ws - 1) & mod_sns);
dir.ul.v_n.mark_received(index);
dir.ul.window.raise(rh->bsn, &dir.ul.v_n);
dir.ul.window.raise_v_r(rh->bsn, &dir.ul.v_n);
/* 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.*/
while (this->dir.ul.window.v_q() != this->dir.ul.window.v_r()) {
index = dir.ul.window.v_q() & mod_sns_half;
if (!dir.ul.v_n.is_received(index))
break;
LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising "
"V(Q) to %d\n", dir.ul.window.v_q(),
(dir.ul.window.v_q() + 1) & mod_sns);
/* get LLC data from block */
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);
/* Retrieve LLC frames from blocks that are ready */
for (uint16_t i = 0; i < count; ++i) {
uint16_t index = (v_q_beg + i) & mod_sns_half;
assemble_forward_llc(&m_rlc.blocks[index]);
/* raise V(Q), because block already received */
dir.ul.window.increment_q(1);
}
/* Check CV of last frame in buffer */