gwenhywfar 5.12.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_DirectlyToBuffer(unsigned int tagType,
226 const char *p,
227 int size,
228 GWEN_BUFFER *buf)
229{
230 _writeTagToBuffer(tagType, (const uint8_t*) p, (size==-1)?strlen(p):size, buf);
231}
232
233
234
235uint8_t GWEN_Tag16_GetTagDataAsUint8(const GWEN_TAG16 *tag, uint8_t defaultValue)
236{
237 if (tag && tag->tagLength>=sizeof(uint8_t))
238 return *(uint8_t*)(tag->tagData);
239 return defaultValue;
240}
241
242
243
244uint16_t GWEN_Tag16_GetTagDataAsUint16(const GWEN_TAG16 *tag, uint16_t defaultValue)
245{
246 if (tag && tag->tagLength>=sizeof(uint16_t))
247 return le16toh(*(uint16_t*)(tag->tagData));
248 return defaultValue;
249}
250
251
252
253uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
254{
255 if (tag && tag->tagLength>=sizeof(uint32_t))
256 return le32toh(*(uint32_t*)(tag->tagData));
257 return defaultValue;
258}
259
260
261
262uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
263{
264 if (tag && tag->tagLength>=sizeof(uint64_t))
265 return le64toh(*(uint64_t*)(tag->tagData));
266 return defaultValue;
267}
268
269
270
271char *GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
272{
273 if (tag && tag->tagLength)
274 return GWEN_Text_strndup((const char*)(tag->tagData), tag->tagLength);
275 return defaultValue?strdup(defaultValue):NULL;
276}
277
278
279
280const GWEN_TAG16 *GWEN_Tag16_List_FindFirstByTagType(const GWEN_TAG16_LIST *tagList, unsigned int tagType)
281{
282 const GWEN_TAG16 *tag;
283
284 tag=GWEN_Tag16_List_First(tagList);
285 while(tag) {
286 if (tag->tagType==tagType)
287 return tag;
288 tag=GWEN_Tag16_List_Next(tag);
289 }
290
291 return NULL;
292}
293
294
295
296const GWEN_TAG16 *GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
297{
298 if (tag) {
299 tag=GWEN_Tag16_List_Next(tag);
300 while(tag) {
301 if (tag->tagType==tagType)
302 return tag;
303 tag=GWEN_Tag16_List_Next(tag);
304 }
305 }
306
307 return NULL;
308}
309
310
311
312GWEN_TAG16_LIST *GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
313{
314 GWEN_TAG16_LIST *tagList;
315
316 tagList=GWEN_Tag16_List_new();
317 while(l) {
318 GWEN_TAG16 *tag;
319
320 tag=GWEN_Tag16_fromBuffer2(p, l, doCopy);
321 if (tag==NULL) {
322 DBG_INFO(GWEN_LOGDOMAIN, "here");
323 GWEN_Tag16_List_free(tagList);
324 return NULL;
325 }
326 GWEN_Tag16_List_Add(tag, tagList);
327 if (l<tag->tagSize) {
328 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid remaining data (%d < %d)", l, tag->tagSize);
329 GWEN_Tag16_List_free(tagList);
330 return NULL;
331 }
332 p+=tag->tagSize;
333 l-=tag->tagSize;
334 }
335
336 if (GWEN_Tag16_List_GetCount(tagList)<1) {
337 DBG_ERROR(GWEN_LOGDOMAIN, "No entries in tag list");
338 GWEN_Tag16_List_free(tagList);
339 return NULL;
340 }
341 return tagList;
342}
343
344
345
346void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
347{
348 _writeTagToBuffer(tagType, s, size, buf);
349}
350
351
352
353void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
354{
355 if (GWEN_Buffer_AllocRoom(buf, size+3)==0) {
356 uint8_t *posPtr;
357
358 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
359 *(posPtr++)=tagType & 0xff;
360 *(posPtr++)=size & 0xff;
361 *(posPtr++)=(size>>8) & 0xff;
362 if (size)
363 memmove(posPtr, p, size);
364 GWEN_Buffer_IncrementPos(buf, size+3);
366 }
367 else {
368 DBG_INFO(GWEN_LOGDOMAIN, "here");
369 }
370}
371
372
373
374int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
375{
376 if (buf) {
377 int pos;
378 int rv;
379
380 pos=GWEN_Buffer_GetPos(buf);
381 rv=GWEN_Buffer_AllocRoom(buf, 3);
382 if (rv==0) {
383 uint8_t *posPtr;
384
385 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
386 *(posPtr++)=tagType & 0xff;
387 *(posPtr++)=0;
388 *(posPtr++)=0;
391 }
392 else {
393 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
394 return rv;
395 }
396 return pos;
397 }
398 else {
399 DBG_INFO(GWEN_LOGDOMAIN, "NULLPOINTER");
400 return GWEN_ERROR_INVALID;
401 }
402}
403
404
405
407{
408 int currentPos;
409 int payloadSize;
410
411 currentPos=GWEN_Buffer_GetPos(buf);
412 payloadSize=currentPos-startPos-3;
413 if (payloadSize<0) {
414 DBG_ERROR(GWEN_LOGDOMAIN, "Bad size(%d) or startpos(%d)", payloadSize, startPos);
415 return GWEN_ERROR_GENERIC;
416 }
417 else {
418 uint8_t *posPtr;
419
420 posPtr=(uint8_t*) GWEN_Buffer_GetStart(buf)+startPos+1;
421 *(posPtr++)=payloadSize & 0xff;
422 *(posPtr++)=(payloadSize>>8) & 0xff;
423 return 0;
424 }
425}
426
427
428
429
430
431
432#include "tag16-t.c"
433
434
#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:35
#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:346
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:244
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:235
const GWEN_TAG16 * GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
Definition tag16.c:296
uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
Definition tag16.c:262
void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType, const char *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:225
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:271
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:374
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:253
GWEN_TAG16_LIST * GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
Definition tag16.c:312
static void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:353
int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
Definition tag16.c:406
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:280
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