gwenhywfar 5.12.0
tlv.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Sun Jun 13 2004
3 copyright : (C) 2004-2011 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10
11#ifdef HAVE_CONFIG_H
12# include <config.h>
13#endif
14
15#define DISABLE_DEBUGLOG
16
17
18#include "tlv_p.h"
19#include <gwenhywfar/debug.h>
20#include <gwenhywfar/inherit.h>
21#include <gwenhywfar/misc.h>
22#include <gwenhywfar/text.h>
23
24#include <stdlib.h>
25#include <assert.h>
26#include <string.h>
27
28#define BER_TLV_TAG_FIRST_BYTE_BYTE_FOLLOWS 0b00011111
29#define BER_TLV_TAG_SECOND_BYTE_BYTE_FOLLOWS 0b10000000
30#define BER_TLV_TAG_IS_CONSTRUCTED 0b00100000
31
33
34
36{
37 GWEN_TLV *tlv;
38
41
42 return tlv;
43}
44
45
46
48{
49 if (tlv) {
50 free(tlv->tagData);
53 }
54}
55
56
57
58GWEN_TLV *GWEN_TLV_create(unsigned int tagType,
59 unsigned int tagMode,
60 const void *p,
61 unsigned int dlen,
62 int isBerTlv)
63{
64 GWEN_TLV *tlv;
65
66 /* some checks first */
67 if (tagType>255) {
68 DBG_ERROR(GWEN_LOGDOMAIN, "Tag type too high");
69 abort();
70 }
71 if (isBerTlv) {
72 if (dlen>65535) {
73 DBG_ERROR(GWEN_LOGDOMAIN, "Data too long");
74 abort();
75 }
76 }
77 else {
78 if (dlen>255) {
79 DBG_ERROR(GWEN_LOGDOMAIN, "Data too long");
80 abort();
81 }
82 }
83
84 /* limits ok, create TLV */
85 tlv=GWEN_TLV_new();
86 tlv->tagType=tagType;
87 tlv->tagMode=tagMode;
88 tlv->isBerTlv=isBerTlv;
89
90 tlv->tagLength=dlen;
91 if (dlen) {
92 tlv->tagData=malloc(dlen);
93 assert(tlv->tagData);
94 memmove(tlv->tagData, p, dlen);
95 }
96
97 return tlv;
98}
99
100
101
103{
104 assert(tlv);
105 return tlv->isBerTlv;
106}
107
108
109
110unsigned int GWEN_TLV_GetTagType(const GWEN_TLV *tlv)
111{
112 assert(tlv);
113 return tlv->tagType;
114}
115
116
117
118unsigned int GWEN_TLV_GetTagLength(const GWEN_TLV *tlv)
119{
120 assert(tlv);
121 return tlv->tagLength;
122}
123
124
125
126unsigned int GWEN_TLV_GetTagSize(const GWEN_TLV *tlv)
127{
128 assert(tlv);
129 return tlv->tagSize;
130}
131
132
133
134const void *GWEN_TLV_GetTagData(const GWEN_TLV *tlv)
135{
136 assert(tlv);
137 return tlv->tagData;
138}
139
140
141
143{
144 const char *p;
145 unsigned int tagMode;
146 unsigned int tagType;
147 unsigned int tagLength;
148 const char *tagData;
149 unsigned int size;
150 unsigned int pos;
151 unsigned int j;
152 GWEN_TLV *tlv;
153 uint32_t startPos;
154
155 if (!GWEN_Buffer_GetBytesLeft(mbuf)) {
156 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer empty");
157 return 0;
158 }
159
160 startPos=GWEN_Buffer_GetPos(mbuf);
161
162 tagMode=tagType=tagLength=0;
163
165 pos=0;
166 size=GWEN_Buffer_GetBytesLeft(mbuf);
167
168 /* get tag type */
169 if (size<2) {
170 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes for BER-TLV");
171 return 0;
172 }
173 j=(unsigned char)(p[pos]);
174 tagMode=(j & 0xe0);
175 if (isBerTlv) {
176 if ((j & 0x1f)==0x1f) {
177 pos++;
178 if (pos>=size) {
179 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
180 return 0;
181 }
182 j=(unsigned char)(p[pos]);
183 }
184 else
185 j&=0x1f;
186 }
187 DBG_DEBUG(GWEN_LOGDOMAIN, "Tag type %02x%s", j,
188 isBerTlv?" (BER-TLV)":"");
189 tagType=j;
190
191 /* get length */
192 pos++;
193 if (pos>=size) {
194 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
195 return 0;
196 }
197 j=(unsigned char)(p[pos]);
198 if (isBerTlv) {
199 if (j & 0x80) {
200 if (j==0x81) {
201 pos++;
202 if (pos>=size) {
203 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
204 return 0;
205 }
206 j=(unsigned char)(p[pos]);
207 } /* 0x81 */
208 else if (j==0x82) {
209 if (pos+1>=size) {
210 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
211 return 0;
212 }
213 pos++;
214 j=((unsigned char)(p[pos]))<<8;
215 pos++;
216 j+=(unsigned char)(p[pos]);
217 } /* 0x82 */
218 else {
219 DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected tag length modifier %02x at %d", j, pos);
220 return 0;
221 }
222 } /* if tag length modifier */
223 }
224 else {
225 if (j==255) {
226 if (pos+2>=size) {
227 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
228 return 0;
229 }
230 pos++;
231 j=((unsigned char)(p[pos]))<<8;
232 pos++;
233 j+=(unsigned char)(p[pos]);
234 }
235 }
236 pos++;
237 tagLength=j;
238 tagData=p+pos;
239 GWEN_Buffer_IncrementPos(mbuf, pos);
240
241 DBG_DEBUG(GWEN_LOGDOMAIN, "Tag: %02x (%d bytes)", tagType, tagLength);
242 if (pos+j>size) {
243 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
244 return 0;
245 }
246
247 tlv=GWEN_TLV_new();
248 assert(tlv);
249 tlv->isBerTlv=isBerTlv;
250 tlv->tagMode=tagMode;
251 tlv->tagType=tagType;
252 tlv->tagLength=tagLength;
253 if (tagLength) {
254 tlv->tagData=(void *)malloc(tagLength);
255 memmove(tlv->tagData, tagData, tagLength);
256 }
257
258 GWEN_Buffer_IncrementPos(mbuf, tagLength);
259 tlv->tagSize=GWEN_Buffer_GetPos(mbuf)-startPos;
260 return tlv;
261}
262
263
264
266{
267 assert(tlv);
268 return (tlv->tagMode & 0x20);
269}
270
271
272
273unsigned int GWEN_TLV_GetClass(const GWEN_TLV *tlv)
274{
275 assert(tlv);
276 return (tlv->tagMode & 0xc0);
277}
278
279
280
282{
283 assert(tlv);
284 return GWEN_TLV_DirectlyToBuffer(tlv->tagType,
285 tlv->tagMode,
286 tlv->tagData,
287 tlv->tagLength,
288 tlv->isBerTlv,
289 mbuf);
290}
291
292
293
294int GWEN_TLV_DirectlyToBuffer(unsigned int tagType,
295 unsigned int tagMode,
296 const void *tagData,
297 int tagLength,
298 int isBerTlv,
299 GWEN_BUFFER *mbuf)
300{
301 if (tagLength==-1)
302 tagLength=strlen(tagData);
303
304 if (isBerTlv) {
305 unsigned char j;
306
307 /* write tag type */
308 j=tagMode;
309 if (tagType>=0x1f) {
310 j|=0x1f;
311 GWEN_Buffer_AppendByte(mbuf, j);
312 GWEN_Buffer_AppendByte(mbuf, (unsigned char)tagType);
313 }
314 else {
315 j|=tagType;
316 GWEN_Buffer_AppendByte(mbuf, j);
317 }
318
319 /* write tag length */
320 if (tagLength>255) {
321 /* two byte size */
322 GWEN_Buffer_AppendByte(mbuf, 0x82);
323 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>8) & 0xff));
324 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
325 }
326 else if (tagLength>127) {
327 /* one byte size */
328 GWEN_Buffer_AppendByte(mbuf, 0x81);
329 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
330 }
331 else {
332 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0x7f));
333 }
334
335 /* write tag data */
336 if (tagLength)
337 GWEN_Buffer_AppendBytes(mbuf, tagData, tagLength);
338 }
339 else {
340 /* write tag type */
341 GWEN_Buffer_AppendByte(mbuf, (unsigned char)tagType);
342
343 /* write tag length */
344 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
345
346 /* write tag data */
347 if (tagLength)
348 GWEN_Buffer_AppendBytes(mbuf, tagData, tagLength);
349 }
350
351 return 0;
352}
353
354
355
356int GWEN_TLV_ReadHeader(GWEN_TLV *tlv, const uint8_t *p, uint32_t size, int isBerTlv)
357{
358 uint64_t tagMode;
359 uint64_t tagType;
360 uint64_t tagLength;
361 unsigned int pos;
362 uint64_t j;
363
364 tagMode=tagType=tagLength=0;
365
366 pos=0;
367
368 /* get tag type */
369 if (size<2) {
370 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes for TLV");
371 return GWEN_ERROR_BAD_DATA;
372 }
373 j=(unsigned char)(p[pos]);
374 tagMode=(j & 0xe0);
375 if (isBerTlv) {
376 if ((j & 0x1f)==0x1f) {
377 pos++;
378 if (pos>=size) {
379 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
380 return 0;
381 }
382 j=(unsigned char)(p[pos]);
383 }
384 else
385 j&=0x1f;
386 }
387 DBG_DEBUG(GWEN_LOGDOMAIN, "Tag type %02x%s", j,
388 isBerTlv?" (BER-TLV)":"");
389 tagType=j;
390
391 /* get length */
392 pos++;
393 if (pos>=size) {
394 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
395 return GWEN_ERROR_BAD_DATA;
396 }
397 j=(unsigned char)(p[pos]);
398 if (isBerTlv) {
399 if (j & 0x80) {
400 if (j==0x81) {
401 pos++;
402 if (pos>=size) {
403 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
404 return GWEN_ERROR_BAD_DATA;
405 }
406 j=(unsigned char)(p[pos]);
407 } /* 0x81 */
408 else if (j==0x82) {
409 if (pos+1>=size) {
410 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
411 return GWEN_ERROR_BAD_DATA;
412 }
413 pos++;
414 j=((unsigned char)(p[pos]))<<8;
415 pos++;
416 j+=(unsigned char)(p[pos]);
417 } /* 0x82 */
418 else if (j==0x83) {
419 if (pos+2>=size) {
420 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
421 return GWEN_ERROR_BAD_DATA;
422 }
423 pos++;
424 j=((unsigned char)(p[pos]))<<16;
425 pos++;
426 j+=((unsigned char)(p[pos]))<<8;
427 pos++;
428 j+=(unsigned char)(p[pos]);
429 } /* 0x83 */
430 else if (j==0x84) {
431 if (pos+3>=size) {
432 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
433 return GWEN_ERROR_BAD_DATA;
434 }
435 pos++;
436 j=((unsigned char)(p[pos]))<<24;
437 pos++;
438 j+=((unsigned char)(p[pos]))<<16;
439 pos++;
440 j+=((unsigned char)(p[pos]))<<8;
441 pos++;
442 j+=(unsigned char)(p[pos]);
443 } /* 0x84 */
444 else if (j==0x85) {
445 if (pos+4>=size) {
446 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
447 return GWEN_ERROR_BAD_DATA;
448 }
449 pos++;
450 j=((uint64_t)((unsigned char)(p[pos])))<<32;
451 pos++;
452 j+=((uint64_t)((unsigned char)(p[pos])))<<24;
453 pos++;
454 j+=((uint64_t)((unsigned char)(p[pos])))<<16;
455 pos++;
456 j+=((uint64_t)((unsigned char)(p[pos])))<<8;
457 pos++;
458 j+=(unsigned char)(p[pos]);
459 } /* 0x85 */
460 else {
461 DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected tag length modifier %02x at %d", (int) j, pos);
462 return GWEN_ERROR_BAD_DATA;
463 }
464 } /* if tag length modifier */
465 }
466 else {
467 if (j==255) {
468 if (pos+2>=size) {
469 DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
470 return GWEN_ERROR_BAD_DATA;
471 }
472 pos++;
473 j=((unsigned char)(p[pos]))<<8;
474 pos++;
475 j+=(unsigned char)(p[pos]);
476 }
477 }
478 pos++;
479 tagLength=j;
480
481 DBG_DEBUG(GWEN_LOGDOMAIN, "Tag: %02x (%d bytes)", tagType, tagLength);
482
483 tlv->isBerTlv=isBerTlv;
484 tlv->tagMode=tagMode;
485 tlv->tagType=tagType;
486 tlv->tagLength=tagLength;
487
488 tlv->tagSize=pos+tagLength;
489 return (int) pos;
490}
491
492
493
494int GWEN_TLV_WriteHeader(unsigned int tagType,
495 unsigned int tagMode,
496 uint64_t tagLength,
497 int isBerTlv,
498 GWEN_BUFFER *mbuf)
499{
500 if (isBerTlv) {
501 unsigned char j;
502
503 /* write tag type */
504 j=tagMode;
505 if (tagType>=0x1f) {
506 j|=0x1f;
507 GWEN_Buffer_AppendByte(mbuf, j);
508 GWEN_Buffer_AppendByte(mbuf, (unsigned char)tagType);
509 }
510 else {
511 j|=tagType;
512 GWEN_Buffer_AppendByte(mbuf, j);
513 }
514
515 /* write tag length */
516 if (tagLength>0xffffffffL) {
517 /* five byte size */
518 GWEN_Buffer_AppendByte(mbuf, 0x85);
519 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>32) & 0xff));
520 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>24) & 0xff));
521 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>16) & 0xff));
522 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>8) & 0xff));
523 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
524 }
525 else if (tagLength>0xffffffL) {
526 /* four byte size */
527 GWEN_Buffer_AppendByte(mbuf, 0x84);
528 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>24) & 0xff));
529 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>16) & 0xff));
530 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>8) & 0xff));
531 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
532 }
533 else if (tagLength>0xffff) {
534 /* three byte size */
535 GWEN_Buffer_AppendByte(mbuf, 0x83);
536 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>16) & 0xff));
537 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>8) & 0xff));
538 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
539 }
540 else if (tagLength>0xff) {
541 /* two byte size */
542 GWEN_Buffer_AppendByte(mbuf, 0x82);
543 GWEN_Buffer_AppendByte(mbuf, ((tagLength>>8) & 0xff));
544 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
545 }
546 else if (tagLength>127) {
547 /* one byte size */
548 GWEN_Buffer_AppendByte(mbuf, 0x81);
549 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
550 }
551 else {
552 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0x7f));
553 }
554 }
555 else {
556 /* write tag type */
557 GWEN_Buffer_AppendByte(mbuf, (unsigned char)tagType);
558
559 /* write tag length */
560 GWEN_Buffer_AppendByte(mbuf, (tagLength & 0xff));
561 }
562
563 return 0;
564}
565
566static void hex2char(char byte, char *character)
567{
568 uint8_t nibbles[2];
569 int i;
570 nibbles[0]=(byte>>4) &0x0f;
571 nibbles[1]=byte & 0x0f;
572
573 for (i = 0 ; i < 2 ; i++) {
574 switch (nibbles[i]) {
575 case 0:
576 character[i]='0';
577 break;
578 case 1:
579 character[i]='1';
580 break;
581 case 2:
582 character[i]='2';
583 break;
584 case 3:
585 character[i]='3';
586 break;
587 case 4:
588 character[i]='4';
589 break;
590 case 5:
591 character[i]='5';
592 break;
593 case 6:
594 character[i]='6';
595 break;
596 case 7:
597 character[i]='7';
598 break;
599 case 8:
600 character[i]='8';
601 break;
602 case 9:
603 character[i]='9';
604 break;
605 case 10:
606 character[i]='A';
607 break;
608 case 11:
609 character[i]='B';
610 break;
611 case 12:
612 character[i]='C';
613 break;
614 case 13:
615 character[i]='D';
616 break;
617 case 14:
618 character[i]='E';
619 break;
620 case 15:
621 character[i]='F';
622 break;
623 default: /* can't get here, this is just to keep the compiler happy */
624 break;
625 }
626 }
627}
628
629int GWEN_TLV_Buffer_To_DB(GWEN_DB_NODE *dbRecord, GWEN_BUFFER *mbuf, int len)
630{
631 int tlv_len=0;
632 unsigned int tag_len=0;
633 uint32_t data_len;
634 uint8_t byte;
635 int isConstructed;
636 int anotherByte;
637 char tag[128];
638 GWEN_DB_NODE *dbTLV;
639
640
641 /* get first byte */
642 while (tlv_len < len) {
643 tag_len=0;
644 memset(tag, '\0', 128);
645 byte = GWEN_Buffer_ReadByte(mbuf);
646 isConstructed = byte & BER_TLV_TAG_IS_CONSTRUCTED;
647 tlv_len++;
648 hex2char(byte, &tag[tag_len++]);
650 while (anotherByte) {
651 byte = GWEN_Buffer_ReadByte(mbuf);
652 tlv_len++;
653 hex2char(byte, &tag[tag_len++]);
654 anotherByte= byte > 127;
655 }
656 dbTLV=GWEN_DB_Group_new(tag);
657 byte = GWEN_Buffer_ReadByte(mbuf);
658 tlv_len++;
659 if (byte >= 0x81) {
660 uint8_t numLengthBytes= byte-128;
661 assert(byte!=0xFF);
662 data_len=0;
663 while (numLengthBytes--) {
664 byte = GWEN_Buffer_ReadByte(mbuf);
665 tlv_len++;
666 data_len<<=8;
667 data_len+=(uint32_t)byte;
668 }
669 }
670 else {
671 data_len= (uint8_t) byte;
672 }
673 GWEN_DB_SetIntValue(dbTLV, 0, "length", data_len);
674 if (isConstructed) {
675 tlv_len+=GWEN_TLV_Buffer_To_DB(dbTLV, mbuf, data_len);
676 }
677 else {
678 char *buffer;
679
680 buffer=(char *)GWEN_Memory_malloc((data_len*2)+1);
681 assert(buffer);
683 buffer, data_len*2+1);
684 GWEN_DB_SetCharValue(dbTLV, 0, "data", buffer);
685 GWEN_DB_SetBinValue(dbTLV, 0, "dataBin", GWEN_Buffer_GetPosPointer(mbuf), data_len);
686 GWEN_Memory_dealloc(buffer);
687 GWEN_Buffer_IncrementPos(mbuf, data_len);
688 tlv_len+=data_len;
689
690 }
691 GWEN_DB_AddGroup(dbRecord, dbTLV);
692 }
693 assert(len==tlv_len);
694 return tlv_len;
695}
696
697
698
699uint32_t GWEN_TLV_ParseLength(GWEN_BUFFER *mbuf, uint32_t *tag_len_len)
700{
701 uint32_t data_len=0;
702 uint32_t tlv_len=0;
703 int rv;
704 uint8_t byte;
705 uint8_t anotherByte;
706
707 /* get first byte */
708 rv=GWEN_Buffer_ReadByte(mbuf);
709 if (rv<0) {
710 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
711 abort();
712 return 0;
713 }
714 byte=(uint8_t) rv;
715 tlv_len++;
717 while (anotherByte) {
718 rv=GWEN_Buffer_ReadByte(mbuf);
719 if (rv<0) {
720 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
721 abort();
722 return 0;
723 }
724 byte=(uint8_t) rv;
725 tlv_len++;
726 anotherByte= byte > 127;
727 }
728 byte = GWEN_Buffer_ReadByte(mbuf);
729 tlv_len++;
730 if (byte & 0x80) {
731 uint8_t numLengthBytes= byte-128;
732 assert(byte!=0xFF);
733 data_len=0;
734 while (numLengthBytes--) {
735 rv=GWEN_Buffer_ReadByte(mbuf);
736 if (rv<0) {
737 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
738 abort();
739 return 0;
740 }
741 byte=(uint8_t) rv;
742 tlv_len++;
743 data_len<<=8;
744 data_len+=(uint32_t)byte;
745 }
746 }
747 else {
748 data_len= (uint8_t) byte;
749 }
750 *tag_len_len=tlv_len;
751
752 return data_len;
753}
754
755
756
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:451
uint32_t GWEN_Buffer_GetBytesLeft(GWEN_BUFFER *bf)
Definition buffer.c:536
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition buffer.c:548
int GWEN_Buffer_AppendBytes(GWEN_BUFFER *bf, const char *buffer, uint32_t size)
Definition buffer.c:360
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition buffer.c:253
int GWEN_Buffer_ReadByte(GWEN_BUFFER *bf)
Definition buffer.c:438
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition buffer.c:393
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition db.c:173
int GWEN_DB_SetIntValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, int val)
Definition db.c:1202
int GWEN_DB_AddGroup(GWEN_DB_NODE *n, GWEN_DB_NODE *nn)
Definition db.c:1482
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
int GWEN_DB_SetBinValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const void *val, unsigned int valSize)
Definition db.c:1269
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_DEBUG(dbg_logger, format,...)
Definition debug.h:214
#define GWEN_ERROR_BAD_DATA
Definition error.h:121
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_LIST_FINI(t, element)
Definition list1.h:475
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition list1.h:367
#define GWEN_LIST_INIT(t, element)
Definition list1.h:466
#define GWEN_LOGDOMAIN
Definition logger.h:35
void * GWEN_Memory_malloc(size_t wsize)
Definition memory.c:39
void GWEN_Memory_dealloc(void *p)
Definition memory.c:69
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
char * GWEN_Text_ToHex(const char *src, unsigned l, char *buffer, unsigned int maxsize)
Definition text.c:657
int GWEN_TLV_IsBerTlv(const GWEN_TLV *tlv)
Definition tlv.c:102
unsigned int GWEN_TLV_GetTagLength(const GWEN_TLV *tlv)
Definition tlv.c:118
GWEN_TLV * GWEN_TLV_create(unsigned int tagType, unsigned int tagMode, const void *p, unsigned int dlen, int isBerTlv)
Definition tlv.c:58
int GWEN_TLV_Buffer_To_DB(GWEN_DB_NODE *dbRecord, GWEN_BUFFER *mbuf, int len)
Definition tlv.c:629
#define BER_TLV_TAG_IS_CONSTRUCTED
Definition tlv.c:30
unsigned int GWEN_TLV_GetTagType(const GWEN_TLV *tlv)
Definition tlv.c:110
static void hex2char(char byte, char *character)
Definition tlv.c:566
const void * GWEN_TLV_GetTagData(const GWEN_TLV *tlv)
Definition tlv.c:134
GWEN_TLV * GWEN_TLV_new(void)
Definition tlv.c:35
int GWEN_TLV_ReadHeader(GWEN_TLV *tlv, const uint8_t *p, uint32_t size, int isBerTlv)
Definition tlv.c:356
void GWEN_TLV_free(GWEN_TLV *tlv)
Definition tlv.c:47
GWEN_TLV * GWEN_TLV_fromBuffer(GWEN_BUFFER *mbuf, int isBerTlv)
Definition tlv.c:142
unsigned int GWEN_TLV_GetTagSize(const GWEN_TLV *tlv)
Definition tlv.c:126
int GWEN_TLV_IsContructed(const GWEN_TLV *tlv)
Definition tlv.c:265
int GWEN_TLV_toBuffer(GWEN_TLV *tlv, GWEN_BUFFER *mbuf)
Definition tlv.c:281
uint32_t GWEN_TLV_ParseLength(GWEN_BUFFER *mbuf, uint32_t *tag_len_len)
Definition tlv.c:699
int GWEN_TLV_DirectlyToBuffer(unsigned int tagType, unsigned int tagMode, const void *tagData, int tagLength, int isBerTlv, GWEN_BUFFER *mbuf)
Definition tlv.c:294
unsigned int GWEN_TLV_GetClass(const GWEN_TLV *tlv)
Definition tlv.c:273
#define BER_TLV_TAG_FIRST_BYTE_BYTE_FOLLOWS
Definition tlv.c:28
int GWEN_TLV_WriteHeader(unsigned int tagType, unsigned int tagMode, uint64_t tagLength, int isBerTlv, GWEN_BUFFER *mbuf)
Definition tlv.c:494
struct GWEN_TLV GWEN_TLV
Definition tlv.h:19