gwenhywfar  5.11.2beta
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_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 
198 void 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 
208 void 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 
218 uint32_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 
227 uint64_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 
236 char *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 
245 const 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 
261 const 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 
277 GWEN_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 
311 void 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 
318 void _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 
339 int 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;
354  GWEN_Buffer_IncrementPos(buf, 3);
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 
371 int GWEN_Tag16_EndTagInBuffer(int startPos, GWEN_BUFFER *buf)
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 
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:371
#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:318
#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:198
int GWEN_Buffer_AdjustUsedBytes(GWEN_BUFFER *bf)
Definition: buffer.c:468
#define GWEN_LOGDOMAIN
Definition: logger.h:35
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:218
char * GWEN_Tag16_GetTagDataAsNewString(const GWEN_TAG16 *tag, const char *defaultValue)
Definition: tag16.c:236
void GWEN_Tag16_DirectlyToBuffer(unsigned int tagType, const char *p, int size, GWEN_BUFFER *buf)
Definition: tag16.c:208
struct GWEN_TAG16 GWEN_TAG16
Definition: tag16.h:35
#define GWEN_ERROR_GENERIC
Definition: error.h:62
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:227
void GWEN_Tag16_WriteTagToBuffer(unsigned int tagType, const uint8_t *s, int size, GWEN_BUFFER *buf)
Definition: tag16.c:311
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:188
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:245
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:277
#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:261
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:367
#define DBG_INFO(dbg_logger, format,...)
Definition: debug.h:181
unsigned int GWEN_Tag16_GetTagType(const GWEN_TAG16 *tag)
Definition: tag16.c:115
int GWEN_Tag16_StartTagInBuffer(unsigned int tagType, GWEN_BUFFER *buf)
Definition: tag16.c:339
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:475
#define GWEN_UNUSED
void GWEN_Tag16_List_free(GWEN_TAG16_LIST *l)