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