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