2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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.
18 /* standard library header */
22 /* SLP library header */
25 #include "ISO7816BERTLV.h"
27 namespace smartcard_service_api
29 ISO7816BERTLV::ISO7816BERTLV():TLVHelper()
35 ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent):TLVHelper(parent)
43 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array):TLVHelper(array)
49 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent):TLVHelper(array, parent)
57 ISO7816BERTLV::~ISO7816BERTLV()
66 int ISO7816BERTLV::decodeTag(unsigned char *buffer)
68 /* 0x00 is invalid tag value */
69 if (buffer[0] == 0x00)
75 tagClass = (buffer[0] & 0xE0) >> 6;
76 encoding = (buffer[0] & 0x20) >> 5;
80 if ((buffer[0] & 0x1F) < 0x1F)
86 currentT = (currentT << 8) | buffer[1];
95 currentT = (currentT << 8) | buffer[2];
103 int ISO7816BERTLV::decodeLength(unsigned char *buffer)
105 if (buffer[0] & 0x80)
107 uint8_t count = (buffer[0] & 0x7F);
110 /* count will be less than 5 */
114 count++; /* increse count and increase i value, too */
116 for (i = 1; i < count; i++)
119 currentL = (currentL << 8) | buffer[i];
121 /* if little endian */
122 /* currentL = currentL | (buffer[i] << (8 * (i - 1))); */
129 currentL = buffer[0];
135 int ISO7816BERTLV::decodeValue(unsigned char *buffer)
140 currentV.setBuffer(buffer, currentL);
145 unsigned int ISO7816BERTLV::getClass()
150 unsigned int ISO7816BERTLV::getEncoding()
155 ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, ByteArray buffer)
157 unsigned char temp_tag[3] = { 0, };
158 unsigned char temp_tag_len = 0;
159 unsigned char temp_len[5] = { 0, };
160 unsigned char temp_len_len = 0;
162 unsigned int total_len = 0;
163 unsigned int current = 0;
164 unsigned char *temp_buffer = NULL;
166 /* add tag's length */
170 temp_tag[0] = (tagClass << 6) | (encoding << 5);
189 temp_tag[1] = (tag & 0x000000FF);
190 temp_tag[2] = (tag & 0x0000FF00);
196 total_len += temp_tag_len;
198 /* add length's length */
199 if (buffer.getLength() < 128)
201 temp_len[0] = buffer.getLength();
210 if (buffer.getLength() > 0x00FFFFFF)
212 temp_len[4] = (buffer.getLength() & 0xFF000000) >> 24;
216 if (buffer.getLength() > 0x0000FFFF)
218 temp_len[3] = (buffer.getLength() & 0x00FF0000) >> 16;
222 if (buffer.getLength() > 0x000000FF)
224 temp_len[2] = (buffer.getLength() & 0x0000FF00) >> 8;
228 temp_len[1] = buffer.getLength() & 0x000000FF;
231 temp_len[0] |= temp_len_len;
234 /* add buffer's length */
235 total_len += buffer.getLength();
237 /* alloc new buffer */
238 temp_buffer = new unsigned char[total_len];
239 if (temp_buffer == NULL)
243 memset(temp_buffer, 0, total_len);
246 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
247 current += temp_tag_len;
250 memcpy(temp_buffer + current, temp_len, temp_len_len);
251 current += temp_len_len;
254 if (buffer.getLength() > 0)
255 memcpy(temp_buffer + current, buffer.getBuffer(), buffer.getLength());
257 result.setBuffer(temp_buffer, total_len);
259 delete []temp_buffer;
264 ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
266 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
269 TLVHelper *ISO7816BERTLV::getChildTLV(ByteArray data)
271 if (childTLV != NULL)
276 childTLV = new ISO7816BERTLV(data, this);
278 return (TLVHelper *)childTLV;
281 } /* namespace smartcard_service_api */