gwenhywfar 5.12.0
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_WriteUint32TagToBuffer(unsigned int tagType, uint32_t data, GWEN_BUFFER *buf)
189{
190 uint32_t dataInLittleEndian;
191
192 dataInLittleEndian=htole32(data);
193 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint32_t), buf);
194}
195
196
197
198void GWEN_Tag16_WriteUint64TagToBuffer(unsigned int tagType, uint64_t data, GWEN_BUFFER *buf)
199{
200 uint64_t dataInLittleEndian;
201
202 dataInLittleEndian=htole64(data);
203 _writeTagToBuffer(tagType, (const uint8_t*) &dataInLittleEndian, sizeof(uint64_t), buf);
204}
205
206
207
208void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType,
209 const char *p,
210 int size,
211 GWEN_BUFFER *buf)
212{
213 _writeTagToBuffer(tagType, (const uint8_t*) p, (size==-1)?strlen(p):size, buf);
214}
215
216
217
218uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
219{
220 if (tag && tag->tagLength>=sizeof(uint32_t))
221 return le32toh(*(uint32_t*)(tag->tagData));
222 return defaultValue;
223}
224
225
226
227uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
228{
229 if (tag && tag->tagLength>=sizeof(uint64_t))
230 return le64toh(*(uint64_t*)(tag->tagData));
231 return defaultValue;
232}
233
234
235
236char *GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
237{
238 if (tag && tag->tagLength)
239 return GWEN_Text_strndup((const char*)(tag->tagData), tag->tagLength);
240 return defaultValue?strdup(defaultValue):NULL;
241}
242
243
244
245const GWEN_TAG16 *GWEN_Tag16_List_FindFirstByTagType(const GWEN_TAG16_LIST *tagList, unsigned int tagType)
246{
247 const GWEN_TAG16 *tag;
248
249 tag=GWEN_Tag16_List_First(tagList);
250 while(tag) {
251 if (tag->tagType==tagType)
252 return tag;
253 tag=GWEN_Tag16_List_Next(tag);
254 }
255
256 return NULL;
257}
258
259
260
261const GWEN_TAG16 *GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
262{
263 if (tag) {
264 tag=GWEN_Tag16_List_Next(tag);
265 while(tag) {
266 if (tag->tagType==tagType)
267 return tag;
268 tag=GWEN_Tag16_List_Next(tag);
269 }
270 }
271
272 return NULL;
273}
274
275
276
277GWEN_TAG16_LIST *GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
278{
279 GWEN_TAG16_LIST *tagList;
280
281 tagList=GWEN_Tag16_List_new();
282 while(l) {
283 GWEN_TAG16 *tag;
284
285 tag=GWEN_Tag16_fromBuffer2(p, l, doCopy);
286 if (tag==NULL) {
287 DBG_INFO(GWEN_LOGDOMAIN, "here");
288 GWEN_Tag16_List_free(tagList);
289 return NULL;
290 }
291 GWEN_Tag16_List_Add(tag, tagList);
292 if (l<tag->tagSize) {
293 DBG_ERROR(GWEN_LOGDOMAIN, "Invalid remaining data (%d < %d)", l, tag->tagSize);
294 GWEN_Tag16_List_free(tagList);
295 return NULL;
296 }
297 p+=tag->tagSize;
298 l-=tag->tagSize;
299 }
300
301 if (GWEN_Tag16_List_GetCount(tagList)<1) {
302 DBG_ERROR(GWEN_LOGDOMAIN, "No entries in tag list");
303 GWEN_Tag16_List_free(tagList);
304 return NULL;
305 }
306 return tagList;
307}
308
309
310
311void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
312{
313 _writeTagToBuffer(tagType, s, size, buf);
314}
315
316
317
318void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
319{
320 if (GWEN_Buffer_AllocRoom(buf, size+3)==0) {
321 uint8_t *posPtr;
322
323 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
324 *(posPtr++)=tagType & 0xff;
325 *(posPtr++)=size & 0xff;
326 *(posPtr++)=(size>>8) & 0xff;
327 if (size)
328 memmove(posPtr, p, size);
329 GWEN_Buffer_IncrementPos(buf, size+3);
331 }
332 else {
333 DBG_INFO(GWEN_LOGDOMAIN, "here");
334 }
335}
336
337
338
339int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
340{
341 if (buf) {
342 int pos;
343 int rv;
344
345 pos=GWEN_Buffer_GetPos(buf);
346 rv=GWEN_Buffer_AllocRoom(buf, 3);
347 if (rv==0) {
348 uint8_t *posPtr;
349
350 posPtr=(uint8_t*) GWEN_Buffer_GetPosPointer(buf);
351 *(posPtr++)=tagType & 0xff;
352 *(posPtr++)=0;
353 *(posPtr++)=0;
356 }
357 else {
358 DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
359 return rv;
360 }
361 return pos;
362 }
363 else {
364 DBG_INFO(GWEN_LOGDOMAIN, "NULLPOINTER");
365 return GWEN_ERROR_INVALID;
366 }
367}
368
369
370
372{
373 int currentPos;
374 int payloadSize;
375
376 currentPos=GWEN_Buffer_GetPos(buf);
377 payloadSize=currentPos-startPos-3;
378 if (payloadSize<0) {
379 DBG_ERROR(GWEN_LOGDOMAIN, "Bad size(%d) or startpos(%d)", payloadSize, startPos);
380 return GWEN_ERROR_GENERIC;
381 }
382 else {
383 uint8_t *posPtr;
384
385 posPtr=(uint8_t*) GWEN_Buffer_GetStart(buf)+startPos+1;
386 *(posPtr++)=payloadSize & 0xff;
387 *(posPtr++)=(payloadSize>>8) & 0xff;
388 return 0;
389 }
390}
391
392
393
394
395
396
397#include "tag16-t.c"
398
399
#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:311
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
const GWEN_TAG16 * GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
Definition tag16.c:261
uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
Definition tag16.c:227
void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType, const char *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:208
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:236
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:339
void GWEN_Tag16_WriteUint32TagToBuffer(unsigned int tagType, uint32_t data, GWEN_BUFFER *buf)
Definition tag16.c:188
unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
Definition tag16.c:115
uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
Definition tag16.c:218
GWEN_TAG16_LIST * GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
Definition tag16.c:277
static void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
Definition tag16.c:318
int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
Definition tag16.c:371
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:245
void GWEN_Tag16_WriteUint64TagToBuffer(unsigned int tagType, uint64_t data, GWEN_BUFFER *buf)
Definition tag16.c:198
struct GWEN_TAG16 GWEN_TAG16
Definition tag16.h:35
char * GWEN_Text_strndup(const char *s, size_t n)
Definition text.c:2088