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 */
20 /* SLP library header */
24 #include "FileObject.h"
25 #include "APDUHelper.h"
27 namespace smartcard_service_api
29 FileObject::FileObject(Channel *channel)
30 : ProviderHelper(channel)
35 FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
36 : ProviderHelper(channel)
39 setSelectResponse(selectResponse);
42 FileObject::~FileObject()
47 void FileObject::close()
50 selectResponse.clear();
53 bool FileObject::setSelectResponse(const ByteArray &response)
57 if (response.size() >= 2)
59 ResponseHelper resp(response);
60 selectResponse = response;
62 if (resp.getStatus() >= 0)
66 fcp.setFCP(resp.getDataField());
68 _DBG("FCP : %s", fcp.toString().c_str());
75 _ERR("status word [ %02X %02X ]",
76 resp.getSW1(), resp.getSW2());
81 _ERR("invalid response");
87 int FileObject::_select(const ByteArray &command)
89 int ret = ERROR_ILLEGAL_STATE;
92 if (channel == NULL || channel->isClosed())
94 _ERR("channel is not open");
101 ret = channel->transmitSync(command, result);
104 ResponseHelper resp(result);
106 ret = resp.getStatus();
108 if (setSelectResponse(result) == true)
115 _ERR("select apdu is failed, rv [%d], length [%d]",
118 ret = ERROR_ILLEGAL_STATE;
124 int FileObject::select(const ByteArray &aid)
126 int ret = ERROR_ILLEGAL_STATE;
129 /* make apdu command */
130 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid);
132 ret = _select(command);
137 int FileObject::select(const ByteArray &path, bool fromCurrentDF)
139 int ret = ERROR_ILLEGAL_STATE;
142 /* make apdu command */
143 if (fromCurrentDF == true)
145 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF, 0, path);
149 ByteArray temp(path);
151 if (path.size() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */
153 /* remove MF from path */
154 temp.assign(path.getBuffer(2), path.size() - 2);
157 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, temp);
160 ret = _select(command);
165 int FileObject::select(unsigned int fid)
167 int ret = ERROR_ILLEGAL_STATE;
168 ByteArray command, fidData((unsigned char *)&fid, 2);
170 /* make apdu command */
171 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData);
173 ret = _select(command);
178 int FileObject::selectParent()
180 int ret = ERROR_ILLEGAL_STATE;
183 /* make apdu command */
184 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY);
186 ret = _select(command);
191 const FCI *FileObject::getFCI() const
196 const FCP *FileObject::getFCP() const
201 int FileObject::readRecord(unsigned int sfi, unsigned int recordId, Record &result)
203 ByteArray command, response;
207 apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, APDUCommand::LE_MAX);
208 apdu.getBuffer(command);
210 ret = channel->transmitSync(command, response);
211 if (ret == 0 && response.size() >= 2)
213 ResponseHelper resp(response);
215 ret = resp.getStatus();
218 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
220 result = Record(recordId, resp.getDataField());
224 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
229 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
235 int FileObject::writeRecord(unsigned int sfi, const Record &record)
240 int FileObject::searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result)
245 int FileObject::readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result)
247 ByteArray command, response;
251 apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length);
252 apdu.getBuffer(command);
254 ret = channel->transmitSync(command, response);
255 if (ret == 0 && response.size() >= 2)
257 ResponseHelper resp(response);
259 if (resp.getStatus() >= 0)
261 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
263 result = resp.getDataField();
269 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
274 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
280 int FileObject::writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length)
282 ByteArray command, response;
286 apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0);
287 apdu.getBuffer(command);
289 ret = channel->transmitSync(command, response);
290 if (ret == 0 && response.size() >= 2)
292 ResponseHelper resp(response);
294 if (resp.getStatus() >= 0)
296 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
302 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
307 _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
312 } /* namespace smartcard_service_api */