Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / aqbanking / backendsupport / msgengine.c @ 5bc3f3e7

History | View | Annotate | Download (26.1 KB)

1
/***************************************************************************
2
    begin       : Mon Mar 01 2004
3
    copyright   : (C) 2004 by Martin Preuss
4
    email       : martin@libchipcard.de
5

6
 ***************************************************************************
7
 * This file is part of the project "AqBanking".                           *
8
 * Please see toplevel file COPYING of that project for license details.   *
9
 ***************************************************************************/
10

    
11

    
12
#ifdef HAVE_CONFIG_H
13
# include <config.h>
14
#endif
15

    
16
#include "msgengine_p.h"
17
#include <gwenhywfar/debug.h>
18
#include <gwenhywfar/inherit.h>
19
#include <gwenhywfar/misc.h>
20
#include <gwenhywfar/text.h>
21

    
22

    
23
#include <stdlib.h>
24
#include <assert.h>
25
#include <string.h>
26

    
27

    
28
GWEN_INHERIT(GWEN_MSGENGINE, AB_MSGENGINE)
29

    
30

    
31

    
32
GWEN_MSGENGINE *AB_MsgEngine_new(void){
33
  GWEN_MSGENGINE *e;
34
  AB_MSGENGINE *le;
35

    
36
  e=GWEN_MsgEngine_new();
37
  GWEN_NEW_OBJECT(AB_MSGENGINE, le);
38
  GWEN_INHERIT_SETDATA(GWEN_MSGENGINE, AB_MSGENGINE,
39
                       e, le, AB_MsgEngine_FreeData);
40
  GWEN_MsgEngine_SetTypeReadFunction(e, AB_MsgEngine_TypeRead);
41
  GWEN_MsgEngine_SetTypeWriteFunction(e, AB_MsgEngine_TypeWrite);
42
  GWEN_MsgEngine_SetTypeCheckFunction(e, AB_MsgEngine_TypeCheck);
43
  GWEN_MsgEngine_SetBinTypeReadFunction(e, AB_MsgEngine_BinTypeRead);
44
  GWEN_MsgEngine_SetBinTypeWriteFunction(e, AB_MsgEngine_BinTypeWrite);
45
  GWEN_MsgEngine_SetGetCharValueFunction(e, AB_MsgEngine_GetCharValue);
46
  GWEN_MsgEngine_SetGetIntValueFunction(e, AB_MsgEngine_GetIntValue);
47
  GWEN_MsgEngine_SetEscapeChar(e, '?');
48
  GWEN_MsgEngine_SetDelimiters(e, "");
49

    
50
  return e;
51
}
52

    
53

    
54

    
55
void GWENHYWFAR_CB AB_MsgEngine_FreeData(void *bp, void *p){
56
  //GWEN_MSGENGINE *e;
57
  AB_MSGENGINE *le;
58

    
59
  //e=(GWEN_MSGENGINE*)bp;
60
  le=(AB_MSGENGINE*)p;
61

    
62
  /* free all objects inside AB_MsgEngine */
63

    
64
  GWEN_FREE_OBJECT(le);
65
}
66

    
67

    
68

    
69
uint32_t AB_MsgEngine__FromBCD(uint32_t value) {
70
  uint32_t rv;
71

    
72
  rv=0;
73
  rv+=((value>>28)&0xf)*10000000;
74
  rv+=((value>>24)&0xf)*1000000;
75
  rv+=((value>>20)&0xf)*100000;
76
  rv+=((value>>16)&0xf)*10000;
77
  rv+=((value>>12)&0xf)*1000;
78
  rv+=((value>>8)&0xf)*100;
79
  rv+=((value>>4)&0xf)*10;
80
  rv+=((value)&0xf);
81

    
82
  return rv;
83
}
84

    
85

    
86

    
87
uint32_t AB_MsgEngine__ToBCD(uint32_t value) {
88
  uint32_t rv;
89

    
90
  rv=0;
91
  rv+=value/10000000;
92
  value%=10000000;
93
  rv<<=4;
94

    
95
  rv+=value/1000000;
96
  value%=1000000;
97
  rv<<=4;
98

    
99
  rv+=value/100000;
100
  value%=100000;
101
  rv<<=4;
102

    
103
  rv+=value/10000;
104
  value%=10000;
105
  rv<<=4;
106

    
107
  rv+=value/1000;
108
  value%=1000;
109
  rv<<=4;
110

    
111
  rv+=value/100;
112
  value%=100;
113
  rv<<=4;
114

    
115
  rv+=value/10;
116
  value%=10;
117
  rv<<=4;
118

    
119
  rv+=value;
120

    
121
  return rv;
122
}
123

    
124

    
125

    
126

    
127

    
128
int AB_MsgEngine_TypeRead(GWEN_MSGENGINE *e,
129
                          GWEN_BUFFER *msgbuf,
130
                          GWEN_XMLNODE *node,
131
                          GWEN_BUFFER *vbuf,
132
                          char escapeChar,
133
                          const char *delimiters){
134
  AB_MSGENGINE *le;
135
  const char *type;
136

    
137
  assert(e);
138
  le=GWEN_INHERIT_GETDATA(GWEN_MSGENGINE, AB_MSGENGINE, e);
139
  assert(le);
140

    
141
  if (!GWEN_Buffer_GetBytesLeft(msgbuf)) {
142
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Buffer empty");
143
    return 0;
144
  }
145
  type=GWEN_XMLNode_GetProperty(node, "type","");
146
  if (strcasecmp(type, "byte")==0) {
147
    int isBCD;
148
    int c;
149
    char numbuf[32];
150
    unsigned int value;
151

    
152
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
153
    c=GWEN_Buffer_ReadByte(msgbuf);
154
    if (c==-1)
155
      return -1;
156
    value=c&0xff;
157
    if (isBCD)
158
      value=AB_MsgEngine__FromBCD(value);
159
    snprintf(numbuf, sizeof(numbuf), "%d", (unsigned int)value);
160
    if (GWEN_Buffer_AppendString(vbuf, numbuf)) {
161
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
162
      return -1;
163
    }
164
    return 0;
165
  }
166
  else if (strcasecmp(type, "word")==0) {
167
    int bigEndian;
168
    int isBCD;
169
    unsigned int value;
170
    int c;
171
    char numbuf[32];
172

    
173
    bigEndian=atoi(GWEN_XMLNode_GetProperty(node, "bigEndian", "1"));
174
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
175
    value=0;
176
    if (bigEndian) {
177
      c=GWEN_Buffer_ReadByte(msgbuf);
178
      if (c==-1)
179
        return -1;
180
      value=(((unsigned char)(c&0xff)<<8));
181
      c=GWEN_Buffer_ReadByte(msgbuf);
182
      if (c==-1)
183
        return -1;
184
      value|=(unsigned char)((c&0xff));
185
    } /* if bigEndian */
186
    else {
187
      c=GWEN_Buffer_ReadByte(msgbuf);
188
      if (c==-1)
189
        return -1;
190
      value=(unsigned char)((c&0xff));
191
      c=GWEN_Buffer_ReadByte(msgbuf);
192
      if (c==-1)
193
        return -1;
194
      value|=(unsigned char)(((c&0xff)<<8));
195
    }
196
    if (isBCD)
197
      value=AB_MsgEngine__FromBCD(value);
198
    snprintf(numbuf, sizeof(numbuf), "%d", (unsigned int)value);
199
    if (GWEN_Buffer_AppendString(vbuf, numbuf)) {
200
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
201
      return -1;
202
    }
203
    return 0;
204
  } /* if word */
205
  else if (strcasecmp(type, "dword")==0) {
206
    int bigEndian;
207
    int isBCD;
208
    uint32_t value=0;
209
    int c;
210
    char numbuf[32];
211

    
212
    bigEndian=atoi(GWEN_XMLNode_GetProperty(node, "bigEndian", "1"));
213
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
214

    
215
    if (bigEndian) {
216
      c=GWEN_Buffer_ReadByte(msgbuf);
217
      if (c==-1)
218
        return -1;
219
      value=(((unsigned char)(c&0xff)<<24));
220
      c=GWEN_Buffer_ReadByte(msgbuf);
221
      if (c==-1)
222
        return -1;
223
      value|=(((unsigned char)(c&0xff)<<16));
224
      c=GWEN_Buffer_ReadByte(msgbuf);
225
      if (c==-1)
226
        return -1;
227
      value|=(((unsigned char)(c&0xff)<<8));
228
      c=GWEN_Buffer_ReadByte(msgbuf);
229
      if (c==-1)
230
        return -1;
231
      value|=(unsigned char)((c&0xff));
232
    } /* if bigEndian */
233
    else {
234
      c=GWEN_Buffer_ReadByte(msgbuf);
235
      if (c==-1)
236
        return -1;
237
      value=(unsigned char)((c&0xff));
238
      c=GWEN_Buffer_ReadByte(msgbuf);
239
      if (c==-1)
240
        return -1;
241
      value|=(unsigned char)(((c&0xff)<<8));
242
      c=GWEN_Buffer_ReadByte(msgbuf);
243
      if (c==-1)
244
        return -1;
245
      value|=(unsigned char)(((c&0xff)<<16));
246
      c=GWEN_Buffer_ReadByte(msgbuf);
247
      if (c==-1)
248
        return -1;
249
      value|=(unsigned char)(((c&0xff)<<24));
250
    }
251
    if (isBCD)
252
      value=AB_MsgEngine__FromBCD(value);
253
    snprintf(numbuf, sizeof(numbuf), "%d", (unsigned int)value);
254
    if (GWEN_Buffer_AppendString(vbuf, numbuf)) {
255
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
256
      return -1;
257
    }
258
    return 0;
259
  } /* if word */
260
  else if (strcasecmp(type, "bytes")==0) {
261
    int size;
262

    
263
    if (1!=sscanf(GWEN_XMLNode_GetProperty(node, "size", "-1"),
264
                  "%i", &size)) {
265
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number of bytes");
266
      return -1;
267
    }
268
    if (size==-1) {
269
      size=GWEN_Buffer_GetBytesLeft(msgbuf);
270
      if (size==0) {
271
        DBG_INFO(AQBANKING_LOGDOMAIN, "No bytes found");
272
        return 0;
273
      }
274
    }
275
    else {
276
      if (size>GWEN_Buffer_GetBytesLeft(msgbuf)) {
277
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes in message (%d>%d)",
278
                  size, GWEN_Buffer_GetBytesLeft(msgbuf));
279
        return -1;
280
      }
281
    }
282
    if (GWEN_Buffer_AppendBytes(vbuf,
283
                                GWEN_Buffer_GetPosPointer(msgbuf),
284
                                size)) {
285
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
286
      return -1;
287
    }
288
    if (GWEN_Buffer_IncrementPos(msgbuf, size)) {
289
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
290
      return -1;
291
    }
292
    return 0;
293
  }
