aboutsummaryrefslogtreecommitdiffstats
path: root/src/rlc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/rlc.h')
-rw-r--r--src/rlc.h404
1 files changed, 4 insertions, 400 deletions
diff --git a/src/rlc.h b/src/rlc.h
index 45cbb95f..dd2f0c7c 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -12,10 +12,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.
*/
#pragma once
#ifdef __cplusplus
@@ -33,34 +29,10 @@ extern "C" {
#include <string.h>
#define RLC_GPRS_SNS 128 /* GPRS, must be power of 2 */
-#define RLC_GPRS_WS 64 /* max window size */
-#define RLC_EGPRS_MIN_WS 64 /* min window size */
-#define RLC_EGPRS_MAX_WS 1024 /* min window size */
#define RLC_EGPRS_SNS 2048 /* EGPRS, must be power of 2 */
-#define RLC_EGPRS_MAX_BSN_DELTA 512
#define RLC_MAX_SNS RLC_EGPRS_SNS
-#define RLC_MAX_WS RLC_EGPRS_MAX_WS
#define RLC_MAX_LEN 74 /* MCS-9 data unit */
-struct gprs_rlcmac_bts;
-
-/* The state of a BSN in the send/receive window */
-enum gprs_rlc_ul_bsn_state {
- GPRS_RLC_UL_BSN_INVALID,
- GPRS_RLC_UL_BSN_RECEIVED,
- GPRS_RLC_UL_BSN_MISSING,
- GPRS_RLC_UL_BSN_MAX,
-};
-
-enum gprs_rlc_dl_bsn_state {
- GPRS_RLC_DL_BSN_INVALID,
- GPRS_RLC_DL_BSN_NACKED,
- GPRS_RLC_DL_BSN_ACKED,
- GPRS_RLC_DL_BSN_UNACKED,
- GPRS_RLC_DL_BSN_RESEND,
- GPRS_RLC_DL_BSN_MAX,
-};
-
/*
* EGPRS resegment status information for UL
* When only first split block is received bsn state
@@ -243,138 +215,6 @@ struct gprs_rlc {
gprs_rlc_data m_blocks[RLC_MAX_SNS/2];
};
-/**
- * TODO: for GPRS/EDGE maybe make sns a template parameter
- * so we create specialized versions...
- */
-struct gprs_rlc_v_b {
- /* Check for an individual frame */
- bool is_unacked(int bsn) const;
- bool is_nacked(int bsn) const;
- bool is_acked(int bsn) const;
- bool is_resend(int bsn) const;
- bool is_invalid(int bsn) const;
- gprs_rlc_dl_bsn_state get_state(int bsn) const;
-
- /* Mark a RLC frame for something */
- void mark_unacked(int bsn);
- void mark_nacked(int bsn);
- void mark_acked(int bsn);
- void mark_resend(int bsn);
- void mark_invalid(int bsn);
-
- void reset();
-
-
-private:
- bool is_state(int bsn, const gprs_rlc_dl_bsn_state state) const;
- void mark(int bsn, const gprs_rlc_dl_bsn_state state);
-
- gprs_rlc_dl_bsn_state m_v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
-};
-
-
-/**
- * TODO: The UL/DL code could/should share a base class.
- */
-class gprs_rlc_window {
-public:
- gprs_rlc_window();
-
- const uint16_t mod_sns() const;
- const uint16_t mod_sns(uint16_t bsn) const;
- const uint16_t sns() const;
- const uint16_t ws() const;
-
- void set_sns(uint16_t sns);
- void set_ws(uint16_t ws);
-
-protected:
- uint16_t m_sns;
- uint16_t m_ws;
-};
-
-struct gprs_rlc_dl_window: public gprs_rlc_window {
- void reset();
-
- bool window_stalled() const;
- bool window_empty() const;
-
- void increment_send();
- void raise(int moves);
-
- const uint16_t v_s() const;
- const uint16_t v_s_mod(int offset) const;
- const uint16_t v_a() const;
- const uint16_t distance() const;
-
- /* Methods to manage reception */
- int resend_needed() const;
- int mark_for_resend();
- void update(struct gprs_rlcmac_bts *bts, char *show_rbb, uint16_t ssn,
- uint16_t *lost, uint16_t *received);
- void update(struct gprs_rlcmac_bts *bts, const struct bitvec *rbb,
- uint16_t first_bsn, uint16_t *lost,
- uint16_t *received);
- int move_window();
- void show_state(char *show_rbb);
- int count_unacked();
-
- uint16_t m_v_s; /* send state */
- uint16_t m_v_a; /* ack state */
-
- gprs_rlc_v_b m_v_b;
-
- gprs_rlc_dl_window();
-};
-
-struct gprs_rlc_v_n {
- void reset();
-
- void mark_received(int bsn);
- void mark_missing(int bsn);
-
- bool is_received(int bsn) const;
-
- gprs_rlc_ul_bsn_state state(int bsn) const;
-private:
- bool is_state(int bsn, const gprs_rlc_ul_bsn_state state) const;
- void mark(int bsn, const gprs_rlc_ul_bsn_state state);
- gprs_rlc_ul_bsn_state m_v_n[RLC_MAX_SNS/2]; /* receive state array */
-};
-
-struct gprs_rlc_ul_window: public gprs_rlc_window {
- const uint16_t v_r() const;
- const uint16_t v_q() const;
-
- const void set_v_r(int);
- const void set_v_q(int);
- void reset_state();
-
- const uint16_t ssn() const;
-
- bool is_in_window(uint16_t bsn) const;
- bool is_received(uint16_t bsn) const;
-
- void update_rbb(char *rbb);
- uint16_t update_egprs_rbb(uint8_t *rbb);
- void raise_v_r_to(int moves);
- void raise_v_r(const uint16_t bsn);
- uint16_t raise_v_q();
-
- void raise_v_q(int);
-
- void receive_bsn(const uint16_t bsn);
- bool invalidate_bsn(const uint16_t bsn);
-
- uint16_t m_v_r; /* receive state */
- uint16_t m_v_q; /* receive window state */
-
- gprs_rlc_v_n m_v_n;
-
- gprs_rlc_ul_window();
-};
-
extern "C" {
/* TS 44.060 10.2.2 */
struct rlc_ul_header {
@@ -390,7 +230,7 @@ struct rlc_ul_header {
uint8_t e:1,
bsn:7;
#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t pt:2, cv:4, si:1, r:1;
uint8_t spare:1, pi:1, tfi:5, ti:1;
uint8_t bsn:7, e:1;
@@ -409,7 +249,7 @@ struct rlc_dl_header {
uint8_t e:1,
bsn:7;
#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t pt:2, rrbp:2, s_p:1, usf:3;
uint8_t pr:2, tfi:5, fbi:1;
uint8_t bsn:7, e:1;
@@ -422,7 +262,7 @@ struct rlc_li_field {
m:1,
li:6;
#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t li:6, m:1, e:1;
#endif
} __attribute__ ((packed));
@@ -432,248 +272,12 @@ struct rlc_li_field_egprs {
uint8_t e:1,
li:7;
#elif OSMO_IS_BIG_ENDIAN
-/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */
+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianness.py) */
uint8_t li:7, e:1;
#endif
} __attribute__ ((packed));
}
-inline bool gprs_rlc_v_b::is_state(int bsn, const gprs_rlc_dl_bsn_state type) const
-{
- return m_v_b[bsn & mod_sns_half()] == type;
-}
-
-inline void gprs_rlc_v_b::mark(int bsn, const gprs_rlc_dl_bsn_state type)
-{
- m_v_b[bsn & mod_sns_half()] = type;
-}
-
-inline bool gprs_rlc_v_b::is_nacked(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_DL_BSN_NACKED);
-}
-
-inline bool gprs_rlc_v_b::is_acked(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_DL_BSN_ACKED);
-}
-
-inline bool gprs_rlc_v_b::is_unacked(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_DL_BSN_UNACKED);
-}
-
-inline bool gprs_rlc_v_b::is_resend(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_DL_BSN_RESEND);
-}
-
-inline bool gprs_rlc_v_b::is_invalid(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_DL_BSN_INVALID);
-}
-
-inline gprs_rlc_dl_bsn_state gprs_rlc_v_b::get_state(int bsn) const
-{
- return m_v_b[bsn & mod_sns_half()];
-}
-
-inline void gprs_rlc_v_b::mark_resend(int bsn)
-{
- return mark(bsn, GPRS_RLC_DL_BSN_RESEND);
-}
-
-inline void gprs_rlc_v_b::mark_unacked(int bsn)
-{
- return mark(bsn, GPRS_RLC_DL_BSN_UNACKED);
-}
-
-inline void gprs_rlc_v_b::mark_acked(int bsn)
-{
- return mark(bsn, GPRS_RLC_DL_BSN_ACKED);
-}
-
-inline void gprs_rlc_v_b::mark_nacked(int bsn)
-{
- return mark(bsn, GPRS_RLC_DL_BSN_NACKED);
-}
-
-inline void gprs_rlc_v_b::mark_invalid(int bsn)
-{
- return mark(bsn, GPRS_RLC_DL_BSN_INVALID);
-}
-
-inline gprs_rlc_window::gprs_rlc_window()
- : m_sns(RLC_GPRS_SNS)
- , m_ws(RLC_GPRS_WS)
-{
-}
-
-inline const uint16_t gprs_rlc_window::sns() const
-{
- return m_sns;
-}
-
-inline const uint16_t gprs_rlc_window::ws() const
-{
- return m_ws;
-}
-
-inline const uint16_t gprs_rlc_window::mod_sns() const
-{
- return sns() - 1;
-}
-
-inline const uint16_t gprs_rlc_window::mod_sns(uint16_t bsn) const
-{
- return bsn & mod_sns();
-}
-
-inline gprs_rlc_dl_window::gprs_rlc_dl_window()
- : m_v_s(0)
- , m_v_a(0)
-{
- reset();
-}
-
-inline const uint16_t gprs_rlc_dl_window::v_s() const
-{
- return m_v_s;
-}
-
-inline const uint16_t gprs_rlc_dl_window::v_s_mod(int offset) const
-{
- return mod_sns(m_v_s + offset);
-}
-
-inline const uint16_t gprs_rlc_dl_window::v_a() const
-{
- return m_v_a;
-}
-
-inline bool gprs_rlc_dl_window::window_stalled() const
-{
- return (mod_sns(m_v_s - m_v_a)) == ws();
-}
-
-inline bool gprs_rlc_dl_window::window_empty() const
-{
- return m_v_s == m_v_a;
-}
-
-inline void gprs_rlc_dl_window::increment_send()
-{
- m_v_s = (m_v_s + 1) & mod_sns();
-}
-
-inline void gprs_rlc_dl_window::raise(int moves)
-{
- m_v_a = (m_v_a + moves) & mod_sns();
-}
-
-inline const uint16_t gprs_rlc_dl_window::distance() const
-{
- return (m_v_s - m_v_a) & mod_sns();
-}
-
-inline gprs_rlc_ul_window::gprs_rlc_ul_window()
- : m_v_r(0)
- , m_v_q(0)
-{
- m_v_n.reset();
-}
-
-inline bool gprs_rlc_ul_window::is_in_window(uint16_t bsn) const
-{
- uint16_t offset_v_q;
-
- /* current block relative to lowest unreceived block */
- offset_v_q = (bsn - m_v_q) & mod_sns();
- /* If out of window (may happen if blocks below V(Q) are received
- * again. */
- return offset_v_q < ws();
-}
-
-inline bool gprs_rlc_ul_window::is_received(uint16_t bsn) const
-{
- uint16_t offset_v_r;
-
- /* Offset to the end of the received window */
- offset_v_r = (m_v_r - 1 - bsn) & mod_sns();
- return is_in_window(bsn) && m_v_n.is_received(bsn) && offset_v_r < ws();
-}
-
-inline void gprs_rlc_ul_window::reset_state()
-{
- m_v_r = 0;
- m_v_q = 0;
-}
-
-inline const void gprs_rlc_ul_window::set_v_r(int v_r)
-{
- m_v_r = v_r;
-}
-
-inline const void gprs_rlc_ul_window::set_v_q(int v_q)
-{
- m_v_q = v_q;
-}
-
-inline const uint16_t gprs_rlc_ul_window::v_r() const
-{
- return m_v_r;
-}
-
-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_to(int moves)
-{
- m_v_r = mod_sns(m_v_r + moves);
-}
-
-inline void gprs_rlc_ul_window::raise_v_q(int incr)
-{
- m_v_q = mod_sns(m_v_q + incr);
-}
-
-inline void gprs_rlc_v_n::mark_received(int bsn)
-{
- return mark(bsn, GPRS_RLC_UL_BSN_RECEIVED);
-}
-
-inline void gprs_rlc_v_n::mark_missing(int bsn)
-{
- return mark(bsn, GPRS_RLC_UL_BSN_MISSING);
-}
-
-inline bool gprs_rlc_v_n::is_received(int bsn) const
-{
- return is_state(bsn, GPRS_RLC_UL_BSN_RECEIVED);
-}
-
-inline bool gprs_rlc_v_n::is_state(int bsn, gprs_rlc_ul_bsn_state type) const
-{
- return m_v_n[bsn & mod_sns_half()] == type;
-}
-
-inline void gprs_rlc_v_n::mark(int bsn, gprs_rlc_ul_bsn_state type)
-{
- m_v_n[bsn & mod_sns_half()] = type;
-}
-
-inline gprs_rlc_ul_bsn_state gprs_rlc_v_n::state(int bsn) const
-{
- return m_v_n[bsn & mod_sns_half()];
-}
-
inline void gprs_rlc::init()
{
memset(m_blocks, 0, sizeof(m_blocks));