tbf/rlc: Move the v_n handling into a dedicated object

This commit is contained in:
Holger Hans Peter Freyther 2013-11-24 20:55:02 +01:00
parent f1593b7c49
commit 270f7fce1d
4 changed files with 36 additions and 7 deletions

View File

@ -385,7 +385,7 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts,
// RECEIVE_BLOCK_BITMAP
for (i = 0, bbn = (tbf->dir.ul.window.v_r() - 64) & mod_sns_half; i < 64;
i++, bbn = (bbn + 1) & mod_sns_half) {
bit = tbf->dir.ul.v_n[bbn];
bit = tbf->dir.ul.v_n.state(bbn);
if (bit == 0)
bit = ' ';
show_v_n[i] = bit;

View File

@ -129,6 +129,16 @@ private:
char m_v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
};
struct gprs_rlc_v_n {
void mark_received(int index);
void mark_missing(int index);
bool is_received(int index) const;
char state(int index) const;
private:
char m_v_n[RLC_MAX_SNS/2]; /* receive state array */
};
extern "C" {
/* TS 04.60 10.2.2 */
@ -329,3 +339,23 @@ inline void gprs_rlc_ul_window::increment_q(int incr)
{
m_v_q = (m_v_q + incr) & mod_sns();
}
inline void gprs_rlc_v_n::mark_received(int index)
{
m_v_n[index] = 'R';
}
inline void gprs_rlc_v_n::mark_missing(int index)
{
m_v_n[index] = 'N';
}
inline bool gprs_rlc_v_n::is_received(int index) const
{
return m_v_n[index] == 'R';
}
inline char gprs_rlc_v_n::state(int index) const
{
return m_v_n[index];
}

View File

@ -1616,7 +1616,7 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len
index = rh->bsn & mod_sns_half; /* memory index of block */
memcpy(m_rlc.blocks[index].block, data, len); /* Copy block. */
m_rlc.blocks[index].len = len;
this->dir.ul.v_n[index] = 'R'; /* Mark received block. */
dir.ul.v_n.mark_received(index);
LOGP(DRLCMACUL, LOGL_DEBUG, "- BSN %d storing in window (%d..%d)\n",
rh->bsn, dir.ul.window.v_q(),
(dir.ul.window.v_q() + ws - 1) & mod_sns);
@ -1625,8 +1625,7 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len
if (offset_v_r < (sns() >> 1)) { /* Positive offset, so raise. */
while (offset_v_r--) {
if (offset_v_r) /* all except the received block */
dir.ul.v_n[dir.ul.window.v_r() & mod_sns_half]
= 'N'; /* Mark block as not received */
dir.ul.v_n.mark_missing(dir.ul.window.v_r() & mod_sns_half);
this->dir.ul.window.raise(1);
/* Inc V(R). */
}
@ -1638,8 +1637,8 @@ int gprs_rlcmac_tbf::rcv_data_block_acknowledged(const uint8_t *data, size_t len
/* 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() && this->dir.ul.v_n[
(index = this->dir.ul.window.v_q() & mod_sns_half)] == 'R') {
while (this->dir.ul.window.v_q() != this->dir.ul.window.v_r() && this->dir.ul.v_n.
is_received(index = this->dir.ul.window.v_q() & mod_sns_half)) {
LOGP(DRLCMACUL, LOGL_DEBUG, "- Taking block %d out, raising "
"V(Q) to %d\n", this->dir.ul.window.v_q(),
(this->dir.ul.window.v_q() + 1) & mod_sns);

View File

@ -171,7 +171,7 @@ struct gprs_rlcmac_tbf {
} dl;
struct {
gprs_rlc_ul_window window;
char v_n[RLC_MAX_SNS/2]; /* receive state array */
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) */