294
  else if (strcasecmp(type, "bcd")==0) {
295
    int size;
296
    int skipLeadingZeroes;
297

    
298
    skipLeadingZeroes=atoi(GWEN_XMLNode_GetProperty(node,
299
                                                    "skipZeroes", "0"));
300
    if (1!=sscanf(GWEN_XMLNode_GetProperty(node, "size", "-1"),
301
                  "%i", &size)) {
302
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number of bytes");
303
      return -1;
304
    }
305
    if (size==-1) {
306
      size=GWEN_Buffer_GetBytesLeft(msgbuf);
307
      if (size==0) {
308
        DBG_INFO(AQBANKING_LOGDOMAIN, "No bytes found");
309
        return 0;
310
      }
311
    }
312
    else {
313
      if (size>GWEN_Buffer_GetBytesLeft(msgbuf)) {
314
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes in message (%d>%d)",
315
                  size, GWEN_Buffer_GetBytesLeft(msgbuf));
316
        return -1;
317
      }
318
    }
319

    
320
    if (GWEN_Text_ToBcdBuffer(GWEN_Buffer_GetPosPointer(msgbuf),
321
                              size,
322
                              vbuf,
323
                              0, 0, skipLeadingZeroes)) {
324
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Error parsing BCD string");
325
      return -1;
326
    }
