ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/rohc/d_util.c
Revision: 1.3
Committed: Tue Apr 26 00:55:56 2005 UTC (19 years, 1 month ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_01, rel-3_0, rel-2_2, rel-2_0, rel-2_21, rel-2_22, rel-2_25, HEAD
Changes since 1.2: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 ROHC Project 2003 at Lulea University of Technology, Sweden.
3 Authors: Andreas Vernersson <andver-8@student.luth.se>
4 Daniel Pettersson <danpet-7@student.luth.se>
5 Erik Soderstrom <soderstrom@yahoo.com>
6 Fredrik Lindstrom <frelin-9@student.luth.se>
7 Johan Stenmark <johste-8@student.luth.se>
8 Martin Juhlin <juhlin@users.sourceforge.net>
9 Mikael Larsson <larmik-9@student.luth.se>
10 Robert Maxe <robmax-1@student.luth.se>
11
12 Copyright (C) 2003 Andreas Vernersson, Daniel Pettersson,
13 Erik Soderström, Fredrik Lindström, Johan Stenmark,
14 Martin Juhlin, Mikael Larsson, Robert Maxe.
15
16 This program is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or
19 (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31 #include "d_util.h"
32
33 static const unsigned char D_PADDING = 0xe0;
34 static const unsigned char D_ADD_CID = 0xe;
35 static const unsigned char D_FEEDBACK = 0xf0 >> 3;
36 static const unsigned char D_IR_DYN_PACKET = 0xf8;
37 static const unsigned char D_IR_PACKET = 0xfc >> 1;
38 static const unsigned char D_SEGMENT = 0xfe >> 1;
39
40 // Decide if the field is a segment field
41 // Return: 1 = segment
42 // 0 = else
43 int d_is_segment(const unsigned char *data)
44 {
45 if (GET_BIT_1_7(data) == D_SEGMENT)
46 return 1;
47 return 0;
48 }
49
50
51 // Decide if the field is a padding field
52 // Return: 1 = padding
53 // 0 = else
54 int d_is_paddning(const unsigned char *data)
55 {
56 if (GET_BIT_0_7(data) == D_PADDING)
57 return 1;
58 return 0;
59 }
60
61 // Decide if the field is a feedback field
62 // Return: 1 = feedback header
63 // 0 = else
64 int d_is_feedback(const unsigned char *data)
65 {
66 if (GET_BIT_3_7(data) == D_FEEDBACK)
67 return 1;
68 return 0;
69 }
70
71 // Return the size of the feedback
72 // In: Bytes of a feedback header
73 // Out: Size
74 int d_feedback_size(const unsigned char *data)
75 {
76 if(GET_BIT_0_2(data)!=(0x0 >> 1))
77 return GET_BIT_0_2(data);
78 else{
79 data++; //change data to point on the next field
80 return GET_BIT_0_7(data);
81 }
82 }
83
84 // Decide how many bytes the feedback header is
85 // In: Bytes of a feedback header
86 // Out: the size in bytes (1-2)
87 int d_feedback_headersize(const unsigned char *data)
88 {
89 if(GET_BIT_0_2(data)==(0x0 >> 1) )
90 return 2;
91 return 1;
92 }
93
94 // Check if a byte is a add-cid value
95 // It is also possible to use d_decode_add_cid instead.
96 // In: Bytes
97 // Out: 1 = Add-cid value
98 // 0 = else
99 int d_is_add_cid(const unsigned char *data)
100 {
101 if (GET_BIT_4_7(data) == D_ADD_CID)
102 return 1;
103 return 0;
104 }
105
106 // Decode the add-cid value
107 // In: Bytes
108 // Out: 1-15, cid value
109 // 0, no cid value
110 int d_decode_add_cid(const unsigned char *data)
111 {
112 if (GET_BIT_4_7(data) == D_ADD_CID)
113 return GET_BIT_0_3(data);
114 return 0;
115 }
116
117 // Decide if a byte is a ir-field
118 // In: Bytes
119 // Out: 1 = IR, 0 = else
120 int d_is_ir(const unsigned char *data)
121 {
122 if (GET_BIT_1_7(data) == D_IR_PACKET)
123 return 1;
124 return 0;
125 }
126
127 // Decide if a byte is a irdyn-field
128 // In: Bytes
129 // Out: 1 = IR-Dyn, 0 = else
130 int d_is_irdyn(const unsigned char *data)
131 {
132 if (GET_BIT_0_7(data) == D_IR_DYN_PACKET)
133 return 1;
134 return 0;
135 }
136
137 // Decide the size of the self-decsribing variable-length value
138 // In: Bytes
139 // Out: 1-4
140 int d_sdvalue_size(const unsigned char *data)
141 {
142 if(!GET_BIT_7( data )) //bit == 0
143 return 1;
144 else if(GET_BIT_6_7(data) == (0x8 >> 2)) //bits == 10
145 return 2;
146 else if(GET_BIT_5_7(data) == (0xc >> 1)) //bits == 110
147 return 3;
148 else if(GET_BIT_5_7(data) == (0xe >> 1)) //bits == 111
149 return 4;
150 else
151 return -1; //should not happen
152 }
153
154 // Decode a self-describing variable-length value
155 // In: Bytes
156 // Out: The self-describing variable-length value
157 int d_sdvalue_decode(const unsigned char *data)
158 {
159 if(!GET_BIT_7( data )){ //bit == 0
160
161 return GET_BIT_0_6(data);
162 }
163 else if(GET_BIT_6_7(data) == (0x8 >> 2)){ //bits == 10
164
165 return (GET_BIT_0_5(data) << 8 | GET_BIT_0_7((data+1)));
166 }
167 else if(GET_BIT_5_7(data) == (0xc >> 1)){ //bits == 110
168
169 return (GET_BIT_0_4(data) << 16 | GET_BIT_0_7((data+1)) << 8
170 | GET_BIT_0_7((data+2)));
171 }
172 else if(GET_BIT_5_7(data) == (0xe >> 1)){ //bits == 111
173
174 return (GET_BIT_0_4(data) << 24 | GET_BIT_0_7((data+1)) << 16
175 | GET_BIT_0_7((data+2)) << 8 | GET_BIT_0_7((data+3)));
176 }
177 else
178 return -1; //should not happen
179
180 }
181
182 //-----------------------------------------------------------------------------
183
184 // Decode the static part of a ipv4 rohc packet and store it in a ip-structure
185 // Return the number of used bytes
186 int d_decode_static_ip4(const unsigned char *data, struct iphdr * dest)
187 {
188 dest->version = GET_BIT_4_7(data);
189 if((dest->version)!=4)
190 return -1;
191 data++;
192 dest->protocol = GET_BIT_0_7(data);
193 data++;
194 dest->saddr = *((u32 *)data);
195 data += 4;
196 dest->daddr = *((u32 *)data);
197 return 10;
198 }
199
200 // Decode the static part in a udp rohc packet and store it in a udp-structure
201 // Return the number of used bytes
202 int d_decode_static_udp(const unsigned char *data, struct udphdr * dest)
203 {
204 dest-> source = *((u16 *)data);
205 data += 2;
206 dest-> dest = *((u16 *)data);
207 return 4;
208 }
209
210 // Decode the dynamic part in a ipv4 rohc packet and store it in a ip-structure
211 // Return the number of used bytes
212 int d_decode_dynamic_ip4(const unsigned char *data, struct iphdr * dest,
213 int * rnd, int * nbo)
214 {
215 dest->tos = GET_BIT_0_7(data);
216 data++;
217 dest->ttl = GET_BIT_0_7(data);
218 data++;
219 dest-> id = *((u16 *)data);
220 data += 2;
221 if(GET_BIT_7(data)){
222 dest->frag_off = htons(0x4000);
223 }else{
224 dest->frag_off = htons(0x0000);
225 }
226 *nbo = GET_REAL(GET_BIT_5(data));
227 *rnd = GET_REAL(GET_BIT_6(data));
228
229 return 5;
230 }
231
232 // Decode the dynamic part in a udp rohc packet and store it in a udp-structure
233 // Return the number of used bytes
234 int d_decode_dynamic_udp(const unsigned char *data, struct udphdr * dest)
235 {
236 dest-> check = *((u16 *)data);
237 return 2;
238 }
239
240 // Decode the dynamic part in a udp-lite rohc packet and store it in a udp-structure
241 // Return the number of used bytes
242 int d_decode_dynamic_udp_lite(const unsigned char *data, struct udphdr * dest)
243 {
244 dest-> len = *((u16 *)data);
245 data += 2;
246 dest-> check = *((u16 *)data);
247 return 4;
248 }
249
250
251 // Initiate the lsb struct
252 // in: the value of v_ref_d and type of p value
253 void d_lsb_init(struct sd_lsb_decode * s,int v_ref_d, int p)
254 {
255 s->p = p;
256 s->v_ref_d = v_ref_d;
257 s->old_v_ref_d = v_ref_d;
258 }
259
260 // Decode a LSB-value
261 // in: the struct were the old received value is present
262 // m = the LSB-value to decode
263 // k = the length of m in bits
264 //
265 // out:the decoded value
266 int d_lsb_decode(struct sd_lsb_decode * s, int m, int k)
267 {
268 int lower = (s->v_ref_d - s->p);
269 // int higher = (ref - s->p) + 1 << k - 1;
270
271 int bitmask = ~((1 << k) - 1);
272 int sn = (s->v_ref_d & bitmask) | m;
273 if (sn < lower) sn += 1 << k;
274
275 return sn & 0xFFFF;
276 }
277
278 // update the reference value, called after a crc-success to update the
279 // last decoded value, eg the sn number
280 void d_lsb_update(struct sd_lsb_decode * s, int v_ref_d)
281 {
282 s->v_ref_d = v_ref_d;
283 }
284
285 // copy the value in v_ref_d to old_v_ref_d
286 void d_lsb_sync_ref(struct sd_lsb_decode * s){
287 s->old_v_ref_d = s->v_ref_d;
288 }
289
290 // get the old value of v_ref_d
291 int d_get_lsb_old_ref(struct sd_lsb_decode * s){
292 return s->old_v_ref_d;
293 }
294
295 // get the reference value
296 int d_get_lsb_ref(struct sd_lsb_decode * s)
297 {
298 return s->v_ref_d;
299 }
300
301
302 // initiate the ip-id struct
303 // in: the ip-id struct, the reference for ip-id, the sequenze number
304 void d_ip_id_init(struct sd_ip_id_decode * s,int id_ref, int sn_ref)
305 {
306 s->id_ref = id_ref;
307 s->sn_ref = sn_ref;
308 }
309
310 // Decode the ip-id offset in packet m and return the ip_id
311 // in: the ip-id struct, the packet m containing the ip-id offset,
312 // m = the length of the offset
313 // k = number of bits in m
314 // sn = the sequence number of packet m.
315 // out:ip_id
316 int d_ip_id_decode(struct sd_ip_id_decode * s, int m, int k, int sn)
317 {
318 int offset_ref = (s->id_ref - s->sn_ref)%(65536);
319 int offset_m = -1;
320
321 int bitmask = ~((1 << k) - 1);
322 int ip_id = (offset_ref & bitmask) | m;
323
324 if (ip_id < offset_ref) ip_id += 1 << k;
325
326 offset_m = ip_id & 0xFFFF;
327 return ((sn + offset_m)%(65536));
328 }
329
330
331 // update the reference values for the ip-id and the sequence number
332 void d_ip_id_update(struct sd_ip_id_decode * s, int id_ref, int sn_ref)
333 {
334 s->id_ref = id_ref;
335 s->sn_ref = sn_ref;
336 }
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355