tbf/rlc: Move raising of V(Q) into the ul window code
This commit is contained in:
parent
cbb00ebd04
commit
7f3e662b34
25
src/rlc.cpp
25
src/rlc.cpp
|
@ -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;
|
||||
}
|
||||
|
|
11
src/rlc.h
11
src/rlc.h
|
@ -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();
|
||||
}
|
||||
|
|
18
src/tbf.cpp
18
src/tbf.cpp
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue