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