327

    
328
    if (GWEN_Buffer_IncrementPos(msgbuf, size)) {
329
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
330
      return -1;
331
    }
332
    return 0;
333
  }
334

    
335
  else if (strcasecmp(type, "ascii")==0) {
336
    int size;
337
    int condense;
338
    int kvk;
339
    //uint32_t vpos=0;
340

    
341
    kvk=atoi(GWEN_XMLNode_GetProperty(node, "kvk", "0"));
342
    condense=atoi(GWEN_XMLNode_GetProperty(node, "condense", "1"));
343
    if (1!=sscanf(GWEN_XMLNode_GetProperty(node, "size", "-1"),
344
                  "%i", &size)) {
345
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number of bytes");
346
      return -1;
347
    }
348
    if (size==-1) {
349
      /* if no fixed size given let GWEN handle this */
350
      return 1;
351
    }
352
    else {
353
      if (size>GWEN_Buffer_GetBytesLeft(msgbuf)) {
354
        DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes in message (%d>%d)",
355
                  size, GWEN_Buffer_GetBytesLeft(msgbuf));
356
        return -1;
357
      }
358
    }
359

    
360
    if (kvk) {
361
//      vpos=GWEN_Buffer_GetPos(vbuf);
362
    }
363
    if (condense) {
364
      GWEN_BUFFER *tbuf;
365

    
366
      tbuf=GWEN_Buffer_new(0, size, 0, 1);
367
      GWEN_Buffer_AppendBytes(tbuf, GWEN_Buffer_GetPosPointer(msgbuf), size);
368
      GWEN_Text_CondenseBuffer(tbuf);
369
      GWEN_Buffer_Rewind(tbuf);
370
      if (GWEN_Buffer_GetUsedBytes(tbuf)==0) {
371
        /* just to fool the caller */
372
        GWEN_Buffer_AppendByte(tbuf, 0);
373
      }
374
      if (GWEN_Buffer_AppendBuffer(vbuf, tbuf)) {
375
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
376
        GWEN_Buffer_free(tbuf);
377
        return -1;
378
      }
379
      GWEN_Buffer_free(tbuf);
380
    }
