ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/rohc/d_udp.c
Revision: 1.1
Committed: Sun Feb 8 06:02:44 2004 UTC (20 years, 4 months ago) by pcg
Content type: text/plain
Branch: MAIN
CVS Tags: ROHC-IMPORT-2004-02-08
Log Message:
*** empty log message ***

File Contents

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