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