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
29 ISO7816BERTLV::ISO7816BERTLV() : TLVHelper(), firstByte(0), tagClass(0),
34 ISO7816BERTLV::ISO7816BERTLV(TLVHelper *parent) : TLVHelper(parent),
35 firstByte(0), tagClass(0), encoding(0)
39 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array) : TLVHelper(array),
40 firstByte(0), tagClass(0), encoding(0)
44 ISO7816BERTLV::ISO7816BERTLV(const ByteArray &array, TLVHelper *parent) :
45 TLVHelper(array, parent), firstByte(0), tagClass(0), encoding(0)
49 ISO7816BERTLV::~ISO7816BERTLV()
58 int ISO7816BERTLV::decodeTag(const unsigned char *buffer)
60 /* 0x00 is invalid tag value */
61 if (buffer[0] == 0x00)
67 tagClass = (buffer[0] & 0xC0) >> 6;
68 encoding = (buffer[0] & 0x20) >> 5;
72 if ((buffer[0] & 0x1F) < 0x1F)
78 currentT = (currentT << 8) | buffer[1];
87 currentT = (currentT << 8) | buffer[2];
95 int ISO7816BERTLV::decodeLength(const unsigned char *buffer)
98 uint8_t count = buffer[offset];
107 /* count will be less than 5 */
111 for (i = 0; i < count; i++) {
113 currentL = (currentL << 8) | buffer[offset + i];
115 /* if little endian */
116 /* currentL = currentL | (buffer[offset + i] << (8 * (i - 1))); */
127 int ISO7816BERTLV::decodeValue(const unsigned char *buffer)
132 currentV.assign(buffer, currentL);
137 unsigned int ISO7816BERTLV::getClass() const
142 unsigned int ISO7816BERTLV::getEncoding() const
147 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, const ByteArray &buffer)
149 unsigned char temp_tag[3] = { 0, };
150 unsigned char temp_tag_len = 0;
151 unsigned char temp_len[5] = { 0, };
152 unsigned char temp_len_len = 0;
154 unsigned int total_len = 0;
155 unsigned int current = 0;
156 unsigned char *temp_buffer = NULL;
158 /* add tag's length */
162 temp_tag[0] = (tagClass << 6) | (encoding << 5);
175 temp_tag[1] = (tag & 0x000000FF);
176 temp_tag[2] = (tag & 0x0000FF00);
182 total_len += temp_tag_len;
184 /* add length's length */
185 if (buffer.size() < 128) {
186 temp_len[0] = buffer.size();
193 if (buffer.size() > 0x00FFFFFF)
195 temp_len[4] = (buffer.size() & 0xFF000000) >> 24;
199 if (buffer.size() > 0x0000FFFF)
201 temp_len[3] = (buffer.size() & 0x00FF0000) >> 16;
205 if (buffer.size() > 0x000000FF)
207 temp_len[2] = (buffer.size() & 0x0000FF00) >> 8;
211 temp_len[1] = buffer.size() & 0x000000FF;
214 temp_len[0] |= temp_len_len;
217 /* add buffer's length */
218 total_len += buffer.size();
220 /* alloc new buffer */
221 temp_buffer = new unsigned char[total_len];
222 if (temp_buffer == NULL)
226 memset(temp_buffer, 0, total_len);
229 memcpy(temp_buffer + current, temp_tag, temp_tag_len);
230 current += temp_tag_len;
233 memcpy(temp_buffer + current, temp_len, temp_len_len);
234 current += temp_len_len;
237 if (buffer.size() > 0)
238 memcpy(temp_buffer + current, buffer.getBuffer(), buffer.size());
240 result.assign(temp_buffer, total_len);
242 delete []temp_buffer;
247 const ByteArray ISO7816BERTLV::encode(unsigned int tagClass, unsigned int encoding, unsigned int tag, unsigned char *buffer, unsigned int length)
249 return encode(tagClass, encoding, tag, ByteArray(buffer, length));
252 TLVHelper *ISO7816BERTLV::getChildTLV(const ByteArray &data)
254 if (childTLV != NULL)
259 childTLV = new ISO7816BERTLV(data, this);
261 return (TLVHelper *)childTLV;
265 } /* namespace smartcard_service_api */