diff options
Diffstat (limited to 'src/rlc.cpp')
-rw-r--r-- | src/rlc.cpp | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/src/rlc.cpp b/src/rlc.cpp index a2cc52c2..2166e4d9 100644 --- a/src/rlc.cpp +++ b/src/rlc.cpp @@ -10,10 +10,6 @@ * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bts.h" @@ -45,275 +41,6 @@ uint8_t *prepare(struct gprs_rlc_data *rlc, size_t block_data_len) return rlc->block; } -void gprs_rlc_v_b::reset() -{ - for (size_t i = 0; i < ARRAY_SIZE(m_v_b); ++i) - mark_invalid(i); -} - -void gprs_rlc_dl_window::reset() -{ - m_v_s = 0; - m_v_a = 0; - m_v_b.reset(); -} - -int gprs_rlc_dl_window::resend_needed() const -{ - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { - if (m_v_b.is_nacked(bsn) || m_v_b.is_resend(bsn)) - return bsn; - } - - return -1; -} - -int gprs_rlc_dl_window::mark_for_resend() -{ - int resend = 0; - - for (uint16_t bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { - if (m_v_b.is_unacked(bsn)) { - /* mark to be re-send */ - m_v_b.mark_resend(bsn); - resend += 1; - } - } - - return resend; -} - -/* Update the receive block bitmap */ -uint16_t gprs_rlc_ul_window::update_egprs_rbb(uint8_t *rbb) -{ - uint16_t i; - uint16_t bsn; - uint16_t bitmask = 0x80; - int8_t pos = 0; - int8_t bit_pos = 0; - for (i = 0, bsn = (v_q()+1); ((bsn < (v_r())) && (i < ws())); i++, - bsn = this->mod_sns(bsn + 1)) { - if (m_v_n.is_received(bsn)) { - rbb[pos] = rbb[pos] | bitmask; - } else { - rbb[pos] = rbb[pos] & (~bitmask); - } - bitmask = bitmask >> 1; - bit_pos++; - bit_pos = bit_pos % 8; - if (bit_pos == 0) { - pos++; - bitmask = 0x80; - } - } - return i; -} - -int gprs_rlc_dl_window::count_unacked() -{ - uint16_t unacked = 0; - uint16_t bsn; - - for (bsn = v_a(); bsn != v_s(); bsn = mod_sns(bsn + 1)) { - if (!m_v_b.is_acked(bsn)) - unacked += 1; - } - - return unacked; -} - -static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn) -{ - return (ssn - 1 - bitnum); -} - -void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb, - uint16_t first_bsn, uint16_t *lost, - uint16_t *received) -{ - unsigned dist = distance(); - unsigned num_blocks = rbb->cur_bit > dist - ? dist : rbb->cur_bit; - unsigned bsn; - - /* first_bsn is in range V(A)..V(S) */ - - for (unsigned int bitpos = 0; bitpos < num_blocks; bitpos++) { - bool is_ack; - bsn = mod_sns(first_bsn + bitpos); - if (bsn == mod_sns(v_a() - 1)) - break; - - is_ack = bitvec_get_bit_pos(rbb, bitpos) == 1; - - if (is_ack) { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got ack for BSN=%d\n", bsn); - if (!m_v_b.is_acked(bsn)) - *received += 1; - m_v_b.mark_acked(bsn); - } else { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); - m_v_b.mark_nacked(bsn); - bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED); - *lost += 1; - } - } -} - -void gprs_rlc_dl_window::update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn, - uint16_t *lost, uint16_t *received) -{ - /* SSN - 1 is in range V(A)..V(S)-1 */ - for (int bitpos = 0; bitpos < ws(); bitpos++) { - uint16_t bsn = mod_sns(bitnum_to_bsn(bitpos, ssn)); - - if (bsn == mod_sns(v_a() - 1)) - break; - - if (show_rbb[ws() - 1 - bitpos] == 'R') { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got ack for BSN=%d\n", bsn); - if (!m_v_b.is_acked(bsn)) - *received += 1; - m_v_b.mark_acked(bsn); - } else { - LOGP(DRLCMACDL, LOGL_DEBUG, "- got NACK for BSN=%d\n", bsn); - m_v_b.mark_nacked(bsn); - bts_do_rate_ctr_inc(bts, CTR_RLC_NACKED); - *lost += 1; - } - } -} - -int gprs_rlc_dl_window::move_window() -{ - int i; - uint16_t bsn; - int moved = 0; - - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { - if (m_v_b.is_acked(bsn)) { - m_v_b.mark_invalid(bsn); - moved += 1; - } else - break; - } - - return moved; -} - -void gprs_rlc_dl_window::show_state(char *show_v_b) -{ - int i; - uint16_t bsn; - - for (i = 0, bsn = v_a(); bsn != v_s(); i++, bsn = mod_sns(bsn + 1)) { - uint16_t index = bsn & mod_sns_half(); - switch(m_v_b.get_state(index)) { - case GPRS_RLC_DL_BSN_INVALID: - show_v_b[i] = 'I'; - break; - case GPRS_RLC_DL_BSN_ACKED: - show_v_b[i] = 'A'; - break; - case GPRS_RLC_DL_BSN_RESEND: - show_v_b[i] = 'X'; - break; - case GPRS_RLC_DL_BSN_NACKED: - show_v_b[i] = 'N'; - break; - default: - show_v_b[i] = '?'; - } - } - show_v_b[i] = '\0'; -} - -void gprs_rlc_v_n::reset() -{ - for (size_t i = 0; i < ARRAY_SIZE(m_v_n); ++i) - m_v_n[i] = GPRS_RLC_UL_BSN_INVALID; -} - -void gprs_rlc_window::set_sns(uint16_t sns) -{ - OSMO_ASSERT(sns >= RLC_GPRS_SNS); - OSMO_ASSERT(sns <= RLC_MAX_SNS); - /* check for 2^n */ - OSMO_ASSERT((sns & (-sns)) == sns); - m_sns = sns; -} - -void gprs_rlc_window::set_ws(uint16_t ws) -{ - LOGP(DRLCMAC, LOGL_INFO, "ws(%d)\n", - ws); - OSMO_ASSERT(ws >= RLC_GPRS_SNS/2); - OSMO_ASSERT(ws <= RLC_MAX_SNS/2); - m_ws = ws; -} - -/* Update the receive block bitmap */ -void gprs_rlc_ul_window::update_rbb(char *rbb) -{ - int i; - for (i=0; i < ws(); i++) { - if (m_v_n.is_received((ssn()-1-i) & mod_sns())) - 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) -{ - uint16_t offset_v_r; - offset_v_r = mod_sns(bsn + 1 - v_r()); - /* Positive offset, so raise. */ - if (offset_v_r < (sns() >> 1)) { - while (offset_v_r--) { - if (offset_v_r) /* all except the received block */ - m_v_n.mark_missing(v_r()); - raise_v_r_to(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() -{ - uint16_t count = 0; - - while (v_q() != v_r()) { - 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(), mod_sns(v_q() + 1)); - raise_v_q(1); - count += 1; - } - - return count; -} - -void gprs_rlc_ul_window::receive_bsn(const uint16_t bsn) -{ - m_v_n.mark_received(bsn); - raise_v_r(bsn); -} - -bool gprs_rlc_ul_window::invalidate_bsn(const uint16_t bsn) -{ - bool was_valid = m_v_n.is_received(bsn); - m_v_n.mark_missing(bsn); - - return was_valid; -} - static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc, enum CodingScheme cs, bool with_padding, unsigned int header_bits, const unsigned int spb) |