1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
14 * Szabo, Janos Zoltan – initial implementation
17 ******************************************************************************/
23 #include "../common/memory.h"
24 #include "Basetype.hh"
29 /** An \c ASN_Tagnumber_t with 7 bits set in the most significant byte */
30 static const ASN_Tagnumber_t ASN_Tagnumber_t_7msb
31 =static_cast<ASN_Tagnumber_t
>(0x7F)<<(sizeof(ASN_Tagnumber_t
)*8-8);
33 /** A \c size_t value with 8 bits set (0xFF) in the most significant byte */
34 static const size_t size_t_8msb
35 =static_cast<size_t>(0xFF)<<(sizeof(size_t)*8-8);
37 const unsigned long long unsigned_llong_7msb
38 =static_cast<unsigned long long>(0x7F)<<(sizeof(unsigned long long)*8-8);
40 const unsigned long unsigned_long_8msb
41 =static_cast<unsigned long>(0xFF)<<(sizeof(unsigned long)*8-8);
43 char* ASN_Tag_t::print() const
51 prefix
= "UNIVERSAL ";
54 prefix
= "APPLICATION ";
66 return mprintf("[%s%u]", prefix
, tagnumber
);
69 char* ASN_BERdescriptor_t::print_tags() const
71 if (n_tags
== 0) return mcopystr("<no tags>");
74 for (size_t i
= n_tags
; i
> 0; i
--) {
75 char *tagstr
= tags
[i
- 1].print();
76 s
= mputstr(s
, tagstr
);
78 if (i
!= 1) s
= mputc(s
, ' ');
84 static const ASN_Tag_t BOOLEAN_tag_
[]={{ASN_TAG_UNIV
, 1u}};
85 const ASN_BERdescriptor_t BOOLEAN_ber_
={1u, BOOLEAN_tag_
};
87 static const ASN_Tag_t INTEGER_tag_
[]={{ASN_TAG_UNIV
, 2u}};
88 const ASN_BERdescriptor_t INTEGER_ber_
={1u, INTEGER_tag_
};
90 static const ASN_Tag_t BITSTRING_tag_
[]={{ASN_TAG_UNIV
, 3u}};
91 const ASN_BERdescriptor_t BITSTRING_ber_
={1u, BITSTRING_tag_
};
93 static const ASN_Tag_t OCTETSTRING_tag_
[]={{ASN_TAG_UNIV
, 4u}};
94 const ASN_BERdescriptor_t OCTETSTRING_ber_
={1u, OCTETSTRING_tag_
};
96 static const ASN_Tag_t ASN_NULL_tag_
[]={{ASN_TAG_UNIV
, 5u}};
97 const ASN_BERdescriptor_t ASN_NULL_ber_
={1u, ASN_NULL_tag_
};
99 static const ASN_Tag_t OBJID_tag_
[]={{ASN_TAG_UNIV
, 6u}};
100 const ASN_BERdescriptor_t OBJID_ber_
={1u, OBJID_tag_
};
102 static const ASN_Tag_t ObjectDescriptor_tag_
[]={{ASN_TAG_UNIV
, 7u}};
103 const ASN_BERdescriptor_t ObjectDescriptor_ber_
={1u, ObjectDescriptor_tag_
};
105 static const ASN_Tag_t EXTERNAL_tag_
[]={{ASN_TAG_UNIV
, 8u}};
106 const ASN_BERdescriptor_t EXTERNAL_ber_
={1u, EXTERNAL_tag_
};
108 static const ASN_Tag_t REAL_tag_
[]={{ASN_TAG_UNIV
, 9u}};
109 const ASN_BERdescriptor_t FLOAT_ber_
={1u, REAL_tag_
};
111 static const ASN_Tag_t ENUMERATED_tag_
[]={{ASN_TAG_UNIV
, 10u}};
112 const ASN_BERdescriptor_t ENUMERATED_ber_
={1u, ENUMERATED_tag_
};
114 static const ASN_Tag_t EMBEDDED_PDV_tag_
[]={{ASN_TAG_UNIV
, 11u}};
115 const ASN_BERdescriptor_t EMBEDDED_PDV_ber_
={1u, EMBEDDED_PDV_tag_
};
117 static const ASN_Tag_t UTF8String_tag_
[]={{ASN_TAG_UNIV
, 12u}};
118 const ASN_BERdescriptor_t UTF8String_ber_
={1u, UTF8String_tag_
};
120 static const ASN_Tag_t ASN_ROID_tag_
[]={{ASN_TAG_UNIV
, 13u}};
121 const ASN_BERdescriptor_t ASN_ROID_ber_
={1u, ASN_ROID_tag_
};
123 static const ASN_Tag_t SEQUENCE_tag_
[]={{ASN_TAG_UNIV
, 16u}};
124 const ASN_BERdescriptor_t SEQUENCE_ber_
={1u, SEQUENCE_tag_
};
126 static const ASN_Tag_t SET_tag_
[]={{ASN_TAG_UNIV
, 17u}};
127 const ASN_BERdescriptor_t SET_ber_
={1u, SET_tag_
};
129 const ASN_BERdescriptor_t CHOICE_ber_
={0u, NULL
};
131 const ASN_BERdescriptor_t ASN_ANY_ber_
={0u, NULL
};
133 static const ASN_Tag_t NumericString_tag_
[]={{ASN_TAG_UNIV
, 18u}};
134 const ASN_BERdescriptor_t NumericString_ber_
={1u, NumericString_tag_
};
136 static const ASN_Tag_t PrintableString_tag_
[]={{ASN_TAG_UNIV
, 19u}};
137 const ASN_BERdescriptor_t PrintableString_ber_
={1u, PrintableString_tag_
};
139 static const ASN_Tag_t TeletexString_tag_
[]={{ASN_TAG_UNIV
, 20u}};
140 const ASN_BERdescriptor_t TeletexString_ber_
={1u, TeletexString_tag_
};
142 static const ASN_Tag_t VideotexString_tag_
[]={{ASN_TAG_UNIV
, 21u}};
143 const ASN_BERdescriptor_t VideotexString_ber_
={1u, VideotexString_tag_
};
145 static const ASN_Tag_t IA5String_tag_
[]={{ASN_TAG_UNIV
, 22u}};
146 const ASN_BERdescriptor_t IA5String_ber_
={1u, IA5String_tag_
};
148 static const ASN_Tag_t ASN_UTCTime_tag_
[]={{ASN_TAG_UNIV
, 23u}};
149 const ASN_BERdescriptor_t ASN_UTCTime_ber_
={1u, ASN_UTCTime_tag_
};
151 static const ASN_Tag_t ASN_GeneralizedTime_tag_
[]={{ASN_TAG_UNIV
, 24u}};
152 const ASN_BERdescriptor_t ASN_GeneralizedTime_ber_
={1u, ASN_GeneralizedTime_tag_
};
154 static const ASN_Tag_t GraphicString_tag_
[]={{ASN_TAG_UNIV
, 25u}};
155 const ASN_BERdescriptor_t GraphicString_ber_
={1u, GraphicString_tag_
};
157 static const ASN_Tag_t VisibleString_tag_
[]={{ASN_TAG_UNIV
, 26u}};
158 const ASN_BERdescriptor_t VisibleString_ber_
={1u, VisibleString_tag_
};
160 const ASN_Tag_t GeneralString_tag_
[]={{ASN_TAG_UNIV
, 27u}};
161 const ASN_BERdescriptor_t GeneralString_ber_
={1u, GeneralString_tag_
};
163 static const ASN_Tag_t UniversalString_tag_
[]={{ASN_TAG_UNIV
, 28u}};
164 const ASN_BERdescriptor_t UniversalString_ber_
={1u, UniversalString_tag_
};
166 static const ASN_Tag_t CHARACTER_STRING_tag_
[]={{ASN_TAG_UNIV
, 29u}};
167 const ASN_BERdescriptor_t CHARACTER_STRING_ber_
={1u, CHARACTER_STRING_tag_
};
169 static const ASN_Tag_t BMPString_tag_
[]={{ASN_TAG_UNIV
, 30u}};
170 const ASN_BERdescriptor_t BMPString_ber_
={1u, BMPString_tag_
};
172 ASN_BER_TLV_t
* ASN_BER_TLV_t::construct(ASN_BER_TLV_t
*p_tlv
)
174 ASN_BER_TLV_t
*new_tlv
= (ASN_BER_TLV_t
*)Malloc(sizeof(*new_tlv
));
175 new_tlv
->isConstructed
= TRUE
;
176 new_tlv
->V_tlvs_selected
= TRUE
;
177 new_tlv
->isLenDefinite
= FALSE
;
178 new_tlv
->isLenShort
= FALSE
;
179 new_tlv
->isTagComplete
= FALSE
;
180 new_tlv
->isComplete
= FALSE
;
181 new_tlv
->tagclass
= ASN_TAG_UNIV
;
182 new_tlv
->tagnumber
= 0;
185 new_tlv
->Tstr
= NULL
;
186 new_tlv
->Lstr
= NULL
;
188 new_tlv
->V
.tlvs
.n_tlvs
= 1;
189 new_tlv
->V
.tlvs
.tlvs
= (ASN_BER_TLV_t
**)
190 Malloc(sizeof(*new_tlv
->V
.tlvs
.tlvs
));
191 new_tlv
->V
.tlvs
.tlvs
[0] = p_tlv
;
193 new_tlv
->V
.tlvs
.n_tlvs
= 0;
194 new_tlv
->V
.tlvs
.tlvs
= NULL
;
199 ASN_BER_TLV_t
* ASN_BER_TLV_t::construct(size_t p_Vlen
, unsigned char *p_Vstr
)
201 ASN_BER_TLV_t
*new_tlv
= (ASN_BER_TLV_t
*)Malloc(sizeof(*new_tlv
));
202 new_tlv
->isConstructed
= FALSE
;
203 new_tlv
->V_tlvs_selected
= FALSE
;
204 new_tlv
->isLenDefinite
= FALSE
;
205 new_tlv
->isLenShort
= FALSE
;
206 new_tlv
->isTagComplete
= FALSE
;
207 new_tlv
->isComplete
= FALSE
;
208 new_tlv
->tagclass
= ASN_TAG_UNIV
;
209 new_tlv
->tagnumber
= 0;
212 new_tlv
->Tstr
= NULL
;
213 new_tlv
->Lstr
= NULL
;
214 new_tlv
->V
.str
.Vlen
= p_Vlen
;
215 if (p_Vstr
!= NULL
) new_tlv
->V
.str
.Vstr
= p_Vstr
;
216 else new_tlv
->V
.str
.Vstr
= (unsigned char*)Malloc(p_Vlen
);
220 ASN_BER_TLV_t
* ASN_BER_TLV_t::construct()
222 ASN_BER_TLV_t
*new_tlv
= (ASN_BER_TLV_t
*)Malloc(sizeof(*new_tlv
));
223 new_tlv
->isConstructed
= FALSE
;
224 new_tlv
->V_tlvs_selected
= FALSE
;
225 new_tlv
->isLenDefinite
= FALSE
;
226 new_tlv
->isLenShort
= FALSE
;
227 new_tlv
->isTagComplete
= FALSE
;
228 new_tlv
->isComplete
= FALSE
;
229 new_tlv
->tagclass
= ASN_TAG_UNIV
;
230 new_tlv
->tagnumber
= 0;
233 new_tlv
->Tstr
= NULL
;
234 new_tlv
->Lstr
= NULL
;
235 new_tlv
->V
.str
.Vlen
= 0;
236 new_tlv
->V
.str
.Vstr
= NULL
;
240 void ASN_BER_TLV_t::destruct(ASN_BER_TLV_t
*p_tlv
, boolean no_str
)
242 if (p_tlv
== NULL
) return;
247 if(p_tlv
->V_tlvs_selected
) {
248 for(size_t i
=0; i
<p_tlv
->V
.tlvs
.n_tlvs
; i
++)
249 ASN_BER_TLV_t::destruct(p_tlv
->V
.tlvs
.tlvs
[i
], no_str
);
250 Free(p_tlv
->V
.tlvs
.tlvs
);
254 Free(p_tlv
->V
.str
.Vstr
);
259 void ASN_BER_TLV_t::chk_constructed_flag(boolean flag_expected
) const
261 if (Tlen
> 0 && isConstructed
!= flag_expected
)
262 TTCN_EncDec_ErrorContext::error
263 (TTCN_EncDec::ET_INVAL_MSG
,
264 "Invalid 'constructed' flag (must be %sset).",
265 flag_expected
?"":"un");
269 void ASN_BER_TLV_t::add_TLV(ASN_BER_TLV_t
*p_tlv
)
271 if(!isConstructed
|| !V_tlvs_selected
)
272 TTCN_EncDec_ErrorContext::error_internal
273 ("ASN_BER_TLV_t::add_TLV() invoked for a non-constructed TLV.");
275 V
.tlvs
.tlvs
=(ASN_BER_TLV_t
**)
276 Realloc(V
.tlvs
.tlvs
, V
.tlvs
.n_tlvs
*sizeof(*V
.tlvs
.tlvs
));
277 V
.tlvs
.tlvs
[V
.tlvs
.n_tlvs
-1]=p_tlv
;
280 void ASN_BER_TLV_t::add_UNIV0_TLV()
282 ASN_BER_TLV_t
*new_tlv
=(ASN_BER_TLV_t
*)Malloc(sizeof(*new_tlv
));
283 new_tlv
->isConstructed
=FALSE
;
284 new_tlv
->V_tlvs_selected
=FALSE
;
285 new_tlv
->isLenDefinite
=TRUE
;
286 new_tlv
->isLenShort
=TRUE
;
287 new_tlv
->tagclass
=ASN_TAG_UNIV
;
288 new_tlv
->tagnumber
=0;
290 new_tlv
->Tstr
=(unsigned char*)Malloc(1);
291 new_tlv
->Tstr
[0]=0x00;
293 new_tlv
->Lstr
=(unsigned char*)Malloc(1);
294 new_tlv
->Lstr
[0]=0x00;
295 new_tlv
->V
.str
.Vlen
=0;
296 new_tlv
->V
.str
.Vstr
=NULL
;
300 size_t ASN_BER_TLV_t::get_len() const
302 size_t len
=Tlen
+Llen
;
306 for(size_t i
=0; i
<V
.tlvs
.n_tlvs
; i
++)
307 len
+=V
.tlvs
.tlvs
[i
]->get_len();
311 void ASN_BER_TLV_t::add_TL(ASN_Tagclass_t p_tagclass
,
312 ASN_Tagnumber_t p_tagnumber
,
315 TTCN_EncDec_ErrorContext
ec("ASN_BER_TLV_t::add_TL(): ");
317 tagnumber
=p_tagnumber
;
319 if(coding
==BER_ENCODE_CER
&& isConstructed
) {
332 Llen
=1+(min_needed_bits(Vlen
)+7)/8;
340 Lstr
=(unsigned char*)Malloc(Llen
);
342 if(isLenShort
) Lstr
[0]=(unsigned char)Vlen
;
344 size_t i
=Llen
-1; // number of needed octets
345 Lstr
[0]=(i
& 0x7F) | 0x80;
354 else { // indefinite form
358 if(tagnumber
>30) Tlen
=1+(min_needed_bits(tagnumber
)+6)/7;
360 Tstr
=(unsigned char*)Malloc(Tlen
);
363 case ASN_TAG_UNIV
: Tstr
[0]=0x00; break;
364 case ASN_TAG_APPL
: Tstr
[0]=0x40; break;
365 case ASN_TAG_CONT
: Tstr
[0]=0x80; break;
366 case ASN_TAG_PRIV
: Tstr
[0]=0xC0; break;
369 ec
.error_internal("Unhandled case or undefined tagclass.");
372 if(isConstructed
) Tstr
[0]|=0x20;
373 if(tagnumber
<=30) Tstr
[0]|=(unsigned char)tagnumber
;
376 size_t tmp
=tagnumber
;
377 size_t i
=Tlen
-1; // number of needed octets
379 Tstr
[i
]=(tmp
& 0x7F) | 0x80;
386 isTagComplete
= TRUE
;
389 void ASN_BER_TLV_t::put_in_buffer(TTCN_Buffer
& p_buf
)
391 p_buf
.put_s(Tlen
, Tstr
);
392 p_buf
.put_s(Llen
, Lstr
);
395 p_buf
.put_s(V
.str
.Vlen
, V
.str
.Vstr
);
397 for(size_t i
=0; i
<V
.tlvs
.n_tlvs
; i
++)
398 V
.tlvs
.tlvs
[i
]->put_in_buffer(p_buf
);
401 unsigned char ASN_BER_TLV_t::get_pos(size_t p_pos
) const
404 boolean success
=FALSE
;
405 unsigned char c
=_get_pos(pos
, success
);
407 TTCN_EncDec_ErrorContext::error_internal
408 ("Index overflow in ASN_BER_TLV_t::get_pos()");
412 unsigned char ASN_BER_TLV_t::_get_pos(size_t& pos
, boolean
& success
) const
414 if(pos
<Tlen
) {success
=TRUE
; return Tstr
[pos
];}
416 if(pos
<Llen
) {success
=TRUE
; return Lstr
[pos
];}
419 if(!V_tlvs_selected
) {
420 if(pos
<V
.str
.Vlen
) {success
=TRUE
; return V
.str
.Vstr
[pos
];}
423 else { // V_tlvs_selected
424 for(size_t i
=0; i
<V
.tlvs
.n_tlvs
; i
++) {
425 unsigned char c
=V
.tlvs
.tlvs
[i
]->_get_pos(pos
, success
);
426 if(success
) return c
;
429 success
=FALSE
; return 0;
432 int ASN_BER_TLV_t::compare(const ASN_BER_TLV_t
*other
) const
434 size_t pos
=0, pos1
, pos2
;
437 unsigned char c1
, c2
;
440 c1
=_get_pos(pos1
, success1
);
441 c2
=other
->_get_pos(pos2
, success2
);
442 if(!success1
&& !success2
) return 0;
449 /** This functions is used by qsort() in
450 * ASN_BER_TLV_t::sort_tlvs(). */
451 int ASN_BER_compare_TLVs(const void *p1
, const void *p2
)
453 const ASN_BER_TLV_t
*left
=*((ASN_BER_TLV_t
const* const*)p1
);
454 const ASN_BER_TLV_t
*right
=*((ASN_BER_TLV_t
const* const*)p2
);
455 return left
->compare(right
);
458 void ASN_BER_TLV_t::sort_tlvs()
461 TTCN_EncDec_ErrorContext::error_internal
462 ("ASN_BER_TLV_t::sort_tlvs() called but !V_tlvs_selected");
463 qsort(V
.tlvs
.tlvs
, V
.tlvs
.n_tlvs
, sizeof(ASN_BER_TLV_t
*),
464 ASN_BER_compare_TLVs
);
467 int ASN_BER_TLV_t::compare_tags(const ASN_BER_TLV_t
*other
) const
469 if(tagclass
<other
->tagclass
) return -1;
470 if(tagclass
>other
->tagclass
) return 1;
471 if(tagnumber
<other
->tagnumber
) return -1;
472 if(tagnumber
>other
->tagnumber
) return 1;
476 /** This functions is used by qsort() in
477 * ASN_BER_TLV_t::sort_tlvs_tag(). */
478 int ASN_BER_compare_TLVs_tag(const void *p1
, const void *p2
)
480 const ASN_BER_TLV_t
*left
=*((ASN_BER_TLV_t
const* const*)p1
);
481 const ASN_BER_TLV_t
*right
=*((ASN_BER_TLV_t
const* const*)p2
);
482 return left
->compare_tags(right
);
485 void ASN_BER_TLV_t::sort_tlvs_tag()
488 TTCN_EncDec_ErrorContext::error_internal
489 ("ASN_BER_TLV_t::sort_tlvs_tag() called but !V_tlvs_selected");
490 qsort(V
.tlvs
.tlvs
, V
.tlvs
.n_tlvs
, sizeof(ASN_BER_TLV_t
*),
491 ASN_BER_compare_TLVs_tag
);
494 boolean
ASN_BER_str2TLV(size_t p_len_s
,
495 const unsigned char* p_str
,
502 TTCN_EncDec_ErrorContext
ec("While splitting TLV: ");
504 tlv
.isConstructed
=FALSE
;
505 tlv
.V_tlvs_selected
=FALSE
;
506 tlv
.isLenDefinite
=TRUE
;
508 tlv
.isTagComplete
=FALSE
;
509 tlv
.isComplete
=FALSE
;
510 tlv
.tagclass
=ASN_TAG_UNIV
;
521 tlv
.Tstr
=const_cast<unsigned char*>(p_str
);
523 switch((c
& 0xC0) >> 6) {
524 case 0: tlv
.tagclass
=ASN_TAG_UNIV
; break;
525 case 1: tlv
.tagclass
=ASN_TAG_APPL
; break;
526 case 2: tlv
.tagclass
=ASN_TAG_CONT
; break;
527 case 3: tlv
.tagclass
=ASN_TAG_PRIV
; break;
529 if(c
& 0x20) tlv
.isConstructed
=TRUE
;
530 else tlv
.isConstructed
=FALSE
;
532 if(c2
!= 0x1F) // low tag number
534 else { // high tag number
535 tlv
.tagnumber
=0; doit
=TRUE
;
536 boolean err_repr
=FALSE
;
539 if(curr_pos
>=p_len_s
)
543 if(tlv
.tagnumber
& ASN_Tagnumber_t_7msb
) {
545 ec
.error(TTCN_EncDec::ET_REPR
, "Tag number is too big.");
546 tlv
.tagnumber
=~(ASN_Tagnumber_t
)0;
550 tlv
.tagnumber
|=c
& 0x7F;
553 if(!(c
& 0x80)) doit
=FALSE
;
556 tlv
.isTagComplete
=TRUE
;
558 if(curr_pos
>=p_len_s
)
561 tlv
.Lstr
=const_cast<unsigned char*>(p_str
+curr_pos
);
562 tlv
.Tlen
=tlv
.Lstr
-tlv
.Tstr
;
563 tlv
.isLenDefinite
=TRUE
;
564 tlv
.isLenShort
=FALSE
;
566 if(!(c
& 0x80)) { // short form
570 if(!(L_form
& BER_ACCEPT_SHORT
)) {
571 ec
.error(TTCN_EncDec::ET_LEN_FORM
,
572 "Short length form is not acceptable.");
576 if(c
==0x80) { // indefinite len
578 tlv
.isLenDefinite
=FALSE
;
579 if(!(L_form
& BER_ACCEPT_INDEFINITE
)) {
580 ec
.error(TTCN_EncDec::ET_LEN_FORM
,
581 "Indefinite length form is not acceptable.");
584 else if(c
==0xFF) { // reserved len
585 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
586 "Error in L: In the long form, the value 0xFF shall"
587 " not be used (see X.690 clause 8.1.3.5.c)).");
588 // using as normal long form
591 if(!(L_form
& BER_ACCEPT_LONG
)) {
592 ec
.error(TTCN_EncDec::ET_LEN_FORM
,
593 "Long length form is not acceptable.");
595 tlv
.Llen
=(c
& 0x7F)+1;
596 if(tlv
.Tlen
+tlv
.Llen
>p_len_s
) {
597 tlv
.Llen
=p_len_s
-tlv
.Tlen
;
601 boolean err_repr
=FALSE
;
602 for(size_t i
=tlv
.Llen
-1; i
; i
--) {
604 if(tlv
.V
.str
.Vlen
& size_t_8msb
) {
606 ec
.error(TTCN_EncDec::ET_REPR
,
607 "In long form L: Length of V is too big.");
608 tlv
.V
.str
.Vlen
=~(size_t)0;
622 tlv
.V
.str
.Vstr
=const_cast<unsigned char*>(p_str
+curr_pos
);
623 if(tlv
.isLenDefinite
) {
624 if(tlv
.V
.str
.Vlen
>p_len_s
-tlv
.Tlen
-tlv
.Llen
) {
628 else { // indefinite len for V
629 if(!tlv
.isConstructed
) {
630 ec
.error(TTCN_EncDec::ET_INVAL_MSG
,
631 "A sender can use the indefinite form only if the"
632 " encoding is constructed (see X.690 clause 8.1.3.2.a).");
633 } // if !isConstructed
635 TTCN_EncDec_ErrorContext tmp_ec
;
636 ASN_BER_TLV_t tmp_tlv
;
641 tmp_ec
.set_msg("While checking constructed V part #%lu: ",
643 if(!ASN_BER_str2TLV(p_len_s
-curr_pos
, &p_str
[curr_pos
],
644 tmp_tlv
, BER_ACCEPT_ALL
))
646 tmp_len
=tmp_tlv
.get_len();
648 tlv
.V
.str
.Vlen
+=tmp_len
;
649 if(tmp_tlv
.tagclass
==ASN_TAG_UNIV
&& tmp_tlv
.tagnumber
==0)
650 doit
=FALSE
; // End-of-contents
653 // tlv.V.str.Vlen=&p_str[curr_pos]-tlv.V.str.Vstr;
654 } // if indefinite len for V
658 if(tlv
.Tlen
==0) tlv
.Tlen
=p_len_s
;
659 if(tlv
.V
.str
.Vstr
!=NULL
&& tlv
.V
.str
.Vstr
>tlv
.Lstr
+tlv
.Llen
)
660 tlv
.Llen
=tlv
.V
.str
.Vstr
-tlv
.Lstr
;
661 if(tlv
.Tlen
+tlv
.Llen
+tlv
.V
.str
.Vlen
>p_len_s
)
662 tlv
.V
.str
.Vlen
=p_len_s
-tlv
.Tlen
-tlv
.Llen
;
666 ASN_BER_TLV_t
* ASN_BER_V2TLV(ASN_BER_TLV_t
* p_tlv
,
667 const TTCN_Typedescriptor_t
& p_td
,
670 if(p_td
.ber
->n_tags
==0) return p_tlv
;
672 if(!(p_tlv
->tagclass
==ASN_TAG_UNIV
&& p_tlv
->tagnumber
==0))
673 tlv2
=ASN_BER_TLV_t::construct(p_tlv
);
675 const ASN_BERdescriptor_t
*ber
=p_td
.ber
;
676 for(size_t i
=0; i
<ber
->n_tags
; i
++) {
677 const ASN_Tag_t
*tag
=ber
->tags
+i
;
678 tlv2
->add_TL(tag
->tagclass
, tag
->tagnumber
, coding
);
680 tlv2
=ASN_BER_TLV_t::construct(tlv2
);