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