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