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