2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 /* standard library header */
24 /* SLP library header */
26 #include "net_nfc_internal_se.h"
30 #include "TerminalInterface.h"
31 #include "NFCTerminal.h"
34 #define EXPORT_API __attribute__((visibility("default")))
39 using namespace smartcard_service_api;
41 static const char *se_name = "eSE";
43 /* below functions will be called when dlopen or dlclose is called */
44 void __attribute__ ((constructor)) lib_init()
48 void __attribute__ ((destructor)) lib_fini()
52 /* below trhee functions must be implemented */
53 extern "C" EXPORT_API const char *get_name()
58 extern "C" EXPORT_API void *create_instance()
60 return (void *)NFCTerminal::getInstance();
63 extern "C" EXPORT_API void destroy_instance(void *instance)
65 NFCTerminal *inst = (NFCTerminal *)instance;
66 if (inst == NFCTerminal::getInstance())
72 SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", NFCTerminal::getInstance(), instance);
76 namespace smartcard_service_api
78 NFCTerminal::NFCTerminal():Terminal()
82 name = (char *)se_name;
86 /* TODO : disable nfc library temporary */
91 NFCTerminal *NFCTerminal::getInstance()
93 static NFCTerminal instance;
98 NFCTerminal::~NFCTerminal()
103 bool NFCTerminal::initialize()
107 if (initialized == false)
110 if ((ret = net_nfc_initialize()) == NET_NFC_OK)
112 if ((ret = net_nfc_set_response_callback(&NFCTerminal::nfcResponseCallback, this)) == NET_NFC_OK)
114 SCARD_DEBUG("nfc initialize success");
120 SCARD_DEBUG_ERR("net_nfc_set_response_callback failed [%d]", ret);
125 SCARD_DEBUG_ERR("net_nfc_initialize failed [%d]", ret);
133 void NFCTerminal::finalize()
135 if (isInitialized() && isClosed() == false && seHandle != NULL)
137 net_nfc_close_internal_secure_element(seHandle, this);
140 net_nfc_deinitialize();
143 bool NFCTerminal::open()
150 if (isClosed() == true)
153 if ((ret = net_nfc_open_internal_secure_element(NET_NFC_SE_TYPE_ESE, this)) == NET_NFC_OK)
158 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
161 SCARD_DEBUG("net_nfc_open_internal_secure_element returns [%d]", ret);
166 SCARD_DEBUG_ERR("net_nfc_open_internal_secure_element failed cbResult [%d], rv [%d]", error, rv);
174 SCARD_DEBUG_ERR("net_nfc_set_secure_element_type failed [%d]", ret);
185 void NFCTerminal::close()
191 if (isInitialized() && isClosed() == false && seHandle != NULL)
193 if ((ret = net_nfc_close_internal_secure_element(seHandle, this)) == NET_NFC_OK)
199 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
202 SCARD_DEBUG("net_nfc_close_internal_secure_element returns [%d]", ret);
207 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed, error [%d], rv [%d]", error, rv);
214 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed [%d]", ret);
221 bool NFCTerminal::isClosed()
226 int NFCTerminal::transmitSync(ByteArray command, ByteArray &response)
233 if (isClosed() == false)
237 if (command.getLength() > 0)
239 SCARD_DEBUG("command : %s", command.toString());
242 response.releaseBuffer();
244 net_nfc_create_data(&data, command.getBuffer(), command.getLength());
245 net_nfc_send_apdu(seHandle, data, this);
248 rv = waitTimedCondition(3);
250 if (rv == 0 && error == NET_NFC_OK)
252 SCARD_DEBUG("transmit success, length [%d]", response.getLength());
256 SCARD_DEBUG_ERR("transmit failed, rv [%d], cbResult [%d]", rv, error);
262 net_nfc_free_data(data);
280 int NFCTerminal::getATRSync(ByteArray &atr)
288 /* TODO : implement nfc first */
296 bool NFCTerminal::isSecureElementPresence()
298 return (seHandle != NULL);
301 void NFCTerminal::nfcResponseCallback(net_nfc_message_e message, net_nfc_error_e result, void *data , void *userContext, void *transData)
303 NFCTerminal *instance = (NFCTerminal *)userContext;
307 if (instance == NULL)
309 SCARD_DEBUG_ERR("instance is null");
315 case NET_NFC_MESSAGE_SET_SE :
316 SCARD_DEBUG("NET_NFC_MESSAGE_SET_SE");
319 case NET_NFC_MESSAGE_GET_SE :
320 SCARD_DEBUG("NET_NFC_MESSAGE_GET_SE");
323 case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
324 SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
326 if (result == NET_NFC_OK)
330 instance->seHandle = (net_nfc_target_handle_h)data;
331 instance->closed = false;
335 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed");
340 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
343 instance->error = result;
346 instance->syncLock();
347 instance->signalCondition();
348 instance->syncUnlock();
350 /* TODO : async process */
354 case NET_NFC_MESSAGE_CLOSE_INTERNAL_SE :
355 SCARD_DEBUG("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE");
357 if (result == NET_NFC_OK)
359 instance->closed = true;
363 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE failed [%d]", result);
366 instance->error = result;
369 instance->syncLock();
370 instance->signalCondition();
371 instance->syncUnlock();
373 /* TODO : async process */
377 case NET_NFC_MESSAGE_SEND_APDU_SE :
379 data_h resp = (data_h)data;
381 SCARD_DEBUG("NET_NFC_MESSAGE_SEND_APDU_SE");
383 if (result == NET_NFC_OK)
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));
393 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed [%d]", result);
396 instance->error = result;
399 instance->syncLock();
400 instance->signalCondition();
401 instance->syncUnlock();
403 /* TODO : async process */
408 case NET_NFC_MESSAGE_INIT :
410 instance->finalize();
412 /* send notification */
413 if (instance->statusCallback != NULL)
415 instance->statusCallback((void *)se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
420 case NET_NFC_MESSAGE_DEINIT :
422 instance->initialize();
423 if (instance->open() == true)
425 /* send notification */
426 if (instance->statusCallback != NULL)
428 instance->statusCallback((void *)se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
435 SCARD_DEBUG("unknown message : [%d], [%d], [%p], [%p], [%p]", message, result, data, userContext, instance);
441 } /* namespace smartcard_service_api */