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)
97 uint8_t count = buffer[offset];
106 /* count will be less than 5 */
110 for (i = 0; i < count; i++) {
112 currentL = (currentL << 8) | buffer[offset + i];
114 /* if little endian */
115 /* currentL = currentL | (buffer[offset + i] << (8 * (i - 1))); */
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);
174 temp_tag[1] = (tag & 0x000000FF);
175 temp_tag[2] = (tag & 0x0000FF00);
181 total_len += temp_tag_len;
183 /* add length's length */
184 if (buffer.size() < 128) {
185 temp_len[0] = buffer.size();
192 if (buffer.size() > 0x00FFFFFF)
194 temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
198 if (buffer.size() > 0x0000FFFF)
200 temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
204 if (buffer.size() > 0x000000FF)
206 temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
210 temp_len[1] = buffer.size() & 0x000000FF;
213 temp_len[0] |= temp_len_len;
216 /* add buffer's length */
217 total_len += buffer.size();
219 /* alloc new buffer */
220 temp_buffer = new unsigned char[total_len];
221 if (temp_buffer == NULL)
225 memset(temp_buffer, 0, total_len);
228 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
229 current += temp_tag_len;
232 memcpy(temp_buffer + current, temp_len, temp_len_len);
233 current += temp_len_len;
236 if (buffer.size() > 0)
237 memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
239 result.assign(temp_buffer, total_len);
241 delete []temp_buffer;
246 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
248 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
251 TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
253 if (childTLV != NULL)
258 childTLV = new ISO7816BERTLV(data, this);
260 return (TLVHelper *)childTLV;
263 } /* namespace smartcard_service_api */