381
    else {
382
      if (GWEN_Buffer_AppendBytes(vbuf,
383
                                  GWEN_Buffer_GetPosPointer(msgbuf),
384
                                  size)) {
385
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
386
        return -1;
387
      }
388
    }
389

    
390
    if (GWEN_Buffer_IncrementPos(msgbuf, size)) {
391
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
392
      return -1;
393
    }
394
    return 0;
395
  }
396

    
397
  else if (strcasecmp(type, "tlv")==0) {
398
    int isBerTlv;
399
    const char *p;
400
    unsigned int size;
401
    unsigned int pos;
402
    unsigned int j;
403

    
404
    p=GWEN_Buffer_GetPosPointer(msgbuf);
405
    pos=0;
406
    size=GWEN_Buffer_GetBytesLeft(msgbuf);
407
    isBerTlv=(strcasecmp(GWEN_XMLNode_GetProperty(node,
408
                                                  "tlvtype",
409
                                                  "bertlv"),
410
                         "BER")==0);
411
    /* get tag type */
412
    if (size<2) {
413
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes for BER-TLV");
414
      return -1;
415
    }
416
    j=(unsigned char)(p[pos]);
417
    if (isBerTlv) {
418
      if ((j & 0x1f)==0x1f) {
419
        pos++;
420
        if (pos>=size) {
421
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
422
          return -1;
423
        }
424
        j=(unsigned char)(p[pos]);
425
      }
426
      else
427
        j&=0x1f;
428
    }
429
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Tag type %02x%s", j,
430
              isBerTlv?" (BER-TLV)":"");
431

    
432
    /* get length */
433
    pos++;
434
    if (pos>=size) {
435
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
436
      return -1;
437
    }
438
    j=(unsigned char)(p[pos]);
439
    if (isBerTlv) {
440
      if (j & 0x80) {
441
        if (j==0x81) {
442
          pos++;
443
          if (pos>=size) {
444
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
445
            return -1;
446
          }
447
          j=(unsigned char)(p[pos]);
448
        } /* 0x81 */
449
        else if (j==0x82) {
450
          if (pos+1>=size) {
451
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
452
            return -1;
453
          }
454
          pos++;
455
          j=((unsigned char)(p[pos]))<<8;
456
          pos++;
457
          j+=(unsigned char)(p[pos]);
458
        } /* 0x82 */
459
        else {
460
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Unexpected tag length modifier %02x", j);
461
          return -1;
462
        }
463
      } /* if tag length modifier */
464
    }
465
    else {
466
      if (j==255) {
467
        if (pos+2>=size) {
468
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
469
          return -1;
470
        }
471
        pos++;
472
        j=((unsigned char)(p[pos]))<<8;
473
        pos++;
474
        j+=(unsigned char)(p[pos]);
475
      }
476
    }
477
    pos++;
478
    pos+=j;
479

    
480
    if (pos>size) {
481
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
482
      return -1;
483
    }
484
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Tag data length is %d (total %d)", j, pos);
485
    if (GWEN_Buffer_AppendBytes(vbuf,
486
                                GWEN_Buffer_GetPosPointer(msgbuf),
487
                                pos)) {
488
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
489
      return -1;
490
    }
491
    if (GWEN_Buffer_IncrementPos(msgbuf, pos)) {
492
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
493
      return -1;
494
    }
