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 
39 static 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 
60 GWEN_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 
78 GWEN_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 
115 unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
116 {
117  return tag?(tag->tagType):0;
118 }
119 
120 
121 
122 unsigned int GWEN_Tag16_GetTagLength(const GWEN_TAG16 *tag)
123 {
124  return tag?(tag->tagLength):0;
125 }
126 
127 
128 
129 unsigned int GWEN_Tag16_GetTagSize(const GWEN_TAG16 *tag)
130 {
131  return tag?(tag->tagSize):0;
132 }
133 
134 
135 
136 const 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 
148  tag=GWEN_Tag16_fromBuffer2((const uint8_t*) GWEN_Buffer_GetPosPointer(mbuf), GWEN_Buffer_GetUsedBytes(mbuf), 1);
149  if (tag)
150  GWEN_Buffer_IncrementPos(mbuf, tag->tagSize);
151  return tag;
152 }
153 
154 
155 
156 GWEN_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 
181 void 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 
188 void 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 
195 void 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 
205 void 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 
215 void 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 
225 void 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 
240 void 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 
250 uint8_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 
259 uint16_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 
268 uint32_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 
277 uint64_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 
286 double 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 
302 char *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 
311 const 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 
327 const 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 
343 GWEN_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 
377 void 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 
384 void _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 
405 int 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;
420  GWEN_Buffer_IncrementPos(buf, 3);
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 
437 int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
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 
void GWEN_Tag16_List_Add(GWEN_TAG16 *element, GWEN_TAG16_LIST *list)
#define DBG_ERROR(dbg_logger, format,...)
Definition: debug.h:97
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
void GWEN_Tag16_free(GWEN_TAG16 *tag)
Definition: tag16.c:103
int GWEN_Buffer_AllocRoom(GWEN_BUFFER *bf, uint32_t size)
Definition: buffer.c:285
int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
Definition: tag16.c:437
#define GWEN_ERROR_INVALID
Definition: error.h:67
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
static void _writeTagToBuffer(unsigned int tagType, const uint8_t *p, int size, GWEN_BUFFER *buf)
Definition: tag16.c:384
double GWEN_Tag16_GetTagDataAsDouble(const GWEN_TAG16 *tag, double defaultValue)
Definition: tag16.c:286
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:300
unsigned int GWEN_Tag16_GetTagLength(const GWEN_TAG16 *tag)
Definition: tag16.c:122
void GWEN_Tag16_WriteUint64TagToBuffer(unsigned int tagType, uint64_t data, GWEN_BUFFER *buf)
Definition: tag16.c:215
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:468
uint8_t GWEN_Tag16_GetTagDataAsUint8(const GWEN_TAG16 *tag, uint8_t defaultValue)
Definition: tag16.c:250
#define GWEN_LOGDOMAIN
Definition: logger.h:32
GWEN_TAG16_LIST * GWEN_Tag16_List_new()
uint32_t GWEN_Buffer_GetPos(const GWEN_BUFFER *bf)
Definition: buffer.c:253
char * GWEN_Buffer_GetPosPointer(const GWEN_BUFFER *bf)
Definition: buffer.c:548
int GWEN_Buffer_IncrementPos(GWEN_BUFFER *bf, uint32_t i)
Definition: buffer.c:451
GWEN_TAG16 * GWEN_Tag16_new(void)
Definition: tag16.c:48
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
GWEN_TAG16 * GWEN_Tag16_List_First(const GWEN_TAG16_LIST *l)
GWEN_TAG16 * GWEN_Tag16_newCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
Definition: tag16.c:78
uint32_t GWEN_Tag16_GetTagDataAsUint32(const GWEN_TAG16 *tag, uint32_t defaultValue)
Definition: tag16.c:268
char * GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
Definition: tag16.c:302
uint16_t GWEN_Tag16_GetTagDataAsUint16(const GWEN_TAG16 *tag, uint16_t defaultValue)
Definition: tag16.c:259
void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType, const char *p, int size, GWEN_BUFFER *buf)
Definition: tag16.c:240
struct GWEN_TAG16 GWEN_TAG16
Definition: tag16.h:35
#define GWEN_ERROR_GENERIC
Definition: error.h:62
void GWEN_Tag16_WriteUint16TagToBuffer(unsigned int tagType, uint16_t data, GWEN_BUFFER *buf)
Definition: tag16.c:195
GWEN_TAG16 * GWEN_Tag16_fromBuffer(GWEN_BUFFER *mbuf, GWEN_UNUSED int isBerTlv)
Definition: tag16.c:143
GWEN_TAG16 * GWEN_Tag16_newNoCopy(unsigned int tagType, unsigned int tagLength, const uint8_t *tagData)
Definition: tag16.c:60
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
uint64_t GWEN_Tag16_GetTagDataAsUint64(const GWEN_TAG16 *tag, uint64_t defaultValue)
Definition: tag16.c:277
void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
Definition: tag16.c:377
GWEN_TAG16 * GWEN_Tag16_List_Next(const GWEN_TAG16 *element)
uint32_t GWEN_Tag16_List_GetCount(const GWEN_TAG16_LIST *l)
GWEN_TAG16 * GWEN_Tag16_fromBuffer2(const uint8_t *bufferPtr, uint32_t bufferLen, int doCopy)
Definition: tag16.c:156
char * GWEN_Text_strndup(const char *s, size_t n)
Definition: text.c:2088
void GWEN_Tag16_WriteUint32TagToBuffer(unsigned int tagType, uint32_t data, GWEN_BUFFER *buf)
Definition: tag16.c:205
const void * GWEN_Tag16_GetTagData(const GWEN_TAG16 *tag)
Definition: tag16.c:136
const GWEN_TAG16 * GWEN_Tag16_List_FindFirstByTagType(const GWEN_TAG16_LIST *tagList, unsigned int tagType)
Definition: tag16.c:311
unsigned int GWEN_Tag16_GetTagSize(const GWEN_TAG16 *tag)
Definition: tag16.c:129
void GWEN_Tag16_WriteStringTagToBuffer(unsigned int tagType, const char *s, GWEN_BUFFER *buf)
Definition: tag16.c:181
GWEN_TAG16_LIST * GWEN_Tag16_List_fromBuffer(const uint8_t *p, uint32_t l, int doCopy)
Definition: tag16.c:343
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:466
const GWEN_TAG16 * GWEN_Tag16_List_FindNextByTagType(const GWEN_TAG16 *tag, unsigned int tagType)
Definition: tag16.c:327
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:367
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
void GWEN_Tag16_WriteUint8TagToBuffer(unsigned int tagType, uint8_t data, GWEN_BUFFER *buf)
Definition: tag16.c:188
unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
Definition: tag16.c:115
void GWEN_Tag16_WriteDoubleTagToBuffer(unsigned int tagType, double data, GWEN_BUFFER *buf)
Definition: tag16.c:225
int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
Definition: tag16.c:405
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:475
#define GWEN_UNUSED
void GWEN_Tag16_List_free(GWEN_TAG16_LIST *l)