blob: 3f65a2c23b048b90cf2df7e739e58849b28cf772 [file] [log] [blame]
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +02001/* rlc header descriptions
2 *
3 * Copyright (C) 2012 Ivan Klyuchnikov
4 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20#pragma once
21
22#include <stdint.h>
23
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010024#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */
25#define RLC_MAX_WS 64 /* max window size */
26#define RLC_MAX_LEN 54 /* CS-4 including spare bits */
27
28
29struct gprs_rlc_data {
30 uint8_t *prepare(size_t block_data_length);
31
32 /* block history */
33 uint8_t block[RLC_MAX_LEN];
34 /* block len of history */
35 uint8_t len;
36};
37
38/*
39 * I hold the currently transferred blocks and will provide
40 * the routines to manipulate these arrays.
41 */
42struct gprs_rlc {
43 gprs_rlc_data blocks[RLC_MAX_SNS/2];
44};
45
46struct gprs_rlc_v_b {
Holger Hans Peter Freyther15777792013-11-24 00:18:47 +010047 int resend_needed(const uint16_t acked, const uint16_t sent,
48 const uint16_t mod_sns, const uint16_t mod_sns_half);
49
50 /* Check for an individual frame */
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +010051 bool is_unacked(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010052 bool is_nacked(int index) const;
53 bool is_acked(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010054 bool is_resend(int index) const;
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +010055 bool is_invalid(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010056
57 char state(int index) const;
58
Holger Hans Peter Freyther15777792013-11-24 00:18:47 +010059 /* Mark a RLC frame for something */
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010060 void mark_unacked(int index);
61 void mark_nacked(int index);
62 void mark_acked(int index);
63 void mark_resend(int index);
64 void mark_invalid(int index);
65
66 void reset();
67
68private:
69 bool is_state(int index, const char state) const;
70 void mark(int index, const char state);
71
72 char m_v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
73};
74
75
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +020076extern "C" {
77/* TS 04.60 10.2.2 */
78struct rlc_ul_header {
79 uint8_t r:1,
80 si:1,
81 cv:4,
82 pt:2;
83 uint8_t ti:1,
84 tfi:5,
85 pi:1,
86 spare:1;
87 uint8_t e:1,
88 bsn:7;
89} __attribute__ ((packed));
90
91struct rlc_dl_header {
92 uint8_t usf:3,
93 s_p:1,
94 rrbp:2,
95 pt:2;
96 uint8_t fbi:1,
97 tfi:5,
98 pr:2;
99 uint8_t e:1,
100 bsn:7;
101} __attribute__ ((packed));
102
103struct rlc_li_field {
104 uint8_t e:1,
105 m:1,
106 li:6;
107} __attribute__ ((packed));
108}
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +0100109
110inline bool gprs_rlc_v_b::is_state(int index, const char type) const
111{
112 return m_v_b[index] == type;
113}
114
115inline void gprs_rlc_v_b::mark(int index, const char type)
116{
117 m_v_b[index] = type;
118}
119
120inline char gprs_rlc_v_b::state(int index) const
121{
122 return m_v_b[index];
123}
124
125inline bool gprs_rlc_v_b::is_nacked(int index) const
126{
127 return is_state(index, 'N');
128}
129
130inline bool gprs_rlc_v_b::is_acked(int index) const
131{
132 return is_state(index, 'A');
133}
134
135inline bool gprs_rlc_v_b::is_unacked(int index) const
136{
137 return is_state(index, 'U');
138}
139
140inline bool gprs_rlc_v_b::is_resend(int index) const
141{
142 return is_state(index, 'X');
143}
144
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100145inline bool gprs_rlc_v_b::is_invalid(int index) const
146{
147 return is_state(index, 'I');
148}
149
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +0100150inline void gprs_rlc_v_b::mark_resend(int index)
151{
152 return mark(index, 'X');
153}
154
155inline void gprs_rlc_v_b::mark_unacked(int index)
156{
157 return mark(index, 'U');
158}
159
160inline void gprs_rlc_v_b::mark_acked(int index)
161{
162 return mark(index, 'A');
163}
164
165inline void gprs_rlc_v_b::mark_nacked(int index)
166{
167 return mark(index, 'N');
168}
169
170inline void gprs_rlc_v_b::mark_invalid(int index)
171{
172 return mark(index, 'I');
173}