495

    
496
    return 0;
497
  }
498

    
499
  else {
500
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Type \"%s\" not supported by AB_MsgEngine", type);
501
    return 1;
502
  }
503
}
504

    
505

    
506

    
507
int AB_MsgEngine_TypeWrite(GWEN_MSGENGINE *e,
508
                           GWEN_BUFFER *gbuf,
509
                           GWEN_BUFFER *data,
510
                           GWEN_XMLNODE *node){
511
  AB_MSGENGINE *le;
512
  const char *type;
513

    
514
  assert(e);
515
  le=GWEN_INHERIT_GETDATA(GWEN_MSGENGINE, AB_MSGENGINE, e);
516
  assert(le);
517

    
518
  type=GWEN_XMLNode_GetProperty(node, "type","");
519
  if (strcasecmp(type, "byte")==0) {
520
    int value;
521
    int isBCD;
522

    
523
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Supporting type \"byte\"");
524
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
525
    if (1!=sscanf(GWEN_Buffer_GetPosPointer(data), "%i", &value)) {
526
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number");
527
      return -1;
528
    }
529

    
530
    if (value>255 || value<0) {
531
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Number out of range (%d)", value);
532
      return -1;
533
    }
534

    
535
    if (isBCD)
536
      value=AB_MsgEngine__ToBCD(value);
537
    if (GWEN_Buffer_AppendByte(gbuf, (unsigned char)value)) {
538
      DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
539
      return -1;
540
    }
541
    return 0;
542
  } /* byte */
543
  else if (strcasecmp(type, "word")==0) {
544
    int bigEndian;
545
    int value;
546
    int isBCD;
547

    
548
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Supporting type \"word\"");
549
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
550
    if (1!=sscanf(GWEN_Buffer_GetPosPointer(data), "%i", &value)) {
551
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number");
552
      return -1;
553
    }
554

    
555
    if (value>0xffff || value<0) {
556
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Number out of range (%d)", value);
557
      return -1;
558
    }
559

    
560
    if (isBCD)
561
      value=AB_MsgEngine__ToBCD(value);
562
    bigEndian=atoi(GWEN_XMLNode_GetProperty(node, "bigEndian", "1"));
563

    
564
    if (bigEndian) {
565
      if (GWEN_Buffer_AppendByte(gbuf,
566
                                 (unsigned char)((value>>8)&0xff))){
567
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
568
        return -1;
569
      }
570
      if (GWEN_Buffer_AppendByte(gbuf,
571
                                 (unsigned char)(value&0xff))){
572
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
573
        return -1;
574
      }
575
    }
576
    else {
577
      if (GWEN_Buffer_AppendByte(gbuf,
578
                                 (unsigned char)(value&0xff))){
579
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
580
        return -1;
581
      }
582
      if (GWEN_Buffer_AppendByte(gbuf,
583
                                 (unsigned char)((value>>8)&0xff))){
584
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
585
        return -1;
586
      }
587
    }
588
    return 0;
589
  } /* word */
590
  else if (strcasecmp(type, "dword")==0) {
591
    int bigEndian;
592
    int isBCD;
593
    uint32_t value;
594

    
595
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Supporting type \"dword\"");
596
    isBCD=atoi(GWEN_XMLNode_GetProperty(node, "bcd", "0"));
597
    if (1!=sscanf(GWEN_Buffer_GetPosPointer(data), "%i", &value)) {
598
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number");
599
      return -1;
600
    }
601
    if (isBCD)
602
      value=AB_MsgEngine__ToBCD(value);
603

    
604
    bigEndian=atoi(GWEN_XMLNode_GetProperty(node, "bigEndian", "1"));
605

    
606
    if (bigEndian) {
607
      if (GWEN_Buffer_AppendByte(gbuf,
608
                                 (unsigned char)((value>>24)&0xff))){
609
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
610
        return -1;
611
      }
612
      if (GWEN_Buffer_AppendByte(gbuf,
613
                                 (unsigned char)((value>>16)&0xff))){
614
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
615
        return -1;
616
      }
617
      if (GWEN_Buffer_AppendByte(gbuf,
618
                                 (unsigned char)((value>>8)&0xff))){
619
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
620
        return -1;
621
      }
622
      if (GWEN_Buffer_AppendByte(gbuf,
623
                                 (unsigned char)(value&0xff))){
624
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
625
        return -1;
626
      }
627
    }
