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 */
26 #include "TerminalInterface.h"
27 #include "NFCTerminal.h"
30 #define EXPORT_API __attribute__((visibility("default")))
35 using namespace smartcard_service_api;
37 static const char *se_name = "eSE";
39 /* below functions will be called when dlopen or dlclose is called */
40 void __attribute__ ((constructor)) lib_init()
44 void __attribute__ ((destructor)) lib_fini()
48 /* below trhee functions must be implemented */
49 extern "C" EXPORT_API const char *get_name()
54 extern "C" EXPORT_API void *create_instance()
56 return (void *)NFCTerminal::getInstance();
59 extern "C" EXPORT_API void destroy_instance(void *instance)
61 NFCTerminal *inst = (NFCTerminal *)instance;
62 if (inst == NFCTerminal::getInstance())
68 SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", NFCTerminal::getInstance(), instance);
72 namespace smartcard_service_api
74 NFCTerminal::NFCTerminal():Terminal()
78 name = (char *)se_name;
82 /* TODO : disable nfc library temporary */
87 NFCTerminal *NFCTerminal::getInstance()
89 static NFCTerminal instance;
94 NFCTerminal::~NFCTerminal()
99 bool NFCTerminal::initialize()
103 if (initialized == false)
106 if ((ret = net_nfc_client_initialize()) == NET_NFC_OK)
108 if ((ret = net_nfc_set_response_callback(&NFCTerminal::nfcResponseCallback, this)) == NET_NFC_OK)
110 SCARD_DEBUG("nfc initialize success");
116 SCARD_DEBUG_ERR("net_nfc_set_response_callback failed [%d]", ret);
121 SCARD_DEBUG_ERR("net_nfc_initialize failed [%d]", ret);
129 void NFCTerminal::finalize()
131 if (isInitialized() && isClosed() == false && seHandle != NULL)
133 net_nfc_client_se_close_internal_secure_element_sync(seHandle);
136 net_nfc_client_deinitialize();
139 bool NFCTerminal::open()
146 if (isClosed() == true)
149 if ((ret = net_nfc_open_internal_secure_element(NET_NFC_SE_TYPE_ESE, this)) == NET_NFC_OK)
154 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
157 SCARD_DEBUG("net_nfc_open_internal_secure_element returns [%d]", ret);
162 SCARD_DEBUG_ERR("net_nfc_open_internal_secure_element failed cbResult [%d], rv [%d]", error, rv);
170 SCARD_DEBUG_ERR("net_nfc_set_secure_element_type failed [%d]", ret);
181 void NFCTerminal::close()
187 if (isInitialized() && isClosed() == false && seHandle != NULL)
189 if ((ret = net_nfc_client_se_close_internal_secure_element_sync(seHandle)) == NET_NFC_OK)
195 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
198 SCARD_DEBUG("net_nfc_close_internal_secure_element returns [%d]", ret);
203 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed, error [%d], rv [%d]", error, rv);
210 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed [%d]", ret);
217 bool NFCTerminal::isClosed()
222 int NFCTerminal::transmitSync(ByteArray command, ByteArray &response)
229 if (isClosed() == false)
233 if (command.getLength() > 0)
235 SCARD_DEBUG("command : %s", command.toString());
238 response.releaseBuffer();
240 net_nfc_create_data(&data, command.getBuffer(), command.getLength());
241 net_nfc_client_se_send_apdu_sync(seHandle, data, NULL);
244 rv = waitTimedCondition(3);
246 if (rv == 0 && error == NET_NFC_OK)
248 SCARD_DEBUG("transmit success, length [%d]", response.getLength());
252 SCARD_DEBUG_ERR("transmit failed, rv [%d], cbResult [%d]", rv, error);
258 net_nfc_free_data(data);
276 int NFCTerminal::getATRSync(ByteArray &atr)
284 /* TODO : implement nfc first */
292 bool NFCTerminal::isSecureElementPresence()
294 return (seHandle != NULL);
297 void NFCTerminal::nfcResponseCallback(net_nfc_message_e message, net_nfc_error_e result, void *data , void *userContext, void *transData)
299 NFCTerminal *instance = (NFCTerminal *)userContext;
303 if (instance == NULL)
305 SCARD_DEBUG_ERR("instance is null");
311 case NET_NFC_MESSAGE_SET_SE :
312 SCARD_DEBUG("NET_NFC_MESSAGE_SET_SE");
315 case NET_NFC_MESSAGE_GET_SE :
316 SCARD_DEBUG("NET_NFC_MESSAGE_GET_SE");
319 case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
320 SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
322 if (result == NET_NFC_OK)
326 instance->seHandle = (net_nfc_target_handle_h)data;
327 instance->closed = false;
331 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed");
336 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
339 instance->error = result;
342 instance->syncLock();
343 instance->signalCondition();
344 instance->syncUnlock();
346 /* TODO : async process */
350 case NET_NFC_MESSAGE_CLOSE_INTERNAL_SE :
351 SCARD_DEBUG("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE");
353 if (result == NET_NFC_OK)
355 instance->closed = true;
359 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE failed [%d]", result);
362 instance->error = result;
365 instance->syncLock();
366 instance->signalCondition();
367 instance->syncUnlock();
369 /* TODO : async process */
373 case NET_NFC_MESSAGE_SEND_APDU_SE :
375 data_h resp = (data_h)data;
377 SCARD_DEBUG("NET_NFC_MESSAGE_SEND_APDU_SE");
379 if (result == NET_NFC_OK)
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));
389 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed [%d]", result);
392 instance->error = result;
395 instance->syncLock();
396 instance->signalCondition();
397 instance->syncUnlock();
399 /* TODO : async process */
404 case NET_NFC_MESSAGE_INIT :
406 instance->finalize();
408 /* send notification */
409 if (instance->statusCallback != NULL)
411 instance->statusCallback((void *)se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
416 case NET_NFC_MESSAGE_DEINIT :
418 instance->initialize();
419 if (instance->open() == true)
421 /* send notification */
422 if (instance->statusCallback != NULL)
424 instance->statusCallback((void *)se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
431 SCARD_DEBUG("unknown message : [%d], [%d], [%p], [%p], [%p]", message, result, data, userContext, instance);
437 } /* namespace smartcard_service_api */