blob: e75a07818919428ed99675202c72ff4f7628adc8 [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 Freyther95255672013-11-23 16:18:18 +010047 bool is_unacked(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010048 bool is_nacked(int index) const;
49 bool is_acked(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010050 bool is_resend(int index) const;
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +010051 bool is_invalid(int index) const;
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +010052
53 char state(int index) const;
54
55 void mark_unacked(int index);
56 void mark_nacked(int index);
57 void mark_acked(int index);
58 void mark_resend(int index);
59 void mark_invalid(int index);
60
61 void reset();
62
63private:
64 bool is_state(int index, const char state) const;
65 void mark(int index, const char state);
66
67 char m_v_b[RLC_MAX_SNS/2]; /* acknowledge state array */
68};
69
70
Holger Hans Peter Freytherd11290b2013-10-26 17:32:04 +020071extern "C" {
72/* TS 04.60 10.2.2 */
73struct rlc_ul_header {
74 uint8_t r:1,
75 si:1,
76 cv:4,
77 pt:2;
78 uint8_t ti:1,
79 tfi:5,
80 pi:1,
81 spare:1;
82 uint8_t e:1,
83 bsn:7;
84} __attribute__ ((packed));
85
86struct rlc_dl_header {
87 uint8_t usf:3,
88 s_p:1,
89 rrbp:2,
90 pt:2;
91 uint8_t fbi:1,
92 tfi:5,
93 pr:2;
94 uint8_t e:1,
95 bsn:7;
96} __attribute__ ((packed));
97
98struct rlc_li_field {
99 uint8_t e:1,
100 m:1,
101 li:6;
102} __attribute__ ((packed));
103}
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +0100104
105inline bool gprs_rlc_v_b::is_state(int index, const char type) const
106{
107 return m_v_b[index] == type;
108}
109
110inline void gprs_rlc_v_b::mark(int index, const char type)
111{
112 m_v_b[index] = type;
113}
114
115inline char gprs_rlc_v_b::state(int index) const
116{
117 return m_v_b[index];
118}
119
120inline bool gprs_rlc_v_b::is_nacked(int index) const
121{
122 return is_state(index, 'N');
123}
124
125inline bool gprs_rlc_v_b::is_acked(int index) const
126{
127 return is_state(index, 'A');
128}
129
130inline bool gprs_rlc_v_b::is_unacked(int index) const
131{
132 return is_state(index, 'U');
133}
134
135inline bool gprs_rlc_v_b::is_resend(int index) const
136{
137 return is_state(index, 'X');
138}
139
Holger Hans Peter Freyther95255672013-11-23 16:18:18 +0100140inline bool gprs_rlc_v_b::is_invalid(int index) const
141{
142 return is_state(index, 'I');
143}
144
Holger Hans Peter Freyther6b5660c2013-11-23 16:10:48 +0100145inline void gprs_rlc_v_b::mark_resend(int index)
146{
147 return mark(index, 'X');
148}
149
150inline void gprs_rlc_v_b::mark_unacked(int index)
151{
152 return mark(index, 'U');
153}
154
155inline void gprs_rlc_v_b::mark_acked(int index)
156{
157 return mark(index, 'A');
158}
159
160inline void gprs_rlc_v_b::mark_nacked(int index)
161{
162 return mark(index, 'N');
163}
164
165inline void gprs_rlc_v_b::mark_invalid(int index)
166{
167 return mark(index, 'I');
168}