gwenhywfar 5.14.1
tag16.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Sun Jun 13 2004
3 copyright : (C) 2024 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14#define DISABLE_DEBUGLOG
15
16
17#include "tag16_p.h"
18#include <gwenhywfar/debug.h>
19#include <gwenhywfar/inherit.h>
20#include <gwenhywfar/misc.h>
21#include <gwenhywfar/text.h>
22#include <gwenhywfar/portable_endian.h>
23
24#include <stdlib.h>
25#include <assert.h>
26#include <string.h>
27
28
29
31
32
33
34/* ------------------------------------------------------------------------------------------------
35 * forward declarations
36 * ------------------------------------------------------------------------------------------------
37 */
38
39static void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf);
40
41
42
43/* ------------------------------------------------------------------------------------------------
44 * code
45 * ------------------------------------------------------------------------------------------------
46 */
47
49{
50 GWEN_TAG16 *tag;
51
54
55 return tag;
56}
57
58
59
60GWEN_TAG16 *GWEN_Tag16_newNoCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
61{
62 GWEN_TAG16 *tag;
63
64 tag=GWEN_Tag16_new();
65 tag->tagType=tagType;
66 tag->tagLength=tagLength;
67 if (tagLength) {
68 tag->tagData=tagData;
69 tag->dataOwned=0;
70 }
71
72 tag->tagSize=tagLength+3;
73 return tag;
74}
75
76
77
78GWEN_TAG16 *GWEN_Tag16_newCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
79{
80 GWEN_TAG16 *tag;
81
82 tag=GWEN_Tag16_new();
83 tag->tagType=tagType;
84 tag->tagLength=tagLength;
85 if (tagLength) {
86 uint8_t *p;
87
88 p=malloc(tagLength);
89 memmove(p, tagData, tagLength);
90 tag->tagData=(const uint8_t*)p;
91 tag->dataOwned=1;
92 }
93
94 tag->tagSize=tagLength+3;
95 return tag;
96}
97
98
99
100
101
102
104{
105 if (tag) {
106 if (tag->dataOwned)
107 free((uint8_t*)(tag->tagData));
109 GWEN_FREE_OBJECT(tag);
110 }
111}
112
113
114
115unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
116{
117 return tag?(tag->tagType):0;
118}
119
120
121
122unsigned int GWEN_Tag16_GetTagLength(const GWEN_TAG16 *tag)
123{
124 return tag?(tag->tagLength):0;
125}
126
127
128
129unsigned int GWEN_Tag16_GetTagSize(const GWEN_TAG16 *tag)
130{
131 return tag?(tag->tagSize):0;
132}
133
134
135
136const void *GWEN_Tag16_GetTagData(const GWEN_TAG16 *tag)
137{
138 return tag?(tag->tagData):NULL;
139}
140
141
142
144{
145
146 GWEN_TAG16 *tag;
147
149 if (tag)
150 GWEN_Buffer_IncrementPos(mbuf, tag->tagSize);
151 return tag;
152}
153
154
155
156GWEN_TAG16 *GWEN_Tag16_fromBuffer2(const uint8_t *bufferPtr, uint32_t bufferLen, int doCopy)
157{
158 unsigned int tagType;
159 unsigned int tagLength;
160
161 if (bufferLen<3) {
162 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small to contain a TAG16 object (%d < 3)", bufferLen);
163 return NULL;
164 }
165
166 tagType=*(bufferPtr++);
167 bufferLen--;
168 tagLength=(uint16_t)(bufferPtr[0])+(bufferPtr[1]<<8);
169 bufferPtr+=2;
170 bufferLen-=2;
171 if (bufferLen<tagLength) {
172 DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small to contain complete TAG16 object with data (%d < %d)", bufferLen, tagLength);
173 return NULL;
174 }
175
176 return (doCopy?GWEN_Tag16_newCopy(tagType, tagLength, bufferPtr):GWEN_Tag16_newNoCopy(tagType, tagLength, bufferPtr));
177}
178
179
180
181void GWEN_Tag16_WriteStringTagToBuffer(unsigned int tagType, const char *s, GWEN_BUFFER *buf)
182{
183 _writeTagToBuffer(tagType, (const uint8_t*) s, s?(strlen(s)+1):0, buf);
184}
185
186
187
188void GWEN_Tag16_WriteUint8TagToBuffer(unsigned int tagType, uint8_t data, GWEN_BUFFER *buf)
189{
190 _writeTagToBuffer(tagType, (const uint8_t*) &data, 1, buf);
191}
192
193
194
195void GWEN_Tag16_WriteUint16TagToBuffer(unsigned int tagType, uint16_t data, GWEN_BUFFER *buf)
196{
197 uint16_t dataInLittleEndian;
198
199 dataInLittleEndian=htole16(data);
200 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint16_t), buf);
201}
202
203
204
205void GWEN_Tag16_WriteUint32TagToBuffer(unsigned int tagType, uint32_t data, GWEN_BUFFER *buf)
206{
207 uint32_t dataInLittleEndian;
208
209 dataInLittleEndian=htole32(data);
210 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint32_t), buf);
211}
212
213
214
215void GWEN_Tag16_WriteUint64TagToBuffer(unsigned int tagType, uint64_t data, GWEN_BUFFER *buf)
216{
217 uint64_t dataInLittleEndian;
218
219 dataInLittleEndian=htole64(data);
220 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint64_t), buf);
221}
222
223
224
225void GWEN_Tag16_WriteDoubleTagToBuffer(unsigned int tagType, double data, GWEN_BUFFER *buf)
226{
227 uint64_t dataInLittleEndian;
228 union {
229 double d;
230 uint64_t u;
231 } v;
232
233 v.d=data;
234 dataInLittleEndian=htole64(v.u);
235 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint64_t), buf);
236}
237
238
239
240void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType,
241 const char *p,
242 int size,
243 GWEN_BUFFER *buf)
244{
245 _writeTagToBuffer(tagType, (const uint8_t*) p, (size==-1)?strlen(p):size, buf);
246}
247
248
249
250uint8_t GWEN_Tag16_GetTagDataAsUint8(const GWEN_TAG16 *tag, uint8_t defaultValue)
251{
252 if (tag && tag->tagLength>=sizeof(uint8_t))
253 return *(uint8_t*)(tag->tagData);
254 return defaultValue;
255}
256
257
258
259uint16_t GWEN_Tag16_GetTagDataAsUint16(const GWEN_TAG16 *tag, uint16_t defaultValue)
260{
261 if (tag && tag->tagLength>=sizeof(uint16_t))
262 return le16toh(*(uint16_t*)(tag->tagData));
263 return defaultValue;
264}
265
266
267
268uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
269{
270 if (tag && tag->tagLength>=sizeof(uint32_t))
271 return le32toh(*(uint32_t*)(tag->tagData));
272 return defaultValue;
273}
274
275
276
277uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
278{
279 if (tag && tag->tagLength>=sizeof(uint64_t))
280 return le64toh(*(uint64_t*)(tag->tagData));
281 return defaultValue;
282}
283
284
285
286double GWEN_Tag16_GetTagDataAsDouble(const GWEN_TAG16 *tag, double defaultValue)
287{
288 if (tag && tag->tagLength>=sizeof(uint64_t)) {
289 union {
290 double d;
291 uint64_t u;
292 } v;
293
294 v.u=le64toh(*(uint64_t*)(tag->tagData));
295 return v.d;
296 }
297 return defaultValue;
298}
299
300
301
302char *GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
303{
304 if (tag && tag->tagLength)
305 return GWEN_Text_strndup((const char*)(tag->tagData), tag->tagLength);
306 return defaultValue?strdup(defaultValue):NULL;
307}
308
309
310
311const GWEN_TAG16 *GWEN_Tag16_List_FindFirstByTagType(const GWEN_TAG16_LIST *tagList, unsigned int tagType)
312{
313 const GWEN_TAG16 *tag;
314
315 tag=GWEN_Tag16_List_First(tagList);
316 while(tag) {
317 if (tag->tagType==tagType)
318 return tag;
319 tag=GWEN_Tag16_List_Next(tag);
320 }
321
322 return NULL;
323}
324
325
326
327const GWEN_TAG16 *GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
328{
329 if (tag) {
330 tag=GWEN_Tag16_List_Next(tag);
331 while(tag) {
332 if (tag->tagType==tagType)
333 return tag;
334 tag=GWEN_Tag16_List_Next(tag);
335 }
336 }
337
338 return NULL;
339}
340
341
342
343GWEN_TAG16_LIST *GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
344{
345 GWEN_TAG16_LIST *tagList;
346
347 tagList=GWEN_Tag16_List_new();
348 while(l) {
349 GWEN_TAG16 *tag;
350
351 tag=GWEN_Tag16_fromBuffer2(p, l, doCopy);
352 if (tag==NULL) {
353 DBG_INFO(GWEN_LOGDOMAIN, "here");
354 GWEN_Tag16_List_free(tagList);
355 return NULL;
356 }
357 GWEN_Tag16_List_Add(tag, tagList);
358 if (l<tag->tagSize) {
359 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid remaining data (%d < %d)", l, tag->tagSize);
360 GWEN_Tag16_List_free(tagList);
361 return NULL;
362 }
363 p+=tag->tagSize;
364 l-=tag->tagSize;
365 }
366
367 if (GWEN_Tag16_List_GetCount(tagList)<1) {
368 DBG_ERROR(GWEN_LOGDOMAIN, "No entries in tag list");
369 GWEN_Tag16_List_free(tagList);
370 return NULL;
371 }
372 return tagList;
373}
374
375
376
377void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
378{
379 _writeTagToBuffer(tagType, s, size, buf);
380}
381
382
383
384void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
385{
386 if (GWEN_Buffer_AllocRoom(buf, size+3)==0) {
387 uint8_t *posPtr;
388
389 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
390 *(posPtr++)=tagType & 0xff;
391 *(posPtr++)=size & 0xff;
392 *(posPtr++)=(size>>8) & 0xff;
393 if (size)
394 memmove(posPtr, p, size);
395 GWEN_Buffer_IncrementPos(buf, size+3);
397 }
398 else {
399 DBG_INFO(GWEN_LOGDOMAIN, "here");
400 }
401}
402
403
404
405int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
406{
407 if (buf) {
408 int pos;
409 int rv;
410
411 pos=GWEN_Buffer_GetPos(buf);
412 rv=GWEN_Buffer_AllocRoom(buf, 3);
413 if (rv==0) {
414 uint8_t *posPtr;
415
416 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
417 *(posPtr++)=tagType & 0xff;
418 *(posPtr++)=0;
419 *(posPtr++)=0;
422 }
423 else {
424 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
425 return rv;
426 }
427 return pos;
428 }
429 else {
430 DBG_INFO(GWEN_LOGDOMAIN, "NULLPOINTER");
431 return GWEN_ERROR_INVALID;
432 }
433}
434
435
436
438{
439 int currentPos;
440 int payloadSize;
441
442 currentPos=GWEN_Buffer_GetPos(buf);
443 payloadSize=currentPos-startPos-3;
444 if (payloadSize<0) {
445 DBG_ERROR(GWEN_LOGDOMAIN, "Bad size(%d) or startpos(%d)", payloadSize, startPos);
446 return GWEN_ERROR_GENERIC;
447 }
448 else {
449 uint8_t *posPtr;
450
451 posPtr=(uint8_t*) GWEN_Buffer_GetStart(buf)+startPos+1;
452 *(posPtr++)=payloadSize & 0xff;
453 *(posPtr++)=(payloadSize>>8) & 0xff;
454 return 0;
455 }
456}
457
458
459
460
461
462
463#include "tag16-t.c"
464
465
#define NULL
Definition binreloc.c:300
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition buffer.c:451
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition buffer.c:468
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition buffer.c:548
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition buffer.c:253
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition buffer.c:277
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition buffer.c:285
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define GWEN_ERROR_INVALID
Definition error.h:67
#define GWEN_ERROR_GENERIC
Definition error.h:62
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
#define GWEN_UNUSED
#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
GWEN_TAG16 * GWEN_Tag16_List_First(const GWEN_TAG16_LIST *l)
void GWEN_Tag16_List_free(GWEN_TAG16_LIST *l)
uint32_t GWEN_Tag16_List_GetCount(const GWEN_TAG16_LIST *l)
void GWEN_Tag16_List_Add(GWEN_TAG16 *element, GWEN_TAG16_LIST *list)
GWEN_TAG16 * GWEN_Tag16_List_Next(const GWEN_TAG16 *element)
GWEN_TAG16_LIST * GWEN_Tag16_List_new()
#define GWEN_LOGDOMAIN
Definition logger.h:32
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55
void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
Definition tag16.c:377
double GWEN_Tag16_GetTagDataAsDouble(const GWEN_TAG16 *tag, double defaultValue)
Definition tag16.c:286
void GWEN_Tag16_WriteStringTagToBuffer(unsigned int tagType, const char *s, GWEN_BUFFER *buf)
Definition tag16.c:181
GWEN_TAG16 * GWEN_Tag16_new(void)
Definition tag16.c:48
GWEN_TAG16 * GWEN_Tag16_newNoCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
Definition tag16.c:60
uint16_t GWEN_Tag16_GetTagDataAsUint16(const GWEN_TAG16 *tag, uint16_t defaultValue)
Definition tag16.c:259
void GWEN_Tag16_WriteUint8TagToBuffer(unsigned int tagType, uint8_t data, GWEN_BUFFER *buf)
Definition tag16.c:188
uint8_t GWEN_Tag16_GetTagDataAsUint8(const GWEN_TAG16 *tag, uint8_t defaultValue)
Definition tag16.c:250
const GWEN_TAG16 * GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
Definition tag16.c:327
uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
Definition tag16.c:277
void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType, const char *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:240
GWEN_TAG16 * GWEN_Tag16_fromBuffer(GWEN_BUFFER *mbuf, GWEN_UNUSED int isBerTlv)
Definition tag16.c:143
char * GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
Definition tag16.c:302
unsigned int GWEN_Tag16_GetTagLength(const GWEN_TAG16 *tag)
Definition tag16.c:122
GWEN_TAG16 * GWEN_Tag16_newCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
Definition tag16.c:78
const void * GWEN_Tag16_GetTagData(const GWEN_TAG16 *tag)
Definition tag16.c:136
void GWEN_Tag16_free(GWEN_TAG16 *tag)
Definition tag16.c:103
int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
Definition tag16.c:405
void GWEN_Tag16_WriteUint32TagToBuffer(unsigned int tagType, uint32_t data, GWEN_BUFFER *buf)
Definition tag16.c:205
unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
Definition tag16.c:115
void GWEN_Tag16_WriteUint16TagToBuffer(unsigned int tagType, uint16_t data, GWEN_BUFFER *buf)
Definition tag16.c:195
uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
Definition tag16.c:268
GWEN_TAG16_LIST * GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
Definition tag16.c:343
static void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:384
int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
Definition tag16.c:437
void GWEN_Tag16_WriteDoubleTagToBuffer(unsigned int tagType, double data, GWEN_BUFFER *buf)
Definition tag16.c:225
GWEN_TAG16 * GWEN_Tag16_fromBuffer2(const uint8_t *bufferPtr, uint32_t bufferLen, int doCopy)
Definition tag16.c:156
unsigned int GWEN_Tag16_GetTagSize(const GWEN_TAG16 *tag)
Definition tag16.c:129
const GWEN_TAG16 * GWEN_Tag16_List_FindFirstByTagType(const GWEN_TAG16_LIST *tagList, unsigned int tagType)
Definition tag16.c:311
void GWEN_Tag16_WriteUint64TagToBuffer(unsigned int tagType, uint64_t data, GWEN_BUFFER *buf)
Definition tag16.c:215
struct GWEN_TAG16 GWEN_TAG16
Definition tag16.h:35
char * GWEN_Text_strndup(const char *s, size_t n)
Definition text.c:2088