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