f47a4b9d78aa2880c6ffbdd8a50268b2d09d59a2
[platform/core/connectivity/smartcard-plugin-nfc.git] / NFCTerminal.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
18 /* standard library header */
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <sys/time.h>
23
24 /* local header */
25 #include "Debug.h"
26 #include "TerminalInterface.h"
27 #include "NFCTerminal.h"
28
29 #ifndef EXPORT_API
30 #define EXPORT_API __attribute__((visibility("default")))
31 #endif
32
33 #define ASYNC
34
35 using namespace smartcard_service_api;
36
37 static const char *se_name = "eSE";
38
39 /* below functions will be called when dlopen or dlclose is called */
40 void __attribute__ ((constructor)) lib_init()
41 {
42 }
43
44 void __attribute__ ((destructor)) lib_fini()
45 {
46 }
47
48 /* below trhee functions must be implemented */
49 extern "C" EXPORT_API const char *get_name()
50 {
51         return se_name;
52 }
53
54 extern "C" EXPORT_API void *create_instance()
55 {
56         return (void *)NFCTerminal::getInstance();
57 }
58
59 extern "C" EXPORT_API void destroy_instance(void *instance)
60 {
61         NFCTerminal *inst = (NFCTerminal *)instance;
62         if (inst == NFCTerminal::getInstance())
63         {
64                 inst->finalize();
65         }
66         else
67         {
68                 SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", NFCTerminal::getInstance(), instance);
69         }
70 }
71
72 namespace smartcard_service_api
73 {
74         NFCTerminal::NFCTerminal():Terminal()
75         {
76                 seHandle = NULL;
77                 closed = true;
78                 name = (char *)se_name;
79
80                 if (initialize())
81                 {
82                         /* TODO : disable nfc library temporary */
83 //                      open();
84                 }
85         }
86
87         NFCTerminal *NFCTerminal::getInstance()
88         {
89                 static NFCTerminal instance;
90
91                 return &instance;
92         }
93
94         NFCTerminal::~NFCTerminal()
95         {
96                 finalize();
97         }
98
99         bool NFCTerminal::initialize()
100         {
101                 int ret = 0;
102
103                 if (initialized == false)
104                 {
105 #if 0
106                         if ((ret = net_nfc_client_initialize()) == NET_NFC_OK)
107                         {
108                                 if ((ret = net_nfc_set_response_callback(&NFCTerminal::nfcResponseCallback, this)) == NET_NFC_OK)
109                                 {
110                                         SCARD_DEBUG("nfc initialize success");
111
112                                         initialized = true;
113                                 }
114                                 else
115                                 {
116                                         SCARD_DEBUG_ERR("net_nfc_set_response_callback failed [%d]", ret);
117                                 }
118                         }
119                         else
120                         {
121                                 SCARD_DEBUG_ERR("net_nfc_initialize failed [%d]", ret);
122                         }
123 #endif
124                 }
125
126                 return initialized;
127         }
128
129         void NFCTerminal::finalize()
130         {
131                 if (isInitialized() && isClosed() == false && seHandle != NULL)
132                 {
133                         net_nfc_client_se_close_internal_secure_element_sync(seHandle);
134                 }
135
136                 net_nfc_client_deinitialize();
137         }
138
139         bool NFCTerminal::open()
140         {
141                 bool result = true;
142                 net_nfc_error_e ret;
143
144                 SCARD_BEGIN();
145
146                 if (isClosed() == true)
147                 {
148 #if 0
149                         if ((ret = net_nfc_open_internal_secure_element(NET_NFC_SE_TYPE_ESE, this)) == NET_NFC_OK)
150                         {
151 #ifndef ASYNC
152                                 int rv;
153                                 syncLock();
154                                 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
155                                 {
156 #endif
157                                         SCARD_DEBUG("net_nfc_open_internal_secure_element returns [%d]", ret);
158 #ifndef ASYNC
159                                 }
160                                 else
161                                 {
162                                         SCARD_DEBUG_ERR("net_nfc_open_internal_secure_element failed cbResult [%d], rv [%d]", error, rv);
163                                         result = false;
164                                 }
165                                 syncUnlock();
166 #endif
167                         }
168                         else
169                         {
170                                 SCARD_DEBUG_ERR("net_nfc_set_secure_element_type failed [%d]", ret);
171                                 result = false;
172                         }
173 #endif
174                 }
175
176                 SCARD_END();
177
178                 return result;
179         }
180
181         void NFCTerminal::close()
182         {
183                 net_nfc_error_e ret;
184
185                 SCARD_BEGIN();
186
187                 if (isInitialized() && isClosed() == false && seHandle != NULL)
188                 {
189                         if ((ret = net_nfc_client_se_close_internal_secure_element_sync(seHandle)) == NET_NFC_OK)
190                         {
191 #ifndef ASYNC
192                                 int rv;
193
194                                 syncLock();
195                                 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
196                                 {
197 #endif
198                                         SCARD_DEBUG("net_nfc_close_internal_secure_element returns [%d]", ret);
199 #ifndef ASYNC
200                                 }
201                                 else
202                                 {
203                                         SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed, error [%d], rv [%d]", error, rv);
204                                 }
205                                 syncUnlock();
206 #endif
207                         }
208                         else
209                         {
210                                 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed [%d]", ret);
211                         }
212                 }
213
214                 SCARD_END();
215         }
216
217         bool NFCTerminal::isClosed()
218         {
219                 return closed;
220         }
221
222         int NFCTerminal::transmitSync(ByteArray command, ByteArray &response)
223         {
224                 int rv = 0;
225                 data_h data;
226
227                 SCARD_BEGIN();
228
229                 if (isClosed() == false)
230                 {
231                         SCOPE_LOCK(mutex)
232                         {
233                                 if (command.getLength() > 0)
234                                 {
235                                         SCARD_DEBUG("command : %s", command.toString());
236
237 #ifndef ASYNC
238                                         response.releaseBuffer();
239 #endif
240                                         net_nfc_create_data(&data, command.getBuffer(), command.getLength());
241                                         net_nfc_client_se_send_apdu_sync(seHandle, data, NULL);
242 #ifndef ASYNC
243                                         syncLock();
244                                         rv = waitTimedCondition(3);
245
246                                         if (rv == 0 && error == NET_NFC_OK)
247                                         {
248                                                 SCARD_DEBUG("transmit success, length [%d]", response.getLength());
249                                         }
250                                         else
251                                         {
252                                                 SCARD_DEBUG_ERR("transmit failed, rv [%d], cbResult [%d]", rv, error);
253                                         }
254                                         syncUnlock();
255
256                                         rv = error;
257 #endif
258                                         net_nfc_free_data(data);
259                                 }
260                                 else
261                                 {
262                                         rv = -1;
263                                 }
264                         }
265                 }
266                 else
267                 {
268                         rv = -1;
269                 }
270
271                 SCARD_END();
272
273                 return rv;
274         }
275
276         int NFCTerminal::getATRSync(ByteArray &atr)
277         {
278                 int rv = 0;
279
280                 SCARD_BEGIN();
281
282                 SCOPE_LOCK(mutex)
283                 {
284                         /* TODO : implement nfc first */
285                 }
286
287                 SCARD_END();
288
289                 return rv;
290         }
291
292         bool NFCTerminal::isSecureElementPresence()
293         {
294                 return (seHandle != NULL);
295         }
296
297         void NFCTerminal::nfcResponseCallback(net_nfc_message_e message, net_nfc_error_e result, void *data , void *userContext, void *transData)
298         {
299                 NFCTerminal *instance = (NFCTerminal *)userContext;
300
301                 SCARD_BEGIN();
302
303                 if (instance == NULL)
304                 {
305                         SCARD_DEBUG_ERR("instance is null");
306                         return;
307                 }
308
309                 switch(message)
310                 {
311                 case NET_NFC_MESSAGE_SET_SE :
312                         SCARD_DEBUG("NET_NFC_MESSAGE_SET_SE");
313                         break;
314
315                 case NET_NFC_MESSAGE_GET_SE :
316                         SCARD_DEBUG("NET_NFC_MESSAGE_GET_SE");
317                         break;
318
319                 case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
320                         SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
321
322                         if (result == NET_NFC_OK)
323                         {
324                                 if (data != NULL)
325                                 {
326                                         instance->seHandle = (net_nfc_target_handle_h)data;
327                                         instance->closed = false;
328                                 }
329                                 else
330                                 {
331                                         SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed");
332                                 }
333                         }
334                         else
335                         {
336                                 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
337                         }
338
339                         instance->error = result;
340
341 #ifndef ASYNC
342                         instance->syncLock();
343                         instance->signalCondition();
344                         instance->syncUnlock();
345 #else
346                         /* TODO : async process */
347 #endif
348                         break;
349
350                 case NET_NFC_MESSAGE_CLOSE_INTERNAL_SE :
351                         SCARD_DEBUG("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE");
352
353                         if (result == NET_NFC_OK)
354                         {
355                                 instance->closed = true;
356                         }
357                         else
358                         {
359                                 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE failed [%d]", result);
360                         }
361
362                         instance->error = result;
363
364 #ifndef ASYNC
365                         instance->syncLock();
366                         instance->signalCondition();
367                         instance->syncUnlock();
368 #else
369                         /* TODO : async process */
370 #endif
371                         break;
372
373                 case NET_NFC_MESSAGE_SEND_APDU_SE :
374                         {
375                                 data_h resp = (data_h)data;
376
377                                 SCARD_DEBUG("NET_NFC_MESSAGE_SEND_APDU_SE");
378
379                                 if (result == NET_NFC_OK)
380                                 {
381                                         if (resp != NULL)
382                                         {
383                                                 SCARD_DEBUG("apdu result length [%d]", net_nfc_get_data_length(resp));
384                                                 instance->response.setBuffer(net_nfc_get_data_buffer(resp), net_nfc_get_data_length(resp));
385                                         }
386                                 }
387                                 else
388                                 {
389                                         SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed [%d]", result);
390                                 }
391
392                                 instance->error = result;
393
394 #ifndef ASYNC
395                                 instance->syncLock();
396                                 instance->signalCondition();
397                                 instance->syncUnlock();
398 #else
399                                 /* TODO : async process */
400 #endif
401                         }
402                         break;
403
404                 case NET_NFC_MESSAGE_INIT :
405                         {
406                                 instance->finalize();
407
408                                 /* send notification */
409                                 if (instance->statusCallback != NULL)
410                                 {
411                                         instance->statusCallback((void *)se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
412                                 }
413                         }
414                         break;
415
416                 case NET_NFC_MESSAGE_DEINIT :
417                         {
418                                 instance->initialize();
419                                 if (instance->open() == true)
420                                 {
421                                         /* send notification */
422                                         if (instance->statusCallback != NULL)
423                                         {
424                                                 instance->statusCallback((void *)se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
425                                         }
426                                 }
427                         }
428                         break;
429
430                 default:
431                         SCARD_DEBUG("unknown message : [%d], [%d], [%p], [%p], [%p]", message, result, data, userContext, instance);
432                         break;
433                 }
434
435                 SCARD_END();
436         }
437 } /* namespace smartcard_service_api */
438