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.
17 /* standard library header */
21 /* SLP library header */
24 #include "ISO7816BERTLV.h"
26 namespace smartcard_service_api
28 ISO7816BERTLV::ISO7816BERTLV() : TLVHelper(), firstByte(0), tagClass(0),
33 ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent) : TLVHelper(parent),
34 firstByte(0), tagClass(0), encoding(0)
38 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array) : TLVHelper(array),
39 firstByte(0), tagClass(0), encoding(0)
43 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent) :
44 TLVHelper(array, parent), firstByte(0), tagClass(0), encoding(0)
48 ISO7816BERTLV::~ISO7816BERTLV()
57 int ISO7816BERTLV::decodeTag(const unsigned char *buffer)
59 /* 0x00 is invalid tag value */
60 if (buffer[0] == 0x00)
66 tagClass = (buffer[0] & 0xC0) >> 6;
67 encoding = (buffer[0] & 0x20) >> 5;
71 if ((buffer[0] & 0x1F) < 0x1F)
77 currentT = (currentT << 8) | buffer[1];
86 currentT = (currentT << 8) | buffer[2];
94 int ISO7816BERTLV::decodeLength(const unsigned char *buffer)
98 uint8_t count = (buffer[0] & 0x7F);
101 /* count will be less than 5 */
107 for (i = 1; i < count; i++)
110 currentL = (currentL << 8) | buffer[i];
112 /* if little endian */
113 /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
120 currentL = buffer[0];
126 int ISO7816BERTLV::decodeValue(const unsigned char *buffer)
131 currentV.assign(buffer, currentL);
136 unsigned int ISO7816BERTLV::getClass() const
141 unsigned int ISO7816BERTLV::getEncoding() const
146 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer)
148 unsigned char temp_tag[3] = { 0, };
149 unsigned char temp_tag_len = 0;
150 unsigned char temp_len[5] = { 0, };
151 unsigned char temp_len_len = 0;
153 unsigned int total_len = 0;
154 unsigned int current = 0;
155 unsigned char *temp_buffer = NULL;
157 /* add tag's length */
161 temp_tag[0] = (tagClass << 6) | (encoding << 5);
180 temp_tag[1] = (tag & 0x000000FF);
181 temp_tag[2] = (tag & 0x0000FF00);
187 total_len += temp_tag_len;
189 /* add length's length */
190 if (buffer.size() < 128)
192 temp_len[0] = buffer.size();
201 if (buffer.size() > 0x00FFFFFF)
203 temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
207 if (buffer.size() > 0x0000FFFF)
209 temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
213 if (buffer.size() > 0x000000FF)
215 temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
219 temp_len[1] = buffer.size() & 0x000000FF;
222 temp_len[0] |= temp_len_len;
225 /* add buffer's length */
226 total_len += buffer.size();
228 /* alloc new buffer */
229 temp_buffer = new unsigned char[total_len];
230 if (temp_buffer == NULL)
234 memset(temp_buffer, 0, total_len);
237 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
238 current += temp_tag_len;
241 memcpy(temp_buffer + current, temp_len, temp_len_len);
242 current += temp_len_len;
245 if (buffer.size() > 0)
246 memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
248 result.assign(temp_buffer, total_len);
250 delete []temp_buffer;
255 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
257 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
260 TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
262 if (childTLV != NULL)
267 childTLV = new ISO7816BERTLV(data, this);
269 return (TLVHelper *)childTLV;
272 } /* namespace smartcard_service_api */