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