blob: 4023e1b8f2a8fb6faa2618cfdbc68deba9a86f02 [file] [log] [blame]
Harald Welte9a8f5032017-07-25 08:23:52 +02001///////////////////////////////////////////////////////////////////////////////
2// //
3// Copyright Test Competence Center (TCC) ETH 2003 //
4// //
5// The copyright to the computer program(s) herein is the property of TCC. //
6// The program(s) may be used and/or copied only with the written permission //
7// of TCC or in accordance with the terms and conditions stipulated in the //
8// agreement/contract under which the program(s) has been supplied. //
9// //
10///////////////////////////////////////////////////////////////////////////////
11//
12// File: ROHC_EncDec.cc
13// Description: ROHC
14// Rev: R3A01
15// Prodnr: CNL 113 426
16// Updated: 2007-02-07
17// Contact: http://ttcn.ericsson.se
18//
19
20/* Based on RFC 3095, July 2001 */
21
22#include "IP_Types.hh"
23#include "UDP_Types.hh"
24#include "RTP_Types.hh"
25#include "ROHC_Types.hh"
26
27/* ============ Constants ============ */
28
29/* Encoding and decoding is performed using static buffers */
30#define MAX_PACKET_SIZE 1500
31#define HEXDUMP_BUFFER_SIZE 1500
32
33/* ROHC mode constants */
34#define ROHC_mode_C 0
35#define ROHC_mode_U 1
36#define ROHC_mode_O 2
37#define ROHC_mode_R 3
38
39/* Inner and outer IP level numbers */
40#define Inner_IP 1
41#define Outer_IP 0
42
43/* ============ Utilities ============ */
44
45#define isIR(val) (((val) & 0xFE) == 0xFC)
46#define isIRDYN(val) ((val) == 0xF8)
47#define isUOR2(val) (((val) & 0xE0) == 0xC0)
48
49/* Shifts the passed bit value from the position 0 to position N. */
50#define ShiftUpBit(val, position) ((val) << (position)) & (0x01 << (position))
51
52/* Shifts the passed bit value from the position N to position 0. */
53#define ShiftDownBit(val, position) (((val) >> (position)) & 0x01)
54
55/* Logs an event, when the 'value' field in the type 'typename' is not
56 implemented. 'typename' must be provided in '"'s */
57#define Log_not_implemented_union_field(typename, value) \
58TTCN_error("Encoding of the selected union field (%u) in type " \
59 typename " is not implemented", (value));
60
61/* Prints a hexdump of the buffer 'buf' in length 'length'. */
62#define Log_hexdump(buf, length) \
63TTCN_logger.log(TTCN_DEBUG, "Buffer (length = %d):\n%s", \
64 (length), debug_hexdump((buf), debug_buf, (length)));
65
66/* Logs the name of the function on entering */
67#define Log_function_name_on_enter() \
68TTCN_logger.log(TTCN_DEBUG, "Entering %s", __FUNCTION__);
69
70/* Logs the name of the function on leaving */
71#define Log_function_name_on_leave() \
72TTCN_logger.log(TTCN_DEBUG, "Leaving %s", __FUNCTION__);
73
74/* Logs an object */
75#define Log_object(o) \
76TTCN_logger.begin_event(TTCN_DEBUG); \
77(o).log(); \
78TTCN_logger.end_event(); \
79
80//**********************************************************
81// NAMESPACE
82//**********************************************************
83
84namespace ROHC__Types {
85
86using namespace General__Types;
87using namespace IP__Types;
88using namespace UDP__Types;
89using namespace RTP__Types;
90
91/* Umbrella type for parsing an incoming ROHC packet */
92typedef struct
93{
94 ROHC__context & context;
95 int cid;
96 int compressed_ah_data_len[2];
97 bool ipx_gre_cksum_present[2];
98} t_dat;
99
100/* TODO: this is not a thread-safe thing to do. For FT, it does not
101 matter, but the buffer should be allocated dynamically. */
102static char debug_buf[HEXDUMP_BUFFER_SIZE];
103
104static char *
105debug_hexdump(const unsigned char *src_buf, char *dest_buf, unsigned int len)
106{
107 unsigned int offset = 0;
108 char val;
109
110 memset(dest_buf, 0, HEXDUMP_BUFFER_SIZE);
111
112 if (src_buf == NULL || len == 0)
113 return dest_buf;
114
115 for (unsigned int i = 0; i < len; i++)
116 {
117 if ((i % 16) == 0 && i > 0)
118 {
119 dest_buf[offset] = 0x0A; /* newline after each line */
120 offset++;
121 }
122 if ((i % 8) == 0)
123 {
124 dest_buf[offset] = 0x20; /* space after 8 characters */
125 offset++;
126 }
127 val = (src_buf[i] >> 4) & 0x0F; /* First digit */
128 val = (val < 10) ? (val + 48) : (val + 65 - 10);
129 dest_buf[offset] = val;
130 offset++;
131 val = src_buf[i] & 0x0F; /* Second digit */
132 val = (val < 10) ? (val + 48) : (val + 65 - 10);
133 dest_buf[offset] += val;
134 offset++;
135 dest_buf[offset] = 0x20; /* space after the value */
136 offset++;
137 }
138
139 return dest_buf;
140}
141
142/* ============ Consistency check routines ============ */
143void
144Check_field_value(char *text, int urherenow, int wannabe)
145{
146 if (wannabe != urherenow)
147 {
148 TTCN_logger.log(TTCN_WARNING, "Field '%s' must be %u, %u is given",
149 text, wannabe, urherenow);
150 }
151}
152
153void
154Check_field_presence(char *text, bool flag, bool presence)
155{
156 if (flag && !presence)
157 {
158 TTCN_logger.log(TTCN_WARNING, "Field '%s' must be present, when "
159 "its presence flag is set", text);
160 }
161 else if (!flag && presence)
162 {
163 TTCN_logger.log(TTCN_WARNING, "Field '%s' must not be present, when "
164 "its presence flag is unset", text);
165 }
166}
167
168void
169Check_feedback_code__size(const INT3b & code, const OPTIONAL < LIN1 > &size)
170{
171 if (size.ispresent() && code > 0)
172 {
173 TTCN_logger.log(TTCN_WARNING,
174 "Code field must be 0, when size field is specified");
175 }
176}
177
178void
179Check_feedback_optlen__optsize(const INT4b & len,
180 const OPTIONAL < OCTETSTRING > &data)
181{
182 if (data.ispresent() && (data().lengthof() != len))
183 {
184 int flen = len;
185 int fdatalen = data().lengthof();
186 TTCN_logger.log(TTCN_WARNING,
187 "Feedback option length (%u) is different from "
188 "the length of feedback option data (%u)", flen, fdatalen);
189 }
190 else if (!data.ispresent() && len > 0)
191 {
192 int flen = len;
193 TTCN_logger.log(TTCN_WARNING,
194 "No feedback option data, but feedback option length "
195 "is not 0 (%u)", flen);
196 }
197}
198
199void
200Check_ps_bit__xi_format(const BIT1 & psbit,
201 const OPTIONAL < XI__list > &xilist)
202{
203 if (!xilist.ispresent())
204 return;
205 if (xilist().get_selection() == XI__list::ALT_xi__item8 && (*psbit) == 0)
206 {
207 TTCN_logger.log(TTCN_WARNING, "PS bit is 0, 4-bit indices must be used");
208 }
209 else if (xilist().get_selection() == XI__list::ALT_xi__item4 && (*psbit) == 1)
210 {
211 TTCN_logger.log(TTCN_WARNING, "PS bit is 1, 8-bit indices must be used");
212 }
213}
214
215INTEGER
216ComputeCRC(const unsigned char *buf, int length, int crclen)
217{
218 int crcval, poly, shiftmask;
219
220 Log_function_name_on_enter();
221 TTCN_logger.log(TTCN_DEBUG, "Calculating CRC-%d over:", crclen);
222 Log_hexdump(buf, length);
223
224 switch (crclen)
225 {
226 case 3:
227 poly = 0x06;
228 crcval = 0x07;
229 shiftmask = 0x03;
230 break;
231
232 case 7:
233 poly = 0x79;
234 crcval = 0x7F;
235 shiftmask = 0x3F;
236 break;
237
238 case 8:
239 poly = 0xE0;
240 crcval = 0xFF;
241 shiftmask = 0x7F;
242 break;
243
244 case 32:
245 poly = 0xEDB88320;
246 crcval = 0xFFFFFFFF;
247 shiftmask = 0x7FFFFFFF;
248 break;
249
250 default:
251 poly = 0;
252 TTCN_error("Unknown CRC length(%d)\n", crclen);
253 break;
254 }
255
256 if (poly == 0)
257 return 0;
258
259 for (int i = 0; i < length; i++)
260 {
261 for (int j = 0; j < 8; j++)
262 {
263 if ((crcval & 0x01) ^ (ShiftDownBit(buf[i], j)))
264 {
265 crcval = (crcval >> 1) & shiftmask;
266 crcval ^= poly;
267 }
268 else
269 {
270 crcval = (crcval >> 1) & shiftmask;
271 }
272 }
273 }
274
275 /* CRC-32 in ROHC needs to be negated at the end */
276 if (crclen == 32)
277 {
278 crcval ^= 0xffffffff;
279 }
280
281 Log_function_name_on_leave();
282
283 unsigned int ui = (unsigned int)crcval;
284 char sbuf[16];
285 sprintf(sbuf, "%u", ui);
286
287 return INTEGER(sbuf);
288}
289
290/* ============ Encoding functions for base types ============ */
291
292/** Returns the index of the innermost IP level, based on the number of
293 IP levels in the context. */
294int
295getInnermostIPidx(t_dat *dat)
296{
297 // More than 1 levels: the innermost is always the index = 1
298 if (dat->context.ip__ctx().size_of() > 1)
299 return Inner_IP;
300 else
301 // The index is the one and only 0.
302 return Outer_IP;
303}
304
305/* Returns the index of the inner or outer IP level in the context, based on the
306 number of the IP levels in the context. If the return value is negative,
307 it indicates that the outer IP level does not exists. Negative value is
308 never returned, if the ip_level is the Inner IP level. */
309int
310getIPidx(t_dat *dat, int ip_level)
311{
312 if (ip_level == Outer_IP)
313 {
314 if (dat->context.ip__ctx().size_of() > 1)
315 return Outer_IP;
316 else
317 return -1;
318 }
319 else if (ip_level == Inner_IP)
320 return getInnermostIPidx(dat);
321 else
322 return ip_level;
323}
324
325/** Initializes the context of the specified IP level. */
326void
327initIPcontext(t_dat *dat, int ip_level, int ip_version)
328{
329 unsigned char ctemp = 0;
330 IP__context & field = dat->context.ip__ctx()[ip_level];
331
332 Log_function_name_on_enter();
333
334 field.version() = INTEGER(ip_version);
335 if (! field.rnd__bit().is_bound()) field.rnd__bit() = BOOLEAN(ctemp);
336 if (! field.ah__present().is_bound()) field.ah__present() = BOOLEAN(ctemp);
337 if (! field.gre__present().is_bound()) field.gre__present() = BOOLEAN(ctemp);
338 if (! field.esp__present().is_bound()) field.esp__present() = BOOLEAN(ctemp);
339 if (! field.ah__data__len().is_bound())
340 field.ah__data__len() = INTEGER(ctemp);
341 if (! field.gre__cksum__present().is_bound())
342 field.gre__cksum__present() = BOOLEAN(ctemp);
343
344 Log_object(dat->context);
345
346 Log_function_name_on_leave();
347}
348
349/** Initializes the UDP context. */
350void
351initUDPcontext(t_dat *dat)
352{
353 unsigned char ctemp = 1;
354 UDP__context & field = dat->context.udp__ctx();
355
356 if (! field.udp__cksum().is_bound()) field.udp__cksum() = BOOLEAN(ctemp);
357}
358
359/** Initializes the specified CID's context. */
360void
361initCIDcontext(t_dat *dat)
362{
363 unsigned char ctemp = 0;
364 ROHC__context & field = dat->context;
365
366 if (! field.mode().is_bound()) field.mode() = INTEGER(cg__ROHC__mode__U);
367 if (! field.profile().is_bound()) field.profile() = INTEGER(ctemp);
368 if (! field.pkt().is_bound()) field.pkt() = Packet__type(Packet__type::IR);
369 if (! field.ip__ctx().is_bound()) initIPcontext(dat, 0, 4);
370 initUDPcontext(dat);
371}
372
373/** Initializes the umbrella type before the ROHC packet parsing starts. */
374t_dat
375initTDAT(ROHC__config & config, int cid)
376{
377 t_dat dat = { config.context()[cid], cid, {0, 0}, {false, false} };
378
379 // Expect AH auth data and GRE checksum after the compressed header
380 // by default. If the uncompressed form is used, these values will be
381 // set to 0 or false during parsing.
382 dat.compressed_ah_data_len[0] =
383 config.context()[cid].ip__ctx()[0].ah__data__len();
384 dat.ipx_gre_cksum_present[0] =
385 config.context()[cid].ip__ctx()[0].gre__cksum__present();
386 if (config.context()[cid].ip__ctx().size_of() > 1)
387 {
388 dat.compressed_ah_data_len[1] =
389 config.context()[cid].ip__ctx()[1].ah__data__len();
390 dat.ipx_gre_cksum_present[1] =
391 config.context()[cid].ip__ctx()[1].gre__cksum__present();
392 }
393 return dat;
394}
395
396/** Returns, whether there is any compressed IPv4 level,
397 where the RND bit is 0. */
398bool
399isAnyIPv4RNDunset(t_dat *dat)
400{
401 for (int i = 0; i < 2; i++)
402 {
403 int ip_idx = getIPidx(dat, i);
404
405 if (ip_idx >= 0) // IP level exists
406 {
407 if (! dat->context.ip__ctx()[ip_idx].rnd__bit())
408 return true;
409 }
410 }
411 return false;
412}
413
414/* Encodes an OCTETSTING value */
415int
416Set_octetstring(unsigned char *buf, const OCTETSTRING & val)
417{
418 memcpy(&(buf[0]), val, val.lengthof());
419 return val.lengthof();
420}
421
422/* Encodes a LIN2_BO_LAST value */
423int
424Set_LIN2_BO_LAST(unsigned char *buf, const LIN2__BO__LAST & val)
425{
426 buf[0] = (val >> 8) & 0xFF;
427 buf[1] = val & 0xFF;
428 return 2;
429}
430
431/* Encodes a LIN4_BO_LAST value */
432int
433Set_LIN4_BO_LAST(unsigned char *buf, const LIN4__BO__LAST & val)
434{
435 buf[0] = (val >> 24) & 0xFF;
436 buf[1] = (val >> 16) & 0xFF;
437 buf[2] = (val >> 8) & 0xFF;
438 buf[3] = val & 0xFF;
439 return 4;
440}
441
442/* Encodes a LIN1 value */
443int
444Set_LIN1(unsigned char *buf, const LIN1 & val)
445{
446 buf[0] = val & 0xFF;
447 return 1;
448}
449
450/* Returns the length of the SDVL encoded CID value 'val'. If the value
451 is invalid, exits via the ttcn_error(). */
452int
453SDVL_encoded_CID_length(int val)
454{
455 if (val <= 0x7F)
456 return 1;
457 else if (val <= 0x3FFF)
458 return 2;
459 else if (val <= 0x1FFFFF)
460 return 3;
461 else if (val <= 0x1FFFFFFF)
462 return 4;
463 else
464 TTCN_error("Value %u is too big for the SDVL encoder "
465 "(at most 29 bits can be used)", val);
466
467 return 0;
468}
469
470int
471Set_SDVL_field(unsigned char *buf, const INTEGER & val, int encoded_length)
472{
473 int len = 0;
474
475 Log_function_name_on_enter();
476
477 if ((val <= 0x7F && encoded_length == 0) || encoded_length == 1)
478 {
479 buf[len] = val & 0x7F;
480 len += 1;
481 }
482 else if ((val <= 0x3FFF && encoded_length == 0) || encoded_length == 2)
483 {
484 buf[len] = 0x80 | ((val >> 8) & 0x7F);
485 len += 1;
486 buf[len] = val & 0xFF;
487 len += 1;
488 }
489 else if ((val <= 0x1FFFFF && encoded_length == 0) || encoded_length == 3)
490 {
491 buf[len] = 0xC0 | ((val >> 16) & 0x3F);
492 len += 1;
493 buf[len] = (val >> 8) & 0xFF;
494 len += 1;
495 buf[len] = val & 0xFF;
496 len += 1;
497 }
498 else if ((val <= 0x1FFFFFFF && encoded_length == 0) || encoded_length == 4)
499 {
500 buf[len] = 0xE0 | ((val >> 24) & 0x1F);
501 len += 1;
502 buf[len] = (val >> 16) & 0xFF;
503 len += 1;
504 buf[len] = (val >> 8) & 0xFF;
505 len += 1;
506 buf[len] = val & 0xFF;
507 len += 1;
508 }
509 else
510 {
511 int tmp = val;
512 TTCN_error("Value %u (specified length is %u) is too big for the "
513 "SDVL encoder (at most 29 bits can be used)",
514 tmp, encoded_length);
515 }
516
517 Log_hexdump(buf, len);
518 Log_function_name_on_leave();
519
520 return len;
521}
522
523/* ============ Encoding wrappers for optional base types ============ */
524
525/* Encodes an optional OCTETSTING value */
526int
527Set_octetstring_opt(unsigned char *buf, const OPTIONAL < OCTETSTRING > &val)
528{
529 if (!val.ispresent())
530 return 0;
531 return Set_octetstring(buf, val());
532}
533
534/* Encodes an optional LIN2_BO_LAST value */
535int
536Set_LIN2_BO_LAST_opt(unsigned char *buf,
537 const OPTIONAL < LIN2__BO__LAST > &val)
538{
539 if (!val.ispresent())
540 return 0;
541 return Set_LIN2_BO_LAST(buf, val());
542}
543
544/* Encodes an optional LIN4_BO_LAST value */
545int
546Set_LIN4_BO_LAST_opt(unsigned char *buf,
547 const OPTIONAL < LIN4__BO__LAST > &val)
548{
549 if (!val.ispresent())
550 return 0;
551 return Set_LIN4_BO_LAST(buf, val());
552}
553
554/* Encodes an optional LIN1 value */
555int
556Set_LIN1_opt(unsigned char *buf, const OPTIONAL < LIN1 > &val)
557{
558 if (!val.ispresent())
559 return 0;
560 return Set_LIN1(buf, val());
561}
562
563int
564Set_SDVL_field_opt(unsigned char *buf,
565 const OPTIONAL < INTEGER > &val, int length)
566{
567 int len = 0;
568
569 Log_function_name_on_enter();
570
571 if (!val.ispresent())
572 return 0;
573 len += Set_SDVL_field(buf, val(), length);
574 Log_function_name_on_leave();
575 return len;
576}
577
578/* ============ Encoding functions for common ROHC types ============ */
579
580int
581Set_CID(unsigned char *buf, const INTEGER & cid, BOOLEAN const &large_cid)
582{
583 int len = 0;
584
585 Log_function_name_on_enter();
586
587 if (large_cid == false)
588 {
589 if (cid > 0)
590 {
591 buf[len] = 0xE0 + (cid & 0x0F);
592 len += 1;
593 }
594 }
595 else
596 len += Set_SDVL_field(&buf[len], cid, 0);
597
598 Log_hexdump(buf, len);
599 Log_function_name_on_leave();
600
601 return len;
602}
603
604/* CSRC and IP extension header item list encoding */
605int
606Set_Item_list_opt(unsigned char *buf, const OPTIONAL < Item__list > &item_list)
607{
608 int len = 0;
609
610 Log_function_name_on_enter();
611
612 if (!item_list.ispresent())
613 {
614 Log_function_name_on_leave();
615 return len;
616 }
617
618 /* Item list is an IP extension header list */
619 if (item_list().get_selection() == Item__list::ALT_ip__item__list)
620 {
621 IP__Item__list ip_item_list = item_list().ip__item__list();
622
623 for (int num = 0; num < ip_item_list.size_of(); num++)
624 {
625 int start_pos = len;
626
627 switch (ip_item_list[num].get_selection())
628 {
629 case Item::ALT_ipv6__ext__item:
630 {
631 IPv6__ext__item & item = ip_item_list[num].ipv6__ext__item();
632
633 len += Set_LIN1(&buf[len], item.nexthead());
634 /* Length of the header in 8-octet units, not including
635 the first 8 octets. */
636 if (item.hdr__ext__len() == 0)
637 {
638 if ((item.data().lengthof() + 2) % 8 != 0)
639 {
640 TTCN_error("Invalid length (%u) of the IPv6 extension header",
641 item.data().lengthof());
642 }
643 buf[len] = (item.data().lengthof() + 2) / 8 - 1;
644 len += 1;
645 }
646 else
647 len += Set_LIN1(&buf[len], item.hdr__ext__len());
648 len += Set_octetstring(&buf[len], item.data());
649 break;
650 }
651 case Item::ALT_mine__item:
652 {
653 MINE__item & item = ip_item_list[num].mine__item();
654
655 Check_field_value("MINE protocol", item.protocol(), c__ip__proto__mine);
656 Check_field_value("MINE reserved", *item.reserved(), 0);
657
658 len += Set_LIN1(&buf[len], item.protocol());
659 buf[len] = (*item.s__bit()) << 7;
660 buf[len] += *item.reserved();
661 len += 1;
662 len += Set_LIN2_BO_LAST(&buf[len], item.cksum());
663 len += Set_octetstring(&buf[len], item.dstaddr());
664 len += Set_octetstring_opt(&buf[len], item.srcaddr());
665 break;
666 }
667 case Item::ALT_ah__item:
668 {
669 AH__item & item = ip_item_list[num].ah__item();
670
671 Check_field_value("AH nexthead", item.nexthead(), c__ip__proto__ah);
672 len += Set_LIN1(&buf[len], item.nexthead());
673
674 /* RFC 2402: This 8-bit field specifies the length of AH in
675 32-bit words (4-byte units), minus "2". */
676 if (item.payload__len() == 0)
677 {
678 if (item.auth__data().ispresent())
679 buf[len] = (item.auth__data()().lengthof() / 4) + 3 - 2;
680 else
681 buf[len] = 1;
682 len += 1;
683 }
684 else
685 len += Set_LIN1(&buf[len], item.payload__len());
686
687 Check_field_value("AH reserved", item.reserved(), 0);
688 len += Set_LIN2_BO_LAST(&buf[len], item.reserved());
689 len += Set_LIN4_BO_LAST(&buf[len], item.spi());
690 len += Set_LIN4_BO_LAST(&buf[len], item.sn());
691 len += Set_octetstring_opt(&buf[len], item.auth__data());
692 break;
693 }
694 case Item::ALT_esp__item:
695 {
696 ESP__item & item = ip_item_list[num].esp__item();
697
698 Check_field_value("ESP nexthead", item.nexthead(), c__ip__proto__esp);
699 len += Set_LIN1(&buf[len], item.nexthead());
700 len += Set_LIN4_BO_LAST(&buf[len], item.spi());
701 len += Set_LIN4_BO_LAST(&buf[len], item.sn());
702 break;
703 }
704 case Item::ALT_gre__item:
705 {
706 GRE__item & item = ip_item_list[num].gre__item();
707
708 Check_field_value("GRE nexthead", item.nexthead(), c__ip__proto__gre2);
709 len += Set_LIN1(&buf[len], item.nexthead());
710 buf[len] = (*item.C__bit()) << 7;
711 Check_field_value("GRE reserved1", (int) *item.reserved__1(), 0);
712 buf[len] += (*item.reserved__1()) << 6;
713 buf[len] += (*item.K__bit()) << 5;
714 buf[len] += (*item.S__bit()) << 4;
715 Check_field_value("GRE reserved2", (int) *item.reserved__2(), 0);
716 buf[len] += (*item.reserved__2()) << 3;
717 buf[len] += *item.version();
718 len += 1;
719 Check_field_presence("checksum", *item.C__bit() == 1,
720 item.cksum().ispresent());
721 Check_field_presence("key", *item.K__bit() == 1,
722 item.key().ispresent());
723 Check_field_presence("sn", *item.S__bit() == 1,
724 item.sn().ispresent());
725 len += Set_LIN2_BO_LAST_opt(&buf[len], item.cksum());
726 len += Set_LIN4_BO_LAST_opt(&buf[len], item.key());
727 len += Set_LIN4_BO_LAST_opt(&buf[len], item.sn());
728 break;
729 }
730 default:
731 {
732 Log_not_implemented_union_field("Item",
733 ip_item_list[num].get_selection());
734 break;
735 }
736 }
737 TTCN_logger.log(TTCN_DEBUG, "%uth item:", num);
738 Log_hexdump(&(buf[start_pos]), len - start_pos);
739 }
740 }
741 else if (item_list().get_selection() == Item__list::ALT_csrc__item__list)
742 {
743 /* Item list is CSRC item list */
744 for (int num = 0; num < item_list().csrc__item__list().size_of(); num++)
745 {
746 int start_pos = len;
747
748 len += Set_octetstring( &buf[len],
749 item_list().csrc__item__list()[num] );
750 TTCN_logger.log(TTCN_DEBUG, "%uth item:", num);
751 Log_hexdump(&(buf[start_pos]), len - start_pos);
752 }
753 }
754 else if (item_list().get_selection() == Item__list::ALT_raw__data)
755 {
756 /* Item list is a raw octetstring */
757 for (int num = 0; num < item_list().csrc__item__list().size_of(); num++)
758 {
759 int start_pos = len;
760
761 len += Set_octetstring(&buf[len], item_list().raw__data()[num] );
762 TTCN_logger.log(TTCN_DEBUG, "%uth item:", num);
763 Log_hexdump(&(buf[start_pos]), len - start_pos);
764 }
765 }
766 else
767 {
768 Log_not_implemented_union_field("Item_list", item_list().get_selection());
769 }
770
771 Log_hexdump(buf, len);
772 Log_function_name_on_leave();
773
774 return len;
775}
776
777int
778Set_XI_list_opt(unsigned char *buf, const OPTIONAL < XI__list > &xilist,
779 const OPTIONAL < BITSTRING > &padding, int length)
780{
781 int len = 0;
782 int halfbyte = 0;
783
784 Log_function_name_on_enter();
785
786 if (!xilist.ispresent())
787 {
788 Log_function_name_on_leave();
789 return len;
790 }
791
792 switch (xilist().get_selection())
793 {
794 case XI__list::ALT_xi__item4:
795 {
796 if (length != xilist().xi__item4().size_of())
797 TTCN_logger.log(TTCN_WARNING,
798 "Number of indices != value of CC field");
799 for (int num = 0; num < xilist().xi__item4().size_of(); num++)
800 {
801 if (halfbyte)
802 {
803 buf[len] += ((*xilist().xi__item4()[num].x__ind()) << 3) & 0x08;
804 buf[len] += xilist().xi__item4()[num].index() & 0x07;
805 len += 1;
806 }
807 else
808 {
809 buf[len] = ((*xilist().xi__item4()[num].x__ind()) << 7) & 0x80;
810 buf[len] += (xilist().xi__item4()[num].index() << 4) & 0x70;
811 }
812 halfbyte = 1 - halfbyte; // Invert the value (0 -> 1 or 1 -> 0)
813 }
814 break;
815 }
816
817 case XI__list::ALT_xi__item8:
818 {
819 if (length != xilist().xi__item8().size_of())
820 TTCN_logger.log(TTCN_WARNING,
821 "Number of indices != value of CC field");
822 for (int num = 0; num < xilist().xi__item8().size_of(); num++)
823 {
824 buf[len] = ((*xilist().xi__item8()[num].x__ind()) << 7) & 0x80;
825 buf[len] += xilist().xi__item8()[num].index() & 0x7F;
826 len += 1;
827 }
828 break;
829 }
830
831 default:
832 Log_not_implemented_union_field("XI_list", xilist().get_selection());
833 break;
834 }
835
836 if (padding.ispresent() && halfbyte == 0)
837 {
838 TTCN_logger.log(TTCN_WARNING, "Specified padding is ignored");
839 }
840 else if (!padding.ispresent() && halfbyte)
841 {
842 TTCN_logger.log(TTCN_WARNING,
843 "Padding not specified, padding bits left uninitialized");
844 }
845 else if (padding.ispresent())
846 {
847 Check_field_value("Index padding", *padding(), 0);
848 buf[len] += (*padding()) & 0x0F;
849 len += 1;
850 }
851
852 Log_hexdump(buf, len);
853 Log_function_name_on_leave();
854
855 return len;
856}
857
858int
859Set_Encoding_Type_0(unsigned char *buf, const Enc__Type__0 & enct0)
860{
861 int len = 0;
862
863 Log_function_name_on_enter();
864
865 Check_field_presence("gen_id", *enct0.gp__bit() == 1,
866 enct0.gen__id().ispresent());
867
868 Check_field_value("Encoding type", *enct0.et(), 0);
869 buf[len] = ((*enct0.et()) << 6) & 0xC0;
870 buf[len] += ShiftUpBit(*enct0.gp__bit(), 5);
871 buf[len] += ShiftUpBit(*enct0.ps__bit(), 4);
872 buf[len] += enct0.cc() & 0x0F;
873 len += 1;
874 len += Set_LIN1_opt(&buf[len], enct0.gen__id());
875 Check_ps_bit__xi_format(enct0.ps__bit(), enct0.xi__list());
876 len += Set_XI_list_opt(&buf[len], enct0.xi__list(), enct0.padding(),
877 enct0.cc());
878 len += Set_Item_list_opt(&buf[len], enct0.item__list());
879
880 Log_hexdump(buf, len);
881 Log_function_name_on_leave();
882
883 return len;
884}
885
886
887int
888Set_Encoding_Type_1(unsigned char *buf, const Enc__Type__1 & enct1)
889{
890 int len = 0;
891 int n = 0;
892
893 Log_function_name_on_enter();
894
895 Check_field_presence("gen_id", *enct1.gp__bit() == 1,
896 enct1.gen__id().ispresent());
897
898 Check_field_value("Encoding type", *enct1.et(), 1);
899 buf[len] = ((*enct1.et()) << 6) & 0xC0;
900 buf[len] += ShiftUpBit(*enct1.gp__bit(), 5);
901 buf[len] += ShiftUpBit(*enct1.ps__bit(), 4);
902 buf[len] += enct1.xi1() & 0x0F;
903 len += 1;
904 len += Set_LIN1_opt(&buf[len], enct1.gen__id());
905 len += Set_LIN1_opt(&buf[len], enct1.ref__id());
906 len += Set_octetstring(&buf[len], enct1.insbitmask());
907
908 // Count the number of 1's in the bitmask
909 for (int i = 0; i < enct1.insbitmask().lengthof(); ++i)
910 {
911 if (enct1.insbitmask() & int2oct(i + 1, enct1.insbitmask().lengthof()))
912 ++n;
913 }
914
915 Check_ps_bit__xi_format(enct1.ps__bit(), enct1.xi__list());
916 len += Set_XI_list_opt(&buf[len], enct1.xi__list(), enct1.padding(), n);
917 len += Set_Item_list_opt(&buf[len], enct1.item__list());
918
919 Log_hexdump(buf, len);
920 Log_function_name_on_leave();
921
922 return len;
923}
924
925
926int
927Set_Encoding_Type_2(unsigned char *buf, const Enc__Type__2 & enct2)
928{
929 int len = 0;
930
931 Check_field_presence("gen_id", *enct2.gp__bit() == 1,
932 enct2.gen__id().ispresent());
933
934 Check_field_value("Encoding type", *enct2.et(), 2);
935 buf[len] = ((*enct2.et()) << 6) & 0xC0;
936 buf[len] += ShiftUpBit(*enct2.gp__bit(), 5);
937 buf[len] += ShiftUpBit(*enct2.res(), 4);
938 buf[len] += enct2.count() & 0x0F;
939 len += 1;
940 len += Set_LIN1_opt(&buf[len], enct2.gen__id());
941 len += Set_LIN1_opt(&buf[len], enct2.ref__id());
942 len += Set_octetstring(&buf[len], enct2.rembitmask());
943
944 Log_hexdump(buf, len);
945 Log_function_name_on_leave();
946
947 return len;
948}
949
950
951int
952Set_Encoding_Type_3(unsigned char *buf, const Enc__Type__3 & enct3)
953{
954 int len = 0;
955 int n = 0;
956
957 Check_field_presence("gen_id", *enct3.gp__bit() == 1,
958 enct3.gen__id().ispresent());
959
960 Check_field_value("Encoding type", *enct3.et(), 3);
961 buf[len] = ((*enct3.et()) << 6) & 0xC0;
962 buf[len] += ShiftUpBit(*enct3.gp__bit(), 5);
963 buf[len] += ShiftUpBit(*enct3.ps__bit(), 4);
964 buf[len] += enct3.xi1() & 0x0F;
965 len += 1;
966 len += Set_LIN1_opt(&buf[len], enct3.gen__id());
967 len += Set_LIN1_opt(&buf[len], enct3.ref__id());
968 len += Set_octetstring(&buf[len], enct3.rembitmask());
969 len += Set_octetstring(&buf[len], enct3.insbitmask());
970
971 // Count the number of 1's in the bitmask
972 for (int i = 0; i < enct3.insbitmask().lengthof(); ++i)
973 {
974 if (enct3.insbitmask() & int2oct(i + 1, enct3.insbitmask().lengthof()))
975 ++n;
976 }
977 Check_ps_bit__xi_format(enct3.ps__bit(), enct3.xi__list());
978 len += Set_XI_list_opt(&buf[len], enct3.xi__list(), enct3.padding(), n);
979 len += Set_Item_list_opt(&buf[len], enct3.item__list());
980
981 Log_hexdump(buf, len);
982 Log_function_name_on_leave();
983
984 return len;
985}
986
987int
988Set_Compr_head_list_opt(unsigned char *buf,
989 const OPTIONAL < Compr__head__list > &chl)
990{
991 int len = 0;
992
993 Log_function_name_on_enter();
994
995 if (!chl.ispresent())
996 {
997 Log_function_name_on_leave();
998 return len;
999 }
1000 if (chl().get_selection() == Compr__head__list::ALT_enctype0)
1001 len += Set_Encoding_Type_0(&buf[len], chl().enctype0());
1002 else if (chl().get_selection() == Compr__head__list::ALT_enctype1)
1003 len += Set_Encoding_Type_1(&buf[len], chl().enctype1());
1004 else if (chl().get_selection() == Compr__head__list::ALT_enctype2)
1005 len += Set_Encoding_Type_2(&buf[len], chl().enctype2());
1006 else if (chl().get_selection() == Compr__head__list::ALT_enctype3)
1007 len += Set_Encoding_Type_3(&buf[len], chl().enctype3());
1008 else
1009 {
1010 Log_not_implemented_union_field("Compr_head_list", chl().get_selection());
1011 }
1012
1013 Log_hexdump(buf, len);
1014 Log_function_name_on_leave();
1015
1016 return len;
1017}
1018
1019int
1020Set_AEGSeqnum_opt(unsigned char *buf, const OPTIONAL < AEGSeqnum > &oseqn)
1021{
1022 int len = 0;
1023
1024 Log_function_name_on_enter();
1025
1026 if (!oseqn.ispresent())
1027 {
1028 Log_function_name_on_leave();
1029 return len;
1030 }
1031 if (oseqn().get_selection() == AEGSeqnum::ALT_short__form)
1032 {
1033 Check_field_value("form-bit", (int) *oseqn().short__form().ind(), 0);
1034 buf[len] = ShiftUpBit(*oseqn().short__form().ind(), 7);
1035 buf[len] += oseqn().short__form().lsb__of__seqnum() & 0x7F;
1036 len += 1;
1037 }
1038 else if (oseqn().get_selection() == AEGSeqnum::ALT_long__form)
1039 {
1040 Check_field_value("form-bit", (int) *oseqn().long__form().ind(), 1);
1041 buf[len] = ShiftUpBit(*oseqn().long__form().ind(), 7);
1042 buf[len] += (oseqn().long__form().lsb__of__seqnum() >> 24) & 0x7F;
1043 len += 1;
1044
1045 buf[len] = (oseqn().long__form().lsb__of__seqnum() >> 16) & 0xFF;
1046 len += 1;
1047
1048 buf[len] = (oseqn().long__form().lsb__of__seqnum() >> 8) & 0xFF;
1049 len += 1;
1050
1051 buf[len] = oseqn().long__form().lsb__of__seqnum() & 0xFF;
1052 len += 1;
1053 }
1054 else
1055 Log_not_implemented_union_field("AEGSeqnum", oseqn().get_selection());
1056
1057 Log_hexdump(buf, len);
1058 Log_function_name_on_leave();
1059
1060 return len;
1061}
1062
1063int
1064Set_IPv4_static_chain(unsigned char *buf, const IPv4__Static & chain)
1065{
1066 int len = 0;
1067
1068 Log_function_name_on_enter();
1069
1070 Check_field_value("IPv4 version", chain.version(), 4);
1071 buf[len] = (chain.version() << 4) & 0xF0;
1072 Check_field_value("IPv4 reserved (static chain)", chain.reserved(), 0);
1073 buf[len] += chain.reserved() & 0x0F;
1074 len += 1;
1075 len += Set_LIN1(&buf[len], chain.proto());
1076 len += Set_octetstring(&buf[len], chain.srcaddr());
1077 len += Set_octetstring(&buf[len], chain.dstaddr());
1078
1079 Log_hexdump(buf, len);
1080 Log_function_name_on_leave();
1081
1082 return len;
1083}
1084
1085int
1086Set_IPv6_static_chain(unsigned char *buf, const IPv6__Static & chain)
1087{
1088 int len = 0;
1089
1090 Log_function_name_on_enter();
1091
1092 Check_field_value("IPv6 version", chain.version(), 6);
1093 buf[len] = (chain.version() << 4) & 0xF0;
1094 buf[len] += (chain.flowlabel() >> 16) & 0x0F;
1095 len += 1;
1096
1097 buf[len] = (chain.flowlabel() >> 8) & 0xFF;
1098 len += 1;
1099 buf[len] = chain.flowlabel() & 0xFF;
1100 len += 1;
1101
1102 len += Set_LIN1(&buf[len], chain.nexthead());
1103 len += Set_octetstring(&buf[len], chain.srcaddr());
1104 len += Set_octetstring(&buf[len], chain.dstaddr());
1105
1106 Log_hexdump(buf, len);
1107 Log_function_name_on_leave();
1108
1109 return len;
1110}
1111
1112int
1113Set_UDP_static_chain(unsigned char *buf, const UDP__Static & chain)
1114{
1115 int len = 0;
1116
1117 Log_function_name_on_enter();
1118
1119 len += Set_LIN2_BO_LAST(&buf[len], chain.srcport());
1120 len += Set_LIN2_BO_LAST(&buf[len], chain.dstport());
1121
1122 Log_hexdump(buf, len);
1123 Log_function_name_on_leave();
1124
1125 return len;
1126}
1127
1128int
1129Set_RTP_static_chain(unsigned char *buf, const RTP__Static & chain)
1130{
1131 int len = 0;
1132
1133 Log_function_name_on_enter();
1134
1135 len += Set_octetstring(&buf[len], chain.ssrc());
1136
1137 Log_hexdump(buf, len);
1138 Log_function_name_on_leave();
1139
1140 return len;
1141}
1142
1143int
1144Set_RTP_dynamic_chain(unsigned char *buf, const RTP__Dynamic & chain)
1145{
1146 int len = 0;
1147
1148 Log_function_name_on_enter();
1149
1150 Check_field_value("RTP version", chain.vfield(), 2);
1151 buf[len] = (chain.vfield() << 6) & 0xC0;
1152 buf[len] += ShiftUpBit(*chain.pbit(), 5);
1153 buf[len] += ShiftUpBit(*chain.rxbit(), 4);
1154 buf[len] += chain.ccfield() & 0x0F;
1155 len += 1;
1156 buf[len] = ShiftUpBit(*chain.mbit(), 7);
1157 buf[len] += chain.ptfield() & 0x7F;
1158 len += 1;
1159 len += Set_LIN2_BO_LAST(&buf[len], chain.rtpseqnum());
1160 len += Set_LIN4_BO_LAST(&buf[len], chain.rtpts());
1161 len += Set_Encoding_Type_0(&buf[len], chain.gencsrclist());
1162 Check_field_presence("RTP rx", *chain.rxbit() == 1,
1163 chain.rx__field().ispresent());
1164 if (chain.rx__field().ispresent())
1165 {
1166 Check_field_value("RX reserved", (int) *chain.rx__field()().reserved(), 0);
1167 buf[len] = ((*chain.rx__field()().reserved()) << 5) & 0xE0;
1168 buf[len] += ShiftUpBit(*chain.rx__field()().xbit(), 4);
1169 buf[len] += (chain.rx__field()().mode() << 2) & 0x0C;
1170 buf[len] += ShiftUpBit(*chain.rx__field()().tisbit(), 1);
1171 buf[len] += ShiftUpBit(*chain.rx__field()().tssbit(), 0);
1172 len += 1;
1173 }
1174 Check_field_presence("TS Stride",
1175 chain.rx__field().ispresent() &&
1176 (*chain.rx__field()().tssbit()) == 1,
1177 chain.ts__stride().ispresent());
1178 Check_field_presence("TIME Stride",
1179 chain.rx__field().ispresent() &&
1180 (*chain.rx__field()().tisbit()) == 1,
1181 chain.time__stride().ispresent());
1182 len += Set_SDVL_field_opt(&buf[len], chain.ts__stride(), 0);
1183 len += Set_SDVL_field_opt(&buf[len], chain.time__stride(), 0);
1184
1185 Log_hexdump(buf, len);
1186 Log_function_name_on_leave();
1187
1188 return len;
1189}
1190
1191int
1192Set_RTP_flags_fields_opt(unsigned char *buf,
1193 const OPTIONAL < RTP__flags__fields > &field)
1194{
1195 int len = 0;
1196
1197 Log_function_name_on_enter();
1198
1199 if (!field.ispresent())
1200 {
1201 Log_function_name_on_leave();
1202 return len;
1203 }
1204 buf[len] = (field().mode() << 6) & 0xC0;
1205 buf[len] += ShiftUpBit(*field().r__pt(), 5);
1206 buf[len] += ShiftUpBit(*field().m__bit(), 4);
1207 buf[len] += ShiftUpBit(*field().r__x(), 3);
1208 buf[len] += ShiftUpBit(*field().csrc(), 2);
1209 buf[len] += ShiftUpBit(*field().tss(), 1);
1210 buf[len] += ShiftUpBit(*field().tis(), 0);
1211 len += 1;
1212
1213 Check_field_presence("RTP flags",
1214 *field().r__pt() == 1, field().flags().ispresent());
1215 if (field().flags().ispresent())
1216 {
1217 buf[len] = (((*field().flags()().r__p()) << 7) & 0x80) +
1218 (field().flags()().rtp__pt() & 0x7F);
1219 len += 1;
1220 }
1221 Check_field_presence("Compressed CSRC list",
1222 *field().csrc() == 1, field().csrc__list().ispresent());
1223 len += Set_Compr_head_list_opt(&buf[len], field().csrc__list());
1224 Check_field_presence("TS_STRIDE",
1225 *field().tss() == 1, field().ts__stride().ispresent());
1226 len += Set_SDVL_field_opt(&buf[len], field().ts__stride(), 0);
1227 Check_field_presence("TIME_STRIDE",
1228 *field().tis() == 1,
1229 field().time__stride().ispresent());
1230 len += Set_SDVL_field_opt(&buf[len], field().time__stride(), 0);
1231
1232 Log_hexdump(buf, len);
1233 Log_function_name_on_leave();
1234
1235 return len;
1236}
1237
1238int
1239Set_IPv4_dynamic_chain(unsigned char *buf, const IPv4__Dynamic & chain)
1240{
1241 int len = 0;
1242
1243 Log_function_name_on_enter();
1244
1245 len += Set_LIN1(&buf[len], chain.tos());
1246 len += Set_LIN1(&buf[len], chain.ttl());
1247 len += Set_LIN2_BO_LAST(&buf[len], chain.identification());
1248
1249 buf[len] = ShiftUpBit(*chain.df__bit(), 7);
1250 buf[len] += ShiftUpBit(*chain.rnd__bit(), 6);
1251 buf[len] += ShiftUpBit(*chain.nbo__bit(), 5);
1252 Check_field_value("IPv4 reserved (dynamic chain)", *chain.reserved(), 0);
1253 buf[len] += (*chain.reserved()) & 0x1F;
1254 len += 1;
1255 len += Set_Encoding_Type_0(&buf[len], chain.genextheadlist());
1256
1257 Log_hexdump(buf, len);
1258 Log_function_name_on_leave();
1259
1260 return len;
1261}
1262
1263int
1264Set_IPv6_dynamic_chain(unsigned char *buf, const IPv6__Dynamic & chain)
1265{
1266 int len = 0;
1267
1268 Log_function_name_on_enter();
1269
1270 len += Set_LIN1(&buf[len], chain.trafficclass());
1271 len += Set_LIN1(&buf[len], chain.hoplimit());
1272 len += Set_Encoding_Type_0(&buf[len], chain.genextheadlist());
1273
1274 Log_hexdump(buf, len);
1275 Log_function_name_on_leave();
1276
1277 return len;
1278}
1279
1280/* ============ Encoding functions for ROHC types ============ */
1281int
1282Set_feedback(unsigned char *buf, const Feedback__u & feedback,
1283 BOOLEAN const &large_cid)
1284{
1285 int len = 0, crcpos = 0, crcstart = 0;
1286
1287 Log_function_name_on_enter();
1288
1289 Check_field_value("feedback type", (int) *feedback.feedback__type(), 30);
1290 Check_feedback_code__size(feedback.code(), feedback.size());
1291 buf[len] = ((*feedback.feedback__type()) << 3) & 0xF8;
1292 buf[len] += feedback.code() & 0x07;
1293 len += 1;
1294
1295 len += Set_LIN1_opt(&buf[len], feedback.size());
1296
1297 crcstart = len;
1298
1299 len += Set_CID(&buf[len], feedback.feedback__data().cid(), large_cid);
1300
1301 switch (feedback.feedback__data().feedback__type().get_selection())
1302 {
1303 case Feedback__type::ALT_feedback1:
1304 {
1305 Feedback1 fback1 =
1306 feedback.feedback__data().feedback__type().feedback1();
1307
1308 len += Set_octetstring(&buf[len], fback1);
1309 break;
1310 }
1311
1312 case Feedback__type::ALT_feedback2:
1313 {
1314 Feedback2 fback2 =
1315 feedback.feedback__data().feedback__type().feedback2();
1316
1317 buf[len] = (fback2.acktype() << 6) & 0xC0;
1318 buf[len] += (fback2.mode() << 4) & 0x30;
1319 buf[len] += (fback2.sn() >> 8) & 0x0F;
1320 len += 1;
1321
1322 buf[len] = fback2.sn() & 0xFF;
1323 len += 1;
1324
1325 if (fback2.feedback__opts().ispresent())
1326 {
1327 Feedback__opts & fbopts = fback2.feedback__opts();
1328
1329 for (int num = 0; num < fbopts.size_of(); num++)
1330 {
1331 buf[len] = (fbopts[num].opt__type() << 4) & 0xF0;
1332 Check_feedback_optlen__optsize(fbopts[num].opt__len(),
1333 fbopts[num].opt__data());
1334 buf[len] += fbopts[num].opt__len() & 0x0F;
1335 len += 1;
1336
1337 len += Set_octetstring_opt(&buf[len], fbopts[num].opt__data());
1338 if (fbopts[num].opt__data().ispresent())
1339 {
1340 if ((fbopts[num].opt__len() == 1)
1341 && (fbopts[num].opt__type() == 1) && (buf[len - 1] == 0))
1342 crcpos = len - 1;
1343 }
1344 }
1345 }
1346 break;
1347 }
1348
1349 default:
1350 break;
1351 }
1352
1353 if (feedback.size().ispresent() && feedback.size() == 0)
1354 {
1355 buf[1] = (len - 2) & 0xFF;
1356 }
1357 if ((!feedback.size().ispresent()) && feedback.code() == 0)
1358 {
1359 buf[0] = (buf[0] & 0xF8) + ((len - 1) & 0x07);
1360 }
1361
1362 if ((crcpos > crcstart) && (buf[crcpos] == 0))
1363 buf[crcpos] = ComputeCRC(&(buf[crcstart]), len - crcstart, 8);
1364
1365 Log_hexdump(buf, len);
1366 Log_function_name_on_leave();
1367
1368 return len;
1369}
1370
1371int
1372Set_ROHC_Feedback_opt(unsigned char *buf,
1373 const OPTIONAL < Feedback > &feedback,
1374 BOOLEAN const &large_cid)
1375{
1376 int len = 0;
1377
1378 Log_function_name_on_enter();
1379
1380 if (!feedback.ispresent())
1381 {
1382 Log_function_name_on_leave();
1383 return len;
1384 }
1385 for (int num = 0; num < feedback().size_of(); num++)
1386 {
1387 len += Set_feedback(&buf[len], feedback()[num], large_cid);
1388 }
1389
1390 Log_hexdump(buf, len);
1391 Log_function_name_on_leave();
1392 return len;
1393}
1394
1395/* Inserts CID infomation into the buffer by moving memory areas */
1396int
1397Set_CID_for_packets(unsigned char *buf, ROHC__config const &config,
1398 int cid, int buflen)
1399{
1400 int len = 0;
1401
1402 Log_function_name_on_enter();
1403
1404 if (config.large__cid() == false)
1405 { /* Small CID: first octet is the CID */
1406 if (cid > 0)
1407 {
1408 // Overlapping memory areas, use memmove
1409 memmove(&(buf[1]), &(buf[0]), buflen);
1410 buf[0] = 0xE0 + (cid & 0x0F);
1411 len += 1;
1412 }
1413 }
1414 else
1415 { /* Large CID: CID is placed after the first octet */
1416 int cidlen = SDVL_encoded_CID_length(cid);
1417
1418 // Overlapping memory areas, use memmove
1419 memmove(&(buf[1 + cidlen]), &(buf[1]), buflen - 1);
1420 len += Set_SDVL_field(&(buf[1]), cid, 0);
1421 }
1422
1423 Log_hexdump(buf, len);
1424 Log_function_name_on_leave();
1425
1426 return len;
1427}
1428
1429int
1430Set_ROHC_Header_Profile0(unsigned char *buf,
1431 const Profile0__headers & hdr,
1432 ROHC__config const &config)
1433{
1434 int len = 0, crcpos = 0, cidlen, cid;
1435
1436 Log_function_name_on_enter();
1437
1438 switch (hdr.get_selection())
1439 {
1440 case Profile0__headers::ALT_ir:
1441 {
1442 cid = hdr.ir().cid();
1443 Check_field_value("packet type", (int) *hdr.ir().type__ind(), 126);
1444 buf[len] = ((*hdr.ir().type__ind()) << 1) & 0xFE;
1445 buf[len] += (*hdr.ir().d()) & 0x01;
1446 len += 1;
1447 Check_field_value("profile", hdr.ir().profile(), 0);
1448 len += Set_LIN1(&buf[len], hdr.ir().profile());
1449 crcpos = len;
1450 len += Set_LIN1(&buf[len], hdr.ir().crc());
1451 len += Set_octetstring(&buf[len], hdr.ir().orig__packet());
1452 break;
1453 }
1454
1455 case Profile0__headers::ALT_normal:
1456 {
1457 cid = hdr.normal().cid();
1458 len += Set_octetstring(&buf[len], hdr.normal().orig__packet());
1459 break;
1460 }
1461
1462 default:
1463 Log_not_implemented_union_field("Profile0_headers", hdr.get_selection());
1464 break;
1465 }
1466
1467 cidlen = Set_CID_for_packets(buf, config, cid, len);
1468 crcpos += cidlen;
1469 len += cidlen;
1470
1471 if (hdr.get_selection() == Profile0__headers::ALT_ir && hdr.ir().crc() == 0)
1472 {
1473 buf[crcpos] = ComputeCRC(&(buf[0]), crcpos, 8);
1474 }
1475
1476 Log_hexdump(buf, len);
1477 Log_function_name_on_leave();
1478 return len;
1479}
1480
1481int
1482Set_Static_Chain_Profile1(unsigned char *buf, const Static__Chain & chain)
1483{
1484 int len = 0;
1485
1486 Log_function_name_on_enter();
1487
1488 for (int num = 0; num < chain.size_of(); num++)
1489 {
1490 switch (chain[num].get_selection())
1491 {
1492 case Static__Chain__u::ALT_ipv4__stat:
1493 len += Set_IPv4_static_chain(&buf[len], chain[num].ipv4__stat());
1494 break;
1495 case Static__Chain__u::ALT_ipv6__stat:
1496 len += Set_IPv6_static_chain(&buf[len], chain[num].ipv6__stat());
1497 break;
1498 case Static__Chain__u::ALT_udp__stat:
1499 len += Set_UDP_static_chain(&buf[len], chain[num].udp__stat());
1500 break;
1501 case Static__Chain__u::ALT_rtp__stat:
1502 len += Set_RTP_static_chain(&buf[len], chain[num].rtp__stat());
1503 break;
1504 default:
1505 Log_not_implemented_union_field
1506 ("Static_Chain_u", chain[num].get_selection());
1507 break;
1508 }
1509 }
1510
1511 Log_hexdump(buf, len);
1512 Log_function_name_on_leave();
1513
1514 return len;
1515}
1516
1517int
1518Set_Dynamic_Chain_Profile1(unsigned char *buf, const Dynamic__Chain & dynch)
1519{
1520 int len = 0;
1521
1522 Log_function_name_on_enter();
1523
1524 for (int num = 0; num < dynch.size_of(); num++)
1525 {
1526 switch (dynch[num].get_selection())
1527 {
1528 case Dynamic__Chain__u::ALT_ipv4__dyn:
1529 len += Set_IPv4_dynamic_chain(&buf[len], dynch[num].ipv4__dyn());
1530 break;
1531 case Dynamic__Chain__u::ALT_ipv6__dyn:
1532 len += Set_IPv6_dynamic_chain(&buf[len], dynch[num].ipv6__dyn());
1533 break;
1534 case Dynamic__Chain__u::ALT_udp__dyn:
1535 len += Set_LIN2_BO_LAST(&buf[len], dynch[num].udp__dyn().cksum());
1536 break;
1537 case Dynamic__Chain__u::ALT_rtp__dyn:
1538 len += Set_RTP_dynamic_chain(&buf[len], dynch[num].rtp__dyn());
1539 break;
1540 default:
1541 Log_not_implemented_union_field
1542 ("Dynamic_Chain_u", dynch[num].get_selection());
1543 break;
1544 }
1545 }
1546
1547 Log_hexdump(buf, len);
1548 Log_function_name_on_leave();
1549
1550 return len;
1551}
1552
1553int
1554Set_Profile1_ROHC_Header_ir(unsigned char *buf,
1555 const Profile1__IR__header & hdr)
1556{
1557 int len = 0;
1558
1559 Log_function_name_on_enter();
1560
1561 Check_field_value("packet type", (int) *hdr.type__ind(), 126);
1562 buf[len] = ((*hdr.type__ind()) << 1) & 0xFE;
1563 Check_field_presence("dynamic chain", *hdr.d() == 1,
1564 hdr.dyn__chain().ispresent());
1565 buf[len] += ShiftUpBit(*hdr.d(), 0);
1566 len += 1;
1567 Check_field_value("profile", hdr.profile(), 1);
1568 len += Set_LIN1(&buf[len], hdr.profile());
1569 len += Set_LIN1(&buf[len], hdr.crc());
1570 len += Set_Static_Chain_Profile1(&buf[len], hdr.stat__chain());
1571 if (hdr.dyn__chain().ispresent())
1572 len += Set_Dynamic_Chain_Profile1(&buf[len], hdr.dyn__chain());
1573
1574 Log_hexdump(buf, len);
1575 Log_function_name_on_leave();
1576
1577 return len;
1578}
1579
1580int
1581Set_Profile1_ROHC_Header_irdyn(unsigned char *buf,
1582 const Profile1__IR__DYN__header & hdr)
1583{
1584 int len = 0;
1585
1586 Log_function_name_on_enter();
1587
1588 Check_field_value("packet type", (int) *hdr.type__ind(), 248);
1589 buf[len] = *hdr.type__ind();
1590 len += 1;
1591 Check_field_value("profile", hdr.profile(), 1);
1592 len += Set_LIN1(&buf[len], hdr.profile());
1593 len += Set_LIN1(&buf[len], hdr.crc());
1594 len += Set_Dynamic_Chain_Profile1(&buf[len], hdr.dyn__chain());
1595
1596 Log_hexdump(buf, len);
1597 Log_function_name_on_leave();
1598
1599 return len;
1600}
1601
1602int
1603Set_Profile1_ROHC_Header_r0(unsigned char *buf,
1604 const Profile1__R__0__header & hdr)
1605{
1606 Log_function_name_on_enter();
1607
1608 Check_field_value("packet type", (int) *hdr.type__ind(), 0);
1609 buf[0] = ((*hdr.type__ind()) << 6) & 0xC0;
1610 buf[0] += hdr.sn() & 0x3F;
1611
1612 Log_hexdump(buf, 1);
1613 Log_function_name_on_leave();
1614
1615 return 1;
1616}
1617
1618int
1619Set_Profile1_ROHC_Header_r0crc(unsigned char *buf,
1620 const Profile1__R__0__CRC__header & hdr)
1621{
1622 int len = 0;
1623
1624 Log_function_name_on_enter();
1625
1626 Check_field_value("packet type", (int) *hdr.type__ind(), 1);
1627 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1628 buf[len] += (hdr.sn() >> 1) & 0x3F;
1629 len += 1;
1630 buf[len] = (hdr.sn() << 7) & 0x80;
1631 buf[len] += hdr.crc() & 0x7F;
1632 len += 1;
1633
1634 Log_hexdump(buf, len);
1635 Log_function_name_on_leave();
1636
1637 return len;
1638}
1639
1640int
1641Set_Profile1_ROHC_Header_uo0(unsigned char *buf,
1642 const Profile1__UO__0__header & hdr)
1643{
1644 int len = 0;
1645
1646 Log_function_name_on_enter();
1647
1648 Check_field_value("packet type", (int) *hdr.type__ind(), 0);
1649 buf[len] = ((*hdr.type__ind()) << 7) & 0x80;
1650 buf[len] += (hdr.sn() << 3) & 0x78;
1651 buf[len] += hdr.crc() & 0x07;
1652 len += 1;
1653
1654 Log_hexdump(buf, len);
1655 Log_function_name_on_leave();
1656
1657 return len;
1658}
1659
1660int
1661Set_Profile1_ROHC_Header_r1(unsigned char *buf,
1662 const Profile1__R__1__header & hdr)
1663{
1664 int len = 0;
1665
1666 Log_function_name_on_enter();
1667
1668 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1669 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1670 buf[len] += hdr.sn() & 0x3F;
1671 len += 1;
1672 buf[len] = ShiftUpBit(*hdr.m__bit(), 7);
1673 buf[len] += ShiftUpBit(*hdr.x__bit(), 6);
1674 buf[len] += hdr.ts() & 0x3F;
1675 len += 1;
1676
1677 Log_hexdump(buf, len);
1678 Log_function_name_on_leave();
1679
1680 return len;
1681}
1682
1683int
1684Set_Profile1_ROHC_Header_r1id(unsigned char *buf,
1685 const Profile1__R__1__ID__header & hdr)
1686{
1687 int len = 0;
1688
1689 Log_function_name_on_enter();
1690
1691 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1692 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1693 buf[len] += hdr.sn() & 0x3F;
1694 len += 1;
1695 buf[len] = ShiftUpBit(*hdr.m__bit(), 7);
1696 buf[len] += ShiftUpBit(*hdr.x__bit(), 6);
1697 Check_field_value("T-bit", (int) *hdr.t__bit(), 0);
1698 buf[len] += ShiftUpBit(*hdr.t__bit(), 5);
1699 buf[len] += hdr.ip__id() & 0x1F;
1700 len += 1;
1701
1702 Log_hexdump(buf, len);
1703 Log_function_name_on_leave();
1704
1705 return len;
1706}
1707
1708int
1709Set_Profile1_ROHC_Header_r1ts(unsigned char *buf,
1710 const Profile1__R__1__TS__header & hdr)
1711{
1712 int len = 0;
1713
1714 Log_function_name_on_enter();
1715
1716 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1717 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1718 buf[len] += hdr.sn() & 0x3F;
1719 len += 1;
1720 buf[len] = ShiftUpBit(*hdr.m__bit(), 7);
1721 buf[len] += ShiftUpBit(*hdr.x__bit(), 6);
1722 Check_field_value("T-bit", (int) *hdr.t__bit(), 1);
1723 buf[len] += ShiftUpBit(*hdr.t__bit(), 5);
1724 buf[len] += hdr.ts() & 0x1F;
1725 len += 1;
1726
1727 Log_hexdump(buf, len);
1728 Log_function_name_on_leave();
1729
1730 return len;
1731}
1732
1733int
1734Set_Profile1_ROHC_Header_uo1(unsigned char *buf,
1735 const Profile1__UO__1__header & hdr)
1736{
1737 int len = 0;
1738
1739 Log_function_name_on_enter();
1740
1741 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1742 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1743 buf[len] += hdr.ts() & 0x3F;
1744 len += 1;
1745 buf[len] = ShiftUpBit(*hdr.m__bit(), 7);
1746 buf[len] += (hdr.sn() << 3) & 0x78;
1747 buf[len] += hdr.crc() & 0x07;
1748 len += 1;
1749
1750 Log_hexdump(buf, len);
1751 Log_function_name_on_leave();
1752
1753 return len;
1754}
1755
1756int
1757Set_Profile1_ROHC_Header_uo1id(unsigned char *buf,
1758 const Profile1__UO__1__ID__header & hdr)
1759{
1760 int len = 0;
1761
1762 Log_function_name_on_enter();
1763
1764 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1765 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1766 Check_field_value("T-bit", (int) *hdr.t__bit(), 0);
1767 buf[len] += ShiftUpBit(*hdr.t__bit(), 5);
1768 buf[len] += hdr.ip__id() & 0x1F;
1769 len += 1;
1770 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
1771 buf[len] += (hdr.sn() << 3) & 0x78;
1772 buf[len] += hdr.crc() & 0x07;
1773 len += 1;
1774
1775 Log_hexdump(buf, len);
1776 Log_function_name_on_leave();
1777
1778 return len;
1779}
1780
1781int
1782Set_Profile1_ROHC_Header_uo1ts(unsigned char *buf,
1783 const Profile1__UO__1__TS__header & hdr)
1784{
1785 int len = 0;
1786
1787 Log_function_name_on_enter();
1788
1789 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
1790 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
1791 Check_field_value("T-bit", (int) *hdr.t__bit(), 1);
1792 buf[len] += ShiftUpBit(*hdr.t__bit(), 5);
1793 buf[len] += hdr.ts() & 0x1F;
1794 len += 1;
1795 buf[len] = ShiftUpBit(*hdr.m__bit(), 7);
1796 buf[len] += (hdr.sn() << 3) & 0x78;
1797 buf[len] += hdr.crc() & 0x07;
1798 len += 1;
1799
1800 Log_hexdump(buf, len);
1801 Log_function_name_on_leave();
1802
1803 return len;
1804}
1805
1806int
1807Set_Profile1_ROHC_Header_uor2(unsigned char *buf,
1808 const Profile1__UOR__2__header & hdr)
1809{
1810 int len = 0;
1811
1812 Log_function_name_on_enter();
1813
1814 Check_field_value("packet type", (int) *hdr.type__ind(), 6);
1815 buf[len] = ((*hdr.type__ind()) << 5) & 0xE0;
1816 buf[len] += (hdr.ts() >> 1) & 0x1F;
1817 len += 1;
1818 buf[len] = (hdr.ts() << 7) & 0x80;
1819 buf[len] += ShiftUpBit(*hdr.m__bit(), 6);
1820 buf[len] += hdr.sn() & 0x3F;
1821 len += 1;
1822 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
1823 buf[len] += hdr.crc() & 0x7F;
1824 len += 1;
1825
1826 Log_hexdump(buf, len);
1827 Log_function_name_on_leave();
1828
1829 return len;
1830}
1831
1832int
1833Set_Profile1_ROHC_Header_uor2id(unsigned char *buf,
1834 const Profile1__UOR__2__ID__header & hdr)
1835{
1836 int len = 0;
1837
1838 Log_function_name_on_enter();
1839
1840 Check_field_value("packet type", (int) *hdr.type__ind(), 6);
1841 buf[len] = ((*hdr.type__ind()) << 5) & 0xE0;
1842 buf[len] += hdr.ip__id() & 0x1F;
1843 len += 1;
1844 Check_field_value("T-bit", (int) *hdr.t__bit(), 0);
1845 buf[len] = ShiftUpBit(*hdr.t__bit(), 7);
1846 buf[len] += ShiftUpBit(*hdr.m__bit(), 6);
1847 buf[len] += hdr.sn() & 0x3F;
1848 len += 1;
1849 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
1850 buf[len] += hdr.crc() & 0x7F;
1851 len += 1;
1852
1853 Log_hexdump(buf, len);
1854 Log_function_name_on_leave();
1855
1856 return len;
1857}
1858
1859int
1860Set_Profile1_ROHC_Header_uor2ts(unsigned char *buf,
1861 const Profile1__UOR__2__TS__header & hdr)
1862{
1863 int len = 0;
1864
1865 Log_function_name_on_enter();
1866
1867 Check_field_value("packet type", (int) *hdr.type__ind(), 6);
1868 Log_hexdump(buf, len);
1869 buf[len] = ((*hdr.type__ind()) << 5) & 0xE0;
1870 buf[len] += hdr.ts() & 0x1F;
1871 len += 1;
1872 Check_field_value("T-bit", (int) *hdr.t__bit(), 1);
1873 buf[len] = ShiftUpBit(*hdr.t__bit(), 7);
1874 buf[len] += ShiftUpBit(*hdr.m__bit(), 6);
1875 buf[len] += hdr.sn() & 0x3F;
1876 len += 1;
1877 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
1878 buf[len] += hdr.crc() & 0x7F;
1879 len += 1;
1880
1881 Log_hexdump(buf, len);
1882 Log_function_name_on_leave();
1883
1884 return len;
1885}
1886
1887int
1888Set_Profile1_Inner_IP_flags_opt(unsigned char *buf,
1889 const OPTIONAL < Inner__IP__flags > &field)
1890{
1891 int len = 0;
1892
1893 Log_function_name_on_enter();
1894
1895 if (!field.ispresent())
1896 {
1897 Log_function_name_on_leave();
1898 return len;
1899 }
1900 buf[len] = ShiftUpBit(*field().tos(), 7);
1901 buf[len] += ShiftUpBit(*field().ttl(), 6);
1902 buf[len] += ShiftUpBit(*field().df(), 5);
1903 buf[len] += ShiftUpBit(*field().pr(), 4);
1904 buf[len] += ShiftUpBit(*field().ipx(), 3);
1905 buf[len] += ShiftUpBit(*field().nbo(), 2);
1906 buf[len] += ShiftUpBit(*field().rnd__bit(), 1);
1907 buf[len] += ShiftUpBit(*field().ip2__bit(), 0);
1908 len += 1;
1909
1910 Log_hexdump(buf, len);
1911 Log_function_name_on_leave();
1912
1913 return len;
1914}
1915
1916int
1917Set_Profile1_Outer_IP_flags_opt(unsigned char *buf,
1918 const OPTIONAL < Outer__IP__flags > &field)
1919{
1920 int len = 0;
1921
1922 Log_function_name_on_enter();
1923
1924 if (!field.ispresent())
1925 {
1926 Log_function_name_on_leave();
1927 return len;
1928 }
1929 buf[len] = ShiftUpBit(*field().tos2(), 7);
1930 buf[len] += ShiftUpBit(*field().ttl2(), 6);
1931 buf[len] += ShiftUpBit(*field().df2(), 5);
1932 buf[len] += ShiftUpBit(*field().pr2(), 4);
1933 buf[len] += ShiftUpBit(*field().ipx2(), 3);
1934 buf[len] += ShiftUpBit(*field().nbo2(), 2);
1935 buf[len] += ShiftUpBit(*field().rnd2(), 1);
1936 buf[len] += ShiftUpBit(*field().i2__bit(), 0);
1937 len += 1;
1938
1939 Log_hexdump(buf, len);
1940 Log_function_name_on_leave();
1941
1942 return len;
1943}
1944
1945int
1946Set_Profile1_ipx_headers_opt(unsigned char *buf,
1947 const OPTIONAL < IP__Ext__heads > &field)
1948{
1949 int len = 0;
1950
1951 Log_function_name_on_enter();
1952
1953 if (!field.ispresent())
1954 {
1955 Log_function_name_on_leave();
1956 return len;
1957 }
1958 buf[len] = ShiftUpBit(*field().cl(), 7);
1959 buf[len] += ShiftUpBit(*field().aseq(), 6);
1960 buf[len] += ShiftUpBit(*field().eseq(), 5);
1961 buf[len] += ShiftUpBit(*field().gseq(), 4);
1962 buf[len] += (*field().res()) & 0x0F;
1963 len += 1;
1964
1965 Check_field_presence("AH SN", *field().aseq() == 1,
1966 field().ah__seq().ispresent());
1967 Check_field_presence("ESP SN", *field().eseq() == 1,
1968 field().esp__seq().ispresent());
1969 Check_field_presence("GRE SN", *field().gseq() == 1,
1970 field().gre__seq().ispresent());
1971 Check_field_presence("Compressed header list", *field().cl() == 1,
1972 field().compr__head__list().ispresent());
1973 len += Set_AEGSeqnum_opt(&buf[len], field().ah__seq());
1974 len += Set_AEGSeqnum_opt(&buf[len], field().esp__seq());
1975 len += Set_AEGSeqnum_opt(&buf[len], field().gre__seq());
1976 len += Set_Compr_head_list_opt(&buf[len], field().compr__head__list());
1977
1978 Log_hexdump(buf, len);
1979 Log_function_name_on_leave();
1980
1981 return len;
1982}
1983
1984int
1985Set_Profile1_Inner_IP_fields_opt(unsigned char *buf,
1986 const OPTIONAL < Inner__IP__flags > &flags,
1987 const OPTIONAL < Inner__IP__fields > &field)
1988{
1989 int len = 0;
1990
1991 Log_function_name_on_enter();
1992
1993 if (!field.ispresent())
1994 {
1995 Log_function_name_on_leave();
1996 return len;
1997 }
1998 Check_field_presence("TOS (inner IP)",
1999 flags.ispresent() && (*flags().tos() == 1),
2000 field().tos().ispresent());
2001 len += Set_LIN1_opt(&buf[len], field().tos());
2002 Check_field_presence("TTL (inner IP)",
2003 flags.ispresent() && (*flags().ttl() == 1),
2004 field().ttl().ispresent());
2005 len += Set_LIN1_opt(&buf[len], field().ttl());
2006 Check_field_presence("PROTO (inner IP)",
2007 flags.ispresent() && (*flags().pr() == 1),
2008 field().proto().ispresent());
2009 len += Set_LIN1_opt(&buf[len], field().proto());
2010
2011 Check_field_presence("IP extension headers (inner IP)",
2012 flags.ispresent() && (*flags().ipx() == 1),
2013 field().ext__heads().ispresent());
2014 len += Set_Profile1_ipx_headers_opt(&buf[len], field().ext__heads());
2015
2016 Log_hexdump(buf, len);
2017 Log_function_name_on_leave();
2018
2019 return len;
2020}
2021
2022int
2023Set_Profile1_Outer_IP_fields_opt(unsigned char *buf,
2024 const OPTIONAL < Outer__IP__flags > &flags,
2025 const OPTIONAL < Outer__IP__fields > &field)
2026{
2027 int len = 0;
2028
2029 Log_function_name_on_enter();
2030
2031 if (!field.ispresent())
2032 {
2033 Log_function_name_on_leave();
2034 return len;
2035 }
2036 Check_field_presence("TOS (outer IP)",
2037 flags.ispresent() && (*flags().tos2() == 1),
2038 field().tos().ispresent());
2039 len += Set_LIN1_opt(&buf[len], field().tos());
2040 Check_field_presence("TTL (outer IP)",
2041 flags.ispresent() && (*flags().ttl2() == 1),
2042 field().ttl().ispresent());
2043 len += Set_LIN1_opt(&buf[len], field().ttl());
2044 Check_field_presence("PROTO (outer IP)",
2045 flags.ispresent() && (*flags().pr2() == 1),
2046 field().proto().ispresent());
2047 len += Set_LIN1_opt(&buf[len], field().proto());
2048
2049 Check_field_presence("IP extension headers (outer IP)",
2050 flags.ispresent() && (*flags().ipx2() == 1),
2051 field().ext__heads().ispresent());
2052 len += Set_Profile1_ipx_headers_opt(&buf[len], field().ext__heads());
2053 Check_field_presence("IP-ID (outer IP)",
2054 flags.ispresent() && (*flags().i2__bit() == 1),
2055 field().ip__id().ispresent());
2056 len += Set_LIN2_BO_LAST_opt(&buf[len], field().ip__id());
2057
2058 Log_hexdump(buf, len);
2059 Log_function_name_on_leave();
2060
2061 return len;
2062}
2063
2064int
2065Set_Profile1_ROHC_Header_Extension0(unsigned char *buf, const Extension0 & ext)
2066{
2067 int len = 0;
2068
2069 Log_function_name_on_enter();
2070
2071 Check_field_value("extension type", (int) *ext.ext__type(), 0);
2072 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2073 buf[len] += (ext.sn() << 3) & 0x38;
2074 buf[len] += ext.plust() & 0x07;
2075 len += 1;
2076
2077 Log_hexdump(buf, len);
2078 Log_function_name_on_leave();
2079
2080 return len;
2081}
2082
2083int
2084Set_Profile1_ROHC_Header_Extension1(unsigned char *buf, const Extension1 & ext)
2085{
2086 int len = 0;
2087
2088 Log_function_name_on_enter();
2089
2090 Check_field_value("extension type", (int) *ext.ext__type(), 1);
2091 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2092 buf[len] += (ext.sn() << 3) & 0x38;
2093 buf[len] += ext.plust() & 0x07;
2094 len += 1;
2095 len += Set_LIN1(&buf[len], ext.minust());
2096
2097 Log_hexdump(buf, len);
2098 Log_function_name_on_leave();
2099
2100 return len;
2101}
2102
2103int
2104Set_Profile1_ROHC_Header_Extension2(unsigned char *buf, const Extension2 & ext)
2105{
2106 int len = 0;
2107
2108 Log_function_name_on_enter();
2109
2110 Check_field_value("extension type", (int) *ext.ext__type(), 2);
2111 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2112 buf[len] += (ext.sn() << 3) & 0x38;
2113 buf[len] += (ext.plust() >> 8) & 0x07;
2114 len += 1;
2115 buf[len] = ext.plust() & 0xFF;
2116 len += 1;
2117 len += Set_LIN1(&buf[len], ext.minust());
2118
2119 Log_hexdump(buf, len);
2120 Log_function_name_on_leave();
2121
2122 return len;
2123}
2124
2125int
2126Set_Profile1_ROHC_Header_Extension3(unsigned char *buf, const Extension3 & ext)
2127{
2128 int len = 0;
2129 int ts_length = 0;
2130
2131 Log_function_name_on_enter();
2132
2133 Check_field_value("extension type", (int) *ext.ext__type(), 3);
2134 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2135 buf[len] += ShiftUpBit(*ext.s__bit(), 5);
2136 buf[len] += ShiftUpBit(*ext.r__ts__bit(), 4);
2137 buf[len] += ShiftUpBit(*ext.tsc__bit(), 3);
2138 buf[len] += ShiftUpBit(*ext.i__bit(), 2);
2139 buf[len] += ShiftUpBit(*ext.ip__bit(), 1);
2140 buf[len] += ShiftUpBit(*ext.rtp__bit(), 0);
2141 len += 1;
2142
2143 Check_field_presence("Inner IP flags",
2144 *ext.ip__bit() == 1,
2145 ext.inner__ip__flags().ispresent());
2146 len += Set_Profile1_Inner_IP_flags_opt(&buf[len], ext.inner__ip__flags());
2147 Check_field_presence("Outer IP flags",
2148 ext.inner__ip__flags().ispresent() &&
2149 (*ext.inner__ip__flags()().ip2__bit() == 1),
2150 ext.outer__ip__flags().ispresent());
2151 len += Set_Profile1_Outer_IP_flags_opt(&buf[len], ext.outer__ip__flags());
2152 Check_field_presence("SN", *ext.s__bit() == 1, ext.sn().ispresent());
2153 len += Set_LIN1_opt(&buf[len], ext.sn());
2154 Check_field_presence("RTP TS", *ext.r__ts__bit() == 1, ext.ts().ispresent());
2155 if (ext.ts__length().ispresent()) ts_length = ext.ts__length()();
2156 len += Set_SDVL_field_opt(&buf[len], ext.ts(), ts_length);
2157 Check_field_presence("Inner IP fields",
2158 *ext.ip__bit() == 1, ext.inner__ip__hdr().ispresent());
2159 len += Set_Profile1_Inner_IP_fields_opt(&buf[len], ext.inner__ip__flags(),
2160 ext.inner__ip__hdr());
2161 Check_field_presence("Inner IP-ID",
2162 *ext.i__bit() == 1, ext.ip__id().ispresent());
2163 len += Set_LIN2_BO_LAST_opt(&buf[len], ext.ip__id());
2164 Check_field_presence("Outer IP fields",
2165 ext.inner__ip__flags().ispresent() &&
2166 (*ext.inner__ip__flags()().ip2__bit() == 1),
2167 ext.outer__ip__hdr().ispresent());
2168 len += Set_Profile1_Outer_IP_fields_opt(&buf[len], ext.outer__ip__flags(),
2169 ext.outer__ip__hdr());
2170 Check_field_presence("RTP flags and fields",
2171 *ext.rtp__bit() == 1, ext.rtp__fl__fi().ispresent());
2172 len += Set_RTP_flags_fields_opt(&buf[len], ext.rtp__fl__fi());
2173
2174 Log_hexdump(buf, len);
2175 Log_function_name_on_leave();
2176
2177 return len;
2178}
2179
2180int
2181Set_Profile1_ROHC_Header_Extension_opt(unsigned char *buf,
2182 const OPTIONAL < Profile1__Extension >
2183 &ext)
2184{
2185 int len = 0;
2186
2187 Log_function_name_on_enter();
2188
2189 if (ext.ispresent())
2190 {
2191 if (ext().get_selection() == Profile1__Extension::ALT_ext0)
2192 {
2193 len += Set_Profile1_ROHC_Header_Extension0(&buf[len], ext().ext0());
2194 }
2195 else if (ext().get_selection() == Profile1__Extension::ALT_ext1)
2196 {
2197 len += Set_Profile1_ROHC_Header_Extension1(&buf[len], ext().ext1());
2198 }
2199 else if (ext().get_selection() == Profile1__Extension::ALT_ext2)
2200 {
2201 len += Set_Profile1_ROHC_Header_Extension2(&buf[len], ext().ext2());
2202 }
2203 else if (ext().get_selection() == Profile1__Extension::ALT_ext3)
2204 {
2205 len += Set_Profile1_ROHC_Header_Extension3(&buf[len], ext().ext3());
2206 }
2207 else
2208 {
2209 Log_not_implemented_union_field("Profile1_Extension",
2210 ext().get_selection());
2211 }
2212 }
2213
2214 Log_hexdump(buf, len);
2215 Log_function_name_on_leave();
2216
2217 return len;
2218}
2219
2220int
2221Set_Profile1_ROHC_Header_ipid_ah_gre(unsigned char *buf,
2222 const Profile1__headers & hdr)
2223{
2224 int len = 0;
2225
2226 Log_function_name_on_enter();
2227
2228 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.ip__id__outer());
2229 len += Set_octetstring_opt(&buf[len], hdr.ah__outer());
2230 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.gre__cksum1());
2231 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.ip__id__inner());
2232 len += Set_octetstring_opt(&buf[len], hdr.ah__inner());
2233 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.gre__cksum2());
2234
2235 Log_hexdump(buf, len);
2236 Log_function_name_on_leave();
2237
2238 return len;
2239}
2240
2241int
2242Set_Profile1_ROHC_Header(unsigned char *buf,
2243 const Profile1__headers & hdr,
2244 ROHC__config const &config)
2245{
2246 int len = 0, crcpos = 0, cidlen = 0, cid;
2247
2248 Log_function_name_on_enter();
2249
2250 switch (hdr.base__header().get_selection())
2251 {
2252 case Profile1__base__header::ALT_ir:
2253 cid = hdr.base__header().ir().cid();
2254 crcpos = len + 2;
2255 len += Set_Profile1_ROHC_Header_ir(&buf[len], hdr.base__header().ir());
2256 break;
2257 case Profile1__base__header::ALT_ir__dyn:
2258 cid = hdr.base__header().ir__dyn().cid();
2259 crcpos = len + 2;
2260 len += Set_Profile1_ROHC_Header_irdyn(&buf[len],
2261 hdr.base__header().ir__dyn());
2262 break;
2263 case Profile1__base__header::ALT_r__0:
2264 cid = hdr.base__header().r__0().cid();
2265 len += Set_Profile1_ROHC_Header_r0(&buf[len], hdr.base__header().r__0());
2266 break;
2267 case Profile1__base__header::ALT_r__0__crc:
2268 cid = hdr.base__header().r__0__crc().cid();
2269 len += Set_Profile1_ROHC_Header_r0crc(&buf[len],
2270 hdr.base__header().r__0__crc());
2271 break;
2272 case Profile1__base__header::ALT_uo__0:
2273 cid = hdr.base__header().uo__0().cid();
2274 len += Set_Profile1_ROHC_Header_uo0(&buf[len], hdr.base__header().uo__0());
2275 break;
2276 case Profile1__base__header::ALT_r__1:
2277 cid = hdr.base__header().r__1().cid();
2278 len += Set_Profile1_ROHC_Header_r1(&buf[len], hdr.base__header().r__1());
2279 break;
2280 case Profile1__base__header::ALT_r__1__id:
2281 cid = hdr.base__header().r__1__id().cid();
2282 len +=
2283 Set_Profile1_ROHC_Header_r1id(&buf[len], hdr.base__header().r__1__id());
2284 break;
2285 case Profile1__base__header::ALT_r__1__ts:
2286 cid = hdr.base__header().r__1__ts().cid();
2287 len +=
2288 Set_Profile1_ROHC_Header_r1ts(&buf[len], hdr.base__header().r__1__ts());
2289 break;
2290 case Profile1__base__header::ALT_uo__1:
2291 cid = hdr.base__header().uo__1().cid();
2292 len += Set_Profile1_ROHC_Header_uo1(&buf[len], hdr.base__header().uo__1());
2293 break;
2294 case Profile1__base__header::ALT_uo__1__id:
2295 cid = hdr.base__header().uo__1__id().cid();
2296 len +=
2297 Set_Profile1_ROHC_Header_uo1id(&buf[len],
2298 hdr.base__header().uo__1__id());
2299 break;
2300 case Profile1__base__header::ALT_uo__1__ts:
2301 cid = hdr.base__header().uo__1__ts().cid();
2302 len +=
2303 Set_Profile1_ROHC_Header_uo1ts(&buf[len],
2304 hdr.base__header().uo__1__ts());
2305 break;
2306 case Profile1__base__header::ALT_uor__2:
2307 cid = hdr.base__header().uor__2().cid();
2308 len +=
2309 Set_Profile1_ROHC_Header_uor2(&buf[len], hdr.base__header().uor__2());
2310 break;
2311 case Profile1__base__header::ALT_uor__2__id:
2312 cid = hdr.base__header().uor__2__id().cid();
2313 len +=
2314 Set_Profile1_ROHC_Header_uor2id(&buf[len],
2315 hdr.base__header().uor__2__id());
2316 break;
2317 case Profile1__base__header::ALT_uor__2__ts:
2318 cid = hdr.base__header().uor__2__ts().cid();
2319 len +=
2320 Set_Profile1_ROHC_Header_uor2ts(&buf[len],
2321 hdr.base__header().uor__2__ts());
2322 break;
2323 default:
2324 Log_not_implemented_union_field
2325 ("Profile1_base_header", hdr.base__header().get_selection());
2326 break;
2327 }
2328
2329 len += Set_Profile1_ROHC_Header_Extension_opt(&buf[len], hdr.ext());
2330 len += Set_Profile1_ROHC_Header_ipid_ah_gre(&buf[len], hdr);
2331 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.udp__cksum());
2332
2333 cidlen = Set_CID_for_packets(buf, config, cid, len);
2334 crcpos += cidlen;
2335 len += cidlen;
2336
2337 if (hdr.base__header().get_selection() == Profile1__base__header::ALT_ir
2338 && hdr.base__header().ir().crc() == 0)
2339 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
2340 else if (hdr.base__header().get_selection() ==
2341 Profile1__base__header::ALT_ir__dyn
2342 && hdr.base__header().ir__dyn().crc() == 0)
2343 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
2344
2345 Log_hexdump(buf, len);
2346 Log_function_name_on_leave();
2347
2348 return len;
2349}
2350
2351int
2352Set_Profile2_Static_Chain(unsigned char
2353 *buf, const Profile2__Static__Chain & chain)
2354{
2355 int len = 0;
2356
2357 Log_function_name_on_enter();
2358
2359 for (int num = 0; num < chain.size_of(); num++)
2360 {
2361 switch (chain[num].get_selection())
2362 {
2363 case Static__Chain__u::ALT_ipv4__stat:
2364 len += Set_IPv4_static_chain(&buf[len], chain[num].ipv4__stat());
2365 break;
2366 case Static__Chain__u::ALT_ipv6__stat:
2367 len += Set_IPv6_static_chain(&buf[len], chain[num].ipv6__stat());
2368 break;
2369 case Static__Chain__u::ALT_udp__stat:
2370 len += Set_UDP_static_chain(&buf[len], chain[num].udp__stat());
2371 break;
2372 default:
2373 Log_not_implemented_union_field
2374 ("Profile2_Static_Chain", chain[num].get_selection());
2375 break;
2376 }
2377 }
2378
2379 Log_hexdump(buf, len);
2380 Log_function_name_on_leave();
2381
2382 return len;
2383}
2384
2385int
2386Set_Profile2_Dynamic_Chain(unsigned char
2387 *buf, const Profile2__Dynamic__Chain & dynch)
2388{
2389 int len = 0;
2390
2391 Log_function_name_on_enter();
2392
2393 for (int num = 0; num < dynch.size_of(); num++)
2394 {
2395 switch (dynch[num].get_selection())
2396 {
2397 case Profile2__Dynamic__Chain__u::ALT_ipv4__dyn:
2398 len += Set_IPv4_dynamic_chain(&buf[len], dynch[num].ipv4__dyn());
2399 break;
2400 case Profile2__Dynamic__Chain__u::ALT_ipv6__dyn:
2401 len += Set_IPv6_dynamic_chain(&buf[len], dynch[num].ipv6__dyn());
2402 break;
2403 case Profile2__Dynamic__Chain__u::ALT_udp__dyn:
2404 len += Set_LIN2_BO_LAST(&buf[len], dynch[num].udp__dyn().cksum());
2405 len += Set_LIN2_BO_LAST(&buf[len], dynch[num].udp__dyn().udp__sn());
2406 break;
2407 default:
2408 Log_not_implemented_union_field
2409 ("Profile2_Dynamic_Chain", dynch[num].get_selection());
2410 break;
2411 }
2412 }
2413
2414 Log_hexdump(buf, len);
2415 Log_function_name_on_leave();
2416
2417 return len;
2418}
2419
2420int
2421Set_Profile2_ROHC_Header_ir(unsigned char
2422 *buf, const Profile2__IR__header & hdr)
2423{
2424 int len = 0;
2425
2426 Log_function_name_on_enter();
2427
2428 Check_field_value("packet type", (int) *hdr.type__ind(), 126);
2429 buf[len] = ((*hdr.type__ind()) << 1) & 0xFE;
2430 Check_field_presence("dynamic chain", *hdr.d() == 1,
2431 hdr.dyn__chain().ispresent());
2432 buf[len] += ShiftUpBit(*hdr.d(), 0);
2433 len += 1;
2434 Check_field_value("profile", hdr.profile(), 2);
2435 len += Set_LIN1(&buf[len], hdr.profile());
2436 len += Set_LIN1(&buf[len], hdr.crc());
2437 len += Set_Profile2_Static_Chain(&buf[len], hdr.stat__chain());
2438 if (hdr.dyn__chain().ispresent())
2439 len += Set_Profile2_Dynamic_Chain(&buf[len], hdr.dyn__chain());
2440
2441 Log_hexdump(buf, len);
2442 Log_function_name_on_leave();
2443
2444 return len;
2445}
2446
2447int
2448Set_Profile2_ROHC_Header_irdyn(unsigned
2449 char *buf,
2450 const Profile2__IR__DYN__header & hdr)
2451{
2452 int len = 0;
2453
2454 Log_function_name_on_enter();
2455
2456 Check_field_value("packet type", (int) *hdr.type__ind(), 248);
2457 buf[len] = *hdr.type__ind();
2458 len += 1;
2459 Check_field_value("profile", hdr.profile(), 2);
2460 len += Set_LIN1(&buf[len], hdr.profile());
2461 len += Set_LIN1(&buf[len], hdr.crc());
2462 len += Set_Profile2_Dynamic_Chain(&buf[len], hdr.dyn__chain());
2463
2464 Log_hexdump(buf, len);
2465 Log_function_name_on_leave();
2466
2467 return len;
2468}
2469
2470int
2471Set_Profile2_ROHC_Header_r1(unsigned char
2472 *buf, const Profile2__R__1__header & hdr)
2473{
2474 int len = 0;
2475
2476 Log_function_name_on_enter();
2477
2478 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
2479 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
2480 buf[len] += hdr.sn() & 0x3F;
2481 len += 1;
2482 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
2483 buf[len] += hdr.ip__id() & 0x7F;
2484 len += 1;
2485
2486 Log_hexdump(buf, len);
2487 Log_function_name_on_leave();
2488
2489 return len;
2490}
2491
2492int
2493Set_Profile2_ROHC_Header_uo1(unsigned char
2494 *buf, const Profile2__UO__1__header & hdr)
2495{
2496 int len = 0;
2497
2498 Log_function_name_on_enter();
2499
2500 Check_field_value("packet type", (int) *hdr.type__ind(), 2);
2501 buf[len] = ((*hdr.type__ind()) << 6) & 0xC0;
2502 buf[len] += hdr.ip__id() & 0x3F;
2503 len += 1;
2504 buf[len] = (hdr.sn() << 3) & 0xF8;
2505 buf[len] += hdr.crc() & 0x07;
2506 len += 1;
2507
2508 Log_hexdump(buf, len);
2509 Log_function_name_on_leave();
2510
2511 return len;
2512}
2513
2514int
2515Set_Profile2_ROHC_Header_uor2(unsigned char *buf,
2516 const Profile2__UOR__2__header & hdr)
2517{
2518 int len = 0;
2519
2520 Log_function_name_on_enter();
2521
2522 Check_field_value("packet type", (int) *hdr.type__ind(), 6);
2523 buf[len] = ((*hdr.type__ind()) << 5) & 0xE0;
2524 buf[len] += hdr.sn() & 0x1F;
2525 len += 1;
2526 buf[len] = ShiftUpBit(*hdr.x__bit(), 7);
2527 buf[len] += hdr.crc() & 0x7F;
2528 len += 1;
2529
2530 Log_hexdump(buf, len);
2531 Log_function_name_on_leave();
2532
2533 return len;
2534}
2535
2536int
2537Set_Profile2_Inner_IP_flags_opt(unsigned char *buf,
2538 const OPTIONAL < Profile2__Inner__IP__flags >
2539 &field)
2540{
2541 int len = 0;
2542
2543 Log_function_name_on_enter();
2544
2545 if (!field.ispresent())
2546 {
2547 Log_function_name_on_leave();
2548 return len;
2549 }
2550 buf[len] = ShiftUpBit(*field().tos(), 7);
2551 buf[len] += ShiftUpBit(*field().ttl(), 6);
2552 buf[len] += ShiftUpBit(*field().df(), 5);
2553 buf[len] += ShiftUpBit(*field().pr(), 4);
2554 buf[len] += ShiftUpBit(*field().ipx(), 3);
2555 buf[len] += ShiftUpBit(*field().nbo(), 2);
2556 buf[len] += ShiftUpBit(*field().rnd__bit(), 1);
2557 Check_field_value("inner IP flags, reserved", (int) *field().reserved(), 0);
2558 buf[len] += ShiftUpBit(*field().reserved(), 0);
2559 len += 1;
2560
2561 Log_hexdump(buf, len);
2562 Log_function_name_on_leave();
2563
2564 return len;
2565}
2566
2567int
2568Set_Profile2_Inner_IP_fields_opt(unsigned char *buf,
2569 const OPTIONAL < Profile2__Inner__IP__flags >
2570 &flags,
2571 const OPTIONAL < Inner__IP__fields > &field)
2572{
2573 int len = 0;
2574
2575 Log_function_name_on_enter();
2576
2577 if (!field.ispresent())
2578 {
2579 Log_function_name_on_leave();
2580 return len;
2581 }
2582 Check_field_presence("TOS (inner IP)",
2583 flags.ispresent() && (*flags().tos() == 1),
2584 field().tos().ispresent());
2585 len += Set_LIN1_opt(&buf[len], field().tos());
2586 Check_field_presence("TTL (inner IP)",
2587 flags.ispresent() && (*flags().ttl() == 1),
2588 field().ttl().ispresent());
2589 len += Set_LIN1_opt(&buf[len], field().ttl());
2590 Check_field_presence("PROTO (inner IP)",
2591 flags.ispresent() && (*flags().pr() == 1),
2592 field().proto().ispresent());
2593 len += Set_LIN1_opt(&buf[len], field().proto());
2594
2595 len += Set_Profile1_ipx_headers_opt(&buf[len], field().ext__heads());
2596
2597 Log_hexdump(buf, len);
2598 Log_function_name_on_leave();
2599
2600 return len;
2601}
2602
2603
2604int
2605Set_Profile2_ROHC_Header_Extension0(unsigned char *buf,
2606 const Profile2__Extension0 & ext)
2607{
2608 int len = 0;
2609
2610 Log_function_name_on_enter();
2611
2612 Check_field_value("extension type", (int) *ext.ext__type(), 0);
2613 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2614 buf[len] += (ext.sn() << 3) & 0x38;
2615 buf[len] += ext.ip__id() & 0x07;
2616 len += 1;
2617
2618 Log_hexdump(buf, len);
2619 Log_function_name_on_leave();
2620
2621 return len;
2622}
2623
2624int
2625Set_Profile2_ROHC_Header_Extension1(unsigned char *buf,
2626 const Profile2__Extension1 & ext)
2627{
2628 int len = 0;
2629
2630 Log_function_name_on_enter();
2631
2632 Check_field_value("extension type", (int) *ext.ext__type(), 1);
2633 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2634 buf[len] += (ext.sn() << 3) & 0x38;
2635 buf[len] += (ext.ip__id() >> 8) & 0x07;
2636 len += 1;
2637 buf[len] = ext.ip__id() & 0xFF;
2638 len += 1;
2639
2640 Log_hexdump(buf, len);
2641 Log_function_name_on_leave();
2642
2643 return len;
2644}
2645
2646int
2647Set_Profile2_ROHC_Header_Extension2(unsigned char *buf,
2648 const Profile2__Extension2 & ext)
2649{
2650 int len = 0;
2651
2652 Log_function_name_on_enter();
2653
2654 Check_field_value("extension type", (int) *ext.ext__type(), 2);
2655 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2656 buf[len] += (ext.sn() << 3) & 0x38;
2657 buf[len] += (ext.ip__id2() >> 8) & 0x07;
2658 len += 1;
2659 buf[len] = ext.ip__id2() & 0xFF;
2660 len += 1;
2661 buf[len] = ext.ip__id() & 0xFF;
2662 len += 1;
2663
2664 Log_hexdump(buf, len);
2665 Log_function_name_on_leave();
2666
2667 return len;
2668}
2669
2670int
2671Set_Profile2_ROHC_Header_Extension3(unsigned char *buf,
2672 const Profile2__Extension3 & ext)
2673{
2674 int len = 0;
2675
2676 Log_function_name_on_enter();
2677
2678 Check_field_value("extension type", (int) *ext.ext__type(), 3);
2679 buf[len] = ((*ext.ext__type()) << 6) & 0xC0;
2680 buf[len] += ShiftUpBit(*ext.s__bit(), 5);
2681 buf[len] += ((ext.mode()) << 3) & 0x18;
2682 buf[len] += ShiftUpBit(*ext.i__bit(), 2);
2683 buf[len] += ShiftUpBit(*ext.ip__bit(), 1);
2684 buf[len] += ShiftUpBit(*ext.ip2__bit(), 0);
2685 len += 1;
2686
2687 Check_field_presence("Inner IP flags",
2688 *ext.ip__bit() == 1,
2689 ext.inner__ip__flags().ispresent());
2690 len += Set_Profile2_Inner_IP_flags_opt(&buf[len], ext.inner__ip__flags());
2691 Check_field_presence("Outer IP flags",
2692 *ext.ip2__bit() == 1,
2693 ext.outer__ip__flags().ispresent());
2694 len += Set_Profile1_Outer_IP_flags_opt(&buf[len], ext.outer__ip__flags());
2695 Check_field_presence("SN", *ext.s__bit() == 1, ext.sn().ispresent());
2696 len += Set_LIN1_opt(&buf[len], ext.sn());
2697 Check_field_presence("Inner IP fields",
2698 *ext.ip__bit() == 1, ext.inner__ip__hdr().ispresent());
2699 len += Set_Profile2_Inner_IP_fields_opt(&buf[len], ext.inner__ip__flags(),
2700 ext.inner__ip__hdr());
2701 Check_field_presence("Inner IP-ID",
2702 *ext.i__bit() == 1, ext.ip__id().ispresent());
2703 len += Set_LIN2_BO_LAST_opt(&buf[len], ext.ip__id());
2704 Check_field_presence("Outer IP fields",
2705 *ext.ip2__bit() == 1, ext.outer__ip__hdr().ispresent());
2706 len += Set_Profile1_Outer_IP_fields_opt(&buf[len], ext.outer__ip__flags(),
2707 ext.outer__ip__hdr());
2708
2709 Log_hexdump(buf, len);
2710 Log_function_name_on_leave();
2711
2712 return len;
2713}
2714
2715int
2716Set_Profile2_ROHC_Header_Extension_opt(unsigned char *buf,
2717 const OPTIONAL < Profile2__Extension >
2718 &ext)
2719{
2720 int len = 0;
2721
2722 Log_function_name_on_enter();
2723
2724 if (ext.ispresent())
2725 {
2726 if (ext().get_selection() == Profile2__Extension::ALT_ext0)
2727 {
2728 len += Set_Profile2_ROHC_Header_Extension0(&buf[len], ext().ext0());
2729 }
2730 else if (ext().get_selection() == Profile2__Extension::ALT_ext1)
2731 {
2732 len += Set_Profile2_ROHC_Header_Extension1(&buf[len], ext().ext1());
2733 }
2734 else if (ext().get_selection() == Profile2__Extension::ALT_ext2)
2735 {
2736 len += Set_Profile2_ROHC_Header_Extension2(&buf[len], ext().ext2());
2737 }
2738 else if (ext().get_selection() == Profile2__Extension::ALT_ext3)
2739 {
2740 len += Set_Profile2_ROHC_Header_Extension3(&buf[len], ext().ext3());
2741 }
2742 else
2743 {
2744 Log_not_implemented_union_field("Profile2_Extension",
2745 ext().get_selection());
2746 }
2747 }
2748
2749 Log_hexdump(buf, len);
2750 Log_function_name_on_leave();
2751
2752 return len;
2753}
2754
2755int
2756Set_Profile2_ROHC_Header_ipid_ah_gre(unsigned char *buf,
2757 const Profile2__headers & hdr)
2758{
2759 int len = 0;
2760
2761 Log_function_name_on_enter();
2762
2763 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.ip__id__outer());
2764 len += Set_octetstring_opt(&buf[len], hdr.ah__outer());
2765 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.gre__cksum1());
2766 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.ip__id__inner());
2767 len += Set_octetstring_opt(&buf[len], hdr.ah__inner());
2768 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.gre__cksum2());
2769
2770 Log_hexdump(buf, len);
2771 Log_function_name_on_leave();
2772
2773 return len;
2774}
2775
2776int
2777Set_Profile2_ROHC_Header(unsigned char *buf,
2778 const Profile2__headers & hdr,
2779 ROHC__config const &config)
2780{
2781 int len = 0, crcpos = 0, cidlen = 0, cid;
2782
2783 Log_function_name_on_enter();
2784
2785 switch (hdr.base__header().get_selection())
2786 {
2787 case Profile2__base__header::ALT_ir:
2788 cid = hdr.base__header().ir().cid();
2789 crcpos = len + 2;
2790 len += Set_Profile2_ROHC_Header_ir(&buf[len], hdr.base__header().ir());
2791 break;
2792 case Profile2__base__header::ALT_ir__dyn:
2793 cid = hdr.base__header().ir__dyn().cid();
2794 crcpos = len + 2;
2795 len +=
2796 Set_Profile2_ROHC_Header_irdyn(&buf[len], hdr.base__header().ir__dyn());
2797 break;
2798 case Profile1__base__header::ALT_r__0:
2799 cid = hdr.base__header().r__0().cid();
2800 len += Set_Profile1_ROHC_Header_r0(&buf[len], hdr.base__header().r__0());
2801 break;
2802 case Profile1__base__header::ALT_r__0__crc:
2803 cid = hdr.base__header().r__0__crc().cid();
2804 len +=
2805 Set_Profile1_ROHC_Header_r0crc(&buf[len],
2806 hdr.base__header().r__0__crc());
2807 break;
2808 case Profile1__base__header::ALT_uo__0:
2809 cid = hdr.base__header().uo__0().cid();
2810 len += Set_Profile1_ROHC_Header_uo0(&buf[len], hdr.base__header().uo__0());
2811 break;
2812 case Profile2__base__header::ALT_r__1:
2813 cid = hdr.base__header().r__1().cid();
2814 len += Set_Profile2_ROHC_Header_r1(&buf[len], hdr.base__header().r__1());
2815 break;
2816 case Profile2__base__header::ALT_uo__1:
2817 cid = hdr.base__header().uo__1().cid();
2818 len += Set_Profile2_ROHC_Header_uo1(&buf[len], hdr.base__header().uo__1());
2819 break;
2820 case Profile2__base__header::ALT_uor__2:
2821 cid = hdr.base__header().uor__2().cid();
2822 len +=
2823 Set_Profile2_ROHC_Header_uor2(&buf[len], hdr.base__header().uor__2());
2824 break;
2825 default:
2826 Log_not_implemented_union_field
2827 ("Profile2_base_header", hdr.base__header().get_selection());
2828 break;
2829 }
2830
2831 len += Set_Profile2_ROHC_Header_Extension_opt(&buf[len], hdr.ext());
2832 len += Set_Profile2_ROHC_Header_ipid_ah_gre(&buf[len], hdr);
2833 len += Set_LIN2_BO_LAST_opt(&buf[len], hdr.udp__cksum());
2834
2835 cidlen = Set_CID_for_packets(buf, config, cid, len);
2836 crcpos += cidlen;
2837 len += cidlen;
2838
2839 if (hdr.base__header().get_selection() == Profile2__base__header::ALT_ir)
2840 {
2841 if (hdr.base__header().ir().crc() == 0)
2842 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
2843 }
2844 else
2845 if (hdr.base__header().
2846 get_selection() == Profile2__base__header::ALT_ir__dyn)
2847 {
2848 if (hdr.base__header().ir__dyn().crc() == 0)
2849 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
2850 }
2851
2852 Log_hexdump(buf, len);
2853 Log_function_name_on_leave();
2854
2855 return len;
2856} /* Set_Profile2_ROHC_Header */
2857
2858int
2859Set_Profile4_Static_Chain(unsigned char *buf,
2860 const Profile4__Static__Chain & chain)
2861{
2862 int len = 0;
2863
2864 Log_function_name_on_enter();
2865
2866 for (int num = 0; num < chain.size_of(); num++)
2867 {
2868 switch (chain[num].get_selection())
2869 {
2870 case Static__Chain__u::ALT_ipv4__stat:
2871 len += Set_IPv4_static_chain(&buf[len], chain[num].ipv4__stat());
2872 break;
2873 case Static__Chain__u::ALT_ipv6__stat:
2874 len += Set_IPv6_static_chain(&buf[len], chain[num].ipv6__stat());
2875 break;
2876 default:
2877 Log_not_implemented_union_field
2878 ("Profile4_Static_Chain", chain[num].get_selection());
2879 break;
2880 }
2881 }
2882
2883 Log_hexdump(buf, len);
2884 Log_function_name_on_leave();
2885
2886 return len;
2887}
2888
2889int
2890Set_Profile4_IPv4_dynamic(unsigned char *buf,
2891 const Profile4__IPv4__Dynamic & chain)
2892{
2893 int len = 0;
2894
2895 Log_function_name_on_enter();
2896
2897 len += Set_LIN1(&buf[len], chain.tos());
2898 len += Set_LIN1(&buf[len], chain.ttl());
2899 len += Set_LIN2_BO_LAST(&buf[len], chain.identification());
2900
2901 buf[len] = ShiftUpBit(*chain.df__bit(), 7);
2902 buf[len] += ShiftUpBit(*chain.rnd__bit(), 6);
2903 buf[len] += ShiftUpBit(*chain.nbo__bit(), 5);
2904 buf[len] += ShiftUpBit(*chain.sid__bit(), 4);
2905 Check_field_value("IPv4 reserved (dynamic chain)", *chain.reserved(), 0);
2906 buf[len] += (*chain.reserved()) & 0x0F;
2907 len += 1;
2908 len += Set_Encoding_Type_0(&buf[len], chain.genextheadlist());
2909
2910 Log_hexdump(buf, len);
2911 Log_function_name_on_leave();
2912
2913 return len;
2914}
2915
2916int
2917Set_Profile4_Dynamic_Chain(unsigned char *buf,
2918 const Profile4__Dynamic__Chain & dynch)
2919{
2920 int len = 0;
2921
2922 Log_function_name_on_enter();
2923
2924 for (int num = 0; num < dynch.size_of(); num++)
2925 {
2926 switch (dynch[num].get_selection())
2927 {
2928 case Profile4__Dynamic__Chain__u::ALT_ipv4__dyn:
2929 len += Set_Profile4_IPv4_dynamic(&buf[len], dynch[num].ipv4__dyn());
2930 break;
2931 case Profile4__Dynamic__Chain__u::ALT_ipv6__dyn:
2932 len += Set_IPv6_dynamic_chain(&buf[len], dynch[num].ipv6__dyn());
2933 break;
2934 case Profile4__Dynamic__Chain__u::ALT_sn:
2935 len += Set_LIN2_BO_LAST(&buf[len], dynch[num].sn());
2936 break;
2937 default:
2938 Log_not_implemented_union_field
2939 ("Profile4_Dynamic_Chain", dynch[num].get_selection());
2940 break;
2941 }
2942 }
2943
2944 Log_hexdump(buf, len);
2945 Log_function_name_on_leave();
2946
2947 return len;
2948}
2949
2950int
2951Set_Profile4_ROHC_Header_ir(unsigned char *buf,
2952 const Profile4__IR__header & hdr)
2953{
2954 int len = 0;
2955
2956 Log_function_name_on_enter();
2957
2958 Check_field_value("packet type", (int) *hdr.type__ind(), 126);
2959 buf[len] = ((*hdr.type__ind()) << 1) & 0xFE;
2960 Check_field_presence("dynamic chain", *hdr.d() == 1,
2961 hdr.dyn__chain().ispresent());
2962 buf[len] += ShiftUpBit(*hdr.d(), 0);
2963 len += 1;
2964 Check_field_value("profile", hdr.profile(), 4);
2965 len += Set_LIN1(&buf[len], hdr.profile());
2966 len += Set_LIN1(&buf[len], hdr.crc());
2967 len += Set_Profile4_Static_Chain(&buf[len], hdr.stat__chain());
2968 if (hdr.dyn__chain().ispresent())
2969 len += Set_Profile4_Dynamic_Chain(&buf[len], hdr.dyn__chain());
2970
2971 Log_hexdump(buf, len);
2972 Log_function_name_on_leave();
2973
2974 return len;
2975}
2976
2977int
2978Set_Profile4_ROHC_Header_irdyn(unsigned char *buf,
2979 const Profile4__IR__DYN__header & hdr)
2980{
2981 int len = 0;
2982
2983 Log_function_name_on_enter();
2984
2985 Check_field_value("packet type", (int) *hdr.type__ind(), 248);
2986 buf[len] = *hdr.type__ind();
2987 len += 1;
2988 Check_field_value("profile", hdr.profile(), 4);
2989 len += Set_LIN1(&buf[len], hdr.profile());
2990 len += Set_LIN1(&buf[len], hdr.crc());
2991 len += Set_Profile4_Dynamic_Chain(&buf[len], hdr.dyn__chain());
2992
2993 Log_hexdump(buf, len);
2994 Log_function_name_on_leave();
2995
2996 return len;
2997}
2998
2999int
3000Set_Profile4_ROHC_Header_ipid_ah_gre(unsigned char *buf,
3001 const Profile4__headers & other_headers)
3002{
3003 int len = 0;
3004
3005 Log_function_name_on_enter();
3006
3007 len += Set_LIN2_BO_LAST_opt(&buf[len], other_headers.ip__id__outer());
3008 len += Set_octetstring_opt(&buf[len], other_headers.ah__outer());
3009 len += Set_LIN2_BO_LAST_opt(&buf[len], other_headers.gre__cksum1());
3010 len += Set_LIN2_BO_LAST_opt(&buf[len], other_headers.ip__id__inner());
3011 len += Set_octetstring_opt(&buf[len], other_headers.ah__inner());
3012 len += Set_LIN2_BO_LAST_opt(&buf[len], other_headers.gre__cksum2());
3013
3014 Log_hexdump(buf, len);
3015 Log_function_name_on_leave();
3016
3017 return len;
3018}
3019
3020int
3021Set_Profile4_ROHC_Header(unsigned char *buf,
3022 const Profile4__headers & hdr,
3023 ROHC__config const &config)
3024{
3025 int len = 0, crcpos = 0, cidlen = 0, cid;
3026
3027 Log_function_name_on_enter();
3028
3029 switch (hdr.base__header().get_selection())
3030 {
3031 case Profile4__base__header::ALT_ir:
3032 cid = hdr.base__header().ir().cid();
3033 crcpos = len + 2;
3034 len += Set_Profile4_ROHC_Header_ir(&buf[len], hdr.base__header().ir());
3035 break;
3036 case Profile4__base__header::ALT_ir__dyn:
3037 cid = hdr.base__header().ir__dyn().cid();
3038 crcpos = len + 2;
3039 len +=
3040 Set_Profile4_ROHC_Header_irdyn(&buf[len], hdr.base__header().ir__dyn());
3041 break;
3042 case Profile1__base__header::ALT_r__0:
3043 cid = hdr.base__header().r__0().cid();
3044 len += Set_Profile1_ROHC_Header_r0(&buf[len], hdr.base__header().r__0());
3045 break;
3046 case Profile1__base__header::ALT_r__0__crc:
3047 cid = hdr.base__header().r__0__crc().cid();
3048 len +=
3049 Set_Profile1_ROHC_Header_r0crc(&buf[len],
3050 hdr.base__header().r__0__crc());
3051 break;
3052 case Profile1__base__header::ALT_uo__0:
3053 cid = hdr.base__header().uo__0().cid();
3054 len += Set_Profile1_ROHC_Header_uo0(&buf[len], hdr.base__header().uo__0());
3055 break;
3056 case Profile2__base__header::ALT_r__1:
3057 cid = hdr.base__header().r__1().cid();
3058 len += Set_Profile2_ROHC_Header_r1(&buf[len], hdr.base__header().r__1());
3059 break;
3060 case Profile2__base__header::ALT_uo__1:
3061 cid = hdr.base__header().uo__1().cid();
3062 len += Set_Profile2_ROHC_Header_uo1(&buf[len], hdr.base__header().uo__1());
3063 break;
3064 case Profile2__base__header::ALT_uor__2:
3065 cid = hdr.base__header().uor__2().cid();
3066 len +=
3067 Set_Profile2_ROHC_Header_uor2(&buf[len], hdr.base__header().uor__2());
3068 break;
3069 default:
3070 Log_not_implemented_union_field
3071 ("Profile4_base_header", hdr.base__header().get_selection());
3072 break;
3073 }
3074
3075 len += Set_Profile2_ROHC_Header_Extension_opt(&buf[len], hdr.ext());
3076 len += Set_Profile4_ROHC_Header_ipid_ah_gre(&buf[len], hdr);
3077 if (hdr.additional__IP().ispresent())
3078 {
3079 len += Set_Profile4_Dynamic_Chain(&buf[len], hdr.additional__IP()());
3080 }
3081
3082 cidlen = Set_CID_for_packets(buf, config, cid, len);
3083 crcpos += cidlen;
3084 len += cidlen;
3085
3086 if (hdr.base__header().get_selection() == Profile4__base__header::ALT_ir)
3087 {
3088 if (hdr.base__header().ir().crc() == 0)
3089 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
3090 }
3091 else if (hdr.base__header().get_selection() ==
3092 Profile4__base__header::ALT_ir__dyn)
3093 {
3094 if (hdr.base__header().ir__dyn().crc() == 0)
3095 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
3096 }
3097
3098 Log_hexdump(buf, len);
3099 Log_function_name_on_leave();
3100
3101 return len;
3102}
3103
3104OCTETSTRING
3105f__ROHC__enc(ROHC__packet__u const &pdu, ROHC__config const &config)
3106{
3107 unsigned char buf[MAX_PACKET_SIZE];
3108 int len = 0;
3109
3110 Log_function_name_on_enter();
3111
3112 TTCN_logger.begin_event(TTCN_DEBUG);
3113 config.log();
3114 pdu.log();
3115 TTCN_logger.end_event();
3116
3117 if (pdu.get_selection() == ROHC__packet__u::ALT_segment)
3118 {
3119 // Processing padding
3120 len += Set_octetstring_opt(&buf[len], pdu.segment().padding());
3121 // Processing feedback
3122 len +=
3123 Set_ROHC_Feedback_opt(&buf[len],
3124 pdu.segment().feedback(), config.large__cid());
3125 // Processing segment header
3126 Check_field_value("segment header id",
3127 pdu.segment().segment__header__id(), 127);
3128 buf[len] = (pdu.segment().segment__header__id() << 1) & 0xFE;
3129 if (pdu.segment().final())
3130 buf[len] += 1;
3131 len += 1;
3132 // Processing payload
3133 len += Set_octetstring_opt(&buf[len], pdu.segment().payload());
3134 // Processing CRC
3135 if (pdu.segment().crc().ispresent())
3136 {
3137 buf[len] = (pdu.segment().crc()() >> 24) & 0xFF;
3138 len += 1;
3139 buf[len] = (pdu.segment().crc()() >> 16) & 0xFF;
3140 len += 1;
3141 buf[len] = (pdu.segment().crc()() >> 8) & 0xFF;
3142 len += 1;
3143 buf[len] = pdu.segment().crc()() & 0xFF;
3144 len += 1;
3145 }
3146 }
3147 else if (pdu.get_selection() == ROHC__packet__u::ALT_rohc)
3148 {
3149 // Processing padding
3150 len += Set_octetstring_opt(&buf[len], pdu.rohc().padding());
3151 // Processing feedback
3152 len += Set_ROHC_Feedback_opt(&buf[len],
3153 pdu.rohc().feedback(), config.large__cid());
3154 // Processing ROHC header
3155 switch (pdu.rohc().header().get_selection())
3156 {
3157 case Header::ALT_prof0:
3158 len += Set_ROHC_Header_Profile0(&buf[len], pdu.rohc().header().prof0(),
3159 config);
3160 break;
3161 case Header::ALT_prof1:
3162 len += Set_Profile1_ROHC_Header(&buf[len], pdu.rohc().header().prof1(),
3163 config);
3164 break;
3165 case Header::ALT_prof2:
3166 len += Set_Profile2_ROHC_Header(&buf[len], pdu.rohc().header().prof2(),
3167 config);
3168 break;
3169 case Header::ALT_prof4:
3170 len += Set_Profile4_ROHC_Header(&buf[len], pdu.rohc().header().prof4(),
3171 config);
3172 break;
3173 default:
3174 Log_not_implemented_union_field("Header",
3175 pdu.rohc().header().get_selection());
3176 break;
3177 }
3178
3179 // Processing payload
3180 len += Set_octetstring_opt(&buf[len], pdu.rohc().payload());
3181 }
3182
3183 Log_hexdump(buf, len);
3184 Log_function_name_on_leave();
3185
3186 return OCTETSTRING(len, &(buf[0]));
3187}
3188
3189
3190
3191
3192
3193/* ============ Decoding functions for base types ============ */
3194
3195/* Mirrors the bits of an octet and returns the same pointer. */
3196unsigned char *
3197Convert_bitstring(unsigned char *buf, int len)
3198{
3199 unsigned char dst_buf = 0;
3200
3201 if (len > 8)
3202 {
3203 TTCN_error("Bitstring is too long, at most 8 bits can be converted");
3204 }
3205 for (int i = 0; i < 8; i++)
3206 {
3207 dst_buf += ShiftUpBit(ShiftDownBit(buf[0], i), 7 - i);
3208 }
3209 buf[0] = dst_buf;
3210
3211 return buf;
3212}
3213
3214/* Decodes an OCTETSTING value */
3215int
3216Get_octetstring(const unsigned char *buf, OCTETSTRING & octstr, int length)
3217{
3218 octstr = OCTETSTRING(length, buf);
3219 return length;
3220}
3221
3222/* Decodes a LIN1 value */
3223int
3224Get_LIN1(const unsigned char *buf, LIN1 & var)
3225{
3226 var = LIN1(buf[0]);
3227 return 1;
3228}
3229
3230/* Decodes a LIN2_BO_LAST value */
3231int
3232Get_LIN2_BO_LAST(const unsigned char *buf, LIN2__BO__LAST & var)
3233{
3234 var = (buf[0] << 8) + buf[1];
3235 return 2;
3236}
3237
3238/* Decodes a LIN4_BO_LAST value */
3239int
3240Get_LIN4_BO_LAST(const unsigned char *buf, LIN4__BO__LAST & var)
3241{
3242 var = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
3243 return 4;
3244}
3245
3246int
3247Get_SDVL_field(const unsigned char *buf, INTEGER & dest)
3248{
3249 int len = 0;
3250 int decoded_value;
3251
3252 Log_function_name_on_enter();
3253
3254 if ((buf[len] & 0x80) == 0)
3255 {
3256 dest = buf[len] & 0x7F;
3257 len += 1;
3258 }
3259 else if ((buf[len] & 0xC0) == 0x80)
3260 {
3261 dest = ((buf[len] << 8) & 0x3F00) + (buf[len + 1] & 0xFF);
3262 len += 2;
3263 }
3264 else if ((buf[len] & 0xE0) == 0xC0)
3265 {
3266 dest =
3267 ((buf[len] << 16) & 0x1F0000) +
3268 ((buf[len + 1] << 8) & 0xFF00) + (buf[len + 2] & 0xFF);
3269 len += 3;
3270 }
3271 else // if ((buf[len] & 0xE0) == 0xE0)
3272 {
3273 dest =
3274 ((buf[len] << 24) & 0x1F000000) +
3275 ((buf[len + 1] << 16) & 0xFF0000) +
3276 ((buf[len + 2] << 8) & 0xFF00) + (buf[len + 3] & 0xFF);
3277 len += 4;
3278 }
3279
3280 decoded_value = dest;
3281 TTCN_logger.log(TTCN_DEBUG, "Decoded value is %u (encoded on %u octets)",
3282 decoded_value, len);
3283
3284 Log_hexdump(buf, len);
3285 Log_function_name_on_leave();
3286
3287 return len;
3288}
3289
3290/* ============ Decoding wrappers for optional base types ============ */
3291
3292/* Decodes a optional octetstring value */
3293int
3294Get_octetstring_opt(const unsigned char *buf, OPTIONAL < OCTETSTRING > &var,
3295 bool hasvalue, int length)
3296{
3297 if (hasvalue)
3298 {
3299 return Get_octetstring(buf, var(), length);
3300 }
3301 var = OMIT_VALUE;
3302 return 0;
3303}
3304
3305/* Decodes a optional LIN1 value */
3306int
3307Get_LIN1_opt(const unsigned char *buf, OPTIONAL < LIN1 > &var, bool hasvalue)
3308{
3309 if (hasvalue)
3310 {
3311 return Get_LIN1(buf, var());
3312 }
3313 var = OMIT_VALUE;
3314 return 0;
3315}
3316
3317/* Decodes a optional LIN2_BO_LAST value */
3318int
3319Get_LIN2_BO_LAST_opt(const unsigned char *buf,
3320 OPTIONAL < LIN2__BO__LAST > &var, bool hasvalue)
3321{
3322 if (hasvalue)
3323 {
3324 return Get_LIN2_BO_LAST(buf, var());
3325 }
3326 var = OMIT_VALUE;
3327 return 0;
3328}
3329
3330/* Decodes a optional LIN4_BO_LAST value */
3331int
3332Get_LIN4_BO_LAST_opt(const unsigned char *buf,
3333 OPTIONAL < LIN4__BO__LAST > &var, bool hasvalue)
3334{
3335 if (hasvalue)
3336 {
3337 return Get_LIN4_BO_LAST(buf, var());
3338 }
3339 var = OMIT_VALUE;
3340 return 0;
3341}
3342
3343/* Decodes a optional SDVL value */
3344int
3345Get_SDVL_field_opt(const unsigned char *buf,
3346 OPTIONAL < INTEGER > &var, bool hasvalue)
3347{
3348 if (hasvalue)
3349 {
3350 return Get_SDVL_field(buf, var());
3351 }
3352 var = OMIT_VALUE;
3353 return 0;
3354}
3355
3356/* ============ Decoding functions for ROHC types ============ */
3357
3358/* Returns the number of matching octets, that are the same as the passed
3359 'octet'. */
3360int
3361Strip_leading_octet(const unsigned char *buf, int length, unsigned char octet)
3362{
3363 int len = 0;
3364
3365 while ((buf[len] == octet) && (len < length))
3366 len += 1;
3367 return len;
3368}
3369
3370int
3371Get_ROHC_Padding(const unsigned char *buf, int length,
3372 OPTIONAL < Padding > &p_padding, ROHC__config & config)
3373{
3374 int len = Strip_leading_octet(buf, length, 0xE0);
3375
3376 Log_function_name_on_enter();
3377
3378 if (len > 0)
3379 {
3380 p_padding = OCTETSTRING(len, &(buf[0]));
3381 Log_hexdump(buf, len);
3382 }
3383 else
3384 p_padding = OMIT_VALUE;
3385
3386 Log_function_name_on_leave();
3387
3388 return len;
3389}
3390
3391int
3392Get_CID(const unsigned char *buf, INT14b__BO__LAST & cid,
3393 ROHC__config & config)
3394{
3395 int len = 0;
3396 int dec_cid;
3397
3398 Log_function_name_on_enter();
3399
3400 if (config.large__cid() == false)
3401 {
3402 if ((buf[len] & 0xF0) == 0xE0)
3403 {
3404 cid = buf[len] & 0x0F;
3405 len += 1;
3406 }
3407 else
3408 cid = 0;
3409 }
3410 else
3411 {
3412 len += Get_SDVL_field(&buf[len], cid);
3413 }
3414
3415 dec_cid = cid;
3416 TTCN_logger.log(TTCN_DEBUG, "Decoded CID = %u", dec_cid);
3417
3418 Log_hexdump(buf, len);
3419 Log_function_name_on_leave();
3420
3421 return len;
3422}
3423
3424int
3425Get_feedback(const unsigned char *buf, Feedback__u & feedback,
3426 ROHC__config & config)
3427{
3428 int len = 0, fbsize = 0, cidlen;
3429 unsigned char ctemp;
3430
3431 Log_function_name_on_enter();
3432
3433 ctemp = (buf[len] >> 3) & 0x1F;
3434 feedback.feedback__type() = BITSTRING(5, &ctemp);
3435 feedback.code() = buf[len] & 0x07;
3436 fbsize = feedback.code();
3437 len += 1;
3438 len += Get_LIN1_opt(&buf[len], feedback.size(), feedback.code() == 0);
3439 if (feedback.size().ispresent())
3440 {
3441 fbsize = feedback.size()();
3442 }
3443
3444 cidlen = Get_CID(&buf[len], feedback.feedback__data().cid(), config);
3445 fbsize -= cidlen;
3446 len += cidlen;
3447
3448 if (fbsize == 1) /* Feedback type 1 */
3449 {
3450 len += Get_octetstring(&buf[len],
3451 feedback.feedback__data().feedback__type().
3452 feedback1(), fbsize);
3453 }
3454 else /* Feedback type 2 */
3455 {
3456 int optnum = 0;
3457 Feedback__opts fbopts;
3458 Feedback2 feedback2;
3459
3460 feedback2.acktype() = (buf[len] >> 6) & 0x03;
3461 feedback2.mode() = (buf[len] >> 4) & 0x03;
3462 ctemp = buf[len] & 0x0F;
3463 len += 1;
3464 fbsize -= 1;
3465 feedback2.sn() = ((ctemp << 8) & 0x0F00) + buf[len];
3466 len += 1;
3467 fbsize -= 1;
3468 feedback2.feedback__opts() = OMIT_VALUE;
3469 while (fbsize > 0)
3470 {
3471 fbopts[optnum].opt__type() = (buf[len] >> 4) & 0x0F;
3472 fbopts[optnum].opt__len() = buf[len] & 0x0F;
3473 len += 1;
3474 fbsize -= 1;
3475 if (fbopts[optnum].opt__len())
3476 {
3477 len += Get_octetstring(&buf[len], fbopts[optnum].opt__data(),
3478 fbopts[optnum].opt__len());
3479 fbsize -= fbopts[optnum].opt__len();
3480 }
3481 else
3482 fbopts[optnum].opt__data() = OMIT_VALUE;
3483 feedback2.feedback__opts() = fbopts;
3484 optnum += 1;
3485 }
3486
3487 feedback.feedback__data().feedback__type().feedback2() = feedback2;
3488 }
3489
3490 Log_hexdump(buf, len);
3491 Log_function_name_on_leave();
3492
3493 return len;
3494}
3495
3496int
3497Get_ROHC_Feedback(const unsigned char *buf,
3498 int length,
3499 OPTIONAL < Feedback > &feedback, ROHC__config & config)
3500{
3501 int len = 0, fbnum = 0;
3502
3503 Log_function_name_on_enter();
3504
3505 feedback = OMIT_VALUE;
3506 while (((buf[len] & 0xF8) == 0xF0) && (len < length))
3507 {
3508 len += Get_feedback(&buf[len], feedback()[fbnum], config);
3509 fbnum++;
3510 }
3511
3512 Log_hexdump(buf, len);
3513 Log_function_name_on_leave();
3514
3515 return len;
3516}
3517
3518int
3519Get_XI_list(const unsigned char *buf,
3520 OPTIONAL < XI__list > &xilist, int m,
3521 const BITSTRING & ps_bit, int *itemnum,
3522 OPTIONAL < BITSTRING > &padding)
3523{
3524 int len = 0;
3525 unsigned char ctemp;
3526
3527 Log_function_name_on_enter();
3528
3529 if (!m)
3530 {
3531 xilist = OMIT_VALUE;
3532 padding = OMIT_VALUE;
3533 return len;
3534 }
3535
3536 if ((*ps_bit) == 1)
3537 {
3538 for (int num = 0; num < m; num++)
3539 {
3540 ctemp = ShiftDownBit(buf[len], 7);
3541 xilist().xi__item8()[num].x__ind() = BITSTRING(1, &ctemp);
3542 if (ctemp)
3543 *itemnum += 1;
3544 xilist().xi__item8()[num].index() = buf[len] & 0x7F;
3545 len += 1;
3546 }
3547 padding = OMIT_VALUE;
3548 }
3549 else
3550 {
3551 int halfbyte = 0;
3552
3553 for (int num = 0; num < m; num++)
3554 {
3555 if (halfbyte)
3556 {
3557 ctemp = ShiftDownBit(buf[len], 3);
3558 xilist().xi__item4()[num].x__ind() = BITSTRING(1, &ctemp);
3559 if (ctemp)
3560 *itemnum += 1;
3561 xilist().xi__item4()[num].index() = buf[len] & 0x07;
3562 len += 1;
3563 }
3564 else
3565 {
3566 ctemp = ShiftDownBit(buf[len], 7);
3567 xilist().xi__item4()[num].x__ind() = BITSTRING(1, &ctemp);
3568 if (ctemp)
3569 *itemnum += 1;
3570 xilist().xi__item4()[num].index() = (buf[len] >> 4) & 0x07;
3571 }
3572 halfbyte = 1 - halfbyte; /* Invert the value */
3573 }
3574 /* Padding */
3575 if (halfbyte == 1)
3576 {
3577 ctemp = buf[len] & 0x0F;
3578 padding() = BITSTRING(4, &ctemp);
3579 len += 1;
3580 }
3581 else
3582 padding = OMIT_VALUE;
3583 }
3584
3585 Log_hexdump(buf, len);
3586 Log_function_name_on_leave();
3587
3588 return len;
3589}
3590
3591int
3592Get_Item_list(const unsigned char *buf,
3593 OPTIONAL < Item__list > &item_list, int n,
3594 Item__list::union_selection_type selection,
3595 t_dat *dat, int ip_idx)
3596{
3597 int len = 0;
3598
3599 Log_function_name_on_enter();
3600
3601 if (n == 0)
3602 {
3603 item_list = OMIT_VALUE;
3604 Log_function_name_on_leave();
3605 return len;
3606 }
3607
3608 TTCN_logger.log(TTCN_DEBUG, "Expecting %u items", n);
3609
3610 /* Item list is an IP extension header list */
3611 if (selection == Item__list::ALT_ip__item__list)
3612 {
3613 IP__Item__list & itlist = item_list().ip__item__list();
3614 for (int num = 0; num < n; num++)
3615 {
3616 int headid = buf[len];
3617 len += 1;
3618
3619 TTCN_logger.log(TTCN_DEBUG, "%uth item", num);
3620
3621 if (headid == c__ip__proto__ah)
3622 {
3623 AH__item & item = itlist[num].ah__item();
3624 int payload_length, ah_data_len;
3625
3626 TTCN_logger.log(TTCN_DEBUG, "AH header found");
3627 item.nexthead() = headid;
3628 len += Get_LIN1(&buf[len], item.payload__len());
3629 payload_length = item.payload__len();
3630 ah_data_len = (item.payload__len() - 1) * 4;
3631 len += Get_LIN2_BO_LAST(&buf[len], item.reserved());
3632 len += Get_LIN4_BO_LAST(&buf[len], item.spi());
3633 len += Get_LIN4_BO_LAST(&buf[len], item.sn());
3634 len += Get_octetstring_opt(&buf[len], item.auth__data(),
3635 item.payload__len() != 1, ah_data_len);
3636 dat->context.ip__ctx()[ip_idx].ah__data__len() = ah_data_len;
3637 dat->context.ip__ctx()[ip_idx].ah__present() = true;
3638 // There is no compressed AH data after the base header
3639 dat->compressed_ah_data_len[ip_idx] = 0;
3640 TTCN_logger.log(TTCN_DEBUG,
3641 "AH payload length is %d meaning %d octets",
3642 payload_length, ah_data_len);
3643 Log_hexdump(buf, len);
3644 }
3645 else if (headid == c__ip__proto__mine)
3646 {
3647 unsigned char ctemp;
3648 MINE__item & item = itlist[num].mine__item();
3649
3650 TTCN_logger.log(TTCN_DEBUG, "MINE header found");
3651 item.protocol() = headid;
3652 ctemp = ShiftDownBit(buf[len], 7);
3653 item.s__bit() = BITSTRING(1, &ctemp);
3654 item.reserved() = BITSTRING(7, &buf[len]);
3655 len += 1;
3656 len += Get_LIN2_BO_LAST(&buf[len], item.cksum());
3657 len += Get_octetstring(&buf[len], item.dstaddr(), 4);
3658 len += Get_octetstring_opt(&buf[len], item.srcaddr(),
3659 *item.s__bit() == 1, 4);
3660 Log_hexdump(buf, len);
3661 }
3662 else if (headid == c__ip__proto__esp)
3663 {
3664 ESP__item & item = itlist[num].esp__item();
3665
3666 TTCN_logger.log(TTCN_DEBUG, "ESP header found");
3667 item.nexthead() = headid;
3668 len += Get_LIN4_BO_LAST(&buf[len], item.spi());
3669 len += Get_LIN4_BO_LAST(&buf[len], item.sn());
3670
3671 dat->context.ip__ctx()[ip_idx].esp__present() = true;
3672 Log_hexdump(buf, len);
3673 }
3674 else if (headid == c__ip__proto__gre2)
3675 {
3676 GRE__item & item = itlist[num].gre__item();
3677 unsigned char ctemp;
3678
3679 TTCN_logger.log(TTCN_DEBUG, "GRE header found");
3680 item.nexthead() = headid;
3681 ctemp = ShiftDownBit(buf[len], 7);
3682 item.C__bit() = BITSTRING(1, &ctemp);
3683 ctemp = ShiftDownBit(buf[len], 6);
3684 item.reserved__1() = BITSTRING(1, &ctemp);
3685 ctemp = ShiftDownBit(buf[len], 5);
3686 item.K__bit() = BITSTRING(1, &ctemp);
3687 ctemp = ShiftDownBit(buf[len], 4);
3688 item.S__bit() = BITSTRING(1, &ctemp);
3689 ctemp = ShiftDownBit(buf[len], 3);
3690 item.reserved__2() = BITSTRING(1, &ctemp);
3691 ctemp = buf[len] & 0x07;
3692 item.version() = BITSTRING(3, &ctemp);
3693 len += 1;
3694 len += Get_LIN2_BO_LAST_opt(&buf[len], item.cksum(),
3695 *item.C__bit() == 1);
3696 len += Get_LIN4_BO_LAST_opt(&buf[len], item.key(),
3697 *item.K__bit() == 1);
3698 len += Get_LIN4_BO_LAST_opt(&buf[len], item.sn(), *item.S__bit() == 1);
3699
3700 dat->context.ip__ctx()[ip_idx].gre__cksum__present() = (*item.C__bit() == 1);
3701 dat->context.ip__ctx()[ip_idx].gre__present() = true;
3702 // There is no compressed GRE data after the base header
3703 dat->ipx_gre_cksum_present[ip_idx] = false;
3704 Log_hexdump(buf, len);
3705 }
3706 else /* Assuming IPv6 extension header */
3707 /* TODO check: why only these were supported:
3708 if (headid == 0 || headid == 43 || headid == 60) */
3709 {
3710 IPv6__ext__item & item = itlist[num].ipv6__ext__item();
3711 int ext_len;
3712 int ext_len_oct;
3713
3714 TTCN_logger.log(TTCN_DEBUG, "IPv6 header found (type %d)", headid);
3715 item.nexthead() = headid;
3716 len += Get_LIN1(&buf[len], item.hdr__ext__len());
3717 ext_len_oct = item.hdr__ext__len();
3718 ext_len = (item.hdr__ext__len() + 1) * 8;
3719 TTCN_logger.log(TTCN_DEBUG,
3720 "IPv6 extension length is %d meaning %d octets",
3721 ext_len_oct, ext_len);
3722 // 2 octets already been read
3723 len += Get_octetstring(&buf[len], item.data(), ext_len - 2);
3724 Log_hexdump(buf, len);
3725 }
3726 } /* for (num) */
3727 }
3728 else if (selection == Item__list::ALT_csrc__item__list)
3729 {
3730 for (int num = 0; num < n; num++)
3731 {
3732 TTCN_logger.log(TTCN_DEBUG, "%uth item", num);
3733
3734 len +=
3735 Get_octetstring(&buf[len], item_list().csrc__item__list()[num], 4);
3736 }
3737 }
3738 else if (selection == Item__list::ALT_raw__data)
3739 {
3740 /* TODO: RAW_data field is just a temporary hack for Profile4 tests */
3741 RAW__data & itlist = item_list().raw__data();
3742
3743 for (int num = 0; num < n; num++)
3744 {
3745 int headid = char2int(buf[len]);
3746
3747 if (headid == 0 || headid == 43 || headid == 60)
3748 {
3749 int itemlimit = char2int(buf[len + 1]) + 1 * 8;
3750 for (int itemlen = 0; itemlen < itemlimit; itemlen++)
3751 {
3752 if (itemlen == 0)
3753 itlist[num] = OCTETSTRING(1, &buf[len]);
3754 else
3755 itlist[num] = itlist[num] + OCTETSTRING(1, &buf[len]);
3756 len += 1;
3757 }
3758 }
3759 else if (headid == 51)
3760 {
3761 int itemlimit = char2int(buf[len + 1]) + 1 * 8;
3762 for (int itemlen = 0; itemlen < itemlimit; itemlen++)
3763 {
3764 if (itemlen == 0)
3765 itlist[num] = OCTETSTRING(1, &buf[len]);
3766 else
3767 itlist[num] = itlist[num] + OCTETSTRING(1, &buf[len]);
3768 len += 1;
3769 }
3770 }
3771 else if (headid == 50)
3772 {
3773 for (int itemlen = 0; itemlen < 9; itemlen++)
3774 {
3775 if (itemlen == 0)
3776 itlist[num] = OCTETSTRING(1, &buf[len]);
3777 else
3778 itlist[num] = itlist[num] + OCTETSTRING(1, &buf[len]);
3779 len += 1;
3780 }
3781 }
3782 else if (headid == 55 || headid == 47)
3783 {
3784 for (int itemlen = 0; itemlen < 13; itemlen++)
3785 {
3786 if (itemlen == 0)
3787 itlist[num] = OCTETSTRING(1, &buf[len]);
3788 else
3789 itlist[num] = itlist[num] + OCTETSTRING(1, &buf[len]);
3790 len += 1;
3791 }
3792 }
3793 else
3794 TTCN_logger.log(TTCN_WARNING,
3795 "Unrecognized element in encoding type 0");
3796 }
3797 }
3798 else
3799 {
3800 Log_not_implemented_union_field("Item_list", selection);
3801 }
3802
3803 Log_hexdump(buf, len);
3804 Log_function_name_on_leave();
3805
3806 return len;
3807}
3808
3809int
3810Get_Encoding_Type_0(Enc__Type__0 & enct0, const unsigned char *buf,
3811 Item__list::union_selection_type selection,
3812 t_dat *dat, int ip_idx)
3813{
3814 unsigned char ctemp;
3815 int itemnum = 0;
3816 int len = 0;
3817
3818 Log_function_name_on_enter();
3819
3820 ctemp = (buf[len] >> 6) & 0x03;
3821 enct0.et() = BITSTRING(2, &ctemp);
3822 ctemp = ShiftDownBit(buf[len], 5);
3823 enct0.gp__bit() = BITSTRING(1, &ctemp);
3824 ctemp = ShiftDownBit(buf[len], 4);
3825 enct0.ps__bit() = BITSTRING(1, &ctemp);
3826 enct0.cc() = buf[len] & 0x0F;
3827 len += 1;
3828 len += Get_LIN1_opt(&buf[len], enct0.gen__id(), (*enct0.gp__bit()) == 1);
3829 len += Get_XI_list(&buf[len], enct0.xi__list(),
3830 enct0.cc(), enct0.ps__bit(), &itemnum, enct0.padding());
3831 len += Get_Item_list(&buf[len], enct0.item__list(), itemnum, selection,
3832 dat, ip_idx);
3833
3834 Log_hexdump(buf, len);
3835 Log_function_name_on_leave();
3836
3837 return len;
3838}
3839
3840int
3841Get_Encoding_Type_1(Enc__Type__1 & enct1, const unsigned char *buf,
3842 Item__list::union_selection_type selection,
3843 t_dat *dat, int ip_idx)
3844{
3845 unsigned char ctemp;
3846 int knum = 0, itemnum = 0, len = 0;
3847
3848 Log_function_name_on_enter();
3849
3850 ctemp = (buf[len] >> 6) & 0x03;
3851 enct1.et() = BITSTRING(2, &ctemp);
3852 ctemp = ShiftDownBit(buf[len], 5);
3853 enct1.gp__bit() = BITSTRING(1, &ctemp);
3854 ctemp = ShiftDownBit(buf[len], 4);
3855 enct1.ps__bit() = BITSTRING(1, &ctemp);
3856 enct1.xi1() = buf[len] & 0x0F;
3857 len += 1;
3858 len += Get_LIN1_opt(&buf[len], enct1.gen__id(), (*enct1.gp__bit()) == 1);
3859 len += Get_LIN1(&buf[len], enct1.ref__id());
3860 if ((buf[len] & 0x80) == 0) /* 1 octet insertion mask */
3861 {
3862 for (int i = 0; i < 8; i++)
3863 {
3864 if (ShiftDownBit(buf[len], i) == 1)
3865 knum++;
3866 }
3867 len += Get_octetstring(&buf[len], enct1.insbitmask(), 1);
3868 }
3869 else /* 2 octets insertion mask */
3870 {
3871 for (int i = 0; i < 8; i++)
3872 if (ShiftDownBit(buf[len], i) == 1)
3873 knum++;
3874 for (int i = 0; i < 8; i++)
3875 if (ShiftDownBit(buf[len + 1], i) == 1)
3876 knum++;
3877 len += Get_octetstring(&buf[len], enct1.insbitmask(), 2);
3878 }
3879
3880 /* Determine whether xi1 already contains the first index */
3881 if ((*enct1.ps__bit()) == 0)
3882 {
3883 knum--;
3884 }
3885 len +=
3886 Get_XI_list(&buf[len], enct1.xi__list(),
3887 knum, enct1.ps__bit(), &itemnum, enct1.padding());
3888 len += Get_Item_list(&buf[len], enct1.item__list(), itemnum, selection,
3889 dat, ip_idx);
3890
3891 Log_hexdump(buf, len);
3892 Log_function_name_on_leave();
3893
3894 return len;
3895}
3896
3897
3898int
3899Get_Encoding_Type_2(Enc__Type__2 & enct2, const unsigned char *buf,
3900 Item__list::union_selection_type selection)
3901{
3902 unsigned char ctemp;
3903 int len = 0;
3904
3905 Log_function_name_on_enter();
3906
3907 ctemp = (buf[len] >> 6) & 0x03;
3908 enct2.et() = BITSTRING(2, &ctemp);
3909 ctemp = ShiftDownBit(buf[len], 5);
3910 enct2.gp__bit() = BITSTRING(1, &ctemp);
3911 ctemp = ShiftDownBit(buf[len], 4);
3912 enct2.res() = BITSTRING(1, &ctemp);
3913 enct2.count() = buf[len] & 0x0F;
3914 len += 1;
3915 len += Get_LIN1_opt(&buf[len], enct2.gen__id(), (*enct2.gp__bit()) == 1);
3916 len += Get_LIN1(&buf[len], enct2.ref__id());
3917 if ((buf[len] & 0x80) == 0)
3918 len += Get_octetstring(&buf[len], enct2.rembitmask(), 1);
3919 else
3920 len += Get_octetstring(&buf[len], enct2.rembitmask(), 2);
3921
3922 Log_hexdump(buf, len);
3923 Log_function_name_on_leave();
3924
3925 return len;
3926}
3927
3928
3929int
3930Get_Encoding_Type_3(Enc__Type__3 & enct3, const unsigned char *buf,
3931 Item__list::union_selection_type selection,
3932 t_dat *dat, int ip_idx)
3933{
3934 unsigned char ctemp;
3935 int itemnum = 0;
3936 int knum = 0;
3937 int len = 0;
3938
3939 Log_function_name_on_enter();
3940
3941 ctemp = (buf[len] >> 6) & 0x03;
3942 enct3.et() = BITSTRING(2, &ctemp);
3943 ctemp = ShiftDownBit(buf[len], 5);
3944 enct3.gp__bit() = BITSTRING(1, &ctemp);
3945 ctemp = ShiftDownBit(buf[len], 4);
3946 enct3.ps__bit() = BITSTRING(1, &ctemp);
3947 enct3.xi1() = buf[len] & 0x0F;
3948 len += 1;
3949 len += Get_LIN1_opt(&buf[len], enct3.gen__id(), (*enct3.gp__bit()) == 1);
3950 len += Get_LIN1(&buf[len], enct3.ref__id());
3951 if ((buf[len] & 0x80) == 0)
3952 len += Get_octetstring(&buf[len], enct3.rembitmask(), 1);
3953 else
3954 len += Get_octetstring(&buf[len], enct3.rembitmask(), 2);
3955
3956 if ((buf[len] & 0x80) == 0) /* 1 octet insertion mask */
3957 {
3958 for (int i = 0; i < 8; i++)
3959 {
3960 if (ShiftDownBit(buf[len], i) == 1)
3961 knum++;
3962 }
3963 len += Get_octetstring(&buf[len], enct3.insbitmask(), 1);
3964 }
3965 else /* 2 octets insertion mask */
3966 {
3967 for (int i = 0; i < 8; i++)
3968 if (ShiftDownBit(buf[len], i) == 1)
3969 knum++;
3970 for (int i = 0; i < 8; i++)
3971 if (ShiftDownBit(buf[len + 1], i) == 1)
3972 knum++;
3973 len += Get_octetstring(&buf[len], enct3.insbitmask(), 2);
3974 }
3975
3976 /* Determine whether xi1 already contains the first index */
3977 if ((*enct3.ps__bit()) == 0)
3978 {
3979 knum--;
3980 }
3981 len += Get_XI_list(&buf[len], enct3.xi__list(),
3982 knum, enct3.ps__bit(), &itemnum, enct3.padding());
3983 len += Get_Item_list(&buf[len], enct3.item__list(), itemnum, selection,
3984 dat, ip_idx);
3985
3986 Log_hexdump(buf, len);
3987 Log_function_name_on_leave();
3988
3989 return len;
3990}
3991
3992int
3993Get_Compr_head_list(Compr__head__list & chl, const unsigned char *buf,
3994 Item__list::union_selection_type selection,
3995 t_dat *dat, int ip_idx)
3996{
3997 int len = 0;
3998
3999 Log_function_name_on_enter();
4000
4001 if ((buf[len] & 0xC0) == 0)
4002 len += Get_Encoding_Type_0(chl.enctype0(), &buf[len], selection,
4003 dat, ip_idx);
4004 else if ((buf[len] & 0xC0) == 0x40)
4005 len += Get_Encoding_Type_1(chl.enctype1(), &buf[len], selection,
4006 dat, ip_idx);
4007 else if ((buf[len] & 0xC0) == 0x80)
4008 len += Get_Encoding_Type_2(chl.enctype2(), &buf[len], selection);
4009 else
4010 len += Get_Encoding_Type_3(chl.enctype3(), &buf[len], selection,
4011 dat, ip_idx);
4012
4013 Log_hexdump(buf, len);
4014 Log_function_name_on_leave();
4015
4016 return len;
4017}
4018
4019int
4020Get_ipv4_dynamic(const unsigned char *buf, IPv4__Dynamic & chain,
4021 t_dat *dat, int ip_level)
4022{
4023 int len = 0;
4024 unsigned char ctemp;
4025
4026 Log_function_name_on_enter();
4027
4028 len += Get_LIN1(&buf[len], chain.tos());
4029 len += Get_LIN1(&buf[len], chain.ttl());
4030 len += Get_LIN2_BO_LAST(&buf[len], chain.identification());
4031 ctemp = ShiftDownBit(buf[len], 7);
4032 chain.df__bit() = BITSTRING(1, &ctemp);
4033 ctemp = ShiftDownBit(buf[len], 6);
4034 chain.rnd__bit() = BITSTRING(1, &ctemp);
4035 dat->context.ip__ctx()[ip_level].rnd__bit() = BOOLEAN(ctemp);
4036 ctemp = ShiftDownBit(buf[len], 5);
4037 chain.nbo__bit() = BITSTRING(1, &ctemp);
4038 ctemp = buf[len] & 0x1F;
4039 chain.reserved() = BITSTRING(5, &ctemp);
4040 len += 1;
4041 len += Get_Encoding_Type_0(chain.genextheadlist(),
4042 &buf[len], Item__list::ALT_ip__item__list,
4043 dat, ip_level);
4044
4045 Log_hexdump(buf, len);
4046 Log_function_name_on_leave();
4047
4048 return len;
4049}
4050
4051int
4052Get_ipv4_static(const unsigned char *buf, IPv4__Static & chain)
4053{
4054 int len = 0;
4055
4056 Log_function_name_on_enter();
4057
4058 chain.version() = (buf[len] >> 4) & 0x0F;
4059 chain.reserved() = buf[len] & 0x0F;
4060 len += 1;
4061 len += Get_LIN1(&buf[len], chain.proto());
4062 len += Get_octetstring(&buf[len], chain.srcaddr(), 4);
4063 len += Get_octetstring(&buf[len], chain.dstaddr(), 4);
4064
4065 Log_hexdump(buf, len);
4066 Log_function_name_on_leave();
4067
4068 return len;
4069}
4070
4071int
4072Get_ipv6_static(const unsigned char *buf, IPv6__Static & chain)
4073{
4074 int len = 0;
4075
4076 Log_function_name_on_enter();
4077
4078 chain.version() = (buf[len] >> 4) & 0x0F;
4079 chain.flowlabel() =
4080 ((buf[len] & 0x0F) << 16) + (buf[len + 1] << 8) + buf[len + 2];
4081 len += 3;
4082 len += Get_LIN1(&buf[len], chain.nexthead());
4083 len += Get_octetstring(&buf[len], chain.srcaddr(), 16);
4084 len += Get_octetstring(&buf[len], chain.dstaddr(), 16);
4085
4086 Log_hexdump(buf, len);
4087 Log_function_name_on_leave();
4088
4089 return len;
4090}
4091
4092int
4093Get_ipv6_dynamic(const unsigned char *buf, IPv6__Dynamic & chain,
4094 t_dat *dat, int ip_level)
4095{
4096 int len = 0;
4097
4098 Log_function_name_on_enter();
4099
4100 len += Get_LIN1(&buf[len], chain.trafficclass());
4101 len += Get_LIN1(&buf[len], chain.hoplimit());
4102 len += Get_Encoding_Type_0(chain.genextheadlist(), &buf[len],
4103 Item__list::ALT_ip__item__list, dat, ip_level);
4104
4105 Log_hexdump(buf, len);
4106 Log_function_name_on_leave();
4107
4108 return len;
4109}
4110
4111int
4112Get_udp_static(const unsigned char *buf, UDP__Static & chain)
4113{
4114 int len = 0;
4115
4116 Log_function_name_on_enter();
4117
4118 len += Get_LIN2_BO_LAST(&buf[len], chain.srcport());
4119 len += Get_LIN2_BO_LAST(&buf[len], chain.dstport());
4120
4121 Log_hexdump(buf, len);
4122 Log_function_name_on_leave();
4123
4124 return len;
4125}
4126
4127int
4128Get_udp_dynamic_wo_sn(const unsigned char *buf,
4129 UDP__Dynamic & chain, t_dat *dat)
4130{
4131 int len = 0;
4132
4133 Log_function_name_on_enter();
4134
4135 len += Get_LIN2_BO_LAST(&buf[len], chain.cksum());
4136 if (chain.cksum() == 0)
4137 {
4138 /* Checksum value 0 means that no UDP checksum is present in the
4139 forthcoming compressed packets. */
4140 dat->context.udp__ctx().udp__cksum() = false;
4141 }
4142
4143 Log_hexdump(buf, len);
4144 Log_function_name_on_leave();
4145
4146 return len;
4147}
4148
4149int
4150Get_udp_dynamic_w_sn(const unsigned char *buf,
4151 Profile2__UDP__Dynamic & chain, t_dat *dat)
4152{
4153 int len = 0;
4154
4155 Log_function_name_on_enter();
4156
4157 len += Get_LIN2_BO_LAST(&buf[len], chain.cksum());
4158 len += Get_LIN2_BO_LAST(&buf[len], chain.udp__sn());
4159 if (chain.cksum() == 0)
4160 {
4161 /* Checksum value 0 means that no UDP checksum is present in the
4162 forthcoming compressed packets. */
4163 dat->context.udp__ctx().udp__cksum() = false;
4164 }
4165
4166 Log_hexdump(buf, len);
4167 Log_function_name_on_leave();
4168
4169 return len;
4170}
4171
4172int
4173Get_rtp_static(const unsigned char *buf, RTP__Static & chain)
4174{
4175 int len = 0;
4176
4177 Log_function_name_on_enter();
4178
4179 len += Get_octetstring(&buf[len], chain.ssrc(), 4);
4180
4181 Log_hexdump(buf, len);
4182 Log_function_name_on_leave();
4183
4184 return len;
4185}
4186
4187int
4188Get_rtp_dynamic(const unsigned char *buf, RTP__Dynamic & chain,
4189 t_dat *dat)
4190{
4191 int len = 0;
4192 unsigned char ctemp;
4193
4194 Log_function_name_on_enter();
4195
4196 chain.vfield() = (buf[len] >> 6) & 0x03;
4197 ctemp = ShiftDownBit(buf[len], 5);
4198 chain.pbit() = BITSTRING(1, &ctemp);
4199 ctemp = ShiftDownBit(buf[len], 4);
4200 chain.rxbit() = BITSTRING(1, &ctemp);
4201 chain.ccfield() = buf[len] & 0x0F;
4202 len += 1;
4203 ctemp = ShiftDownBit(buf[len], 7);
4204 chain.mbit() = BITSTRING(1, &ctemp);
4205 chain.ptfield() = buf[len] & 0x7F;
4206 len += 1;
4207 len += Get_LIN2_BO_LAST(&buf[len], chain.rtpseqnum());
4208 len += Get_LIN4_BO_LAST(&buf[len], chain.rtpts());
4209 len += Get_Encoding_Type_0(chain.gencsrclist(),
4210 &buf[len], Item__list::ALT_csrc__item__list,
4211 dat, 0);
4212 if ((*chain.rxbit()) == 1)
4213 {
4214 Rx__Field & rxfield = chain.rx__field();
4215
4216 ctemp = (buf[len] >> 5) & 0x07;
4217 rxfield.reserved() = BITSTRING(3, &ctemp);
4218 ctemp = ShiftDownBit(buf[len], 4);
4219 rxfield.xbit() = BITSTRING(1, &ctemp);
4220 rxfield.mode() = (buf[len] >> 2) & 0x03;
4221 ctemp = ShiftDownBit(buf[len], 1);
4222 rxfield.tisbit() = BITSTRING(1, &ctemp);
4223 ctemp = ShiftDownBit(buf[len], 0);
4224 rxfield.tssbit() = BITSTRING(1, &ctemp);
4225 len += 1;
4226 len += Get_SDVL_field_opt(&buf[len], chain.ts__stride(),
4227 *rxfield.tssbit() == 1);
4228 len += Get_SDVL_field_opt(&buf[len], chain.time__stride(),
4229 *rxfield.tisbit() == 1);
4230 }
4231 else
4232 {
4233 chain.rx__field() = OMIT_VALUE;
4234 chain.ts__stride() = OMIT_VALUE;
4235 chain.time__stride() = OMIT_VALUE;
4236 }
4237
4238 Log_hexdump(buf, len);
4239 Log_function_name_on_leave();
4240
4241 return len;
4242}
4243
4244/* Reads the compressed IP-ID field after the base header */
4245int
4246Get_IP_ID_compressed_opt(unsigned char *buf,
4247 OPTIONAL < LIN2__BO__LAST > &field,
4248 t_dat *dat, int ip_level)
4249{
4250 int len = 0;
4251
4252 Log_function_name_on_enter();
4253
4254 if (dat->context.pkt() != Packet__type::IR && dat->context.pkt() != Packet__type::IR__DYN)
4255 {
4256 int ip_idx = getIPidx(dat, ip_level);
4257 TTCN_logger.log(TTCN_DEBUG, "iplevel = %d, ip_idx = %d", ip_level, ip_idx);
4258
4259 if (ip_idx >= 0)
4260 {
4261 if (dat->context.ip__ctx()[ip_idx].rnd__bit())
4262 len += Get_LIN2_BO_LAST(&buf[len], field());
4263 else
4264 field = OMIT_VALUE;
4265 }
4266 else
4267 field = OMIT_VALUE;
4268 }
4269 else
4270 field = OMIT_VALUE;
4271
4272 Log_hexdump(buf, len);
4273 Log_function_name_on_leave();
4274
4275 return len;
4276}
4277
4278/* Reads the AH data field after the base header */
4279int
4280Get_AH_data_opt(unsigned char *buf,
4281 OPTIONAL < OCTETSTRING > &field, t_dat *dat,
4282 int ip_level)
4283{
4284 int len = 0;
4285 int ip_idx = getIPidx(dat, ip_level);
4286
4287 Log_function_name_on_enter();
4288
4289 TTCN_logger.log(TTCN_DEBUG, "iplevel = %d, ip_idx = %d", ip_level, ip_idx);
4290
4291 /* AH present */
4292 if (ip_idx >= 0)
4293 {
4294 int ah_len = dat->compressed_ah_data_len[ip_idx];
4295
4296 if (ah_len > 0)
4297 len += Get_octetstring(&buf[len], field(), ah_len);
4298 else
4299 field = OMIT_VALUE;
4300 }
4301 else
4302 field = OMIT_VALUE;
4303
4304 Log_hexdump(buf, len);
4305 Log_function_name_on_leave();
4306
4307 return len;
4308}
4309
4310/* Reads the GRE checksum field after the base header */
4311int
4312Get_GRE_cksum_opt(unsigned char *buf,
4313 OPTIONAL < LIN2__BO__LAST > &field, t_dat *dat,
4314 int ip_level)
4315{
4316 int len = 0;
4317 int ip_idx = getIPidx(dat, ip_level);
4318
4319 Log_function_name_on_enter();
4320
4321 TTCN_logger.log(TTCN_DEBUG, "iplevel = %d, ip_idx = %d", ip_level, ip_idx);
4322
4323 /* Compressed packet and GRE present */
4324 if (ip_idx >= 0)
4325 {
4326 if (dat->ipx_gre_cksum_present[ip_idx])
4327 len += Get_LIN2_BO_LAST(&buf[len], field());
4328 else
4329 field = OMIT_VALUE;
4330 }
4331 else
4332 field = OMIT_VALUE;
4333
4334 Log_hexdump(buf, len);
4335 Log_function_name_on_leave();
4336
4337 return len;
4338}
4339
4340/* Reads the UDP checksum field after the base header */
4341int
4342Get_UDP_cksum_opt(unsigned char *buf,
4343 OPTIONAL < LIN2__BO__LAST > &field, t_dat *dat)
4344{
4345 int len = 0;
4346
4347 Log_function_name_on_enter();
4348
4349 if (dat->context.pkt() != Packet__type::IR && dat->context.pkt() != Packet__type::IR__DYN &&
4350 dat->context.udp__ctx().udp__cksum())
4351 {
4352 len += Get_LIN2_BO_LAST(&buf[len], field());
4353 }
4354 else
4355 field = OMIT_VALUE;
4356
4357 Log_hexdump(buf, len);
4358 Log_function_name_on_leave();
4359
4360 return len;
4361}
4362
4363int
4364Get_AEGSeqnum_opt(OPTIONAL < AEGSeqnum > &seqn, const unsigned char *buf,
4365 bool hasvalue)
4366{
4367 unsigned char ctemp;
4368 int len = 0;
4369
4370 Log_function_name_on_enter();
4371
4372 if (hasvalue)
4373 {
4374 if ((buf[len] & 0x80) == 0)
4375 {
4376 ctemp = ShiftDownBit(buf[len], 7);
4377 seqn().short__form().ind() = BITSTRING(1, &ctemp);
4378 seqn().short__form().lsb__of__seqnum() = buf[len] & 0x7F;
4379 len += 1;
4380 }
4381 else
4382 {
4383 ctemp = ShiftDownBit(buf[len], 7);
4384 seqn().long__form().ind() = BITSTRING(1, &ctemp);
4385 seqn().long__form().lsb__of__seqnum() =
4386 ((buf[len] & 0x7F) << 24) +
4387 (buf[len + 1] << 16) + (buf[len + 2] << 8) + buf[len + 3];
4388 len += 4;
4389 }
4390 }
4391 else
4392 seqn = OMIT_VALUE;
4393
4394 Log_hexdump(buf, len);
4395 Log_function_name_on_leave();
4396
4397 return len;
4398}
4399
4400int
4401Get_Inner_IP_flags_opt(unsigned char *buf,
4402 OPTIONAL < Inner__IP__flags > &field,
4403 t_dat *dat, bool hasvalue)
4404{
4405 int len = 0;
4406 int ip_idx = getIPidx(dat, Inner_IP);
4407 unsigned char ctemp;
4408
4409 Log_function_name_on_enter();
4410
4411 TTCN_logger.log(TTCN_DEBUG, "iplevel = %d, ip_idx = %d", Inner_IP, ip_idx);
4412
4413 if (hasvalue)
4414 {
4415 ctemp = ShiftDownBit(buf[len], 7);
4416 field().tos() = BITSTRING(1, &ctemp);
4417 ctemp = ShiftDownBit(buf[len], 6);
4418 field().ttl() = BITSTRING(1, &ctemp);
4419 ctemp = ShiftDownBit(buf[len], 5);
4420 field().df() = BITSTRING(1, &ctemp);
4421 ctemp = ShiftDownBit(buf[len], 4);
4422 field().pr() = BITSTRING(1, &ctemp);
4423 ctemp = ShiftDownBit(buf[len], 3);
4424 field().ipx() = BITSTRING(1, &ctemp);
4425 ctemp = ShiftDownBit(buf[len], 2);
4426 field().nbo() = BITSTRING(1, &ctemp);
4427 ctemp = ShiftDownBit(buf[len], 1);
4428 field().rnd__bit() = BITSTRING(1, &ctemp);
4429 dat->context.ip__ctx()[ip_idx].rnd__bit() = BOOLEAN(ctemp);
4430 ctemp = ShiftDownBit(buf[len], 0);
4431 field().ip2__bit() = BITSTRING(1, &ctemp);
4432 len += 1;
4433 }
4434 else
4435 field = OMIT_VALUE;
4436
4437 Log_hexdump(buf, len);
4438 Log_function_name_on_leave();
4439
4440 return len;
4441}
4442
4443int
4444Get_Outer_IP_flags_opt(unsigned char *buf,
4445 OPTIONAL < Outer__IP__flags > &field,
4446 t_dat *dat, bool hasvalue)
4447{
4448 int len = 0;
4449 int ip_idx = getIPidx(dat, Outer_IP);
4450 unsigned char ctemp;
4451
4452 Log_function_name_on_enter();
4453
4454 TTCN_logger.log(TTCN_DEBUG, "iplevel = %d, ip_idx = %d", Outer_IP, ip_idx);
4455
4456 if (hasvalue)
4457 {
4458 ctemp = ShiftDownBit(buf[len], 7);
4459 field().tos2() = BITSTRING(1, &ctemp);
4460 ctemp = ShiftDownBit(buf[len], 6);
4461 field().ttl2() = BITSTRING(1, &ctemp);
4462 ctemp = ShiftDownBit(buf[len], 5);
4463 field().df2() = BITSTRING(1, &ctemp);
4464 ctemp = ShiftDownBit(buf[len], 4);
4465 field().pr2() = BITSTRING(1, &ctemp);
4466 ctemp = ShiftDownBit(buf[len], 3);
4467 field().ipx2() = BITSTRING(1, &ctemp);
4468 ctemp = ShiftDownBit(buf[len], 2);
4469 field().nbo2() = BITSTRING(1, &ctemp);
4470 ctemp = ShiftDownBit(buf[len], 1);
4471 field().rnd2() = BITSTRING(1, &ctemp);
4472 dat->context.ip__ctx()[ip_idx].rnd__bit() = BOOLEAN(ctemp);
4473 ctemp = ShiftDownBit(buf[len], 0);
4474 field().i2__bit() = BITSTRING(1, &ctemp);
4475 len += 1;
4476 }
4477 else
4478 field = OMIT_VALUE;
4479
4480 Log_hexdump(buf, len);
4481 Log_function_name_on_leave();
4482
4483 return len;
4484}
4485
4486int
4487Get_ipx_headers_opt(unsigned char *buf, OPTIONAL < IP__Ext__heads > &field,
4488 t_dat *dat, bool hasvalue, int ip_idx)
4489{
4490 int len = 0;
4491 unsigned char ctemp;
4492
4493 Log_function_name_on_enter();
4494
4495 TTCN_logger.log(TTCN_DEBUG, "present = %d, ip_idx = %d", hasvalue, ip_idx);
4496
4497 if (hasvalue)
4498 {
4499 ctemp = ShiftDownBit(buf[len], 7);
4500 field().cl() = BITSTRING(1, &ctemp);
4501 ctemp = ShiftDownBit(buf[len], 6);
4502 field().aseq() = BITSTRING(1, &ctemp);
4503 ctemp = ShiftDownBit(buf[len], 5);
4504 field().eseq() = BITSTRING(1, &ctemp);
4505 ctemp = ShiftDownBit(buf[len], 4);
4506 field().gseq() = BITSTRING(1, &ctemp);
4507 ctemp = buf[len] & 0x0F;
4508 field().res() = BITSTRING(4, &ctemp);
4509 len += 1;
4510
4511 len +=
4512 Get_AEGSeqnum_opt(field().ah__seq(), &buf[len], *field().aseq() == 1);
4513 len +=
4514 Get_AEGSeqnum_opt(field().esp__seq(), &buf[len], *field().eseq() == 1);
4515 len +=
4516 Get_AEGSeqnum_opt(field().gre__seq(), &buf[len], *field().gseq() == 1);
4517
4518 if (*field().cl() == 1)
4519 {
4520 len += Get_Compr_head_list(field().compr__head__list(), &buf[len],
4521 Item__list::ALT_ip__item__list,
4522 dat, ip_idx);
4523 }
4524 else
4525 field().compr__head__list() = OMIT_VALUE;
4526 }
4527 else
4528 field = OMIT_VALUE;
4529
4530 Log_hexdump(buf, len);
4531 Log_function_name_on_leave();
4532
4533 return len;
4534}
4535
4536int
4537Get_Inner_IP_fields_opt(unsigned char *buf,
4538 OPTIONAL < Inner__IP__fields > &field,
4539 OPTIONAL < Inner__IP__flags > &flags,
4540 t_dat *dat, bool hasvalue)
4541{
4542 int len = 0;
4543
4544 Log_function_name_on_enter();
4545
4546 if (hasvalue)
4547 {
4548 len += Get_LIN1_opt(&buf[len], field().tos(), (*flags().tos()) == 1);
4549 len += Get_LIN1_opt(&buf[len], field().ttl(), (*flags().ttl()) == 1);
4550 len += Get_LIN1_opt(&buf[len], field().proto(), (*flags().pr()) == 1);
4551 len += Get_ipx_headers_opt(&buf[len], field().ext__heads(), dat,
4552 (*flags().ipx()) == 1, getIPidx(dat, Inner_IP));
4553 }
4554 else
4555 field = OMIT_VALUE;
4556
4557 Log_hexdump(buf, len);
4558 Log_function_name_on_leave();
4559
4560 return len;
4561}
4562
4563int
4564Get_Outer_IP_fields_opt(unsigned char *buf,
4565 OPTIONAL < Outer__IP__fields > &field,
4566 OPTIONAL < Outer__IP__flags > &flags,
4567 t_dat *dat, bool hasvalue)
4568{
4569 int len = 0;
4570
4571 Log_function_name_on_enter();
4572
4573 if (hasvalue)
4574 {
4575 len += Get_LIN1_opt(&buf[len], field().tos(), (*flags().tos2()) == 1);
4576 len += Get_LIN1_opt(&buf[len], field().ttl(), (*flags().ttl2()) == 1);
4577 len += Get_LIN1_opt(&buf[len], field().proto(), (*flags().pr2()) == 1);
4578 len += Get_ipx_headers_opt(&buf[len], field().ext__heads(), dat,
4579 (*flags().ipx2()) == 1, getIPidx(dat, Outer_IP));
4580 len += Get_LIN2_BO_LAST_opt(&buf[len], field().ip__id(),
4581 (*flags().i2__bit()) == 1);
4582 }
4583 else
4584 field = OMIT_VALUE;
4585
4586 Log_hexdump(buf, len);
4587 Log_function_name_on_leave();
4588
4589 return len;
4590}
4591
4592int
4593Get_RTP_flags_fields_opt(unsigned char *buf,
4594 OPTIONAL < RTP__flags__fields > &field,
4595 t_dat *dat, bool hasvalue)
4596{
4597 int len = 0;
4598 unsigned char ctemp;
4599
4600 Log_function_name_on_enter();
4601
4602 if (hasvalue)
4603 {
4604 field().mode() = (buf[len] >> 6) & 0x03;
4605 ctemp = ShiftDownBit(buf[len], 5);
4606 field().r__pt() = BITSTRING(1, &ctemp);
4607 ctemp = ShiftDownBit(buf[len], 4);
4608 field().m__bit() = BITSTRING(1, &ctemp);
4609 ctemp = ShiftDownBit(buf[len], 3);
4610 field().r__x() = BITSTRING(1, &ctemp);
4611 ctemp = ShiftDownBit(buf[len], 2);
4612 field().csrc() = BITSTRING(1, &ctemp);
4613 ctemp = ShiftDownBit(buf[len], 1);
4614 field().tss() = BITSTRING(1, &ctemp);
4615 ctemp = ShiftDownBit(buf[len], 0);
4616 field().tis() = BITSTRING(1, &ctemp);
4617 len += 1;
4618
4619 if (*field().r__pt() == 1)
4620 {
4621 ctemp = ShiftDownBit(buf[len], 7);
4622 field().flags()().r__p() = BITSTRING(1, &ctemp);
4623 field().flags()().rtp__pt() = buf[len] & 0x7F;
4624 len += 1;
4625 }
4626 else
4627 field().flags() = OMIT_VALUE;
4628
4629 if (*field().csrc() == 1)
4630 {
4631 len += Get_Compr_head_list(field().csrc__list(),
4632 &buf[len], Item__list::ALT_csrc__item__list,
4633 dat, 0);
4634 }
4635 else
4636 field().csrc__list() = OMIT_VALUE;
4637
4638 len += Get_SDVL_field_opt(&buf[len], field().ts__stride(),
4639 *field().tss() == 1);
4640 len += Get_SDVL_field_opt(&buf[len], field().time__stride(),
4641 *field().tis() == 1);
4642 }
4643 else
4644 field = OMIT_VALUE;
4645
4646 Log_hexdump(buf, len);
4647 Log_function_name_on_leave();
4648
4649 return len;
4650}
4651
4652int
4653Get_Profile0_ROHC_Header(unsigned char *buf, t_dat *dat, int length,
4654 Profile0__headers & p_header, int cid)
4655{
4656 unsigned char ctemp;
4657 int len = 0;
4658
4659 Log_function_name_on_enter();
4660
4661 if (isIR(buf[len]))
4662 {
4663 Profile0__IR__packet & bhead = p_header.ir();
4664
4665 bhead.cid() = cid;
4666 ctemp = (buf[len] >> 1) & 0x7F;
4667 bhead.type__ind() = BITSTRING(7, &ctemp);
4668 ctemp = ShiftDownBit(buf[len], 0);
4669 bhead.d() = BITSTRING(1, &ctemp);
4670 len += 1;
4671 len += Get_LIN1(&buf[len], bhead.profile());
4672 dat->context.profile() = bhead.profile();
4673 len += Get_LIN1(&buf[len], bhead.crc());
4674 Get_octetstring(&buf[len], bhead.orig__packet(), length - len);
4675 len = length;
4676 }
4677 else
4678 {
4679 Profile0__normal__packet & bhead = p_header.normal();
4680 bhead.cid() = cid;
4681 Get_octetstring(&buf[len], bhead.orig__packet(), length - len);
4682 len = length;
4683 }
4684
4685 Log_hexdump(buf, len);
4686 Log_function_name_on_leave();
4687
4688 return len;
4689}
4690
4691int
4692Get_Profile1_Dynamic_Chain(Dynamic__Chain & dynch,
4693 const unsigned char *buf, t_dat *dat)
4694{
4695 int len = 0, num;
4696
4697 Log_function_name_on_enter();
4698
4699 for (num = 0; num < dat->context.ip__ctx().size_of(); num++)
4700 {
4701 if (dat->context.ip__ctx()[num].version() == 4)
4702 {
4703 len += Get_ipv4_dynamic(&buf[len], dynch[num].ipv4__dyn(), dat, num);
4704 }
4705 else if (dat->context.ip__ctx()[num].version() == 6)
4706 {
4707 len += Get_ipv6_dynamic(&buf[len], dynch[num].ipv6__dyn(), dat, num);
4708 }
4709 else
4710 {
4711 int ipver = dat->context.ip__ctx()[num].version();
4712 TTCN_error("Invalid IP version %u on level %d", ipver, num);
4713 }
4714 }
4715
4716 num = dynch.size_of();
4717 len += Get_udp_dynamic_wo_sn(&buf[len], dynch[num].udp__dyn(), dat);
4718
4719 num = dynch.size_of();
4720 len += Get_rtp_dynamic(&buf[len], dynch[num].rtp__dyn(), dat);
4721
4722 Log_hexdump(buf, len);
4723 Log_function_name_on_leave();
4724
4725 return len;
4726}
4727
4728int
4729Get_Profile1_Static_Chain(unsigned char *buf, Static__Chain & chain,
4730 t_dat *dat)
4731{
4732 int len = 0, num = 0, nextheader = 0;
4733
4734 Log_function_name_on_enter();
4735
4736 while (nextheader != c__ip__proto__udp)
4737 {
4738 if (((buf[len] >> 4) & 0x0F) == 4)
4739 {
4740 initIPcontext(dat, num, 4);
4741 len += Get_ipv4_static(&buf[len], chain[num].ipv4__stat());
4742 nextheader = chain[num].ipv4__stat().proto();
4743 }
4744 else if (((buf[len] >> 4) & 0x0F) == 6)
4745 {
4746 initIPcontext(dat, num, 6);
4747 len += Get_ipv6_static(&buf[len], chain[num].ipv6__stat());
4748 nextheader = chain[num].ipv6__stat().nexthead();
4749 }
4750 else
4751 {
4752 TTCN_error("Invalid IP version %u on level %u (nextheader = %d)",
4753 buf[len], num, nextheader);
4754 }
4755 num += 1;
4756 }
4757
4758 len += Get_udp_static(&buf[len], chain[num].udp__stat());
4759 num += 1;
4760
4761 len += Get_rtp_static(&buf[len], chain[num].rtp__stat());
4762
4763 Log_hexdump(buf, len);
4764 Log_function_name_on_leave();
4765
4766 return len;
4767}
4768
4769int
4770Get_Profile1_extension0(unsigned char *buf, Extension0 & ext,
4771 t_dat *dat)
4772{
4773 int len = 0;
4774 unsigned char ctemp;
4775
4776 Log_function_name_on_enter();
4777
4778 ctemp = (buf[len] >> 6) & 0x03;
4779 ext.ext__type() = BITSTRING(2, &ctemp);
4780 ext.sn() = (buf[len] >> 3) & 0x07;
4781 ext.plust() = buf[len] & 0x07;
4782 len += 1;
4783
4784 Log_hexdump(buf, len);
4785 Log_function_name_on_leave();
4786
4787 return len;
4788}
4789
4790int
4791Get_Profile1_extension1(unsigned char *buf, Extension1 & ext,
4792 t_dat *dat)
4793{
4794 int len = 0;
4795 unsigned char ctemp;
4796
4797 Log_function_name_on_enter();
4798
4799 ctemp = (buf[len] >> 6) & 0x03;
4800 ext.ext__type() = BITSTRING(2, &ctemp);
4801 ext.sn() = (buf[len] >> 3) & 0x07;
4802 ext.plust() = buf[len] & 0x07;
4803 len += 1;
4804 ext.minust() = buf[len];
4805 len += 1;
4806
4807 Log_hexdump(buf, len);
4808 Log_function_name_on_leave();
4809
4810 return len;
4811}
4812
4813int
4814Get_Profile1_extension2(unsigned char *buf, Extension2 & ext,
4815 t_dat *dat)
4816{
4817 int len = 0;
4818 unsigned char ctemp;
4819
4820 Log_function_name_on_enter();
4821
4822 ctemp = (buf[len] >> 6) & 0x03;
4823 ext.ext__type() = BITSTRING(2, &ctemp);
4824 ext.sn() = (buf[len] >> 3) & 0x07;
4825 ext.plust() = ((buf[len] & 0x07) << 8) + (buf[len + 1] & 0xFF);
4826 len += 2;
4827 ext.minust() = buf[len];
4828 len += 1;
4829
4830 Log_hexdump(buf, len);
4831 Log_function_name_on_leave();
4832
4833 return len;
4834}
4835
4836int
4837Get_Profile1_extension3(unsigned char *buf, Extension3 & ext,
4838 t_dat *dat)
4839{
4840 int len = 0;
4841 int ts_length = 0;
4842 unsigned char ctemp;
4843
4844 Log_function_name_on_enter();
4845
4846 ctemp = (buf[len] >> 6) & 0x03;
4847 ext.ext__type() = BITSTRING(2, &ctemp);
4848 ctemp = ShiftDownBit(buf[len], 5);
4849 ext.s__bit() = BITSTRING(1, &ctemp);
4850 ctemp = ShiftDownBit(buf[len], 4);
4851 ext.r__ts__bit() = BITSTRING(1, &ctemp);
4852 ctemp = ShiftDownBit(buf[len], 3);
4853 ext.tsc__bit() = BITSTRING(1, &ctemp);
4854 ctemp = ShiftDownBit(buf[len], 2);
4855 ext.i__bit() = BITSTRING(1, &ctemp);
4856 ctemp = ShiftDownBit(buf[len], 1);
4857 ext.ip__bit() = BITSTRING(1, &ctemp);
4858 ctemp = ShiftDownBit(buf[len], 0);
4859 ext.rtp__bit() = BITSTRING(1, &ctemp);
4860 len += 1;
4861
4862 len += Get_Inner_IP_flags_opt(&buf[len], ext.inner__ip__flags(),
4863 dat, *ext.ip__bit() == 1);
4864
4865 len += Get_Outer_IP_flags_opt(&buf[len], ext.outer__ip__flags(), dat,
4866 (ext.inner__ip__flags().ispresent() &&
4867 (*ext.inner__ip__flags()().ip2__bit()) == 1));
4868
4869 len += Get_LIN1_opt(&buf[len], ext.sn(), *ext.s__bit() == 1);
4870 ts_length = Get_SDVL_field_opt(&buf[len], ext.ts(), *ext.r__ts__bit() == 1);
4871 if (ts_length > 0)
4872 {
4873 ext.ts__length()() = ts_length;
4874 }
4875 else
4876 {
4877 ext.ts__length() = OMIT_VALUE;
4878 }
4879 len += ts_length;
4880 len += Get_Inner_IP_fields_opt(&buf[len], ext.inner__ip__hdr(),
4881 ext.inner__ip__flags(), dat,
4882 *ext.ip__bit() == 1);
4883
4884 len += Get_LIN2_BO_LAST_opt(&buf[len], ext.ip__id(), *ext.i__bit() == 1);
4885 len += Get_Outer_IP_fields_opt(&buf[len], ext.outer__ip__hdr(),
4886 ext.outer__ip__flags(), dat,
4887 (ext.inner__ip__flags().ispresent() &&
4888 (*ext.inner__ip__flags()().ip2__bit()) == 1));
4889
4890 len += Get_RTP_flags_fields_opt(&buf[len], ext.rtp__fl__fi(), dat,
4891 *ext.rtp__bit() == 1);
4892
4893 Log_hexdump(buf, len);
4894 Log_function_name_on_leave();
4895
4896 return len;
4897}
4898
4899int
4900Get_Profile1_extensions_opt(unsigned char *buf,
4901 OPTIONAL < Profile1__Extension > &ext,
4902 t_dat *dat, bool hasvalue)
4903{
4904 int len = 0;
4905
4906 Log_function_name_on_enter();
4907
4908 if (hasvalue)
4909 {
4910 if ((buf[len] & 0xC0) == 0)
4911 {
4912 len += Get_Profile1_extension0(&buf[len], ext().ext0(), dat);
4913 }
4914 else if ((buf[len] & 0xC0) == 0x40)
4915 {
4916 len += Get_Profile1_extension1(&buf[len], ext().ext1(), dat);
4917 }
4918 else if ((buf[len] & 0xC0) == 0x80)
4919 {
4920 len += Get_Profile1_extension2(&buf[len], ext().ext2(), dat);
4921 }
4922 else /* if ((buf[len] & 0xC0) == 0xC0) */
4923 {
4924 len += Get_Profile1_extension3(&buf[len], ext().ext3(), dat);
4925 }
4926 }
4927 else
4928 {
4929 ext = OMIT_VALUE;
4930 }
4931
4932 Log_hexdump(buf, len);
4933 Log_function_name_on_leave();
4934
4935 return len;
4936}
4937
4938int
4939Get_Profile1_ROHC_Header_ir(unsigned char *buf, Profile1__IR__header & bhead,
4940 t_dat *dat, int cid)
4941{
4942 int len = 0;
4943 unsigned char ctemp;
4944
4945 Log_function_name_on_enter();
4946
4947 dat->context.pkt() = Packet__type(Packet__type::IR);
4948 bhead.cid() = cid;
4949 ctemp = (buf[len] >> 1) & 0x7F;
4950 bhead.type__ind() = BITSTRING(7, &ctemp);
4951 ctemp = ShiftDownBit(buf[len], 0);
4952 bhead.d() = BITSTRING(1, &ctemp);
4953 len += 1;
4954
4955 len += Get_LIN1(&buf[len], bhead.profile());
4956 dat->context.profile() = bhead.profile();
4957 len += Get_LIN1(&buf[len], bhead.crc());
4958
4959 len += Get_Profile1_Static_Chain(&buf[len], bhead.stat__chain(), dat);
4960
4961 if (*bhead.d() == 1)
4962 len += Get_Profile1_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
4963 else
4964 bhead.dyn__chain() = OMIT_VALUE;
4965
4966 Log_hexdump(buf, len);
4967 Log_function_name_on_leave();
4968
4969 return len;
4970}
4971
4972int
4973Get_Profile1_ROHC_Header_irdyn(unsigned char *buf,
4974 Profile1__IR__DYN__header & bhead,
4975 t_dat *dat, int cid)
4976{
4977 int len = 0;
4978
4979 Log_function_name_on_enter();
4980
4981 dat->context.pkt() = Packet__type(Packet__type::IR__DYN);
4982 bhead.cid() = cid;
4983 bhead.type__ind() = BITSTRING(8, &buf[len]);
4984 len += 1;
4985 len += Get_LIN1(&buf[len], bhead.profile());
4986 dat->context.profile() = bhead.profile();
4987 len += Get_LIN1(&buf[len], bhead.crc());
4988
4989 len += Get_Profile1_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
4990
4991 Log_hexdump(buf, len);
4992 Log_function_name_on_leave();
4993
4994 return len;
4995}
4996
4997int
4998Get_Profile1_ROHC_Header_r0(unsigned char *buf,
4999 Profile1__R__0__header & bhead,
5000 t_dat *dat, int cid)
5001{
5002 int len = 0;
5003 unsigned char ctemp;
5004
5005 Log_function_name_on_enter();
5006
5007 dat->context.pkt() = Packet__type(Packet__type::R__0);
5008
5009 bhead.cid() = cid;
5010 ctemp = (buf[len] >> 6) & 0x03;
5011 bhead.type__ind() = BITSTRING(2, &ctemp);
5012 bhead.sn() = buf[len] & 0x3F;
5013 len += 1;
5014
5015 Log_hexdump(buf, len);
5016 Log_function_name_on_leave();
5017
5018 return len;
5019}
5020
5021int
5022Get_Profile1_ROHC_Header_r0crc(unsigned char *buf,
5023 Profile1__R__0__CRC__header & bhead,
5024 t_dat *dat, int cid)
5025{
5026 int len = 0;
5027 unsigned char ctemp;
5028
5029 Log_function_name_on_enter();
5030
5031 dat->context.pkt() = Packet__type(Packet__type::R__0__CRC);
5032
5033 bhead.cid() = cid;
5034 ctemp = (buf[len] >> 6) & 0x03;
5035 bhead.type__ind() = BITSTRING(2, &ctemp);
5036 ctemp = (buf[len] << 1) & 0x7E;
5037 len += 1;
5038 ctemp += ShiftDownBit(buf[len], 7);
5039 bhead.sn() = ctemp;
5040 bhead.crc() = buf[len] & 0x7F;
5041 len += 1;
5042
5043 Log_hexdump(buf, len);
5044 Log_function_name_on_leave();
5045
5046 return len;
5047}
5048
5049int
5050Get_Profile1_ROHC_Header_uo0(unsigned char *buf,
5051 Profile1__UO__0__header & bhead,
5052 t_dat *dat, int cid)
5053{
5054 int len = 0;
5055 unsigned char ctemp;
5056
5057 Log_function_name_on_enter();
5058
5059 dat->context.pkt() = Packet__type(Packet__type::UO__0);
5060 bhead.cid() = cid;
5061 ctemp = ShiftDownBit(buf[len], 7);
5062 bhead.type__ind() = BITSTRING(1, &ctemp);
5063 bhead.sn() = (buf[len] >> 3) & 0x0F;
5064 bhead.crc() = buf[len] & 0x07;
5065 len += 1;
5066
5067 Log_hexdump(buf, len);
5068 Log_function_name_on_leave();
5069
5070 return len;
5071}
5072
5073int
5074Get_Profile1_ROHC_Header_r1(unsigned char *buf,
5075 Profile1__R__1__header & bhead,
5076 t_dat *dat, int cid,
5077 OPTIONAL < Profile1__Extension > &ext)
5078{
5079 int len = 0;
5080 unsigned char ctemp;
5081
5082 Log_function_name_on_enter();
5083
5084 dat->context.pkt() = Packet__type(Packet__type::R__1);
5085 bhead.cid() = cid;
5086 ctemp = (buf[len] >> 6) & 0x03;
5087 bhead.type__ind() = BITSTRING(2, &ctemp);
5088 bhead.sn() = buf[len] & 0x3F;
5089 len += 1;
5090 ctemp = ShiftDownBit(buf[len], 7);
5091 bhead.m__bit() = BITSTRING(1, &ctemp);
5092 ctemp = ShiftDownBit(buf[len], 6);
5093 bhead.x__bit() = BITSTRING(1, &ctemp);
5094 bhead.ts() = buf[len] & 0x3F;
5095 len += 1;
5096
5097 if (*bhead.x__bit())
5098 {
5099 len += Get_Profile1_extensions_opt(&buf[len], ext, dat,
5100 *bhead.x__bit());
5101 }
5102
5103 Log_hexdump(buf, len);
5104 Log_function_name_on_leave();
5105
5106 return len;
5107}
5108
5109int
5110Get_Profile1_ROHC_Header_r1_id(unsigned char *buf,
5111 Profile1__R__1__ID__header & bhead,
5112 t_dat *dat, int cid,
5113 OPTIONAL < Profile1__Extension > &ext)
5114{
5115 int len = 0;
5116 unsigned char ctemp;
5117
5118 Log_function_name_on_enter();
5119
5120 dat->context.pkt() = Packet__type(Packet__type::R__1__ID);
5121 bhead.cid() = cid;
5122 ctemp = (buf[len] >> 6) & 0x03;
5123 bhead.type__ind() = BITSTRING(2, &ctemp);
5124 bhead.sn() = buf[len] & 0x3F;
5125 len += 1;
5126 ctemp = ShiftDownBit(buf[len], 7);
5127 bhead.m__bit() = BITSTRING(1, &ctemp);
5128 ctemp = ShiftDownBit(buf[len], 6);
5129 bhead.x__bit() = BITSTRING(1, &ctemp);
5130 ctemp = ShiftDownBit(buf[len], 5);
5131 bhead.t__bit() = BITSTRING(1, &ctemp);
5132 bhead.ip__id() = buf[len] & 0x1F;
5133 len += 1;
5134
5135 if (*bhead.x__bit())
5136 {
5137 len += Get_Profile1_extensions_opt(&buf[len], ext, dat,
5138 *bhead.x__bit());
5139 }
5140
5141 Log_hexdump(buf, len);
5142 Log_function_name_on_leave();
5143
5144 return len;
5145}
5146
5147int
5148Get_Profile1_ROHC_Header_r1_ts(unsigned char *buf,
5149 Profile1__R__1__TS__header & bhead,
5150 t_dat *dat, int cid,
5151 OPTIONAL < Profile1__Extension > &ext)
5152{
5153 int len = 0;
5154 unsigned char ctemp;
5155
5156 Log_function_name_on_enter();
5157
5158 dat->context.pkt() = Packet__type(Packet__type::R__1__TS);
5159 bhead.cid() = cid;
5160 ctemp = (buf[len] >> 6) & 0x03;
5161 bhead.type__ind() = BITSTRING(2, &ctemp);
5162 bhead.sn() = buf[len] & 0x3F;
5163 len += 1;
5164 ctemp = ShiftDownBit(buf[len], 7);
5165 bhead.m__bit() = BITSTRING(1, &ctemp);
5166 ctemp = ShiftDownBit(buf[len], 6);
5167 bhead.x__bit() = BITSTRING(1, &ctemp);
5168 ctemp = ShiftDownBit(buf[len], 5);
5169 bhead.t__bit() = BITSTRING(1, &ctemp);
5170 bhead.ts() = buf[len] & 0x1F;
5171 len += 1;
5172
5173 if (*bhead.x__bit())
5174 {
5175 len += Get_Profile1_extensions_opt(&buf[len], ext, dat,
5176 *bhead.x__bit());
5177 }
5178
5179 Log_hexdump(buf, len);
5180 Log_function_name_on_leave();
5181
5182 return len;
5183}
5184
5185int
5186Get_Profile1_ROHC_Header_uo1(unsigned char *buf,
5187 Profile1__UO__1__header & bhead,
5188 t_dat *dat, int cid)
5189{
5190 int len = 0;
5191 unsigned char ctemp;
5192
5193 Log_function_name_on_enter();
5194
5195 dat->context.pkt() = Packet__type(Packet__type::UO__1);
5196 bhead.cid() = cid;
5197 ctemp = (buf[len] >> 6) & 0x03;
5198 bhead.type__ind() = BITSTRING(2, &ctemp);
5199 bhead.ts() = buf[len] & 0x3F;
5200 len += 1;
5201 ctemp = ShiftDownBit(buf[len], 7);
5202 bhead.m__bit() = BITSTRING(1, &ctemp);
5203 bhead.sn() = (buf[len] >> 3) & 0x0F;
5204 bhead.crc() = buf[len] & 0x07;
5205 len += 1;
5206
5207 Log_hexdump(buf, len);
5208 Log_function_name_on_leave();
5209
5210 return len;
5211}
5212
5213int
5214Get_Profile1_ROHC_Header_uo1_id(unsigned char *buf,
5215 Profile1__UO__1__ID__header & bhead,
5216 t_dat *dat, int cid,
5217 OPTIONAL < Profile1__Extension > &ext)
5218{
5219 int len = 0;
5220 unsigned char ctemp;
5221
5222 Log_function_name_on_enter();
5223
5224 dat->context.pkt() = Packet__type(Packet__type::UO__1__ID);
5225 bhead.cid() = cid;
5226 ctemp = (buf[len] >> 6) & 0x03;
5227 bhead.type__ind() = BITSTRING(2, &ctemp);
5228 ctemp = ShiftDownBit(buf[len], 5);
5229 bhead.t__bit() = BITSTRING(1, &ctemp);
5230 bhead.ip__id() = buf[len] & 0x1F;
5231 len += 1;
5232 ctemp = ShiftDownBit(buf[len], 7);
5233 bhead.x__bit() = BITSTRING(1, &ctemp);
5234 bhead.sn() = (buf[len] >> 3) & 0x0F;
5235 bhead.crc() = buf[len] & 0x07;
5236 len += 1;
5237
5238 if (*bhead.x__bit())
5239 {
5240 len += Get_Profile1_extensions_opt(&buf[len], ext,
5241 dat, *bhead.x__bit());
5242 }
5243
5244 Log_hexdump(buf, len);
5245 Log_function_name_on_leave();
5246
5247 return len;
5248}
5249
5250int
5251Get_Profile1_ROHC_Header_uo1_ts(unsigned char *buf,
5252 Profile1__UO__1__TS__header & bhead,
5253 t_dat *dat, int cid)
5254{
5255 int len = 0;
5256 unsigned char ctemp;
5257
5258 Log_function_name_on_enter();
5259
5260 dat->context.pkt() = Packet__type(Packet__type::UO__1__TS);
5261 bhead.cid() = cid;
5262 ctemp = (buf[len] >> 6) & 0x03;
5263 bhead.type__ind() = BITSTRING(2, &ctemp);
5264 ctemp = ShiftDownBit(buf[len], 5);
5265 bhead.t__bit() = BITSTRING(1, &ctemp);
5266 bhead.ts() = buf[len] & 0x1F;
5267 len += 1;
5268 ctemp = ShiftDownBit(buf[len], 7);
5269 bhead.m__bit() = BITSTRING(1, &ctemp);
5270 bhead.sn() = (buf[len] >> 3) & 0x0F;
5271 bhead.crc() = buf[len] & 0x07;
5272 len += 1;
5273
5274 Log_hexdump(buf, len);
5275 Log_function_name_on_leave();
5276
5277 return len;
5278}
5279
5280int
5281Get_Profile1_ROHC_Header_uor2(unsigned char *buf,
5282 Profile1__UOR__2__header & bhead,
5283 t_dat *dat, int cid,
5284 OPTIONAL < Profile1__Extension > &ext)
5285{
5286 int len = 0;
5287 unsigned char ctemp;
5288
5289 Log_function_name_on_enter();
5290
5291 dat->context.pkt() = Packet__type(Packet__type::UOR__2);
5292 bhead.cid() = cid;
5293 ctemp = (buf[len] >> 5) & 0x07;
5294 bhead.type__ind() = BITSTRING(3, &ctemp);
5295 ctemp = (buf[len] & 0x1F) << 1;
5296 len += 1;
5297 ctemp += ShiftDownBit(buf[len], 7);
5298 bhead.ts() = ctemp;
5299 ctemp = ShiftDownBit(buf[len], 6);
5300 bhead.m__bit() = BITSTRING(1, &ctemp);
5301 bhead.sn() = buf[len] & 0x3F;
5302 len += 1;
5303 ctemp = ShiftDownBit(buf[len], 7);
5304 bhead.x__bit() = BITSTRING(1, &ctemp);
5305 bhead.crc() = buf[len] & 0x7F;
5306 len += 1;
5307
5308 if (*bhead.x__bit())
5309 {
5310 len += Get_Profile1_extensions_opt(&buf[len], ext,
5311 dat, *bhead.x__bit());
5312 }
5313
5314 Log_hexdump(buf, len);
5315 Log_function_name_on_leave();
5316
5317 return len;
5318}
5319
5320int
5321Get_Profile1_ROHC_Header_uor2_id(unsigned char *buf,
5322 Profile1__UOR__2__ID__header & bhead,
5323 t_dat *dat, int cid,
5324 OPTIONAL < Profile1__Extension > & ext)
5325{
5326 int len = 0;
5327 unsigned char ctemp;
5328
5329 Log_function_name_on_enter();
5330
5331 dat->context.pkt() = Packet__type(Packet__type::UOR__2__ID);
5332 bhead.cid() = cid;
5333 ctemp = (buf[len] >> 5) & 0x07;
5334 bhead.type__ind() = BITSTRING(3, &ctemp);
5335 bhead.ip__id() = buf[len] & 0x1F;
5336 len += 1;
5337 ctemp = ShiftDownBit(buf[len], 7);
5338 bhead.t__bit() = BITSTRING(1, &ctemp);
5339 ctemp = ShiftDownBit(buf[len], 6);
5340 bhead.m__bit() = BITSTRING(1, &ctemp);
5341 bhead.sn() = buf[len] & 0x3F;
5342 len += 1;
5343 ctemp = ShiftDownBit(buf[len], 7);
5344 bhead.x__bit() = BITSTRING(1, &ctemp);
5345 bhead.crc() = buf[len] & 0x7F;
5346 len += 1;
5347
5348 if (*bhead.x__bit())
5349 {
5350 len += Get_Profile1_extensions_opt(&buf[len], ext,
5351 dat, *bhead.x__bit());
5352 }
5353
5354 Log_hexdump(buf, len);
5355 Log_function_name_on_leave();
5356
5357 return len;
5358}
5359
5360int
5361Get_Profile1_ROHC_Header_uor2_ts(unsigned char *buf,
5362 Profile1__UOR__2__TS__header & bhead,
5363 t_dat *dat, int cid,
5364 OPTIONAL < Profile1__Extension > & ext)
5365{
5366 int len = 0;
5367 unsigned char ctemp;
5368
5369 Log_function_name_on_enter();
5370
5371 dat->context.pkt() = Packet__type(Packet__type::UOR__2__TS);
5372 bhead.cid() = cid;
5373 ctemp = (buf[len] >> 5) & 0x07;
5374 bhead.type__ind() = BITSTRING(3, &ctemp);
5375 bhead.ts() = buf[len] & 0x1F;
5376 len += 1;
5377 ctemp = ShiftDownBit(buf[len], 7);
5378 bhead.t__bit() = BITSTRING(1, &ctemp);
5379 ctemp = ShiftDownBit(buf[len], 6);
5380 bhead.m__bit() = BITSTRING(1, &ctemp);
5381 bhead.sn() = buf[len] & 0x3F;
5382 len += 1;
5383 ctemp = ShiftDownBit(buf[len], 7);
5384 bhead.x__bit() = BITSTRING(1, &ctemp);
5385 bhead.crc() = buf[len] & 0x7F;
5386 len += 1;
5387
5388 if (*bhead.x__bit())
5389 {
5390 len += Get_Profile1_extensions_opt(&buf[len], ext,
5391 dat, *bhead.x__bit());
5392 }
5393
5394 Log_hexdump(buf, len);
5395 Log_function_name_on_leave();
5396
5397 return len;
5398}
5399
5400int
5401Get_Profile1_ROHC_Header(unsigned char *buf, t_dat *dat, int length,
5402 Profile1__headers & hdr, int cid)
5403{
5404 int len = 0;
5405
5406 Log_function_name_on_enter();
5407
5408 if (isIR(buf[len]))
5409 {
5410 len += Get_Profile1_ROHC_Header_ir(&buf[len],
5411 hdr.base__header().ir(), dat, cid);
5412 }
5413 else if (isIRDYN(buf[len]))
5414 {
5415 len += Get_Profile1_ROHC_Header_irdyn(&buf[len],
5416 hdr.base__header().ir__dyn(),
5417 dat, cid);
5418 }
5419 else if (isUOR2(buf[len]))
5420 {
5421 if (isAnyIPv4RNDunset(dat))
5422 {
5423 if (buf[len + 1] & 0x80) // T = 1
5424 {
5425 len += Get_Profile1_ROHC_Header_uor2_ts(&buf[len],
5426 hdr.base__header().
5427 uor__2__ts(), dat, cid,
5428 hdr.ext());
5429 }
5430 else // T = 0
5431 {
5432 len += Get_Profile1_ROHC_Header_uor2_id(&buf[len],
5433 hdr.base__header().
5434 uor__2__id(), dat, cid,
5435 hdr.ext());
5436 }
5437 }
5438 else // at least one RND is unset
5439 {
5440 len += Get_Profile1_ROHC_Header_uor2(&buf[len],
5441 hdr.base__header().uor__2(),
5442 dat, cid, hdr.ext());
5443 }
5444 }
5445 else if (dat->context.mode() == ROHC_mode_R)
5446 {
5447 if ((buf[len] & 0xC0) == 0)
5448 {
5449 len += Get_Profile1_ROHC_Header_r0(&buf[len],
5450 hdr.base__header().r__0(),
5451 dat, cid);
5452 }
5453 else if ((buf[len] & 0xC0) == 0x40)
5454 {
5455 len += Get_Profile1_ROHC_Header_r0crc(&buf[len],
5456 hdr.base__header().r__0__crc(),
5457 dat, cid);
5458 }
5459 else if ((buf[len] & 0xC0) == 0x80) // PT-1
5460 {
5461 if (isAnyIPv4RNDunset(dat))
5462 {
5463 if (buf[len + 1] & 0x20) // T = 1
5464 {
5465 len += Get_Profile1_ROHC_Header_r1_ts(&buf[len],
5466 hdr.base__header().r__1__ts(),
5467 dat, cid, hdr.ext());
5468 }
5469 else // T = 0
5470 {
5471 len += Get_Profile1_ROHC_Header_r1_id(&buf[len],
5472 hdr.base__header().r__1__id(),
5473 dat, cid, hdr.ext());
5474 }
5475 }
5476 else // at least one RND is unset
5477 {
5478 len += Get_Profile1_ROHC_Header_r1(&buf[len],
5479 hdr.base__header().r__1(),
5480 dat, cid, hdr.ext());
5481 }
5482 }
5483 }
5484 else if (dat->context.mode() != ROHC_mode_R) // U-O modes
5485 {
5486 if ((buf[len] & 0x80) == 0)
5487 {
5488 len += Get_Profile1_ROHC_Header_uo0(&buf[len],
5489 hdr.base__header().uo__0(),
5490 dat, cid);
5491 }
5492 else if ((buf[len] & 0xC0) == 0x80) // PT-1
5493 {
5494 if (isAnyIPv4RNDunset(dat))
5495 {
5496 if (buf[len] & 0x20) // T = 1
5497 {
5498 len += Get_Profile1_ROHC_Header_uo1_ts(&buf[len],
5499 hdr.base__header().uo__1__ts(),
5500 dat, cid);
5501 }
5502 else // T = 0
5503 {
5504 len += Get_Profile1_ROHC_Header_uo1_id(&buf[len],
5505 hdr.base__header().uo__1__id(),
5506 dat, cid, hdr.ext());
5507 }
5508 }
5509 else // at least one RND is unset
5510 {
5511 len += Get_Profile1_ROHC_Header_uo1(&buf[len],
5512 hdr.base__header().uo__1(),
5513 dat, cid);
5514 }
5515 }
5516 }
5517
5518 if (!hdr.ext().is_bound())
5519 hdr.ext() = OMIT_VALUE;
5520 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__outer(),
5521 dat, Outer_IP);
5522 len += Get_AH_data_opt(&buf[len], hdr.ah__outer(), dat, Outer_IP);
5523 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum1(), dat, Outer_IP);
5524 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__inner(),
5525 dat, Inner_IP);
5526 len += Get_AH_data_opt(&buf[len], hdr.ah__inner(), dat, Inner_IP);
5527 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum2(), dat, Inner_IP);
5528 len += Get_UDP_cksum_opt(&buf[len], hdr.udp__cksum(), dat);
5529
5530 Log_hexdump(buf, len);
5531 Log_function_name_on_leave();
5532
5533 return len;
5534} /* Get_Profile1_ROHC_Header */
5535
5536int
5537Get_Profile2_Dynamic_Chain(Profile2__Dynamic__Chain & dynch,
5538 const unsigned char *buf, t_dat *dat)
5539{
5540 int len = 0, num;
5541
5542 Log_function_name_on_enter();
5543
5544 for (num = 0; num < dat->context.ip__ctx().size_of(); num++)
5545 {
5546 if (dat->context.ip__ctx()[num].version() == 4)
5547 {
5548 len += Get_ipv4_dynamic(&buf[len], dynch[num].ipv4__dyn(), dat, num);
5549 }
5550 else if (dat->context.ip__ctx()[num].version() == 6)
5551 {
5552 len += Get_ipv6_dynamic(&buf[len], dynch[num].ipv6__dyn(), dat, num);
5553 }
5554 else
5555 {
5556 int ipver = dat->context.ip__ctx()[num].version();
5557 TTCN_error("Invalid IP version %u on level %d", ipver, num);
5558 }
5559 }
5560
5561 num = dynch.size_of();
5562 len += Get_udp_dynamic_w_sn(&buf[len], dynch[num].udp__dyn(), dat);
5563
5564 Log_hexdump(buf, len);
5565 Log_function_name_on_leave();
5566
5567 return len;
5568}
5569
5570int
5571Get_Profile2_extension0(unsigned char *buf, Profile2__Extension0 & ext,
5572 t_dat *dat)
5573{
5574 int len = 0;
5575 unsigned char ctemp;
5576
5577 Log_function_name_on_enter();
5578
5579 ctemp = (buf[len] >> 6) & 0x03;
5580 ext.ext__type() = BITSTRING(2, &ctemp);
5581 ext.sn() = (buf[len] >> 3) & 0x07;
5582 ext.ip__id() = buf[len] & 0x07;
5583 len += 1;
5584
5585 Log_hexdump(buf, len);
5586 Log_function_name_on_leave();
5587
5588 return len;
5589}
5590
5591int
5592Get_Profile2_extension1(unsigned char *buf, Profile2__Extension1 & ext,
5593 t_dat *dat)
5594{
5595 int len = 0;
5596 unsigned char ctemp;
5597
5598 Log_function_name_on_enter();
5599
5600 ctemp = (buf[len] >> 6) & 0x03;
5601 ext.ext__type() = BITSTRING(2, &ctemp);
5602 ext.sn() = (buf[len] >> 3) & 0x07;
5603 ext.ip__id() = ((buf[len] & 0x07) << 8) + (buf[len + 1] & 0xFF);
5604 len += 2;
5605
5606 Log_hexdump(buf, len);
5607 Log_function_name_on_leave();
5608
5609 return len;
5610}
5611
5612int
5613Get_Profile2_extension2(unsigned char *buf, Profile2__Extension2 & ext,
5614 t_dat *dat)
5615{
5616 int len = 0;
5617 unsigned char ctemp;
5618
5619 Log_function_name_on_enter();
5620
5621 ctemp = (buf[len] >> 6) & 0x03;
5622 ext.ext__type() = BITSTRING(2, &ctemp);
5623 ext.sn() = (buf[len] >> 3) & 0x07;
5624 ext.ip__id2() = ((buf[len] & 0x07) << 8) + (buf[len + 1] & 0xFF);
5625 len += 2;
5626 ext.ip__id() = buf[len];
5627 len += 1;
5628
5629 Log_hexdump(buf, len);
5630 Log_function_name_on_leave();
5631
5632 return len;
5633}
5634
5635int
5636Get_Profile2_Inner_IP_flags_opt(unsigned char *buf,
5637 OPTIONAL < Profile2__Inner__IP__flags > &field,
5638 t_dat *dat, bool hasvalue)
5639{
5640 int len = 0;
5641 unsigned char ctemp;
5642
5643 Log_function_name_on_enter();
5644
5645 if (hasvalue)
5646 {
5647 ctemp = ShiftDownBit(buf[len], 7);
5648 field().tos() = BITSTRING(1, &ctemp);
5649 ctemp = ShiftDownBit(buf[len], 6);
5650 field().ttl() = BITSTRING(1, &ctemp);
5651 ctemp = ShiftDownBit(buf[len], 5);
5652 field().df() = BITSTRING(1, &ctemp);
5653 ctemp = ShiftDownBit(buf[len], 4);
5654 field().pr() = BITSTRING(1, &ctemp);
5655 ctemp = ShiftDownBit(buf[len], 3);
5656 field().ipx() = BITSTRING(1, &ctemp);
5657 ctemp = ShiftDownBit(buf[len], 2);
5658 field().nbo() = BITSTRING(1, &ctemp);
5659 ctemp = ShiftDownBit(buf[len], 1);
5660 field().rnd__bit() = BITSTRING(1, &ctemp);
5661 dat->context.ip__ctx()[getIPidx(dat, Inner_IP)].rnd__bit() = BOOLEAN(ctemp);
5662 ctemp = ShiftDownBit(buf[len], 0);
5663 field().reserved() = BITSTRING(1, &ctemp);
5664 len += 1;
5665 }
5666 else
5667 field = OMIT_VALUE;
5668
5669 Log_hexdump(buf, len);
5670 Log_function_name_on_leave();
5671
5672 return len;
5673}
5674
5675int
5676Get_Profile2_Inner_IP_fields_opt(unsigned char *buf,
5677 OPTIONAL < Inner__IP__fields > &field,
5678 OPTIONAL < Profile2__Inner__IP__flags >
5679 &flags, t_dat *dat,
5680 bool hasvalue)
5681{
5682 int len = 0;
5683
5684 Log_function_name_on_enter();
5685
5686 if (hasvalue)
5687 {
5688 len += Get_LIN1_opt(&buf[len], field().tos(), (*flags().tos()) == 1);
5689 len += Get_LIN1_opt(&buf[len], field().ttl(), (*flags().ttl()) == 1);
5690 len += Get_LIN1_opt(&buf[len], field().proto(), (*flags().pr()) == 1);
5691 len += Get_ipx_headers_opt(&buf[len], field().ext__heads(), dat,
5692 (*flags().ipx()) == 1, getIPidx(dat, Inner_IP));
5693 }
5694 else
5695 field = OMIT_VALUE;
5696
5697 Log_hexdump(buf, len);
5698 Log_function_name_on_leave();
5699
5700 return len;
5701}
5702
5703int
5704Get_Profile2_extension3(unsigned char *buf, Profile2__Extension3 & ext,
5705 t_dat *dat)
5706{
5707 int len = 0;
5708 unsigned char ctemp;
5709
5710 Profile2__Inner__IP__flags inipflags;
5711
5712 Log_function_name_on_enter();
5713
5714 ctemp = (buf[len] >> 6) & 0x03;
5715 ext.ext__type() = BITSTRING(2, &ctemp);
5716 ctemp = ShiftDownBit(buf[len], 5);
5717 ext.s__bit() = BITSTRING(1, &ctemp);
5718 ext.mode() = (buf[len] >> 3) & 0x03;
5719 ctemp = ShiftDownBit(buf[len], 2);
5720 ext.i__bit() = BITSTRING(1, &ctemp);
5721 ctemp = ShiftDownBit(buf[len], 1);
5722 ext.ip__bit() = BITSTRING(1, &ctemp);
5723 ctemp = ShiftDownBit(buf[len], 0);
5724 ext.ip2__bit() = BITSTRING(1, &ctemp);
5725 len += 1;
5726
5727 len +=
5728 Get_Profile2_Inner_IP_flags_opt(&buf[len], ext.inner__ip__flags(),
5729 dat, *ext.ip__bit() == 1);
5730
5731 len += Get_Outer_IP_flags_opt(&buf[len], ext.outer__ip__flags(), dat,
5732 *ext.ip2__bit() == 1);
5733
5734 len += Get_LIN1_opt(&buf[len], ext.sn(), *ext.s__bit() == 1);
5735
5736 len += Get_Profile2_Inner_IP_fields_opt(&buf[len], ext.inner__ip__hdr(),
5737 ext.inner__ip__flags(), dat,
5738 *ext.ip__bit() == 1);
5739
5740 len += Get_LIN2_BO_LAST_opt(&buf[len], ext.ip__id(), *ext.i__bit() == 1);
5741
5742 len += Get_Outer_IP_fields_opt(&buf[len], ext.outer__ip__hdr(),
5743 ext.outer__ip__flags(), dat,
5744 *ext.ip2__bit() == 1);
5745
5746 Log_hexdump(buf, len);
5747 Log_function_name_on_leave();
5748
5749 return len;
5750}
5751
5752int
5753Get_Profile2_extensions_opt(unsigned char *buf,
5754 OPTIONAL < Profile2__Extension > &ext,
5755 t_dat *dat, bool hasvalue)
5756{
5757 int len = 0;
5758
5759 Log_function_name_on_enter();
5760
5761 if (hasvalue)
5762 {
5763 if ((buf[len] & 0xC0) == 0)
5764 {
5765 len += Get_Profile2_extension0(&buf[len], ext().ext0(), dat);
5766 }
5767 else if ((buf[len] & 0xC0) == 0x40)
5768 {
5769 len += Get_Profile2_extension1(&buf[len], ext().ext1(), dat);
5770 }
5771 else if ((buf[len] & 0xC0) == 0x80)
5772 {
5773 len += Get_Profile2_extension2(&buf[len], ext().ext2(), dat);
5774 }
5775 else /* if ((buf[len] & 0xC0) == 0xC0) */
5776 {
5777 len += Get_Profile2_extension3(&buf[len], ext().ext3(), dat);
5778 }
5779 }
5780 else
5781 {
5782 ext = OMIT_VALUE;
5783 }
5784
5785 Log_hexdump(buf, len);
5786 Log_function_name_on_leave();
5787
5788 return len;
5789}
5790
5791int
5792Get_Profile2_Static_Chain(unsigned char *buf, Profile2__Static__Chain & chain,
5793 t_dat *dat)
5794{
5795 int len = 0, num = 0, nextheader = 0;
5796
5797 Log_function_name_on_enter();
5798
5799 while (nextheader != c__ip__proto__udp)
5800 {
5801 if (((buf[len] >> 4) & 0x0F) == 4)
5802 {
5803 initIPcontext(dat, num, 4);
5804 len += Get_ipv4_static(&buf[len], chain[num].ipv4__stat());
5805 nextheader = chain[num].ipv4__stat().proto();
5806 }
5807 else if (((buf[len] >> 4) & 0x0F) == 6)
5808 {
5809 initIPcontext(dat, num, 6);
5810 len += Get_ipv6_static(&buf[len], chain[num].ipv6__stat());
5811 nextheader = chain[num].ipv6__stat().nexthead();
5812 }
5813 else
5814 {
5815 TTCN_error("Invalid IP version %u on level %u", buf[len], num);
5816 }
5817 num += 1;
5818 }
5819
5820 len += Get_udp_static(&buf[len], chain[num].udp__stat());
5821
5822 Log_hexdump(buf, len);
5823 Log_function_name_on_leave();
5824
5825 return len;
5826}
5827
5828int
5829Get_Profile2_ROHC_Header_ir(unsigned char *buf, Profile2__IR__header & bhead,
5830 t_dat *dat, int cid)
5831{
5832 int len = 0;
5833 unsigned char ctemp;
5834
5835 Log_function_name_on_enter();
5836
5837 dat->context.pkt() = Packet__type(Packet__type::IR);
5838 bhead.cid() = cid;
5839 ctemp = (buf[len] >> 1) & 0x7F;
5840 bhead.type__ind() = BITSTRING(7, &ctemp);
5841 ctemp = ShiftDownBit(buf[len], 0);
5842 bhead.d() = BITSTRING(1, &ctemp);
5843 len += 1;
5844 len += Get_LIN1(&buf[len], bhead.profile());
5845 dat->context.profile() = bhead.profile();
5846 len += Get_LIN1(&buf[len], bhead.crc());
5847
5848 len += Get_Profile2_Static_Chain(&buf[len], bhead.stat__chain(), dat);
5849
5850 if (*bhead.d() == 1)
5851 len += Get_Profile2_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
5852 else
5853 bhead.dyn__chain() = OMIT_VALUE;
5854
5855 Log_hexdump(buf, len);
5856 Log_function_name_on_leave();
5857
5858 return len;
5859}
5860
5861int
5862Get_Profile2_ROHC_Header_irdyn(unsigned char *buf,
5863 Profile2__IR__DYN__header & bhead,
5864 t_dat *dat, int cid)
5865{
5866 int len = 0;
5867
5868 Log_function_name_on_enter();
5869
5870 dat->context.pkt() = Packet__type(Packet__type::IR__DYN);
5871 bhead.cid() = cid;
5872 bhead.type__ind() = BITSTRING(8, &buf[len]);
5873 len += 1;
5874 len += Get_LIN1(&buf[len], bhead.profile());
5875 dat->context.profile() = bhead.profile();
5876 len += Get_LIN1(&buf[len], bhead.crc());
5877
5878 len += Get_Profile2_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
5879
5880 Log_hexdump(buf, len);
5881 Log_function_name_on_leave();
5882
5883 return len;
5884}
5885
5886int
5887Get_Profile2_ROHC_Header_r1(unsigned char *buf,
5888 Profile2__R__1__header & bhead,
5889 t_dat *dat, int cid,
5890 OPTIONAL < Profile2__Extension > &ext)
5891{
5892 int len = 0;
5893 unsigned char ctemp;
5894
5895 Log_function_name_on_enter();
5896
5897 dat->context.pkt() = Packet__type(Packet__type::R__1);
5898 bhead.cid() = cid;
5899 ctemp = (buf[len] >> 6) & 0x03;
5900 bhead.type__ind() = BITSTRING(2, &ctemp);
5901 bhead.sn() = buf[len] & 0x3F;
5902 len += 1;
5903 ctemp = ShiftDownBit(buf[len], 7);
5904 bhead.x__bit() = BITSTRING(1, &ctemp);
5905 bhead.ip__id() = buf[len] & 0x7F;
5906 len += 1;
5907
5908 if (*bhead.x__bit())
5909 {
5910 len += Get_Profile2_extensions_opt(&buf[len], ext,
5911 dat, *bhead.x__bit());
5912 }
5913
5914 Log_hexdump(buf, len);
5915 Log_function_name_on_leave();
5916
5917 return len;
5918}
5919
5920int
5921Get_Profile2_ROHC_Header_uo1(unsigned char *buf,
5922 Profile2__UO__1__header & bhead,
5923 t_dat *dat, int cid)
5924{
5925 int len = 0;
5926 unsigned char ctemp;
5927
5928 Log_function_name_on_enter();
5929
5930 dat->context.pkt() = Packet__type(Packet__type::UO__1);
5931 bhead.cid() = cid;
5932 ctemp = (buf[len] >> 6) & 0x03;
5933 bhead.type__ind() = BITSTRING(2, &ctemp);
5934 bhead.ip__id() = buf[len] & 0x3F;
5935 len += 1;
5936 bhead.sn() = (buf[len] >> 3) & 0x1F;
5937 bhead.crc() = buf[len] & 0x07;
5938 len += 1;
5939
5940 Log_hexdump(buf, len);
5941 Log_function_name_on_leave();
5942
5943 return len;
5944}
5945
5946int
5947Get_Profile2_ROHC_Header_uor2(unsigned char *buf,
5948 Profile2__UOR__2__header & bhead,
5949 t_dat *dat, int cid,
5950 OPTIONAL < Profile2__Extension > &ext)
5951{
5952 int len = 0;
5953 unsigned char ctemp;
5954
5955 Log_function_name_on_enter();
5956
5957 dat->context.pkt() = Packet__type(Packet__type::UOR__2);
5958 bhead.cid() = cid;
5959 ctemp = (buf[len] >> 5) & 0x07;
5960 bhead.type__ind() = BITSTRING(3, &ctemp);
5961 bhead.sn() = buf[len] & 0x1F;
5962 len += 1;
5963 ctemp = ShiftDownBit(buf[len], 7);
5964 bhead.x__bit() = BITSTRING(1, &ctemp);
5965 bhead.crc() = buf[len] & 0x7F;
5966 len += 1;
5967
5968 if (*bhead.x__bit())
5969 {
5970 len += Get_Profile2_extensions_opt(&buf[len], ext,
5971 dat, *bhead.x__bit());
5972 }
5973
5974 Log_hexdump(buf, len);
5975 Log_function_name_on_leave();
5976
5977 return len;
5978}
5979
5980int
5981Get_Profile2_ROHC_Header(unsigned char *buf, int length,
5982 Profile2__headers & hdr,
5983 t_dat *dat, int cid)
5984{
5985 int len = 0;
5986
5987 Log_function_name_on_enter();
5988
5989 if (isIR(buf[len]))
5990 {
5991 len += Get_Profile2_ROHC_Header_ir(&buf[len],
5992 hdr.base__header().ir(), dat, cid);
5993 }
5994 else if (isIRDYN(buf[len]))
5995 {
5996 len += Get_Profile2_ROHC_Header_irdyn(&buf[len],
5997 hdr.base__header().ir__dyn(),
5998 dat, cid);
5999 }
6000 else if (isUOR2(buf[len]))
6001 {
6002 len += Get_Profile2_ROHC_Header_uor2(&buf[len],
6003 hdr.base__header().uor__2(),
6004 dat, cid, hdr.ext());
6005 }
6006 else if (dat->context.mode() == ROHC_mode_R)
6007 {
6008 if ((buf[len] & 0xC0) == 0)
6009 {
6010 len += Get_Profile1_ROHC_Header_r0(&buf[len],
6011 hdr.base__header().r__0(),
6012 dat, cid);
6013 }
6014 else if ((buf[len] & 0xC0) == 0x40)
6015 {
6016 len += Get_Profile1_ROHC_Header_r0crc(&buf[len],
6017 hdr.base__header().r__0__crc(),
6018 dat, cid);
6019 }
6020 else if ((buf[len] & 0xC0) == 0x80)
6021 {
6022 len += Get_Profile2_ROHC_Header_r1(&buf[len],
6023 hdr.base__header().r__1(),
6024 dat, cid, hdr.ext());
6025 }
6026 else
6027 {
6028 TTCN_error("Unknown compressed packet (R mode) (0x%02x)", buf[len]);
6029 }
6030 }
6031 else if (dat->context.mode() != ROHC_mode_R) // U-O modes
6032 {
6033 if ((buf[len] & 0x80) == 0)
6034 {
6035 len += Get_Profile1_ROHC_Header_uo0(&buf[len],
6036 hdr.base__header().uo__0(),
6037 dat, cid);
6038 }
6039 else if ((buf[len] & 0xC0) == 0x80)
6040 {
6041 len += Get_Profile2_ROHC_Header_uo1(&buf[len],
6042 hdr.base__header().uo__1(),
6043 dat, cid);
6044 }
6045 else
6046 {
6047 TTCN_error("Unknown compressed packet (U-O mode) (0x%02x)", buf[len]);
6048 }
6049 }
6050
6051 if (!hdr.ext().is_bound())
6052 hdr.ext() = OMIT_VALUE;
6053 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__outer(),
6054 dat, Outer_IP);
6055 len += Get_AH_data_opt(&buf[len], hdr.ah__outer(), dat, Outer_IP);
6056 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum1(), dat, Outer_IP);
6057 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__inner(),
6058 dat, Inner_IP);
6059 len += Get_AH_data_opt(&buf[len], hdr.ah__inner(), dat, Inner_IP);
6060 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum2(), dat, Inner_IP);
6061 len += Get_UDP_cksum_opt(&buf[len], hdr.udp__cksum(), dat);
6062
6063 Log_hexdump(buf, len);
6064 Log_function_name_on_leave();
6065
6066 return len;
6067} /* Get_Profile2_ROHC_Header */
6068
6069int
6070Get_Profile4_ipv4_dynamic(const unsigned char *buf,
6071 Profile4__IPv4__Dynamic & chain,
6072 t_dat *dat, int ip_level)
6073{
6074 int len = 0;
6075 unsigned char ctemp;
6076
6077 Log_function_name_on_enter();
6078
6079 len += Get_LIN1(&buf[len], chain.tos());
6080 len += Get_LIN1(&buf[len], chain.ttl());
6081 len += Get_LIN2_BO_LAST(&buf[len], chain.identification());
6082 ctemp = ShiftDownBit(buf[len], 7);
6083 chain.df__bit() = BITSTRING(1, &ctemp);
6084 ctemp = ShiftDownBit(buf[len], 6);
6085 chain.rnd__bit() = BITSTRING(1, &ctemp);
6086 dat->context.ip__ctx()[ip_level].rnd__bit() = BOOLEAN(ctemp);
6087 ctemp = ShiftDownBit(buf[len], 5);
6088 chain.nbo__bit() = BITSTRING(1, &ctemp);
6089 ctemp = ShiftDownBit(buf[len], 4);
6090 chain.sid__bit() = BITSTRING(1, &ctemp);
6091 ctemp = buf[len] & 0x0F;
6092 chain.reserved() = BITSTRING(4, &ctemp);
6093 len += 1;
6094 len += Get_Encoding_Type_0(chain.genextheadlist(),
6095 &buf[len], Item__list::ALT_ip__item__list,
6096 dat, ip_level);
6097
6098 Log_hexdump(buf, len);
6099 Log_function_name_on_leave();
6100
6101 return len;
6102}
6103
6104int
6105Get_Profile4_Dynamic_Chain(Profile4__Dynamic__Chain & dynch,
6106 const unsigned char *buf, t_dat *dat)
6107{
6108 int len = 0, num;
6109
6110 Log_function_name_on_enter();
6111
6112 for (num = 0; num < dat->context.ip__ctx().size_of() && num < 2; num++)
6113 {
6114 if (dat->context.ip__ctx()[num].version() == 4)
6115 {
6116 len += Get_Profile4_ipv4_dynamic(&buf[len], dynch[num].ipv4__dyn(),
6117 dat, num);
6118 }
6119 else if (dat->context.ip__ctx()[num].version() == 6)
6120 {
6121 len += Get_ipv6_dynamic(&buf[len], dynch[num].ipv6__dyn(), dat, num);
6122 }
6123 else
6124 {
6125 int ipver = dat->context.ip__ctx()[num].version();
6126 TTCN_error("Invalid IP version %u on level %d", ipver, num);
6127 }
6128 }
6129
6130 num = dynch.size_of();
6131 len += Get_LIN2_BO_LAST(&buf[len], dynch[num].sn());
6132
6133 Log_hexdump(buf, len);
6134 Log_function_name_on_leave();
6135
6136 return len;
6137}
6138
6139int
6140Get_Profile4_Additional_Dynamic_Chain_opt(OPTIONAL < Profile4__Dynamic__Chain >
6141 &dynch,
6142 const unsigned char *buf,
6143 t_dat *dat)
6144{
6145 int len = 0;
6146
6147 Log_function_name_on_enter();
6148
6149 if (dat->context.ip__ctx().size_of() > 2)
6150 {
6151 for (int num = 2; num < dat->context.ip__ctx().size_of(); num++)
6152 {
6153 if (dat->context.ip__ctx()[num].version() == 4)
6154 {
6155 len += Get_Profile4_ipv4_dynamic(&buf[len],
6156 dynch()[num - 2].ipv4__dyn(),
6157 dat, num);
6158 }
6159 else if (dat->context.ip__ctx()[num].version() == 6)
6160 {
6161 len += Get_ipv6_dynamic(&buf[len], dynch()[num - 2].ipv6__dyn(),
6162 dat, num);
6163 }
6164 else
6165 {
6166 int ipver = dat->context.ip__ctx()[num].version();
6167 TTCN_error("Invalid IP version %u on level %d", ipver, num);
6168 }
6169 }
6170 }
6171 else
6172 dynch = OMIT_VALUE;
6173
6174 Log_hexdump(buf, len);
6175 Log_function_name_on_leave();
6176
6177 return len;
6178}
6179
6180int
6181Get_Profile4_Static_Chain(unsigned char *buf, Profile4__Static__Chain & chain,
6182 t_dat *dat)
6183{
6184 int len = 0, num = 0, nextheader = 0;
6185 bool terminated = false;
6186
6187 Log_function_name_on_enter();
6188
6189 do
6190 {
6191 /* Version does not include the MSB bit of the version field */
6192 int ver = (buf[len] >> 4) & 0x07;
6193
6194 terminated = (buf[len] & 0x80 > 0) ? true : false;
6195 if (ver == c__ip__version__ipv4)
6196 {
6197 // version is stored with the MSB bit
6198 initIPcontext(dat, num, (buf[len] >> 4) & 0x0F);
6199 len += Get_ipv4_static(&buf[len], chain[num].ipv4__stat());
6200 nextheader = chain[num].ipv4__stat().proto();
6201 }
6202 else if (ver == c__ip__version__ipv6)
6203 {
6204 // version is stored with the MSB bit
6205 initIPcontext(dat, num, (buf[len] >> 4) & 0x0F);
6206 len += Get_ipv6_static(&buf[len], chain[num].ipv6__stat());
6207 nextheader = chain[num].ipv6__stat().nexthead();
6208 }
6209 else
6210 {
6211 TTCN_error("Invalid IP version %u on level %u", ver, num);
6212 }
6213 /* Explicit MSB termination */
6214 if (terminated)
6215 {
6216 TTCN_logger.log(TTCN_DEBUG, "MSB static chain termination on level %u",
6217 num);
6218 }
6219 num += 1;
6220 }
6221 while ((nextheader == c__ip__proto__ipv4 || nextheader == c__ip__proto__ipv6) &&
6222 !terminated);
6223
6224 Log_hexdump(buf, len);
6225 Log_function_name_on_leave();
6226
6227 return len;
6228}
6229
6230int
6231Get_Profile4_ROHC_Header_ir(unsigned char *buf, Profile4__IR__header & bhead,
6232 t_dat *dat, int cid)
6233{
6234 int len = 0;
6235 unsigned char ctemp;
6236
6237 Log_function_name_on_enter();
6238
6239 dat->context.pkt() = Packet__type(Packet__type::IR);
6240 bhead.cid() = cid;
6241 ctemp = (buf[len] >> 1) & 0x7F;
6242 bhead.type__ind() = BITSTRING(7, &ctemp);
6243 ctemp = ShiftDownBit(buf[len], 0);
6244 bhead.d() = BITSTRING(1, &ctemp);
6245 len += 1;
6246 len += Get_LIN1(&buf[len], bhead.profile());
6247 dat->context.profile() = bhead.profile();
6248 len += Get_LIN1(&buf[len], bhead.crc());
6249
6250 len += Get_Profile4_Static_Chain(&buf[len], bhead.stat__chain(), dat);
6251
6252 if (*bhead.d() == 1)
6253 len += Get_Profile4_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
6254 else
6255 bhead.dyn__chain() = OMIT_VALUE;
6256
6257 Log_hexdump(buf, len);
6258 Log_function_name_on_leave();
6259
6260 return len;
6261}
6262
6263int
6264Get_Profile4_ROHC_Header_irdyn(unsigned char *buf,
6265 Profile4__IR__DYN__header & bhead,
6266 t_dat *dat, int cid)
6267{
6268 int len = 0;
6269
6270 Log_function_name_on_enter();
6271
6272 dat->context.pkt() = Packet__type(Packet__type::IR__DYN);
6273 bhead.cid() = cid;
6274 bhead.type__ind() = BITSTRING(8, &buf[len]);
6275 len += 1;
6276 len += Get_LIN1(&buf[len], bhead.profile());
6277 dat->context.profile() = bhead.profile();
6278 len += Get_LIN1(&buf[len], bhead.crc());
6279
6280 len += Get_Profile4_Dynamic_Chain(bhead.dyn__chain(), &buf[len], dat);
6281
6282 Log_hexdump(buf, len);
6283 Log_function_name_on_leave();
6284
6285 return len;
6286}
6287
6288int
6289Get_Profile4_ROHC_Header_r1(unsigned char *buf,
6290 Profile2__R__1__header & bhead,
6291 t_dat *dat, int cid,
6292 OPTIONAL < Profile2__Extension > &ext)
6293{
6294 int len = 0;
6295 unsigned char ctemp;
6296
6297 Log_function_name_on_enter();
6298
6299 dat->context.pkt() = Packet__type(Packet__type::R__1);
6300 bhead.cid() = cid;
6301 ctemp = (buf[len] >> 6) & 0x03;
6302 bhead.type__ind() = BITSTRING(2, &ctemp);
6303 bhead.sn() = buf[len] & 0x3F;
6304 len += 1;
6305 ctemp = ShiftDownBit(buf[len], 7);
6306 bhead.x__bit() = BITSTRING(1, &ctemp);
6307 bhead.ip__id() = buf[len] & 0x7F;
6308 len += 1;
6309
6310 if (*bhead.x__bit())
6311 {
6312 len += Get_Profile2_extensions_opt(&buf[len], ext,
6313 dat, *bhead.x__bit());
6314 }
6315
6316 Log_hexdump(buf, len);
6317 Log_function_name_on_leave();
6318
6319 return len;
6320}
6321
6322int
6323Get_Profile4_ROHC_Header_uor2(unsigned char *buf,
6324 Profile2__UOR__2__header & bhead,
6325 t_dat *dat, int cid,
6326 OPTIONAL < Profile2__Extension > &ext)
6327{
6328 int len = 0;
6329 unsigned char ctemp;
6330
6331 Log_function_name_on_enter();
6332
6333 dat->context.pkt() = Packet__type(Packet__type::UOR__2);
6334 bhead.cid() = cid;
6335 ctemp = (buf[len] >> 5) & 0x07;
6336 bhead.type__ind() = BITSTRING(3, &ctemp);
6337 bhead.sn() = buf[len] & 0x1F;
6338 len += 1;
6339 ctemp = ShiftDownBit(buf[len], 7);
6340 bhead.x__bit() = BITSTRING(1, &ctemp);
6341 bhead.crc() = buf[len] & 0x7F;
6342 len += 1;
6343
6344 if (*bhead.x__bit())
6345 {
6346 len += Get_Profile2_extensions_opt(&buf[len], ext,
6347 dat, *bhead.x__bit());
6348 }
6349
6350 Log_hexdump(buf, len);
6351 Log_function_name_on_leave();
6352
6353 return len;
6354}
6355
6356int
6357Get_Profile4_ROHC_Header(unsigned char *buf, int length,
6358 Profile4__headers & hdr, t_dat *dat,
6359 int cid)
6360{
6361 int len = 0;
6362
6363 Log_function_name_on_enter();
6364
6365 if (isIR(buf[len]))
6366 {
6367 len += Get_Profile4_ROHC_Header_ir(&buf[len],
6368 hdr.base__header().ir(), dat, cid);
6369 }
6370 else if (isIRDYN(buf[len]))
6371 {
6372 len += Get_Profile4_ROHC_Header_irdyn(&buf[len],
6373 hdr.base__header().ir__dyn(),
6374 dat, cid);
6375 }
6376 else if (isUOR2(buf[len]))
6377 {
6378 len += Get_Profile4_ROHC_Header_uor2(&buf[len],
6379 hdr.base__header().uor__2(),
6380 dat, cid, hdr.ext());
6381 }
6382 else if (dat->context.mode() == ROHC_mode_R)
6383 {
6384 if ((buf[len] & 0xC0) == 0)
6385 {
6386 len += Get_Profile1_ROHC_Header_r0(&buf[len],
6387 hdr.base__header().r__0(),
6388 dat, cid);
6389 }
6390 else if ((buf[len] & 0xC0) == 0x40)
6391 {
6392 len += Get_Profile1_ROHC_Header_r0crc(&buf[len],
6393 hdr.base__header().r__0__crc(),
6394 dat, cid);
6395 }
6396 else if ((buf[len] & 0xC0) == 0x80)
6397 {
6398 len += Get_Profile4_ROHC_Header_r1(&buf[len],
6399 hdr.base__header().r__1(),
6400 dat, cid, hdr.ext());
6401 }
6402 else
6403 {
6404 TTCN_error("Unknown compressed packet (R mode) (0x%02x)", buf[len]);
6405 }
6406 }
6407 else if (dat->context.mode() != ROHC_mode_R) // U-O modes
6408 {
6409 if ((buf[len] & 0x80) == 0)
6410 {
6411 len += Get_Profile1_ROHC_Header_uo0(&buf[len],
6412 hdr.base__header().uo__0(),
6413 dat, cid);
6414 }
6415 else if ((buf[len] & 0xC0) == 0x80)
6416 {
6417 len += Get_Profile2_ROHC_Header_uo1(&buf[len],
6418 hdr.base__header().uo__1(),
6419 dat, cid);
6420 }
6421 else
6422 {
6423 TTCN_error("Unknown compressed packet (U-O modes) (0x%02x)", buf[len]);
6424 }
6425 }
6426
6427 if (!hdr.ext().is_bound())
6428 hdr.ext() = OMIT_VALUE;
6429 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__outer(),
6430 dat, Outer_IP);
6431 len += Get_AH_data_opt(&buf[len], hdr.ah__outer(), dat, Outer_IP);
6432 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum1(), dat, Outer_IP);
6433 len += Get_IP_ID_compressed_opt(&buf[len], hdr.ip__id__inner(),
6434 dat, Inner_IP);
6435 len += Get_AH_data_opt(&buf[len], hdr.ah__inner(), dat, Inner_IP);
6436 len += Get_GRE_cksum_opt(&buf[len], hdr.gre__cksum2(), dat, Inner_IP);
6437 len += Get_Profile4_Additional_Dynamic_Chain_opt(hdr.additional__IP(),
6438 &buf[len], dat);
6439
6440 Log_hexdump(buf, len);
6441 Log_function_name_on_leave();
6442
6443 return len;
6444} /* Get_Profile4_ROHC_Header */
6445
6446int
6447Get_ROHC_Header(const unsigned char *p_buf,
6448 int length, Header & p_header, ROHC__config & config)
6449{
6450 unsigned char buf[MAX_PACKET_SIZE];
6451 int len = 0, cidlen = 0;
6452 INTEGER cid;
6453
6454 Log_function_name_on_enter();
6455
6456 memcpy(buf, p_buf, length);
6457
6458 if (config.large__cid())
6459 {
6460 /* Skip packet type octet */
6461 cidlen = Get_CID(&p_buf[1], cid, config);
6462 /* Move the packet type octet right after the CID */
6463 buf[cidlen] = buf[0];
6464 }
6465 else
6466 {
6467 cidlen = Get_CID(&p_buf[0], cid, config);
6468 }
6469 len += cidlen;
6470
6471 if (isIR(buf[len]) || isIRDYN(buf[len]))
6472 {
6473 config.context()[cid].profile() = buf[len + 1];
6474 }
6475
6476 t_dat dat = initTDAT(config, cid);
6477 initCIDcontext(&dat);
6478
6479 switch (config.context()[cid].profile())
6480 {
6481 case 0:
6482 len += Get_Profile0_ROHC_Header(&buf[len], &dat,
6483 length - cidlen, p_header.prof0(),
6484 (int) cid);
6485 break;
6486 case 1:
6487 len += Get_Profile1_ROHC_Header(&buf[len], &dat, length - cidlen,
6488 p_header.prof1(), (int) cid);
6489 break;
6490 case 2:
6491 len += Get_Profile2_ROHC_Header(&buf[len], length - cidlen,
6492 p_header.prof2(), &dat,
6493 (int) cid);
6494 break;
6495 case 4:
6496 len += Get_Profile4_ROHC_Header(&buf[len], length - cidlen,
6497 p_header.prof4(), &dat,
6498 (int) cid);
6499 break;
6500 default:
6501 break;
6502 }
6503
6504 Log_hexdump(buf, len);
6505 Log_function_name_on_leave();
6506
6507 return len;
6508}
6509
6510ROHC__packet__u
6511f__ROHC__dec(OCTETSTRING const &data, ROHC__config & p_config)
6512{
6513 ROHC__packet__u packet;
6514 OPTIONAL < Padding > padding;
6515 OPTIONAL < Feedback > feedback;
6516 const unsigned char *buf = (const unsigned char *) data;
6517 int len = 0;
6518
6519 Log_function_name_on_enter();
6520
6521 Log_object(p_config);
6522
6523 // Processing padding
6524 Log_hexdump(buf, data.lengthof() - len);
6525 len += Get_ROHC_Padding(&buf[len], data.lengthof() - len, padding, p_config);
6526 // Processing feedback
6527 len += Get_ROHC_Feedback(&buf[len], data.lengthof() - len, feedback, p_config);
6528 // Processing ROHC header
6529 if ((buf[len] & 0xFE) == 0xFE)
6530 {
6531 packet.segment().padding() = padding;
6532 packet.segment().feedback() = feedback;
6533 packet.segment().segment__header__id() = 0x7F;
6534 if (ShiftDownBit(buf[len], 0))
6535 {
6536 packet.segment().final() = BOOLEAN(true);
6537 len += 1;
6538 if (data.lengthof() - len < 4)
6539 {
6540 packet.segment().payload() =
6541 OCTETSTRING(data.lengthof() - len, &buf[len]);
6542 len = data.lengthof();
6543 packet.segment().crc() = OMIT_VALUE;
6544 }
6545 else
6546 {
6547 packet.segment().payload() =
6548 OCTETSTRING(data.lengthof() - len - 4, &buf[len]);
6549 len = data.lengthof() - 4;
6550 packet.segment().crc() =
6551 ((buf[len] << 24) & 0xFF000000) +
6552 ((buf[len + 1] << 16) & 0xFF0000) +
6553 ((buf[len + 2] << 8) & 0xFF00) + (buf[len + 3] & 0xFF);
6554 }
6555 }
6556 else
6557 {
6558 packet.segment().final() = BOOLEAN(false);
6559 len += 1;
6560 packet.segment().payload() =
6561 OCTETSTRING(data.lengthof() - len, &buf[len]);
6562 packet.segment().crc() = OMIT_VALUE;
6563 }
6564
6565 }
6566 else
6567 {
6568 packet.rohc().padding() = padding;
6569 packet.rohc().feedback() = feedback;
6570 len += Get_ROHC_Header(&buf[len],
6571 data.lengthof() - len, packet.rohc().header(),
6572 p_config);
6573 if (data.lengthof() == len)
6574 {
6575 packet.rohc().payload() = OMIT_VALUE;
6576 }
6577 else
6578 {
6579 packet.rohc().payload() = OCTETSTRING(data.lengthof() - len, &buf[len]);
6580 }
6581 }
6582
6583 TTCN_logger.begin_event(TTCN_DEBUG);
6584 p_config.log();
6585 packet.log();
6586 TTCN_logger.end_event();
6587
6588 Log_function_name_on_leave();
6589
6590 return packet;
6591}
6592
6593INTEGER
6594f__ROHC__CRC(OCTETSTRING const &data, INTEGER const &crclen)
6595{
6596 const unsigned char *buf = (const unsigned char *) data;
6597 INTEGER crcval;
6598 int crclength = crclen;
6599
6600 Log_function_name_on_enter();
6601
6602 TTCN_logger.log(TTCN_DEBUG, "Calculating CRC-%d over:", crclength);
6603 Log_hexdump(buf, data.lengthof());
6604
6605 crcval = INTEGER(ComputeCRC(&(buf[0]), data.lengthof(), crclength));
6606 Log_function_name_on_leave();
6607 return crcval;
6608}
6609
6610OCTETSTRING
6611f__FBCK__enc(Feedback__data const &feedback_data, ROHC__config const &config)
6612{
6613 unsigned char buf[MAX_PACKET_SIZE];
6614 int len = 0, crcpos = 0;
6615 INTEGER cid;
6616
6617 Log_function_name_on_enter();
6618
6619 cid = feedback_data.cid();
6620 if (config.large__cid() == false)
6621 {
6622 if (cid > 0)
6623 {
6624 buf[len] = 0xE0 + (cid & 0x0F);
6625 len += 1;
6626 }
6627 }
6628 else
6629 len += Set_SDVL_field(&buf[len], cid, 0);
6630 switch (feedback_data.feedback__type().get_selection())
6631 {
6632 case Feedback__type::ALT_feedback1:
6633 const unsigned char *tempbuf;
6634 tempbuf =
6635 (const unsigned char *) feedback_data.feedback__type().feedback1();
6636 buf[len] = tempbuf[0];
6637 len += 1;
6638 break;
6639 case Feedback__type::ALT_feedback2:
6640 {
6641 Feedback2 fback2;
6642 fback2 = feedback_data.feedback__type().feedback2();
6643 buf[len] = (fback2.acktype() << 6) & 0xC0;
6644 buf[len] += (fback2.mode() << 4) & 0x30;
6645 buf[len] += (fback2.sn() >> 8) & 0x0F;
6646 len += 1;
6647 buf[len] = fback2.sn() & 0xFF;
6648 len += 1;
6649 if (fback2.feedback__opts().ispresent())
6650 {
6651 Feedback__opts & fbopts = fback2.feedback__opts();
6652 for (int num2 = 0; num2 < fbopts.size_of(); num2++)
6653 {
6654 buf[len] = (fbopts[num2].opt__type() << 4) & 0xF0;
6655 buf[len] += fbopts[num2].opt__len() & 0x0F;
6656 len += 1;
6657 len += Set_octetstring_opt(&buf[len], fbopts[num2].opt__data());
6658 if (fbopts[num2].opt__data().ispresent())
6659 {
6660 OCTETSTRING opt;
6661 opt = fbopts[num2].opt__data();
6662 if (fbopts[num2].opt__len() != opt.lengthof())
6663 TTCN_logger.
6664 log(TTCN_WARNING,
6665 "Feedback option length mismatch: %d, %d",
6666 (int) fbopts[num2].opt__len(), opt.lengthof());
6667 else
6668 if ((fbopts[num2].opt__len() == 1)
6669 && (fbopts[num2].opt__type() == 1) && (buf[len - 1] == 0))
6670 crcpos = len - 1;
6671 }
6672 }
6673 }
6674 break;
6675 }
6676
6677 default:
6678 break;
6679 }
6680
6681 if ((crcpos > 0) && (buf[crcpos] == 0))
6682 buf[crcpos] = ComputeCRC(&(buf[0]), len, 8);
6683
6684 Log_function_name_on_leave();
6685
6686 return OCTETSTRING(len, &(buf[0]));
6687}
6688
6689Feedback__data
6690f__FBCK__dec(OCTETSTRING const &data, ROHC__config const &config)
6691{
6692 Feedback__data feedback_data;
6693 const unsigned char *buf;
6694 unsigned char ctemp;
6695 int len = 0, fbsize, cidlen = 0;
6696 buf = (const unsigned char *) data;
6697 fbsize = data.lengthof();
6698
6699 Log_function_name_on_enter();
6700
6701 if (config.large__cid() == false)
6702 {
6703 if ((buf[len] & 0xF0) == 0xE0)
6704 {
6705 feedback_data.cid() = buf[len] & 0x0F;
6706 len += 1;
6707 fbsize -= 1;
6708 }
6709 else
6710 feedback_data.cid() = 0;
6711 }
6712 else
6713 {
6714 cidlen = Get_SDVL_field(&buf[len], feedback_data.cid());
6715 len += cidlen;
6716 fbsize -= cidlen;
6717 }
6718
6719 if (fbsize == 1)
6720 {
6721 feedback_data.feedback__type().feedback1() = OCTETSTRING(1, &buf[len]);
6722 len += 1;
6723 }
6724 else if (fbsize >= 1)
6725 {
6726 int optnum;
6727 Feedback__opts fbopts;
6728 Feedback2 feedback2;
6729 feedback2.acktype() = (buf[len] >> 6) & 0x03;
6730 feedback2.mode() = (buf[len] >> 4) & 0x03;
6731 ctemp = buf[len] & 0x0F;
6732 len += 1;
6733 fbsize -= 1;
6734 feedback2.sn() = ((ctemp << 8) & 0x0F00) + buf[len];
6735 len += 1;
6736 fbsize -= 1;
6737 optnum = 0;
6738 feedback2.feedback__opts() = OMIT_VALUE;
6739 while (fbsize)
6740 {
6741 fbopts[optnum].opt__type() = (buf[len] >> 4) & 0x0F;
6742 fbopts[optnum].opt__len() = buf[len] & 0x0F;
6743 len += 1;
6744 fbsize -= 1;
6745 if (fbopts[optnum].opt__len())
6746 {
6747 len += Get_octetstring(&buf[len], fbopts[optnum].opt__data(),
6748 fbopts[optnum].opt__len());
6749 fbsize -= fbopts[optnum].opt__len();
6750 }
6751 else
6752 fbopts[optnum].opt__data() = OMIT_VALUE;
6753 feedback2.feedback__opts() = fbopts;
6754 optnum += 1;
6755 }
6756
6757 feedback_data.feedback__type().feedback2() = feedback2;
6758 }
6759 else
6760 TTCN_logger.log(TTCN_WARNING, "Size mismatch in feedback(%d)", fbsize);
6761
6762 Log_function_name_on_leave();
6763
6764 return feedback_data;
6765}
6766
6767}//namespace