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.
20 #include "FileObject.h"
21 #include "APDUHelper.h"
23 namespace smartcard_service_api
25 FileObject::FileObject(Channel *channel)
26 : ProviderHelper(channel)
31 FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
32 : ProviderHelper(channel)
35 setSelectResponse(selectResponse);
38 FileObject::~FileObject()
43 void FileObject::close()
46 selectResponse.clear();
49 bool FileObject::setSelectResponse(const ByteArray &response)
53 if (response.size() >= 2)
55 ResponseHelper resp(response);
56 selectResponse = response;
58 if (resp.getStatus() >= 0)
62 fcp.setFCP(resp.getDataField());
64 _DBG("FCP : %s", fcp.toString().c_str());
71 _ERR("status word [ %02X %02X ]",
72 resp.getSW1(), resp.getSW2());
77 _ERR("invalid response");
83 int FileObject::_select(const ByteArray &command)
85 int ret = ERROR_ILLEGAL_STATE;
88 if (channel == NULL || channel->isClosed())
90 _ERR("channel is not open");
97 ret = channel->transmitSync(command, result);
100 ResponseHelper resp(result);
102 ret = resp.getStatus();
104 if (setSelectResponse(result) == true)
111 _ERR("select apdu is failed, rv [%d], length [%d]",
114 ret = ERROR_ILLEGAL_STATE;
120 int FileObject::select(const ByteArray &aid)
122 int ret = ERROR_ILLEGAL_STATE;
125 /* make apdu command */
126 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid);
128 ret = _select(command);
133 int FileObject::select(const ByteArray &path, bool fromCurrentDF)
135 int ret = ERROR_ILLEGAL_STATE;
138 /* make apdu command */
139 if (fromCurrentDF == true)
141 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF, 0, path);
145 ByteArray temp(path);
147 if (path.size() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */
149 /* remove MF from path */
150 temp.assign(path.getBuffer(2), path.size() - 2);
153 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, temp);
156 ret = _select(command);
161 int FileObject::select(unsigned int fid)
163 int ret = ERROR_ILLEGAL_STATE;
164 ByteArray command, fidData((unsigned char *)&fid, 2);
166 /* make apdu command */
167 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData);
169 ret = _select(command);
174 int FileObject::selectParent()
176 int ret = ERROR_ILLEGAL_STATE;
179 /* make apdu command */
180 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY);
182 ret = _select(command);
187 const FCI *FileObject::getFCI() const
192 const FCP *FileObject::getFCP() const
197 int FileObject::readRecord(unsigned int sfi, unsigned int recordId, Record &result)
199 ByteArray command, response;
203 apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, APDUCommand::LE_MAX);
204 apdu.getBuffer(command);
206 ret = channel->transmitSync(command, response);
207 if (ret == 0 && response.size() >= 2)
209 ResponseHelper resp(response);
211 ret = resp.getStatus();
214 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
216 result = Record(recordId, resp.getDataField());
220 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
225 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
231 int FileObject::writeRecord(unsigned int sfi, const Record &record)
236 int FileObject::searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result)
241 int FileObject::readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result)
243 ByteArray command, response;
247 apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length);
248 apdu.getBuffer(command);
250 ret = channel->transmitSync(command, response);
251 if (ret == 0 && response.size() >= 2)
253 ResponseHelper resp(response);
255 if (resp.getStatus() >= 0)
257 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
259 result = resp.getDataField();
265 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
270 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
276 int FileObject::writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length)
278 ByteArray command, response;
282 apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0);
283 apdu.getBuffer(command);
285 ret = channel->transmitSync(command, response);
286 if (ret == 0 && response.size() >= 2)
288 ResponseHelper resp(response);
290 if (resp.getStatus() >= 0)
292 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
298 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
303 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
308 } /* namespace smartcard_service_api */