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 */
19 /* SLP library header */
24 #include "APDUHelper.h"
25 #include "FileObject.h"
26 #include "NumberStream.h"
27 #include "SimpleTLV.h"
28 #include "ISO7816BERTLV.h"
29 #include "AccessCondition.h"
32 #define EXTERN_API __attribute__((visibility("default")))
35 namespace smartcard_service_api
37 static unsigned char aid_aram[] = { 0xA0, 0x00, 0x00, 0x01, 0x51, 0x41, 0x43, 0x4C, 00 };
38 static ByteArray AID_ARAM(ARRAY_AND_SIZE(aid_aram));
40 #define GET_DATA_ALL 0
41 #define GET_DATA_SPECIFIC 1
42 #define GET_DATA_REFRESH_TAG 2
43 #define GET_DATA_NEXT 3
45 #define ARAM_TAG_ALL_AR 0x0000FF40
46 #define ARAM_TAG_AR 0x0000FF50
47 #define ARAM_TAG_REFRESH 0x0000DF20
49 #define DO_TAG_AID_REF 0x0000004F
50 #define DO_TAG_AID_REF_DEFAULT 0x000000C0
51 #define DO_TAG_HASH_REF 0x000000C1
52 #define DO_TAG_APDU_AR 0x000000D0
53 #define DO_TAG_NFC_AR 0x000000D1
54 #define DO_TAG_REF 0x000000E1
55 #define DO_TAG_REF_AR 0x000000E2
56 #define DO_TAG_AR 0x000000E3
58 GPARAM::GPARAM(Channel *channel)
65 return FileObject::select(AID_ARAM);
68 static int doTransmit(Channel *channel, const ByteArray &command, ByteArray &response)
75 result = channel->transmitSync(command, resp);
76 if (result == SCARD_ERROR_OK) {
77 result = ResponseHelper::getStatus(resp);
78 if (result >= SCARD_ERROR_OK) {
79 response = ResponseHelper::getDataField(resp);
80 _DBG("response[%d] : %s", response.size(), response.toString().c_str());
82 _ERR("transmit returns error, [%d]", result);
85 _ERR("transmitSync failed, [%d]", result);
93 static int doCommand(Channel *channel, int command, ByteArray &response)
103 helper.setCommand(0x80, 0xCA, 0xFF, 0x40, ByteArray::EMPTY, 0);
106 case GET_DATA_REFRESH_TAG :
107 helper.setCommand(0x80, 0xCA, 0xDF, 0x20, ByteArray::EMPTY, 0);
111 helper.setCommand(0x80, 0xCA, 0xFF, 0x60, ByteArray::EMPTY, 0);
115 helper.getBuffer(cmd);
117 _DBG("command[%d] : %s", cmd.size(), cmd.toString().c_str());
119 result = doTransmit(channel, cmd, response);
126 static int doCommand(Channel *channel, ByteArray &data, ByteArray &response)
132 helper.setCommand(0x80, 0xCA, 0xFF, 0x50, data, 0);
133 helper.getBuffer(cmd);
135 result = doTransmit(channel, cmd, response);
140 int GPARAM::getDataAll(ByteArray &data)
147 result = doCommand(channel, GET_DATA_ALL, response);
148 if (result >= SCARD_ERROR_OK) {
149 ISO7816BERTLV tlv(response);
151 if (tlv.decodeTLV() == true &&
152 tlv.getTag() == ARAM_TAG_ALL_AR) {
153 unsigned int length = tlv.size();
156 data = tlv.getValue();
158 while (length > data.size()) {
159 result = doCommand(channel, GET_DATA_NEXT, response);
160 if (result >= SCARD_ERROR_OK) {
163 _ERR("generateCommand failed, [%d]", result);
169 _DBG("data[%d] : %s", data.size(), data.toString().c_str());
171 _INFO("Response-ALL-AR-DO is empty");
175 _ERR("decodeTLV failed, %s", response.toString().c_str());
176 result = SCARD_ERROR_ILLEGAL_PARAM;
179 _ERR("generateCommand failed, [%d]", result);
187 static int createRefDo(const ByteArray &aid, const ByteArray &hash, ByteArray &refDo)
191 temp = SimpleTLV::encode(DO_TAG_AID_REF, aid);
192 temp += SimpleTLV::encode(DO_TAG_HASH_REF, hash);
194 refDo = SimpleTLV::encode(DO_TAG_REF, temp);
195 _DBG("encoded Ref DO : %s", refDo.toString().c_str());
197 return SCARD_ERROR_OK;
200 int GPARAM::getDataSpecific(const ByteArray &aid, const ByteArray &hash,
204 ByteArray refDo, response;
208 createRefDo(aid, hash, refDo);
210 result = doCommand(channel, refDo, response);
211 if (result >= SCARD_ERROR_OK) {
212 ISO7816BERTLV tlv(response);
214 if (tlv.decodeTLV() == true &&
215 tlv.getTag() == ARAM_TAG_AR) {
216 unsigned int length = tlv.size();
219 data = tlv.getValue();
221 while (length > data.size()) {
222 result = doCommand(channel, GET_DATA_NEXT, response);
223 if (result >= SCARD_ERROR_OK) {
226 _ERR("generateCommand failed, [%d]", result);
231 _DBG("data[%d] : %s", data.size(), data.toString().c_str());
233 _INFO("Response-ALL-AR-DO is empty");
237 _ERR("decodeTLV failed, %s", response.toString().c_str());
238 result = SCARD_ERROR_ILLEGAL_PARAM;
241 _ERR("doCommand failed, [%d]", result);
249 int GPARAM::getDataRefreshTag(ByteArray &tag)
256 result = doCommand(channel, GET_DATA_REFRESH_TAG, response);
257 if (result >= SCARD_ERROR_OK) {
258 ISO7816BERTLV tlv(response);
260 if (tlv.decodeTLV() == true &&
261 tlv.getTag() == ARAM_TAG_REFRESH &&
263 tag = tlv.getValue();
264 result = SCARD_ERROR_OK;
265 _DBG("refreshTag[%d] : %s", tag.size(), tag.toString().c_str());
267 _ERR("decodeTLV failed, %s", response.toString().c_str());
268 result = SCARD_ERROR_ILLEGAL_PARAM;
271 _ERR("generateCommand failed, [%d]", result);
278 } /* namespace smartcard_service_api */