ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/rohc/d_udp_lite.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 // The UDP-lite profile in the decompressor
32
33 #include "rohc.h"
34 #include "decomp.h"
35
36 #include "d_ip.h"
37 #include "d_udp_lite.h"
38 #include "d_util.h"
39 #include "comp.h"
40 #include "c_util.h"
41
42
43 //--------------------------------------------------------- Helpfunctions
44
45 /* Decode a UO-0 package */
46 static int udp_lite_decode_uo0(
47 struct sd_rohc * state,
48 struct sd_context * context,
49 unsigned char * head,
50 unsigned char * src,
51 unsigned char * dest,
52 int payload_size
53 );
54
55 /* Decode a UO-1 package */
56 static int udp_lite_decode_uo1(
57 struct sd_rohc * state,
58 struct sd_context * context,
59 unsigned char * head,
60 unsigned char * src2,
61 unsigned char * dest,
62 int payload_size
63 );
64
65 /* Decode a UO-2 package */
66 static int udp_lite_decode_uor2(
67 struct sd_rohc * state,
68 struct sd_context * context,
69 unsigned char * head,
70 unsigned char * src2,
71 unsigned char * dest,
72 int payload_size
73 );
74
75 /* Decode a IR-Dyn package */
76 static int udp_lite_decode_irdyn(
77 struct sd_rohc * state,
78 struct sd_context * context,
79 unsigned char * head,
80 unsigned char * src2,
81 unsigned char * dest,
82 int payload_size
83 );
84
85 /* Decode extention 0 */
86 static int udp_lite_decode_extention0(unsigned char * src, int * sn, int * ip_id);
87
88 /* Decode extention 1 */
89 static int udp_lite_decode_extention1(unsigned char * src, int * sn, int * ip_id);
90
91 /* Decode extention 2 */
92 static int udp_lite_decode_extention2(unsigned char * src, int * sn, int * ip_id, int * ip_id2);
93
94 /* Decode extention 3
95 * - Updates random fields in the s_udp_change
96 * - May update the SN value with 8 lower bits. sn_size is then changed
97 */
98 static int udp_lite_decode_extention3(
99 unsigned char * src,
100 struct sd_rohc * state,
101 struct sd_context * context,
102 int * sn,
103 int * sn_size,
104 int * ip_id_changed,
105 int * id2_updated
106 );
107
108 // Make a copy of the "active"-struct to the "last"-struct.
109 static void udp_lite_syncronize(struct s_udp_lite_profile_data *);
110
111 // Decode package type
112 static int udp_lite_package_type(const unsigned char * p);
113
114 /* Deceide the extention type */
115 static int udp_lite_extention_type(const unsigned char * p);
116
117 /* Write a uncompressed IP v4 header */
118 static void udp_lite_write_uncompressed_ip4(
119 struct s_udp_lite_change * active1,
120 int ip_id,
121 unsigned char * dest,
122 int payload_size
123 );
124
125 /* Write a uncompressed UDP header */
126 static void udp_lite_write_uncompressed_udp(
127 struct s_udp_lite_profile_data *pro,
128 int checksum,
129 int coverage,
130 unsigned char * dest,
131 int payload_size
132 );
133
134 /* Copy the last-struct to active-struct. */
135 static void udp_lite_sync_on_failure(struct s_udp_lite_profile_data * pro);
136
137 /* Decode inner IP flags and fields. Storage the values
138 * in a IP-head struct.
139 */
140 static int udp_lite_decode_inner_header_flags(
141 unsigned char * flags,
142 unsigned char * fields,
143 struct iphdr * ip,
144 int * rnd, int * nbo);
145
146 /* Decode outer IP flags and fields. Storage the values
147 * in a IP-head struct.
148 */
149 static int udp_lite_decode_outer_header_flags(
150 unsigned char * flags,
151 unsigned char * fields,
152 struct iphdr * ip,
153 int * rnd, int * nbo,
154 int * updated_ip);
155
156 /* A functions that decode uo0 and uo1 packets
157 *
158 */
159 static int udp_lite_do_decode_uo0_and_uo1(
160 struct sd_context * context,
161 unsigned char * src,
162 unsigned char * dest,
163 int * payload_size,
164 int sn_bits,
165 int number_of_sn_bits,
166 int * id,
167 int number_of_id_bits,
168 int * id2,
169 int * sn,
170 int * calc_crc
171 );
172
173 /* A functions that decode uor2 packets
174 *
175 */
176 static int udp_lite_do_decode_uor2(
177 struct sd_rohc * state,
178 struct sd_context * context,
179 unsigned char * src2,
180 unsigned char * dest,
181 int * payload_size,
182 int * id,
183 int * id2,
184 int * sn,
185 int * sn_size,
186 int sn_bits,
187 int ext,
188 int * calc_crc
189 );
190
191 /* Try to repair the packet with an other SN value
192 *
193 */
194 static int udp_lite_crc_failure_action(
195 struct sd_rohc * state,
196 struct sd_context * context,
197 unsigned char * src,
198 unsigned char * dest,
199 int sn_size,
200 int * sn_curr1,
201 int sn_bits,
202 int * payload_size,
203 int * id,
204 int id_size,
205 int * id2,
206 int * calc_crc,
207 int * real_crc,
208 int ext
209 );
210
211
212 static void udp_lite_update_packet_time(struct s_udp_lite_profile_data * pro);
213 //---------------------------------------------------------- Code
214
215 // Allocate the profile data
216 void * udp_lite_allocate_decode_data(void)
217 {
218 struct s_udp_lite_profile_data * data;
219 struct s_udp_lite_change * ch;
220 void * p = kmalloc(sizeof(struct s_udp_lite_profile_data) + 4 * sizeof(struct s_udp_lite_change),
221 GFP_ATOMIC);
222
223 if (p==NULL) {
224 rohc_debugf(0, "udp_lite_allocate_decode_data(): no mem for udp-lite profile data\n");
225 return NULL;
226 }
227
228 data = (struct s_udp_lite_profile_data *)p;
229 ch = (struct s_udp_lite_change *)(data + 1);
230
231 memset(p, 0, sizeof(struct s_udp_lite_profile_data) +
232 4 * sizeof(struct s_udp_lite_change) );
233
234 data->last1 = ch; ch++;
235 data->active1 = ch; ch++;
236 data->last2 = ch; ch++;
237 data->active2 = ch;
238
239 return p;
240 }
241
242 // Deallocate the profile data
243 void udp_lite_free_decode_data(void * p)
244 {
245 kfree(p);
246 }
247
248 // Decode an IR-package and initalize context
249 int udp_lite_decode_ir(
250 struct sd_rohc * state,
251 struct sd_context * context,
252 unsigned char * src,
253 int copy_size,
254 int dynamic_present,
255 unsigned char * dest
256 )
257 {
258 struct s_udp_lite_profile_data * pro = context->data;
259 struct s_udp_lite_change * active1 = pro->active1;
260 struct s_udp_lite_change * active2 = pro->active2;
261 unsigned char * s = src;
262 unsigned char * d = dest;
263 int size, sn;
264 int udp_length = 0;
265 pro->current_packet_time = get_microseconds();
266
267 // Ipv4 static
268 size = d_decode_static_ip4(s, &active1->ip);
269
270 if (size == -1)
271 return ROHC_ERROR;
272
273 s += size; copy_size -= size;
274
275 // multiple ip-headers
276 if (active1->ip.protocol == PROTOCOL_IP_IN_IP){
277 pro->multiple_ip = 1;
278 rohc_debugf(1, "Multiple IP header\n");
279 }else{
280 pro->multiple_ip = 0;
281 }
282
283 // if multiple ip-header
284 if(pro->multiple_ip){
285 size = d_decode_static_ip4(s, &active2->ip);
286 s += size; copy_size -= size;
287 if (size == -1)
288 return ROHC_ERROR;
289 }
290
291 // Static udp
292 size = d_decode_static_udp(s, &active1->udp);
293 s += size; copy_size -= size;
294
295 // Dynamic field
296 if (dynamic_present) {
297 // Reset the correction-counter
298 pro->counter = 0;
299
300 size = d_decode_dynamic_ip4(s, &active1->ip, &active1->rnd, &active1->nbo);
301 s += size; copy_size -= (size + 2);
302
303 // if multiple ip-header
304 if(pro->multiple_ip){
305 size = d_decode_dynamic_ip4(s, &active2->ip, &active2->rnd, &active2->nbo);
306 s += size; copy_size -= size;
307 }
308
309 size = d_decode_dynamic_udp_lite(s, &active1->udp);
310 copy_size -= size; s += size;
311
312 udp_length = copy_size + sizeof(struct udphdr);
313
314 // set the checksum coverage flags
315 pro->coverage_present = (udp_length != ntohs(active1->udp.len));
316 pro->coverage_inferred = (udp_length == ntohs(active1->udp.len)); //
317
318 //debug
319 rohc_debugf(2,"(decomp) coverage present %d\n",pro->coverage_present);
320 rohc_debugf(2,"(decomp) coverage inferred %d\n",pro->coverage_inferred);
321
322 // Get and set SN
323 sn = ntohs(* ((u16 *)s));
324 d_lsb_init(&pro->sn, sn, -1);
325 d_ip_id_init(&pro->ip_id1, ntohs(active1->ip.id), sn);
326 s += 2;
327
328 // If multiple-ip-header
329 if(pro->multiple_ip){
330 d_ip_id_init(&pro->ip_id2, ntohs(active2->ip.id), sn);
331 }
332
333 context->state = ROHC_FULL_CONTEXT;
334
335 } else if (context->state != ROHC_FULL_CONTEXT) {
336 // in static/no context and not get dynamic part
337 return ROHC_ERROR;
338 }
339
340 // Header write
341 if (pro->multiple_ip){
342 udp_lite_write_uncompressed_ip4(active1, ntohs(active1->ip.id), d, copy_size+sizeof(struct iphdr)+sizeof(struct udphdr));
343 d += sizeof(struct iphdr);
344 udp_lite_write_uncompressed_ip4(active2, ntohs(active2->ip.id), d, copy_size + sizeof(struct udphdr));
345
346 }else{
347 udp_lite_write_uncompressed_ip4(active1, ntohs(active1->ip.id), d, copy_size + sizeof(struct udphdr));
348 }
349 d += sizeof(struct iphdr);
350
351 // write udp-header
352 memcpy(d, &active1->udp, sizeof(struct udphdr));
353
354 d += sizeof(struct udphdr);
355
356 // Syncronize the change structs
357 udp_lite_syncronize(pro);
358
359 // Update the inter-packet variable
360 udp_lite_update_packet_time(pro);
361
362 // Copy payload
363 if (copy_size == 0) return ROHC_OK_NO_DATA;
364
365 memcpy(d, s, copy_size);
366
367 // Statistics:
368 context->header_compressed_size += s - src;
369 c_add_wlsb(context->header_16_compressed, 0,0, s - src);
370 context->header_uncompressed_size += (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr);
371 c_add_wlsb(context->header_16_uncompressed, 0, 0, (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr));
372
373 return copy_size + (pro->multiple_ip + 1) * sizeof(struct iphdr) + sizeof(struct udphdr);
374 }
375
376 // Calculate the size of data in an IR-package.
377 // return : size or zero.
378 int udp_lite_detect_ir_size(unsigned char * first_byte, int second_byte_add)
379 {
380 int ret = 14;
381 int d = GET_BIT_0(first_byte);
382 if (d) ret += 9 + 2;
383 if (first_byte[second_byte_add + 2] != 0x40) return 0;
384 if (first_byte[second_byte_add + 3] == PROTOCOL_IP_IN_IP){
385 ret += 10;
386 if (d) ret += 5;
387 if (first_byte[second_byte_add + 12] != 0x40) return 0;
388 }
389 return ret;
390 }
391
392 // Calculate the size of data in an IR-package.
393 // return : size or zero.
394 int udp_lite_detect_ir_dyn_size(unsigned char * first_byte, struct sd_context *c)
395 {
396 struct s_udp_lite_profile_data * pro = c->data;
397 if (pro->active1->ip.protocol == PROTOCOL_IP_IN_IP) return 16;
398 return 11;
399 }
400
401 // Decode all package except IR-package.
402 int udp_lite_decode(
403 struct sd_rohc * state,
404 struct sd_context * context,
405 unsigned char * src,
406 int size,
407 int second_byte,
408 unsigned char * dest
409 )
410 {
411 struct s_udp_lite_profile_data * pro = context->data;
412 // ---- DEBUG ----
413 int i; unsigned char * p;
414
415 struct s_udp_lite_change * active1 = pro->active1;
416 struct s_udp_lite_change * active2 = pro->active2;
417 struct s_udp_lite_change * last1 = pro->last1;
418 struct s_udp_lite_change * last2 = pro->last2;
419
420 pro->current_packet_time = get_microseconds();
421
422 rohc_debugf(2,"(udp_lite_decode) nbo = %d rnd = %d\n", last1->nbo, last1->rnd);
423 if (pro->multiple_ip){
424 rohc_debugf(2,"Multiple ip-header\n");
425 rohc_debugf(2,"(udp_lite_decode) nbo2 = %d rnd2 = %d\n", last2->nbo, last2->rnd);
426 }
427 if (memcmp(active1, last1, sizeof(struct s_udp_lite_change)) != 0) {
428 rohc_debugf(0,"(udp_lite_decode) last1 and active1 struct is not synchronized\n");
429 p = (unsigned char *)last1;
430 for (i = 0; i < sizeof(struct s_udp_lite_change); i++) {
431 printk("%2x ", p[i]);
432 }
433 printk("\nvs\n");
434 p = (unsigned char *)active1;
435 for (i = 0; i < sizeof(struct s_udp_lite_change); i++) {
436 printk("%2x ", p[i]);
437 }
438 printk("\n");
439 }
440 if (memcmp(active2, last2, sizeof(struct s_udp_lite_change)) != 0) {
441 rohc_debugf(0,"(udp_lite_decode) last2 and active2 struct is not synchronized\n");
442 p = (unsigned char *)last2;
443 for (i = 0; i < sizeof(struct s_udp_lite_change); i++) {
444 printk("%2x ", p[i]);
445 }
446 printk("\nvs\n");
447 p = (unsigned char *)active2;
448 for (i = 0; i < sizeof(struct s_udp_lite_change); i++) {
449 printk("%2x ", p[i]);
450 }
451 printk("\n");
452 }
453 // ---- DEBUG ----
454
455 if (context->state == ROHC_NO_CONTEXT) return ROHC_ERROR;
456
457 pro->ce_packet = 0;
458 if (*src == 0xf9){ // CE()
459 rohc_debugf(2,"(udp_lite) CE()\n");
460 pro->ce_packet = PACKAGE_CE;
461 }else if(*src == 0xfa){ // CE(ON)
462 rohc_debugf(2,"(udp_lite) CE(ON)\n");
463 pro->coverage_present = 1;
464 pro->ce_packet = PACKAGE_CE;
465 }else if(*src == 0xfb){ // CE(OFF)
466 rohc_debugf(2,"(udp_lite) CE(OFF)\n");
467 pro->coverage_present = 0;
468 pro->ce_packet = PACKAGE_CE_OFF;
469 }
470
471 if(pro->ce_packet){
472 src += second_byte;
473 size--;
474 }
475
476 switch(udp_lite_package_type(src)) {
477 case PACKAGE_UO_0:
478 pro->package_type = PACKAGE_UO_0;
479 if (context->state == ROHC_STATIC_CONTEXT) return ROHC_ERROR;
480 return udp_lite_decode_uo0(state, context, src, (pro->ce_packet ? src + 1 : src + second_byte),
481 dest, size - second_byte);
482 case PACKAGE_UO_1:
483 pro->package_type = PACKAGE_UO_1;
484 if (context->state == ROHC_STATIC_CONTEXT) return ROHC_ERROR;
485 return udp_lite_decode_uo1(state, context, src, (pro->ce_packet ? src + 1 : src + second_byte),
486 dest, size - second_byte);
487 case PACKAGE_UOR_2:
488 pro->package_type = PACKAGE_UOR_2;
489 return udp_lite_decode_uor2(state, context, src, (pro->ce_packet ? src + 1 : src + second_byte),
490 dest, size - second_byte);
491 case PACKAGE_IR_DYN:
492 return udp_lite_decode_irdyn(state, context, src, (pro->ce_packet ? src + 1 : src + second_byte),
493 dest, size - second_byte);
494 default:
495 rohc_debugf(0,"(udp) Unknown package.\n");
496 return ROHC_ERROR;
497 }
498 }
499 /* get the last SN reference value */
500 static int udp_lite_get_sn(struct sd_context * context)
501 {
502 struct s_udp_lite_profile_data * pro = context->data;
503 return d_get_lsb_ref(&pro->sn);
504 }
505
506 static struct s_profile d_udplite_profile = {8,"1.0", "UDP-Lite / Decompressor",
507 udp_lite_decode,
508 udp_lite_decode_ir,
509 udp_lite_allocate_decode_data,
510 udp_lite_free_decode_data,
511 udp_lite_detect_ir_size,
512 udp_lite_detect_ir_dyn_size,
513 udp_lite_get_sn
514 };
515
516 struct s_profile * udp_lite_profile_create()
517 {
518 return &d_udplite_profile;
519 }
520
521
522
523 // --------------------------------------------------------- Package type decoder
524
525
526 /* Decode a UO-0 package */
527 static int udp_lite_decode_uo0(
528 struct sd_rohc * state,
529 struct sd_context * context,
530 unsigned char * head,
531 unsigned char * src,
532 unsigned char * dest,
533 int payload_size
534 )
535 {
536 unsigned char *saved_src = src;
537 struct s_udp_lite_profile_data * pro = context->data;
538
539 int multiple_ip = pro->multiple_ip;
540 int id, id2=-1, sn, sn_bits = GET_BIT_3_6(head), sn_size = 4;
541 int calc_crc, real_crc = GET_BIT_0_2(head);
542 int extra_fields = 0, org_payload_size = payload_size;
543
544 // Do the decoding / find ip-id
545 extra_fields = udp_lite_do_decode_uo0_and_uo1(context, src, dest, &payload_size, sn_bits, sn_size , &id, 0 , &id2, &sn, &calc_crc);
546
547 if (calc_crc != real_crc) {
548 rohc_debugf(0,"UO-0: CRC failure (calc) %x vs %x (real)\n",
549 calc_crc, real_crc);
550
551 payload_size = org_payload_size;
552 udp_lite_crc_failure_action(0, context, src, dest, sn_size, &sn, sn_bits, &payload_size, &id, 0, &id2, &calc_crc, &real_crc, 0);
553
554 return ROHC_ERROR_CRC;
555 }
556
557 if(pro->counter){
558 if(pro->counter==1){
559
560 rohc_debugf(2,"Throw away packet, just 2 packages right so far\n");
561
562 pro->counter++;
563 // Update the inter-packet variable
564
565 udp_lite_update_packet_time(pro);
566
567 udp_lite_syncronize(pro);
568
569 d_lsb_sync_ref(&pro->sn);
570 d_lsb_update(&pro->sn, sn);
571 d_ip_id_update(&pro->ip_id1, id, sn);
572 if (pro->multiple_ip)
573 d_ip_id_update(&pro->ip_id2, id2, sn);
574
575 return ROHC_ERROR_CRC;
576
577 }else if(pro->counter==2){
578 pro->counter = 0;
579 rohc_debugf(2,"The rapair is deemed successful\n");
580 }else{
581 rohc_debugf(2,"XX Should not happen XX\n");
582 }
583 }
584
585 src += extra_fields;
586
587 // Update the inter-packet variable
588 udp_lite_update_packet_time(pro);
589
590 udp_lite_syncronize(pro);
591
592 // Update lsb and id structs on CRC-success
593 d_lsb_sync_ref(&pro->sn);
594 d_lsb_update(&pro->sn, sn);
595 d_ip_id_update(&pro->ip_id1, id, sn);
596 if (pro->multiple_ip){
597 d_ip_id_update(&pro->ip_id2, id2, sn);
598 dest += sizeof(struct iphdr);
599 }
600
601 // Payload
602 dest += sizeof(struct iphdr) + sizeof(struct udphdr);
603
604 memcpy(dest, src, payload_size);
605
606 // Statistics:
607 context->header_compressed_size += src - saved_src;
608 c_add_wlsb(context->header_16_compressed, 0,0, src - saved_src);
609 context->header_uncompressed_size += (multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr);
610 c_add_wlsb(context->header_16_uncompressed, 0, 0, (multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr));
611
612 return payload_size + (multiple_ip + 1) * sizeof(struct iphdr)+ sizeof(struct udphdr);
613 }
614
615
616
617 /* Decode a UO-1 package */
618 static int udp_lite_decode_uo1(
619 struct sd_rohc * state,
620 struct sd_context * context,
621 unsigned char * head,
622 unsigned char * src,
623 unsigned char * dest,
624 int payload_size
625 )
626 {
627 unsigned char *saved_src = src;
628 struct s_udp_lite_profile_data * pro = context->data;
629
630 int id = GET_BIT_0_5(head), id2=-1;
631 int sn, sn_bits = GET_BIT_3_7(src), sn_size = 5;
632 int org_payload_size, extra_fields=0;
633 int calc_crc, real_crc = GET_BIT_0_2(src);
634 src++; payload_size--;
635 org_payload_size = payload_size;
636
637 // Decode the id and sn
638 extra_fields = udp_lite_do_decode_uo0_and_uo1(context, src, dest, &payload_size, sn_bits, sn_size , &id, 6 , &id2, &sn, &calc_crc);
639
640 if (calc_crc != real_crc) {
641 rohc_debugf(0,"UO-1: CRC failure (calc) %x vs %x (real)\n",
642 calc_crc, real_crc);
643 payload_size = org_payload_size;
644 udp_lite_crc_failure_action(0, context, src, dest, sn_size, &sn, sn_bits, &payload_size, &id, 6, &id2, &calc_crc, &real_crc, 0);
645 return ROHC_ERROR_CRC;
646 }
647
648 if(pro->counter){
649 if(pro->counter==1){
650
651 rohc_debugf(2,"Throw away packet, just 2 packages right so far\n");
652
653 pro->counter++;
654 // Update the inter-packet variable
655
656 udp_lite_update_packet_time(pro);
657
658 udp_lite_syncronize(pro);
659
660 d_lsb_sync_ref(&pro->sn);
661 d_lsb_update(&pro->sn, sn);
662 d_ip_id_update(&pro->ip_id1, id, sn);
663 if (pro->multiple_ip)
664 d_ip_id_update(&pro->ip_id2, id2, sn);
665
666
667 return ROHC_ERROR_CRC;
668
669 }else if(pro->counter==2){
670 pro->counter = 0;
671 rohc_debugf(2,"The rapair is deemed successful\n");
672 }else{
673 rohc_debugf(2,"XX Should not happen XX\n");
674 }
675 }
676
677 src += extra_fields;
678
679 // Update the inter-packet variable
680 udp_lite_update_packet_time(pro);
681
682 udp_lite_syncronize(pro);
683
684 d_lsb_sync_ref(&pro->sn);
685 d_lsb_update(&pro->sn, sn);
686 d_ip_id_update(&pro->ip_id1, id, sn);
687
688 if (pro->multiple_ip){
689 d_ip_id_update(&pro->ip_id2, id2, sn);
690 dest += sizeof(struct iphdr);
691 }
692
693 // Payload
694 dest += sizeof(struct iphdr)+ sizeof(struct udphdr);
695 memcpy(dest, src, payload_size);
696
697 // Statistics:
698 context->header_compressed_size += src - saved_src;
699 c_add_wlsb(context->header_16_compressed, 0,0, src - saved_src);
700 context->header_uncompressed_size += (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr);
701 c_add_wlsb(context->header_16_uncompressed, 0, 0, (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr));
702
703 return payload_size + (pro->multiple_ip + 1) * sizeof(struct iphdr) + sizeof(struct udphdr);
704 }
705
706
707
708
709 /* Decode a UO-2 package */
710 static int udp_lite_decode_uor2(
711 struct sd_rohc * state,
712 struct sd_context * context,
713 unsigned char * head,
714 unsigned char * src,
715 unsigned char * dest,
716 int payload_size
717 )
718 {
719 unsigned char *saved_src = src;
720 struct s_udp_lite_profile_data * pro = context->data;
721
722 int org_payload_size = payload_size, extra_fields = 0;
723 int sn_size = 0;
724 int id = 0, id2 = 0, multiple_id = pro->multiple_ip;
725 int calc_crc = 0;
726
727 int sn_bits = GET_BIT_0_4(head) , sn = 0;
728 int real_crc = GET_BIT_0_6(src);
729 int ext = GET_BIT_7(src);
730 src++;
731
732 // Decode
733 extra_fields = udp_lite_do_decode_uor2(state, context, src, dest, &payload_size, &id, &id2, &sn, &sn_size, sn_bits, ext, &calc_crc);
734
735
736 if (calc_crc != real_crc) {
737
738 rohc_debugf(0,"UOR-2: CRC failure (calc) %x vs %x (real)\n",
739 calc_crc, real_crc);
740
741 payload_size = org_payload_size;
742 id =0 ; id2 = 0; calc_crc = 0;
743 udp_lite_crc_failure_action(state, context, src, dest, sn_size, &sn, sn_bits, &payload_size, &id, 0, &id2, &calc_crc, &real_crc, ext);
744 return ROHC_ERROR_CRC;
745 }
746
747 if(pro->counter){
748 if(pro->counter==1){
749
750 rohc_debugf(2,"Throw away packet, just 2 packages right so far\n");
751
752 pro->counter++;
753 // Update the inter-packet variable
754
755 udp_lite_update_packet_time(pro);
756
757 udp_lite_syncronize(pro);
758
759 d_lsb_sync_ref(&pro->sn);
760 d_lsb_update(&pro->sn, sn);
761 d_ip_id_update(&pro->ip_id1, id, sn);
762 if (pro->multiple_ip)
763 d_ip_id_update(&pro->ip_id2, id2, sn);
764
765 return ROHC_ERROR_CRC;
766
767 }else if(pro->counter==2){
768 pro->counter = 0;
769 rohc_debugf(2,"The rapair is deemed successful\n");
770 }else{
771 rohc_debugf(2,"XX Should not happen XX\n");
772 }
773 }
774
775 context->state = ROHC_FULL_CONTEXT;
776 src += extra_fields;
777
778 //if crc success
779 udp_lite_syncronize(pro);
780
781 // Update the inter-packet variable
782 udp_lite_update_packet_time(pro);
783
784 // Update
785 d_lsb_sync_ref(&pro->sn);
786 d_lsb_update(&pro->sn, sn);
787 d_ip_id_update(&pro->ip_id1, id, sn);
788 if (pro->multiple_ip){
789 d_ip_id_update(&pro->ip_id2, id2, sn);
790 dest += sizeof(struct iphdr);
791 }
792 // Payload
793 dest += sizeof(struct iphdr)+ sizeof(struct udphdr);
794 memcpy(dest, src, payload_size);
795
796 // Statistics:
797 context->header_compressed_size += src - saved_src;
798 c_add_wlsb(context->header_16_compressed, 0,0, src - saved_src);
799 context->header_uncompressed_size += (multiple_id+1)*sizeof(struct iphdr) + sizeof(struct udphdr);
800 c_add_wlsb(context->header_16_uncompressed, 0, 0, (multiple_id+1)*sizeof(struct iphdr) + sizeof(struct udphdr));
801
802 return payload_size + (multiple_id +1) *sizeof(struct iphdr)+ sizeof(struct udphdr);
803 }
804
805
806 /* Decode a IR-Dyn package */
807 static int udp_lite_decode_irdyn(
808 struct sd_rohc * state,
809 struct sd_context * context,
810 unsigned char * head,
811 unsigned char * src2,
812 unsigned char * dest,
813 int payload_size
814 )
815 {
816 unsigned char *saved_src = src2;
817 struct s_udp_lite_profile_data * pro = context->data;
818 struct s_udp_lite_change * active1 = pro->active1;
819 struct s_udp_lite_change * active2 = pro->active2;
820 int sn = 0,size = d_decode_dynamic_ip4(src2, &active1->ip, &active1->rnd, &active1->nbo);
821 int udp_length = 0;
822 src2 += size; payload_size -= size + 2;
823
824 if( pro->multiple_ip ){
825 size = d_decode_dynamic_ip4(src2, &active2->ip, &active2->rnd, &active2->nbo);
826 src2 += size; payload_size -= size;
827 }
828
829 size = d_decode_dynamic_udp_lite(src2, &active1->udp);
830
831 payload_size -= size; src2 += size;
832
833 udp_length = payload_size + sizeof(struct udphdr);
834
835 // set the checksum coverage flags
836 pro->coverage_present = (udp_length != ntohs(active1->udp.len));
837 pro->coverage_inferred = (udp_length == ntohs(active1->udp.len));
838
839 //debug
840 rohc_debugf(2,"(decomp) coverage present %d\n",pro->coverage_present);
841 rohc_debugf(2,"(decomp) coverage inferred %d\n",pro->coverage_inferred);
842 sn = ntohs(* ((u16 *)src2));
843 d_lsb_init(&pro->sn, sn, -1);
844 d_ip_id_init(&pro->ip_id1,ntohs(active1->ip.id), sn);
845
846 udp_lite_syncronize(pro);
847 // reset the correction-counter
848 pro->counter = 0;
849 src2 += 2;
850
851 // write header
852 if (pro->multiple_ip){
853 d_ip_id_init(&pro->ip_id2,ntohs(active2->ip.id), sn);
854 udp_lite_write_uncompressed_ip4(active1, ntohs(active1->ip.id), dest, payload_size+sizeof(struct iphdr)+sizeof(struct udphdr));
855 dest += sizeof(struct iphdr);
856 udp_lite_write_uncompressed_ip4(active2, ntohs(active2->ip.id), dest, payload_size + sizeof(struct udphdr));
857 }else{
858 udp_lite_write_uncompressed_ip4(active1, ntohs(active1->ip.id), dest, payload_size+ sizeof(struct udphdr));
859 }
860 context->state = ROHC_FULL_CONTEXT;
861
862 dest += sizeof(struct iphdr);
863 // write udp-header
864 memcpy(dest, &active1->udp, sizeof(struct udphdr));
865 dest += sizeof(struct udphdr);
866
867 // Update the inter-packet variable
868 udp_lite_update_packet_time(pro);
869
870 memcpy(dest, src2, payload_size);
871
872 // Statistics:
873 context->header_compressed_size += src2 - saved_src;
874 c_add_wlsb(context->header_16_compressed, 0,0, src2 - saved_src);
875 context->header_uncompressed_size += (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr);
876 c_add_wlsb(context->header_16_uncompressed, 0, 0, (pro->multiple_ip+1)*sizeof(struct iphdr) + sizeof(struct udphdr));
877
878 return payload_size + ((pro->multiple_ip)+1) * sizeof(struct iphdr) + sizeof(struct udphdr);
879 }
880
881 /* decode uo0 and uo1 packets */
882 static int udp_lite_do_decode_uo0_and_uo1(
883 struct sd_context * context,
884 unsigned char * src,
885 unsigned char * dest,
886 int * payload_size,
887 int sn_bits,
888 int number_of_sn_bits,
889 int * id,
890 int number_of_id_bits,
891 int * id2,
892 int * sn,
893 int * calc_crc
894 )
895 {
896 struct s_udp_lite_profile_data * pro = context->data;
897 struct s_udp_lite_change * active1 = pro->active1;
898 struct s_udp_lite_change * active2 = pro->active2;
899 int field_counter = 0;
900 int checksum = 0;
901 int coverage = 0;
902
903 *sn = d_lsb_decode(&pro->sn, sn_bits, number_of_sn_bits);
904
905 if (active1->rnd) {
906 *id = ntohs(*((u16 *)src));
907 src += 2; field_counter +=2; *payload_size -= 2;
908
909 } else {
910 if(number_of_id_bits)
911 *id = d_ip_id_decode(&pro->ip_id1, *id, number_of_id_bits, *sn);
912 else
913 *id = d_ip_id_decode(&pro->ip_id1, 0, 0, *sn);
914 }
915
916 // If multiple ip header
917 if (pro->multiple_ip){
918
919 if (active2->rnd) {
920 *id2 = ntohs(*((u16 *)src));
921
922 src +=2; field_counter +=2; *payload_size -= 2;
923 } else {
924 *id2 = d_ip_id_decode(&pro->ip_id2, 0, 0, *sn);
925 }
926 }
927
928 // coverage checksum field
929 if ((pro->coverage_present)||(pro->ce_packet)){
930 coverage = ntohs(* ((u16 *)src));
931 if(pro->ce_packet == PACKAGE_CE_OFF){
932 active1->udp.len = * ((u16 *)src);
933 pro->coverage_inferred = ((*payload_size - 4 + sizeof(struct udphdr)) == ntohs(active1->udp.len));
934 }
935 src += 2; field_counter +=2; *payload_size -= 2;
936 }
937
938 //debug
939 rohc_debugf(2,"(decomp) coverage present %d\n",pro->coverage_present);
940 rohc_debugf(2,"(decomp) coverage inferred %d\n",pro->coverage_inferred);
941
942 //checksum
943 checksum = *((u16 *)src);
944 src +=2; field_counter +=2; *payload_size -= 2;
945
946 rohc_debugf(2,"(decomp) udp checksum %x payload size = %d\n",checksum,*payload_size);
947 // Header write
948 if (pro->multiple_ip){
949 udp_lite_write_uncompressed_ip4(active1, *id, dest, *payload_size+sizeof(struct iphdr)+sizeof(struct udphdr));
950 udp_lite_write_uncompressed_ip4(active2, *id2, dest+sizeof(struct iphdr),*payload_size+sizeof(struct udphdr));
951
952 }else{
953 udp_lite_write_uncompressed_ip4(active1, *id, dest, *payload_size+sizeof(struct udphdr));
954 }
955 // udp-header write
956 udp_lite_write_uncompressed_udp(pro, checksum, coverage, dest+(pro->multiple_ip + 1) * sizeof(struct iphdr), *payload_size);
957
958 // Check CRC
959 *calc_crc = crc_calculate(CRC_TYPE_3, dest, (pro->multiple_ip + 1) * sizeof(struct iphdr)+ sizeof(struct udphdr));
960
961 return field_counter;
962 }
963
964 /* decode uor2 packets */
965 static int udp_lite_do_decode_uor2(
966 struct sd_rohc * state,
967 struct sd_context * context,
968 unsigned char * src2,
969 unsigned char * dest,
970 int * payload_size,
971 int * id,
972 int * id2,
973 int * sn,
974 int * sn_size,
975 int sn_bits,
976 int ext,
977 int * calc_crc
978 )
979 {
980 struct s_udp_lite_profile_data * pro = context->data;
981 struct s_udp_lite_change * active1 = pro->active1;
982 struct s_udp_lite_change * active2 = pro->active2;
983 int id2_updated = 0, size = 0;
984 int no_ip_id_update = 0;
985 int field_counter = 0;
986 int checksum = 0, coverage = 0;
987
988 *sn = sn_bits;
989
990 if (ext) {
991 // decode extention
992 switch(udp_lite_extention_type(src2)) {
993 case PACKAGE_EXT_0:
994 size = udp_lite_decode_extention0(src2, sn, id);
995 // ip_id_bits == 3
996 *sn_size = 8;
997 *sn = d_lsb_decode(&pro->sn, *sn, *sn_size );
998 *id = d_ip_id_decode(&pro->ip_id1, *id, 3, *sn);
999 *id2 = d_ip_id_decode(&pro->ip_id2, 0, 0, *sn);
1000 break;
1001
1002 case PACKAGE_EXT_1:
1003 size = udp_lite_decode_extention1(src2, sn, id);
1004 // ip_id bits == 11
1005 *sn_size = 8;
1006 *sn = d_lsb_decode(&pro->sn, *sn, *sn_size );
1007 *id = d_ip_id_decode(&pro->ip_id1, *id, 11, *sn);
1008 *id2 = d_ip_id_decode(&pro->ip_id2, 0, 0, *sn);
1009 break;
1010
1011 case PACKAGE_EXT_2:
1012 size = udp_lite_decode_extention2(src2, sn, id, id2);
1013 // ip_id bits == 8
1014 *sn_size = 8;
1015 *sn = d_lsb_decode(&pro->sn, *sn, *sn_size );
1016 *id2 = d_ip_id_decode(&pro->ip_id1, *id, 8, *sn);
1017 *id = d_ip_id_decode(&pro->ip_id2, *id2, 11, *sn);
1018 break;
1019
1020 case PACKAGE_EXT_3:
1021 *sn_size = 5;
1022 size = udp_lite_decode_extention3(src2, state, context, sn,
1023 sn_size, &no_ip_id_update, &id2_updated);
1024 //udp_lite_syncronize(pro);//flytta denna, synka efter crc-success.
1025 rohc_debugf(2,"(udp_lite_decode) after ext 3 : nbo = %d rnd = %d\n", active1->nbo, active1->rnd);
1026
1027 *sn = d_lsb_decode(&pro->sn, *sn, *sn_size );
1028
1029 if (no_ip_id_update) {
1030 *id = ntohs(active1->ip.id);
1031 } else {
1032 *id = d_ip_id_decode(&pro->ip_id1, 0, 0, *sn);
1033 }
1034 if( pro->multiple_ip ){
1035 rohc_debugf(2,"(udp_lite_decode) after ext 3 : nbo2 = %d rnd2 = %d\n", active2->nbo, active2->rnd);
1036
1037 if (id2_updated){
1038 *id2 = ntohs(active2->ip.id);
1039 }else
1040 *id2 = d_ip_id_decode(&pro->ip_id2, 0, 0, *sn);
1041 }
1042 break;
1043 }
1044
1045
1046 src2 += size;
1047 field_counter +=size;
1048 *payload_size -= size + 1;
1049 } else {
1050 // No extention
1051 *sn_size = 5;
1052 *sn = d_lsb_decode(&pro->sn, *sn , *sn_size);
1053
1054 *id = d_ip_id_decode(&pro->ip_id1, 0, 0, *sn);
1055 if( pro->multiple_ip)
1056 *id2 = d_ip_id_decode(&pro->ip_id1, 0, 0, *sn);
1057 *payload_size -= 1;
1058 }
1059
1060
1061 // Random IP ID ?
1062 if (active1->rnd) {
1063 *id = ntohs(*((u16 *)src2));
1064 src2 +=2; field_counter +=2; *payload_size -= 2;
1065 }
1066
1067 // Multiple ip-header
1068
1069 if (( pro->multiple_ip )&&( active2->rnd )){
1070
1071 *id2 = ntohs(*((u16 *)src2));
1072 src2 +=2; field_counter +=2; *payload_size -= 2;
1073 }
1074
1075
1076 // coverage checksum field
1077 if ((pro->coverage_present)||(pro->ce_packet)){
1078 coverage = ntohs(* ((u16 *)src2));
1079 if(pro->ce_packet == PACKAGE_CE_OFF){
1080 active1->udp.len = * ((u16 *)src2);
1081 pro->coverage_inferred = ((*payload_size - 4 + sizeof(struct udphdr)) == ntohs(active1->udp.len));
1082
1083 }
1084
1085 src2 += 2; field_counter +=2; *payload_size -= 2;
1086 }
1087
1088 //debug
1089 rohc_debugf(2,"(decomp) coverage present %d\n",pro->coverage_present);
1090 rohc_debugf(2,"(decomp) coverage inferred %d\n",pro->coverage_inferred);
1091
1092
1093 checksum = *((u16 *)src2);
1094 src2 +=2; field_counter +=2; *payload_size -= 2;
1095
1096
1097 // Header write
1098 if (pro->multiple_ip){
1099 udp_lite_write_uncompressed_ip4(active1, *id, dest, *payload_size+sizeof(struct iphdr)+sizeof(struct udphdr));
1100 udp_lite_write_uncompressed_ip4(active2, *id2, dest+sizeof(struct iphdr),*payload_size+sizeof(struct udphdr));
1101 }else{
1102 udp_lite_write_uncompressed_ip4(active1, *id, dest, *payload_size+sizeof(struct udphdr));
1103 }
1104
1105 // udp-header write
1106 udp_lite_write_uncompressed_udp(pro, checksum, coverage, dest+(pro->multiple_ip + 1) * sizeof(struct iphdr), *payload_size);
1107
1108 // CRC-check
1109 *calc_crc = crc_calculate(CRC_TYPE_7, dest, (pro->multiple_ip + 1) * sizeof(struct iphdr) + sizeof(struct udphdr));
1110
1111 return field_counter;
1112 }
1113
1114
1115
1116
1117
1118 // ---------------------------------------------------------
1119
1120 /* Decode extention 0.
1121 * - SN value is expanded with 3 lower bits
1122 * - IP-ID is replaced with 3 bits
1123 */
1124 static int udp_lite_decode_extention0(unsigned char * src, int * sn, int * ip_id)
1125 {
1126 *sn = *sn << 3 | GET_BIT_3_5(src);
1127 *ip_id = GET_BIT_0_2(src);
1128 return 1;
1129 }
1130
1131 /* Decode extention 1
1132 * - SN value is expanded with 3 lower bits
1133 * - IP-ID is replaced with 11 bits
1134 */
1135 static int udp_lite_decode_extention1(unsigned char * src, int * sn, int * ip_id)
1136 {
1137 *sn = *sn << 3 | GET_BIT_3_5(src);
1138 *ip_id = GET_BIT_0_2(src);
1139
1140 src++;
1141 *ip_id = *ip_id << 8 | *src;
1142
1143 return 2;
1144 }
1145
1146 /* Decode extention 2
1147 * - SN value is expanded with 3 lower bits
1148 * - IP-ID is replaced with 8 bits
1149 */
1150 static int udp_lite_decode_extention2(unsigned char * src, int * sn, int * ip_id, int * ip_id2)
1151 {
1152
1153 *sn = *sn << 3 | GET_BIT_3_5(src);
1154 *ip_id2 = GET_BIT_0_2(src);
1155 src++;
1156
1157 *ip_id2 = *ip_id2 << 8 | *src;
1158 src++;
1159
1160 *ip_id = *src;
1161 return 3;
1162 }
1163
1164 /* Decode extention 3
1165 * - Updates random fields in the s_udp_change
1166 * - May update the SN value with 8 lower bits. sn_size is then changed
1167 */
1168 static int udp_lite_decode_extention3(
1169 unsigned char * src,
1170 struct sd_rohc * state,
1171 struct sd_context * context,
1172 int * sn,
1173 int * sn_size,
1174 int * ip_id_changed,
1175 int * update_id2)
1176 {
1177 struct s_iponly_profile_data * pro = context->data;
1178 struct s_iponly_change * active1 = pro->active1;
1179 struct s_iponly_change * active2 = pro->active2;
1180 unsigned char * org = src;
1181 unsigned char * fields = src + 1;
1182 int S = GET_BIT_5(src);
1183 int mode = GET_BIT_3_4(src);
1184 int I = GET_BIT_2(src);
1185 int ip = GET_BIT_1(src);
1186 int ip2 = GET_BIT_0(src);
1187 int size;
1188
1189 src++;
1190
1191 if (ip) fields++;
1192 if (ip2) fields++;
1193
1194 if (S) {
1195 *sn = (*sn << 8) + *fields;
1196 *sn_size += 8;
1197 fields++;
1198 }
1199
1200 if (ip) {
1201 if(pro->multiple_ip){
1202 size = decode_inner_header_flags(src, fields, &active2->ip,
1203 &active2->rnd, &active2->nbo);
1204 }else
1205 size = udp_lite_decode_inner_header_flags(src, fields, &active1->ip,
1206 &active1->rnd, &active1->nbo);
1207 fields += size;
1208 }
1209 if (I) {
1210 if(pro->multiple_ip){
1211 active2->ip.id = *((u16 *)fields);
1212 fields += 2;
1213 *update_id2 = 1;
1214 }else{
1215 active1->ip.id = *((u16 *)fields);
1216 fields += 2;
1217 *ip_id_changed = 1;
1218 }
1219 }
1220 if (ip2) {
1221 size = udp_lite_decode_outer_header_flags(src, fields, &active1->ip,
1222 &active1->rnd, &active1->nbo, ip_id_changed );
1223 fields += size;
1224 }
1225
1226 if(mode != context->mode){
1227 rohc_debugf(2,"mode is not equal on decomp and comp.\n");
1228 d_change_mode_feedback(state, context);
1229 }
1230 return fields - org;
1231 }
1232
1233 // --------------------------------------------------------- Local utils functions
1234
1235 // Deceide what package type
1236 static int udp_lite_package_type(const unsigned char * p)
1237 {
1238 if (!GET_BIT_7(p)) {
1239 return PACKAGE_UO_0;
1240 } else if (!GET_BIT_6(p)) {
1241 return PACKAGE_UO_1;
1242 } else if (GET_BIT_5_7(p) == 6) {
1243 return PACKAGE_UOR_2;
1244 } else if (*p == 0xf8) {
1245 return PACKAGE_IR_DYN;
1246 } else if ( (*p & 0xfe) == 0xfc) {
1247 return PACKAGE_IR;
1248 } else {
1249 return PACKAGE_UNKNOWN;
1250 }
1251 }
1252
1253 // Copy the active-structs to last-structs.
1254 void udp_lite_syncronize(struct s_udp_lite_profile_data * pro)
1255 {
1256 memcpy(pro->last1, pro->active1, sizeof(struct s_udp_lite_change));
1257 memcpy(pro->last2, pro->active2, sizeof(struct s_udp_lite_change));
1258 }
1259
1260 // Copy the last-structs to the active-structs.
1261 void udp_lite_sync_on_failure(struct s_udp_lite_profile_data * pro)
1262 {
1263 memcpy(pro->active1, pro->last1, sizeof(struct s_udp_lite_change));
1264 memcpy(pro->active2, pro->last2, sizeof(struct s_udp_lite_change));
1265 }
1266
1267 // Deceide the extention type
1268 static int udp_lite_extention_type(const unsigned char * p)
1269 {
1270 return GET_BIT_6_7(p);
1271 }
1272
1273 /* Decode inner IP flags and fields. Storage the values
1274 * in a IP-head struct.
1275 */
1276 static int udp_lite_decode_inner_header_flags(
1277 unsigned char * flags,
1278 unsigned char * fields,
1279 struct iphdr * ip,
1280 int * rnd, int * nbo)
1281 {
1282 int size = 0;
1283 if (GET_BIT_7(flags)) {
1284 ip->tos = *fields;
1285 fields++; size++;
1286 }
1287 if (GET_BIT_6(flags)) {
1288 ip->ttl = *fields;
1289 fields++; size++;
1290 }
1291 if (GET_BIT_5(flags)) {
1292 ip->frag_off = htons(IP_DF);
1293 } else {
1294 ip->frag_off = 0;
1295 }
1296 if (GET_BIT_4(flags)) {
1297 ip->protocol = *fields;
1298 fields++; size++;
1299 }
1300 if (GET_BIT_3(flags)) {
1301 // TODO, list compression
1302 rohc_debugf(0,"Listcompression is not supported\n");
1303 }
1304 *nbo = GET_BIT_2(flags);
1305 *rnd = GET_BIT_1(flags);
1306 return size;
1307 }
1308
1309 /* Decode outer IP flags and fields. Storage the values
1310 * in a IP-head struct.
1311 */
1312 static int udp_lite_decode_outer_header_flags(
1313 unsigned char * flags,
1314 unsigned char * fields,
1315 struct iphdr * ip,
1316 int * rnd, int * nbo,
1317 int * updated_id)
1318 {
1319 int size = 0;
1320 if (GET_BIT_7(flags)) {
1321 ip->tos = *fields;
1322 fields++; size++;
1323 }
1324 if (GET_BIT_6(flags)) {
1325 ip->ttl = *fields;
1326 fields++; size++;
1327 }
1328 if (GET_BIT_5(flags)) {
1329 ip->frag_off = htons(IP_DF);
1330 } else {
1331 ip->frag_off = 0;
1332 }
1333 if (GET_BIT_4(flags)) {
1334 ip->protocol = *fields;
1335 fields++; size++;
1336 }
1337 if (GET_BIT_3(flags)) {
1338 // TODO, list compression
1339 rohc_debugf(0,"Listcompression is not supported\n");
1340 }
1341 *nbo = GET_BIT_2(flags);
1342 *rnd = GET_BIT_1(flags);
1343
1344 if (GET_BIT_0(flags)) {
1345 ip->id = *((u16 *)fields);
1346 fields += 2; size += 2;
1347 *updated_id = 1;
1348 }
1349 return size;
1350 }
1351
1352 /* Write a uncompressed IP v4 header */
1353 static void udp_lite_write_uncompressed_ip4(
1354 struct s_udp_lite_change * active,
1355 int ip_id,
1356 unsigned char * dest,
1357 int payload_size
1358 )
1359 {
1360 struct iphdr * ip = (struct iphdr *)dest;
1361
1362 // --- static & some changing
1363 memcpy(dest, &active->ip, sizeof(struct iphdr));
1364
1365 // --- ip-id
1366 ip->id = htons(ip_id);
1367 if (!active->nbo) ip->id = __swab16(ip->id);
1368
1369 //--- Static-known fields
1370 ip->ihl = 5;
1371
1372 //--- inferred fields
1373 ip->tot_len = htons(payload_size + (ip->ihl * 4));
1374 ip->check = 0;
1375 ip->check = ip_fast_csum(dest, ip->ihl);
1376 }
1377
1378 static void udp_lite_write_uncompressed_udp(
1379 struct s_udp_lite_profile_data *pro,
1380 int checksum,
1381 int coverage,
1382 unsigned char * dest,
1383 int payload_size
1384 )
1385 {
1386 struct s_udp_lite_change * active = pro->active1;
1387 struct udphdr * udp = (struct udphdr *)dest;
1388
1389 // --- static & some changing
1390 memcpy(dest, &active->udp, sizeof(struct udphdr));
1391
1392 // --- udp-checksum
1393 udp->check = checksum;
1394
1395 // len is checksum coverage in udp-lite
1396 if ((pro->coverage_present)||(pro->ce_packet))
1397 udp->len = htons(coverage);
1398 else{
1399 if(pro->coverage_inferred)
1400 udp->len = htons(payload_size + sizeof(struct udphdr));
1401 }
1402 }
1403
1404 /* This function try to repair the SN in one of two different ways
1405 *
1406 */
1407 static int udp_lite_crc_failure_action(
1408 struct sd_rohc * state,
1409 struct sd_context * context,
1410 unsigned char * src,
1411 unsigned char * dest,
1412 int sn_size,
1413 int * sn,
1414 int sn_bits,
1415 int * payload_size,
1416 int * id,
1417 int id_size,
1418 int * id2,
1419 int * calc_crc,
1420 int * real_crc,
1421 int ext
1422 )
1423 {
1424 struct s_udp_lite_profile_data * pro = context->data;
1425
1426 int sn_ref = 0, intervall = 0;
1427 int sn_curr2 = 0, sn_curr1;
1428 int sn_update = 0;
1429
1430 udp_lite_sync_on_failure(pro);
1431
1432 if(CRC_ACTION){
1433 rohc_debugf(0,"Try to repair the CRC\n");
1434
1435 if(pro->last_packet_time) //if last packettime == 0 then IR was just sent and ...
1436 intervall = pro->current_packet_time - pro->last_packet_time;
1437
1438
1439 if(intervall > ((1 << sn_size)*(pro->inter_arrival_time))){
1440 rohc_debugf(0,"ROHC: repair with the assumption: SN LSB wraparound\n");
1441 rohc_debugf(2,"inter_arrival_time = %d and current intervall is = %d\n", pro->inter_arrival_time, intervall);
1442 rohc_debugf(2,"add %d to SN\n", 1 << sn_size);
1443
1444 // Try and update the SN
1445 sn_ref = d_get_lsb_ref(&pro->sn);
1446 sn_ref += (1 << sn_size);
1447 d_lsb_sync_ref(&pro->sn);
1448 d_lsb_update(&pro->sn, sn_ref);
1449 *sn = d_lsb_decode(&pro->sn, sn_bits, sn_size );
1450
1451 pro->counter = 0;
1452
1453 }else{
1454 // try with the old sn_ref value
1455
1456 rohc_debugf(0,"ROHC: repair with the assumption: incorrect SN-updates\n");
1457
1458 // save current referece value
1459 sn_curr1 = d_get_lsb_ref(&pro->sn);
1460 // test with old reference value
1461 d_lsb_update(&pro->sn, d_get_lsb_old_ref(&pro->sn));
1462
1463 sn_curr2 = d_lsb_decode(&pro->sn, sn_bits, sn_size );
1464
1465 if( sn_curr2 == *sn)
1466 return ROHC_ERROR_CRC;
1467 //*sn = sn_curr2;
1468 d_lsb_update(&pro->sn, sn_curr2);
1469 sn_update = 1;
1470 pro->counter = 0;
1471 }
1472
1473 // Try a new decompression with another SN
1474 switch (pro->package_type){
1475 case PACKAGE_UO_0:
1476 //fall through
1477 case PACKAGE_UO_1:
1478 udp_lite_do_decode_uo0_and_uo1(context, src, dest, payload_size, sn_bits, sn_size , id, id_size, id2, sn, calc_crc);
1479 break;
1480 case PACKAGE_UOR_2:
1481 *sn = sn_bits;
1482 udp_lite_do_decode_uor2(state, context, src, dest, payload_size, id, id2, sn, &sn_size, sn_bits, ext, calc_crc);
1483 break;
1484 default:
1485 rohc_debugf(0,"(Ip-only) A existing packet?\n");
1486 d_lsb_update(&pro->sn, sn_curr1);
1487 return ROHC_ERROR_CRC;
1488 }
1489
1490 if (*calc_crc != *real_crc){
1491 rohc_debugf(0,"ROHC: CRC failure also on the second attempt (calc) %x vs %x (real)\n",*calc_crc, *real_crc);
1492 pro->counter = 0;
1493 if(sn_update)
1494 d_lsb_update(&pro->sn, sn_curr1); //reference curr1 should be used
1495 udp_lite_sync_on_failure(pro);
1496 return ROHC_ERROR_CRC;
1497
1498 }
1499
1500 rohc_debugf(2,"Update and sync with the new SN then throw away the packet\n");
1501 pro->counter++;
1502 udp_lite_update_packet_time(pro);
1503
1504 udp_lite_syncronize(pro);
1505 if(!sn_update){
1506 d_lsb_sync_ref(&pro->sn);
1507 d_lsb_update(&pro->sn, *sn);
1508 }else
1509 d_lsb_update(&pro->sn, sn_curr2);
1510
1511 d_ip_id_update(&pro->ip_id1, *id, *sn);
1512 if (pro->multiple_ip)
1513 d_ip_id_update(&pro->ip_id2, *id2, *sn);
1514
1515 return ROHC_ERROR_CRC;
1516
1517 }else{
1518 return ROHC_ERROR_CRC;
1519 }
1520 }
1521
1522 /* Update the inter-packet time, a sort of averange over the last inter-packet times */
1523 static void udp_lite_update_packet_time(struct s_udp_lite_profile_data * pro)
1524 {
1525 int last_time = pro->last_packet_time;
1526 int delta = 0;
1527 rohc_debugf(2,"current time = %d and last time = %d\n", pro->current_packet_time, last_time);
1528
1529 if (last_time)
1530 delta = pro->current_packet_time - last_time;
1531 pro->last_packet_time = pro->current_packet_time;
1532 if (pro->inter_arrival_time){
1533 pro->inter_arrival_time = (pro->inter_arrival_time >> WEIGHT_OLD) + (delta >> WEIGHT_NEW);
1534
1535 } else
1536 pro->inter_arrival_time = delta;
1537
1538 rohc_debugf(2,"inter_arrival_time = %d and current arrival delta is = %d\n", pro->inter_arrival_time, delta);
1539 }