diff options
author | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-12-12 11:11:02 +0100 |
---|---|---|
committer | Holger Hans Peter Freyther <holger@moiji-mobile.com> | 2013-12-12 11:11:02 +0100 |
commit | 752a3b2baaf5c0b5323271ef1e03a3609b487286 (patch) | |
tree | 385a97840141752d9445ebea55930966972fa9c1 /src | |
parent | 11f2d58dbd0f590da3612a9f587a23b92857436f (diff) | |
parent | 5e94cd4fdedc44ba178a9d3d150f0d5ba7abc742 (diff) |
Merge branch 'sysmocom/gprs-window-handling' into sysmocom/master
Daniel and me worked on the window handling. We now test that what
we encode is compatible to what we decode. The char array now includes
SSN-1 to the right of the array (reflecting a time axis that grows
towards the right..)
Diffstat (limited to 'src')
-rw-r--r-- | src/decoding.cpp | 8 | ||||
-rw-r--r-- | src/encoding.cpp | 53 | ||||
-rw-r--r-- | src/encoding.h | 2 | ||||
-rw-r--r-- | src/rlc.cpp | 30 | ||||
-rw-r--r-- | src/rlc.h | 8 | ||||
-rw-r--r-- | src/tbf.cpp | 2 |
6 files changed, 69 insertions, 34 deletions
diff --git a/src/decoding.cpp b/src/decoding.cpp index 0f70872..fce8124 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -85,14 +85,16 @@ uint8_t Decoding::get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) /** * show_rbb needs to be an array with 65 elements + * The index of the array is the bit position in the rbb + * (show_rbb[63] relates to BSN ssn-1) */ void Decoding::extract_rbb(const uint8_t *rbb, char *show_rbb) { - for (int i = 63; i >= 0; i--) { + for (int i = 0; i < 64; i++) { uint8_t bit; - bit = (rbb[i >> 3] >> (7 - (i&7))) & 1; - show_rbb[i] = bit ? '1' : 'o'; + bit = !!(rbb[i/8] & (1<<(7-i%8))); + show_rbb[i] = bit ? 'R' : 'I'; } show_rbb[64] = '\0'; diff --git a/src/encoding.cpp b/src/encoding.cpp index 085e7c3..9479986 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -352,6 +352,27 @@ int Encoding::write_paging_request(bitvec * dest, uint8_t *ptmsi, uint16_t ptmsi return plen; } +/** + * The index of the array show_rbb is the bit position inside the rbb + * (show_rbb[63] relates to BSN ssn-1) + */ +void Encoding::encode_rbb(const char *show_rbb, uint8_t *rbb) +{ + uint8_t rbb_byte = 0; + + // RECEIVE_BLOCK_BITMAP + for (int i = 0; i < 64; i++) { + /* Set bit at the appropriate position (see 3GPP TS 04.60 9.1.8.1) */ + if (show_rbb[i] == 'R') + rbb_byte |= 1<< (7-(i%8)); + + if((i%8) == 7) { + rbb[i/8] = rbb_byte; + rbb_byte = 0; + } + } +} + /* generate uplink ack */ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *tbf, @@ -359,12 +380,9 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, { // Packet Uplink Ack/Nack TS 44.060 11.2.28 - char show_v_n[65]; + char rbb[65]; - uint8_t rbb = 0; - uint16_t i, bbn; - uint16_t mod_sns = (tbf->sns() - 1); - char bit; + tbf->dir.ul.window.update_rbb(&tbf->dir.ul.v_n, rbb); LOGP(DRLCMACUL, LOGL_DEBUG, "Encoding Ack/Nack for %s " "(final=%d)\n", tbf_name(tbf), final); @@ -381,25 +399,14 @@ void Encoding::write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, block->u.Packet_Uplink_Ack_Nack.UnionType = 0x0; // PU_AckNack_GPRS = on block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.CHANNEL_CODING_COMMAND = bts->initial_cs_ul - 1; // CS1 block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.FINAL_ACK_INDICATION = final; // FINAL ACK INDICATION - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->dir.ul.window.v_r(); // STARTING_SEQUENCE_NUMBER - // RECEIVE_BLOCK_BITMAP - for (i = 0, bbn = (tbf->dir.ul.window.v_r() - 64) & mod_sns; i < 64; - i++, bbn = (bbn + 1) & mod_sns) { - bit = tbf->dir.ul.v_n.state(bbn); - show_v_n[i] = bit; - if (bit == 'R') - rbb = (rbb << 1)|1; - else - rbb = (rbb << 1); - if((i%8) == 7) - { - block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP[i/8] = rbb; - rbb = 0; - } - } - show_v_n[64] = '\0'; + block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.STARTING_SEQUENCE_NUMBER = tbf->dir.ul.window.ssn(); // STARTING_SEQUENCE_NUMBER + + encode_rbb(rbb, block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.Ack_Nack_Description.RECEIVED_BLOCK_BITMAP); + + /* rbb is not NULL terminated */ + rbb[64] = 0; LOGP(DRLCMACUL, LOGL_DEBUG, "- V(N): \"%s\" R=Received " - "N=Not-Received\n", show_v_n); + "I=Invalid\n", rbb); block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.UnionType = 0x0; // Fixed Allocation Dummy = on block->u.Packet_Uplink_Ack_Nack.u.PU_AckNack_GPRS_Struct.u.FixedAllocationDummy = 0x0; // Fixed Allocation Dummy diff --git a/src/encoding.h b/src/encoding.h index d0f8f0a..e62c2c8 100644 --- a/src/encoding.h +++ b/src/encoding.h @@ -54,6 +54,8 @@ public: uint8_t old_downlink, struct gprs_rlcmac_tbf *tbf, uint8_t poll, uint8_t alpha, uint8_t gamma, int8_t ta_idx, uint8_t ta_ts); + static void encode_rbb(const char *show_rbb, uint8_t *rbb); + static void write_packet_uplink_ack(struct gprs_rlcmac_bts *bts, RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *tbf, uint8_t final); diff --git a/src/rlc.cpp b/src/rlc.cpp index 915da87..f31670e 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -84,19 +84,23 @@ int gprs_rlc_v_b::count_unacked(const gprs_rlc_dl_window &w) return unacked; } +static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns) +{ + return (ssn - 1 - bitnum) & mod_sns; +} + void gprs_rlc_v_b::update(BTS *bts, char *show_rbb, uint8_t ssn, const gprs_rlc_dl_window &w, 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) & w.mod_sns(); - i >= 0 && bsn != ((w.v_a() - 1) & w.mod_sns()); - i--, bsn = (bsn - 1) & w.mod_sns()) { + for (int bitpos = 0; bitpos < w.ws(); bitpos++) { + uint16_t bsn = bitnum_to_bsn(bitpos, ssn, w.mod_sns()); - if (show_rbb[i] == '1') { + if (bsn == ((w.v_a() - 1) & w.mod_sns())) + break; + + if (show_rbb[w.ws() - 1 - bitpos] == 'R') { LOGP(DRLCMACDL, LOGL_DEBUG, "- got ack for BSN=%d\n", bsn); if (!is_acked(bsn)) *received += 1; @@ -146,6 +150,18 @@ void gprs_rlc_v_n::reset() memset(m_v_n, 0x0, sizeof(m_v_n)); } +/* Update the receive block bitmap */ +void gprs_rlc_ul_window::update_rbb(const gprs_rlc_v_n *v_n, char *rbb) +{ + int i; + for (i=0; i < ws(); i++) { + if (v_n->is_received(ssn()-1-i)) + rbb[ws()-1-i] = 'R'; + else + rbb[ws()-1-i] = 'I'; + } +} + /* 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) { @@ -89,8 +89,11 @@ struct gprs_rlc_ul_window { const uint16_t v_r() const; const uint16_t v_q() const; + const uint16_t ssn() const; + bool is_in_window(uint8_t bsn) const; + void update_rbb(const gprs_rlc_v_n *v_n, char *rbb); 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); @@ -339,6 +342,11 @@ inline const uint16_t gprs_rlc_ul_window::v_q() const return m_v_q; } +inline const uint16_t gprs_rlc_ul_window::ssn() const +{ + return m_v_r; +} + inline void gprs_rlc_ul_window::raise_v_r(int moves) { m_v_r = (m_v_r + moves) & mod_sns(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 3f4da56..8ffafce 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1348,7 +1348,7 @@ int gprs_rlcmac_tbf::update_window(const uint8_t ssn, const uint8_t *rbb) Decoding::extract_rbb(rbb, show_rbb); /* show received array in debug (bit 64..1) */ LOGP(DRLCMACDL, LOGL_DEBUG, "- ack: (BSN=%d)\"%s\"" - "(BSN=%d) 1=ACK o=NACK\n", (ssn - 64) & mod_sns, + "(BSN=%d) R=ACK I=NACK\n", (ssn - 64) & mod_sns, show_rbb, (ssn - 1) & mod_sns); /* apply received array to receive state (SSN-64..SSN-1) */ |