2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "ISO7816BERTLV.h"
22 namespace smartcard_service_api
24 ISO7816BERTLV::ISO7816BERTLV() : TLVHelper(), firstByte(0), tagClass(0),
29 ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent) : TLVHelper(parent),
30 firstByte(0), tagClass(0), encoding(0)
34 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array) : TLVHelper(array),
35 firstByte(0), tagClass(0), encoding(0)
39 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent) :
40 TLVHelper(array, parent), firstByte(0), tagClass(0), encoding(0)
44 ISO7816BERTLV::~ISO7816BERTLV()
53 int ISO7816BERTLV::decodeTag(const unsigned char *buffer)
55 /* 0x00 is invalid tag value */
56 if (buffer[0] == 0x00)
62 tagClass = (buffer[0] & 0xC0) >> 6;
63 encoding = (buffer[0] & 0x20) >> 5;
67 if ((buffer[0] & 0x1F) < 0x1F)
73 currentT = (currentT << 8) | buffer[1];
82 currentT = (currentT << 8) | buffer[2];
90 int ISO7816BERTLV::decodeLength(const unsigned char *buffer)
94 uint8_t count = (buffer[0] & 0x7F);
97 /* count will be less than 5 */
103 for (i = 1; i < count; i++)
106 currentL = (currentL << 8) | buffer[i];
108 /* if little endian */
109 /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
116 currentL = buffer[0];
122 int ISO7816BERTLV::decodeValue(const unsigned char *buffer)
127 currentV.assign(buffer, currentL);
132 unsigned int ISO7816BERTLV::getClass() const
137 unsigned int ISO7816BERTLV::getEncoding() const
142 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer)
144 unsigned char temp_tag[3] = { 0, };
145 unsigned char temp_tag_len = 0;
146 unsigned char temp_len[5] = { 0, };
147 unsigned char temp_len_len = 0;
149 unsigned int total_len = 0;
150 unsigned int current = 0;
151 unsigned char *temp_buffer = NULL;
153 /* add tag's length */
157 temp_tag[0] = (tagClass << 6) | (encoding << 5);
176 temp_tag[1] = (tag & 0x000000FF);
177 temp_tag[2] = (tag & 0x0000FF00);
183 total_len += temp_tag_len;
185 /* add length's length */
186 if (buffer.size() < 128)
188 temp_len[0] = buffer.size();
197 if (buffer.size() > 0x00FFFFFF)
199 temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
203 if (buffer.size() > 0x0000FFFF)
205 temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
209 if (buffer.size() > 0x000000FF)
211 temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
215 temp_len[1] = buffer.size() & 0x000000FF;
218 temp_len[0] |= temp_len_len;
221 /* add buffer's length */
222 total_len += buffer.size();
224 /* alloc new buffer */
225 temp_buffer = new unsigned char[total_len];
226 if (temp_buffer == NULL)
230 memset(temp_buffer, 0, total_len);
233 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
234 current += temp_tag_len;
237 memcpy(temp_buffer + current, temp_len, temp_len_len);
238 current += temp_len_len;
241 if (buffer.size() > 0)
242 memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
244 result.assign(temp_buffer, total_len);
246 delete []temp_buffer;
251 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
253 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
256 TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
258 if (childTLV != NULL)
263 childTLV = new ISO7816BERTLV(data, this);
265 return (TLVHelper *)childTLV;
268 } /* namespace smartcard_service_api */