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