Fix the Prevent problems
[platform/core/connectivity/smartcard-service.git] / common / FileObject.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19
20 /* SLP library header */
21
22 /* local header */
23 #include "Debug.h"
24 #include "FileObject.h"
25 #include "APDUHelper.h"
26
27 namespace smartcard_service_api
28 {
29         FileObject::FileObject(Channel *channel)
30                 : ProviderHelper(channel)
31         {
32                 opened = false;
33         }
34
35         FileObject::FileObject(Channel *channel, const ByteArray &selectResponse)
36                 : ProviderHelper(channel)
37         {
38                 opened = false;
39                 setSelectResponse(selectResponse);
40         }
41
42         FileObject::~FileObject()
43         {
44                 close();
45         }
46
47         void FileObject::close()
48         {
49                 opened = false;
50                 selectResponse.clear();
51         }
52
53         bool FileObject::setSelectResponse(const ByteArray &response)
54         {
55                 bool result = false;
56
57                 if (response.size() >= 2)
58                 {
59                         ResponseHelper resp(response);
60                         selectResponse = response;
61
62                         if (resp.getStatus() >= 0)
63                         {
64                                 fcp.releaseFCP();
65
66                                 fcp.setFCP(resp.getDataField());
67
68                                 _DBG("FCP : %s", fcp.toString().c_str());
69
70                                 opened = true;
71                                 result = true;
72                         }
73                         else
74                         {
75                                 _ERR("status word [ %02X %02X ]",
76                                         resp.getSW1(), resp.getSW2());
77                         }
78                 }
79                 else
80                 {
81                         _ERR("invalid response");
82                 }
83
84                 return result;
85         }
86
87         int FileObject::_select(const ByteArray &command)
88         {
89                 int ret = ERROR_ILLEGAL_STATE;
90                 ByteArray result;
91
92                 if (channel == NULL || channel->isClosed())
93                 {
94                         _ERR("channel is not open");
95
96                         return ret;
97                 }
98
99                 close();
100
101                 ret = channel->transmitSync(command, result);
102                 if (ret == 0)
103                 {
104                         ResponseHelper resp(result);
105
106                         ret = resp.getStatus();
107
108                         if (setSelectResponse(result) == true)
109                         {
110                                 opened = true;
111                         }
112                 }
113                 else
114                 {
115                         _ERR("select apdu is failed, rv [%d], length [%d]",
116                                 ret, result.size());
117
118                         ret = ERROR_ILLEGAL_STATE;
119                 }
120
121                 return ret;
122         }
123
124         int FileObject::select(const ByteArray &aid)
125         {
126                 int ret = ERROR_ILLEGAL_STATE;
127                 ByteArray command;
128
129                 /* make apdu command */
130                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, 0, aid);
131
132                 ret = _select(command);
133
134                 return ret;
135         }
136
137         int FileObject::select(const ByteArray &path, bool fromCurrentDF)
138         {
139                 int ret = ERROR_ILLEGAL_STATE;
140                 ByteArray command;
141
142                 /* make apdu command */
143                 if (fromCurrentDF == true)
144                 {
145                         command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH_FROM_CURRENT_DF, 0, path);
146                 }
147                 else
148                 {
149                         ByteArray temp(path);
150
151                         if (path.size() > 2 && path[0] == 0x3f && path[1] == 0x00) /* check MF */
152                         {
153                                 /* remove MF from path */
154                                 temp.assign(path.getBuffer(2), path.size() - 2);
155                         }
156
157                         command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_PATH, 0, temp);
158                 }
159
160                 ret = _select(command);
161
162                 return ret;
163         }
164
165         int FileObject::select(unsigned int fid)
166         {
167                 int ret = ERROR_ILLEGAL_STATE;
168                 ByteArray command, fidData((unsigned char *)&fid, 2);
169
170                 /* make apdu command */
171                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_ID, 0, fidData);
172
173                 ret = _select(command);
174
175                 return ret;
176         }
177
178         int FileObject::selectParent()
179         {
180                 int ret = ERROR_ILLEGAL_STATE;
181                 ByteArray command;
182
183                 /* make apdu command */
184                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_PARENT_DF, 0, ByteArray::EMPTY);
185
186                 ret = _select(command);
187
188                 return ret;
189         }
190
191         const FCI *FileObject::getFCI() const
192         {
193                 return NULL;
194         }
195
196         const FCP *FileObject::getFCP() const
197         {
198                 return &fcp;
199         }
200
201         int FileObject::readRecord(unsigned int sfi, unsigned int recordId, Record &result)
202         {
203                 ByteArray command, response;
204                 APDUCommand apdu;
205                 int ret;
206
207                 apdu.setCommand(0, APDUCommand::INS_READ_RECORD, recordId, 4, ByteArray::EMPTY, APDUCommand::LE_MAX);
208                 apdu.getBuffer(command);
209
210                 ret = channel->transmitSync(command, response);
211                 if (ret == 0 && response.size() >= 2)
212                 {
213                         ResponseHelper resp(response);
214
215                         ret = resp.getStatus();
216                         if (ret >= 0)
217                         {
218                                 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
219
220                                 result = Record(recordId, resp.getDataField());
221                         }
222                         else
223                         {
224                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
225                         }
226                 }
227                 else
228                 {
229                         _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
230                 }
231
232                 return ret;
233         }
234
235         int FileObject::writeRecord(unsigned int sfi, const Record &record)
236         {
237                 return 0;
238         }
239
240         int FileObject::searchRecord(unsigned int sfi, const ByteArray &searchParam, vector<int> &result)
241         {
242                 return 0;
243         }
244
245         int FileObject::readBinary(unsigned int sfi, unsigned int offset, unsigned int length, ByteArray &result)
246         {
247                 ByteArray command, response;
248                 APDUCommand apdu;
249                 int ret;
250
251                 apdu.setCommand(0, APDUCommand::INS_READ_BINARY, offset, 0, ByteArray::EMPTY, length);
252                 apdu.getBuffer(command);
253
254                 ret = channel->transmitSync(command, response);
255                 if (ret == 0 && response.size() >= 2)
256                 {
257                         ResponseHelper resp(response);
258
259                         if (resp.getStatus() >= 0)
260                         {
261                                 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
262
263                                 result = resp.getDataField();
264
265                                 ret = SUCCESS;
266                         }
267                         else
268                         {
269                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
270                         }
271                 }
272                 else
273                 {
274                         _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
275                 }
276
277                 return ret;
278         }
279
280         int FileObject::writeBinary(unsigned int sfi, const ByteArray &data, unsigned int offset, unsigned int length)
281         {
282                 ByteArray command, response;
283                 APDUCommand apdu;
284                 int ret;
285
286                 apdu.setCommand(0, APDUCommand::INS_WRITE_BINARY, offset, 0, data, 0);
287                 apdu.getBuffer(command);
288
289                 ret = channel->transmitSync(command, response);
290                 if (ret == 0 && response.size() >= 2)
291                 {
292                         ResponseHelper resp(response);
293
294                         if (resp.getStatus() >= 0)
295                         {
296                                 _DBG("response [%d] : %s", response.size(), response.toString().c_str());
297
298                                 ret = SUCCESS;
299                         }
300                         else
301                         {
302                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
303                         }
304                 }
305                 else
306                 {
307                         _ERR("select apdu is failed, rv [%d], length [%d]", ret, response.size());
308                 }
309
310                 return ret;
311         }
312 } /* namespace smartcard_service_api */