628
    else {
629
      if (GWEN_Buffer_AppendByte(gbuf,
630
                                 (unsigned char)(value&0xff))){
631
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
632
        return -1;
633
      }
634
      if (GWEN_Buffer_AppendByte(gbuf,
635
                                 (unsigned char)((value>>8)&0xff))){
636
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
637
        return -1;
638
      }
639
      if (GWEN_Buffer_AppendByte(gbuf,
640
                                 (unsigned char)((value>>16)&0xff))){
641
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
642
        return -1;
643
      }
644
      if (GWEN_Buffer_AppendByte(gbuf,
645
                                 (unsigned char)((value>>24)&0xff))){
646
        DBG_INFO(AQBANKING_LOGDOMAIN, "called from here");
647
        return -1;
648
      }
649
    }
650
    return 0;
651
  } /* word */
652

    
653
  else if (strcasecmp(type, "bytes")==0) {
654
    if (GWEN_Buffer_GetUsedBytes(data)) {
655
      if (GWEN_Buffer_AppendBytes(gbuf,
656
                                  GWEN_Buffer_GetStart(data),
657
                                  GWEN_Buffer_GetUsedBytes(data))) {
658
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
659
        return -1;
660
      }
661
    }
662
    return 0;
663
  }
664

    
665
  else if (strcasecmp(type, "bcd")==0) {
666
    if (GWEN_Text_FromBcdBuffer(GWEN_Buffer_GetStart(data), gbuf)) {
667
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
668
      return -1;
669
    }
670
    return 0;
671
  }
672

    
673
  else if (strcasecmp(type, "tlv")==0) {
674
    int size;
675

    
676
    size=GWEN_Buffer_GetUsedBytes(data);
677
    if (size) {
678
      if (GWEN_Buffer_AppendBytes(gbuf,
679
                                  GWEN_Buffer_GetStart(data),
680
                                  size)) {
681
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
682
        return -1;
683
      }
684
      if (GWEN_Buffer_IncrementPos(data, size)) {
685
        DBG_INFO(AQBANKING_LOGDOMAIN, "here");
686
        return -1;
687
      }
688
    }
689
    return 0;
690
  }
691

    
692
  else if (strcasecmp(type, "ascii")==0) {
693
    int size;
694

    
695
    if (1!=sscanf(GWEN_XMLNode_GetProperty(node, "size", "-1"),
696
                  "%i", &size)) {
697
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad number of bytes");
698
      return -1;
699
    }
700
    if (size==-1) {
701
      size=GWEN_Buffer_GetUsedBytes(data);
702
    }
703
    else {
704
      if (size>GWEN_Buffer_GetUsedBytes(data)) {
705
        int lfiller;
706
        const char *lfs;
707

    
708
        /* check for left-filler, fill left if needed */
709
        lfs=GWEN_XMLNode_GetProperty(node, "lfiller", 0);
710
        if (lfs) {
711
          if (1!=sscanf(lfs, "%i", &lfiller)) {
712
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad value for property lfiller");
713
            return -1;
714
          }
715
          GWEN_Buffer_FillWithBytes(gbuf, (unsigned char)lfiller,
716
                                    size-GWEN_Buffer_GetUsedBytes(data));
717
        }
718
      }
719
    }
720

    
721
    if (GWEN_Buffer_AppendBytes(gbuf,
722
                                GWEN_Buffer_GetStart(data),
723
                                GWEN_Buffer_GetUsedBytes(data))) {
724
      DBG_INFO(AQBANKING_LOGDOMAIN, "here");
725
      return -1;
726
    }
727
    return 0;
728
  }
729

    
730
  else {
731
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Type \"%s\" not supported by AB_MsgEngine", type);
732
    return 1;
733
  }
