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