]>
Commit | Line | Data |
---|---|---|
9206d3b0 | 1 | #include <tlv.h> |
2 | #include <stddef.h> | |
3 | ||
4 | int decode_ber_tlv_item(uint8_t* data, tlvtag* returnedtag) | |
5 | { | |
6 | uint8_t tag[TAG_LENGTH] = {0x00,0x00}; | |
7 | uint16_t length = 0; | |
8 | //uint8_t value[VALUE_LENGTH]; | |
9 | uint8_t lenlen = 0; | |
10 | int i = 0; | |
11 | int z = 0; | |
12 | //decode tag | |
13 | tag[0] = data[0]; | |
14 | if((tag[0] & TLV_TAG_NUMBER_MASK) == TLV_TAG_NUMBER_MASK) { //see subsequent bytes | |
15 | i++; | |
16 | tag[i] = data[i]; | |
17 | //assume tag is only two bytes long for now | |
18 | /* | |
19 | while((data[i] & TLV_TAG_MASK) == TLV_TAG_MASK){ | |
20 | i++; | |
21 | tag[i] = data[i]; | |
22 | } | |
23 | */ | |
24 | } | |
25 | i++; | |
26 | //decode length | |
27 | if((data[i] & TLV_LENGTH_MASK) == TLV_LENGTH_MASK) { | |
28 | lenlen = data[i] ^ TLV_LENGTH_MASK; | |
29 | i++; | |
30 | length = (uint16_t)data[i]; | |
31 | z = 1; | |
32 | while(z < lenlen){ | |
33 | i++; | |
34 | z++; | |
35 | length <<= 8; | |
36 | length += (uint16_t)data[i]; | |
37 | } | |
38 | i++; | |
39 | } | |
40 | else { | |
41 | length = (uint16_t)data[i]; | |
42 | i++; | |
43 | } | |
44 | //copy results into the structure and return | |
45 | memcpy(returnedtag->tag, tag, TAG_LENGTH); | |
46 | (*returnedtag).valuelength = length; //return length of tag value | |
47 | (*returnedtag).fieldlength = length + i + 1; //return length of total field | |
48 | memcpy(returnedtag->value, &(data[i]), length); | |
49 | return 0; | |
50 | } | |
51 | ||
52 | //generate a TLV tag off input data | |
53 | int encode_ber_tlv_item(uint8_t* tag, uint8_t taglen, uint8_t* data, uint32_t datalen, uint8_t* outputtag, uint32_t* outputtaglen) | |
54 | { | |
55 | if(!tag || !data || !outputtag || !outputtaglen) //null pointer check | |
56 | return 0; | |
57 | ||
58 | uint8_t datafieldlen = (datalen / 128) + 1; //field length of the tag | |
59 | uint8_t tlvtotallen = taglen + datafieldlen + datalen; //total length of the tag | |
60 | uint8_t returnedtag[tlvtotallen]; //buffer for the returned tag | |
61 | uint8_t counter = 0; | |
62 | memcpy(returnedtag, tag, taglen); //copy tag into buffer | |
63 | counter += taglen; | |
64 | if(datalen < 128){ // 1 byte length value | |
65 | returnedtag[counter++] = datalen; | |
66 | } | |
67 | else{ | |
68 | returnedtag[counter++] = datafieldlen | 0x80; //high bit set and number of length bytes | |
69 | for(uint8_t i=datafieldlen; i !=0; i--){ | |
70 | returnedtag[counter++] = (datalen >> (i * 8)) & 0xFF; //get current byte | |
71 | } | |
72 | } | |
73 | memcpy(&returnedtag[counter], data, datalen); | |
74 | *outputtaglen = tlvtotallen; | |
75 | memcpy(outputtag, returnedtag,tlvtotallen); | |
76 | return 0; | |
77 | } | |
78 |