734
}
735

    
736

    
737

    
738
GWEN_DB_NODE_TYPE AB_MsgEngine_TypeCheck(GWEN_MSGENGINE *e,
739
                                         const char *tname){
740
  AB_MSGENGINE *le;
741

    
742
  assert(e);
743
  le=GWEN_INHERIT_GETDATA(GWEN_MSGENGINE, AB_MSGENGINE, e);
744
  assert(le);
745

    
746
  if (strcasecmp(tname, "byte")==0 ||
747
      strcasecmp(tname, "word")==0 ||
748
      strcasecmp(tname, "dword")==0)
749
    return GWEN_DB_NodeType_ValueInt;
750
  else if (strcasecmp(tname, "bytes")==0 ||
751
           strcasecmp(tname, "tlv")==0)
752
    return GWEN_DB_NodeType_ValueBin;
753
  else if (strcasecmp(tname, "bcd")==0)
754
    return GWEN_DB_NodeType_ValueChar;
755
  else
756
    return GWEN_DB_NodeType_Unknown;
757
}
758

    
759

    
760

    
761
const char *AB_MsgEngine_GetCharValue(GWEN_MSGENGINE *e,
762
                                      const char *name,
763
                                      const char *defValue){
764
  AB_MSGENGINE *le;
765

    
766
  assert(e);
767
  le=GWEN_INHERIT_GETDATA(GWEN_MSGENGINE, AB_MSGENGINE, e);
768
  assert(le);
769

    
770
  return defValue;
771
}
772

    
773

    
774

    
775
int AB_MsgEngine_GetIntValue(GWEN_MSGENGINE *e,
776
                             const char *name,
777
                             int defValue){
778
  AB_MSGENGINE *le;
779

    
780
  assert(e);
781
  le=GWEN_INHERIT_GETDATA(GWEN_MSGENGINE, AB_MSGENGINE, e);
782
  assert(le);
783

    
784
  return defValue;
785
}
786

    
787

    
788

    
789
int AB_MsgEngine_BinTypeRead(GWEN_MSGENGINE *e,
790
                             GWEN_XMLNODE *node,
791
                             GWEN_DB_NODE *gr,
792
                             GWEN_BUFFER *vbuf){
793
  const char *typ;
794

    
795
  typ=GWEN_XMLNode_GetProperty(node, "type", "");
796
  if (strcasecmp(typ, "tlv")==0) {
797
    int isBerTlv;
798
    const char *p;
799
    unsigned int tagType;
800
    unsigned int tagLength;
801
    //const char *tagData;
802
    unsigned int size;
803
    unsigned int pos;
804
    unsigned int j;
805
    GWEN_XMLNODE *tlvNode;
806
    GWEN_DB_NODE *ngr;
807
    const char *name;
808

    
809
    GWEN_Buffer_Rewind(vbuf);
810
    if (!GWEN_Buffer_GetBytesLeft(vbuf)) {
811
      DBG_DEBUG(AQBANKING_LOGDOMAIN, "Buffer empty");
812
      return 0;
813
    }
814

    
815
    DBG_VERBOUS(AQBANKING_LOGDOMAIN, "Entering BinTypeRead with this:");
816
    if (GWEN_Logger_GetLevel(0)>=GWEN_LoggerLevel_Verbous)
817
      GWEN_Buffer_Dump(vbuf, 2);
818

    
819
    p=GWEN_Buffer_GetStart(vbuf);
820
    pos=0;
821
    size=GWEN_Buffer_GetBytesLeft(vbuf);
822
    isBerTlv=(strcasecmp(GWEN_XMLNode_GetProperty(node,
823
                                                  "tlvtype",
824
                                                  "bertlv"),
825
                         "BER")==0);
826
    /* get tag type */
827
    if (size<2) {
828
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes for BER-TLV");
829
      return -1;
830
    }
831
    j=(unsigned char)(p[pos]);
832
    if (isBerTlv) {
833
      if ((j & 0x1f)==0x1f) {
834
        pos++;
835
        if (pos>=size) {
836
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
837
          return -1;
838
        }
839
        j=(unsigned char)(p[pos]);
840
      }
841
      else
842
        j&=0x1f;
843
    }
844
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Tag type %02x%s", j,
845
              isBerTlv?" (BER-TLV)":"");
846
    tagType=j;
847

    
848
    /* get length */
849
    pos++;
850
    if (pos>=size) {
851
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
852
      return -1;
853
    }
854
    j=(unsigned char)(p[pos]);
855
    if (isBerTlv) {
856
      if (j & 0x80) {
857
        if (j==0x81) {
858
          pos++;
859
          if (pos>=size) {
860
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
861
            return -1;
862
          }
863
          j=(unsigned char)(p[pos]);
864
        } /* 0x81 */
865
        else if (j==0x82) {
866
          if (pos+1>=size) {
867
            DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
868
            return -1;
869
          }
870
          pos++;
871
          j=((unsigned char)(p[pos]))<<8;
872
          pos++;
873
          j+=(unsigned char)(p[pos]);
874
        } /* 0x82 */
875
        else {
876
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Unexpected tag length modifier %02x", j);
877
          return -1;
878
        }
879
      } /* if tag length modifier */
880
    }
881
    else {
882
      if (j==255) {
883
        if (pos+2>=size) {
884
          DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
885
          return -1;
886
        }
887
        pos++;
888
        j=((unsigned char)(p[pos]))<<8;
889
        pos++;
890
        j+=(unsigned char)(p[pos]);
891
      }
892
    }
893
    pos++;
894
    tagLength=j;
895
    //tagData=p+pos;
896
    GWEN_Buffer_SetPos(vbuf, pos);
897

    
898
    DBG_DEBUG(AQBANKING_LOGDOMAIN, "Tag: %02x (%d bytes)", tagType, tagLength);
899
    if (pos+j>size) {
900
      DBG_ERROR(AQBANKING_LOGDOMAIN, "Too few bytes");
901
      return -1;
902
    }
903

    
904
    /* parse TLV data */
905
    tlvNode=GWEN_XMLNode_FindFirstTag(node, "tlv", 0, 0);
906
    while (tlvNode) {
907
      int ltagType;
908

    
909
      if (1!=sscanf(GWEN_XMLNode_GetProperty(tlvNode, "id", "-1"),
910
                    "%i", &ltagType)) {
911
        DBG_WARN(AQBANKING_LOGDOMAIN, "Bad tag id in XML file");
912
      }
913
      else {
914
        if (ltagType==tagType) {
915
          DBG_DEBUG(AQBANKING_LOGDOMAIN, "Tag %02x found in XML file", ltagType);
916
          name=GWEN_XMLNode_GetProperty(node, "name", 0);
917
          ngr=gr;
918
          if (name) {
919
            if (*name) {
920
              ngr=GWEN_DB_GetGroup(gr,
921
                                   GWEN_DB_FLAGS_DEFAULT,
922
                                   name);
923
              assert(ngr);
924
            }
925
          }
926
          name=GWEN_XMLNode_GetProperty(tlvNode, "name", 0);
927
          if (name) {
928
            if (*name) {
929
              ngr=GWEN_DB_GetGroup(ngr,
930
                                   GWEN_DB_FLAGS_DEFAULT |
931
                                   GWEN_PATH_FLAGS_CREATE_GROUP,
932
                                   name);
933
              assert(ngr);
934
            }
935
          }
936
          if (tagLength) {
937
            if (GWEN_MsgEngine_ParseMessage(e,
938
                                            tlvNode,
939
                                            vbuf,
940
                                            ngr,
941
                                            GWEN_MSGENGINE_READ_FLAGS_DEFAULT)){
942
              DBG_INFO(AQBANKING_LOGDOMAIN, "here");
943
              return -1;
944
            }
945
          }
946
          return 0;
947
        } /* if tag id matches */
948
      } /* if id is ok */
949
      tlvNode=GWEN_XMLNode_FindNextTag(tlvNode, "tlv", 0, 0);
950
    } /* while */
951

    
952
    DBG_INFO(AQBANKING_LOGDOMAIN, "Tag \"%02x\" not found", tagType);
953
    name=GWEN_XMLNode_GetProperty(node, "name", 0);
954
    ngr=gr;
955
    if (name) {
956
      if (*name) {
957
        ngr=GWEN_DB_GetGroup(gr,
958
                             GWEN_DB_FLAGS_DEFAULT,
959
                             name);
960
        assert(ngr);
961
      }
962
    }
963
    ngr=GWEN_DB_GetGroup(ngr,
964
                         GWEN_PATH_FLAGS_CREATE_GROUP,
965
                         "UnknownTag");
966
    assert(ngr);
967
    GWEN_DB_SetIntValue(ngr, GWEN_DB_FLAGS_OVERWRITE_VARS,
968
                        "tag", tagType);
969
    GWEN_DB_SetBinValue(ngr, GWEN_DB_FLAGS_OVERWRITE_VARS,
970
                        "data",
971
                        GWEN_Buffer_GetPosPointer(vbuf),
972
                        GWEN_Buffer_GetBytesLeft(vbuf));
973

    
974
    return 0;
975
  }
976
  else {
977
    return 1;
978
  }
979
}
980

    
981

    
982

    
983
int AB_MsgEngine_BinTypeWrite(GWEN_MSGENGINE *e,
984
                              GWEN_XMLNODE *node,
985
                              GWEN_DB_NODE *gr,
986
                              GWEN_BUFFER *dbuf){
987
  return 1;
988
}
989

    
990

    
991

    
992

    
993

    
994

    
995

    
996

    
997

    
998

    
999

    
1000