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

# User Rev Content
1 pcg 1.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     }