2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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")))
37 using namespace smartcard_service_api;
39 static const char *se_name = "eSE";
41 /* below functions will be called when dlopen or dlclose is called */
42 void __attribute__ ((constructor)) lib_init()
46 void __attribute__ ((destructor)) lib_fini()
50 /* below trhee functions must be implemented */
51 extern "C" EXPORT_API const char *get_name()
56 extern "C" EXPORT_API void *create_instance()
58 return (void *)NFCTerminal::getInstance();
61 extern "C" EXPORT_API void destroy_instance(void *instance)
63 NFCTerminal *inst = (NFCTerminal *)instance;
64 if (inst == NFCTerminal::getInstance())
70 SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", NFCTerminal::getInstance(), instance);
74 namespace smartcard_service_api
76 NFCTerminal::NFCTerminal():Terminal()
80 name = (char *)se_name;
88 NFCTerminal *NFCTerminal::getInstance()
90 static NFCTerminal instance;
95 NFCTerminal::~NFCTerminal()
100 bool NFCTerminal::initialize()
104 if (initialized == false)
106 if ((ret = net_nfc_initialize()) == NET_NFC_OK)
108 net_nfc_state_activate(1);
110 if ((ret = net_nfc_set_response_callback(&NFCTerminal::nfcResponseCallback, this)) == NET_NFC_OK)
112 SCARD_DEBUG("nfc initialize success");
118 SCARD_DEBUG_ERR("net_nfc_set_response_callback failed [%d]", ret);
123 SCARD_DEBUG_ERR("net_nfc_initialize failed [%d]", ret);
130 void NFCTerminal::finalize()
134 if (seHandle != NULL)
136 net_nfc_close_internal_secure_element(seHandle, this);
139 net_nfc_deinitialize();
142 bool NFCTerminal::open()
150 if (isClosed() == true)
152 if ((ret = net_nfc_open_internal_secure_element(NET_NFC_SE_TYPE_ESE, this)) == NET_NFC_OK)
156 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
160 SCARD_DEBUG("net_nfc_open_internal_secure_element returns [%d]", ret);
165 SCARD_DEBUG_ERR("net_nfc_open_internal_secure_element failed cbResult [%d], rv [%d]", error, rv);
172 SCARD_DEBUG_ERR("net_nfc_set_secure_element_type failed [%d]", ret);
181 void NFCTerminal::close()
188 if (isInitialized() && isClosed() == false && seHandle != NULL)
190 if ((ret = net_nfc_close_internal_secure_element(seHandle, this)) == NET_NFC_OK)
194 if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
197 SCARD_DEBUG("net_nfc_close_internal_secure_element returns [%d]", ret);
202 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed, error [%d], rv [%d]", error, rv);
209 SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed [%d]", ret);
216 bool NFCTerminal::isClosed()
221 int NFCTerminal::transmitSync(ByteArray command, ByteArray &response)
230 if (command.getLength() > 0)
232 SCARD_DEBUG("command : %s", command.toString());
235 response.releaseBuffer();
237 net_nfc_create_data(&data, command.getBuffer(), command.getLength());
238 net_nfc_send_apdu(seHandle, data, this);
241 rv = waitTimedCondition(3);
243 if (rv == 0 && error == NET_NFC_OK)
245 if (response.getLength() > 0)
250 SCARD_DEBUG("transmit success, length [%d]", response.getLength());
254 SCARD_DEBUG_ERR("transmit failed, rv [%d], cbResult [%d]", rv, error);
272 int NFCTerminal::getATRSync(ByteArray &atr)
287 bool NFCTerminal::isSecureElementPresence()
289 return (seHandle != NULL);
292 void NFCTerminal::nfcResponseCallback(net_nfc_message_e message, net_nfc_error_e result, void *data , void *userContext, void *transData)
294 NFCTerminal *instance = (NFCTerminal *)userContext;
298 if (instance == NULL)
300 SCARD_DEBUG_ERR("instance is null");
306 case NET_NFC_MESSAGE_SET_SE :
307 SCARD_DEBUG("NET_NFC_MESSAGE_SET_SE");
310 case NET_NFC_MESSAGE_GET_SE :
311 SCARD_DEBUG("NET_NFC_MESSAGE_GET_SE");
314 case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
315 SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
317 if (result == NET_NFC_OK)
321 instance->seHandle = (net_nfc_target_handle_h)data;
322 instance->closed = false;
326 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed");
331 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
334 instance->error = result;
336 instance->syncLock();
337 instance->signalCondition();
338 instance->syncUnlock();
341 case NET_NFC_MESSAGE_CLOSE_INTERNAL_SE :
342 SCARD_DEBUG("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE");
344 if (result == NET_NFC_OK)
346 instance->closed = true;
350 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE failed [%d]", result);
353 instance->error = result;
355 instance->syncLock();
356 instance->signalCondition();
357 instance->syncUnlock();
360 case NET_NFC_MESSAGE_SEND_APDU_SE :
362 data_h resp = (data_h)data;
364 SCARD_DEBUG("NET_NFC_MESSAGE_SEND_APDU_SE");
366 if (result == NET_NFC_OK)
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));
376 SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed [%d]", result);
379 instance->error = result;
381 instance->syncLock();
382 instance->signalCondition();
383 instance->syncUnlock();
387 // case NFC_ON_NOTI_CASE :
391 // /* send notification */
392 // if (instance->statusCallback != NULL)
394 // instance->statusCallback(se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
399 // case NFC_OFF_NOTI_CASE :
402 // if (open() == true)
404 // /* send notification */
405 // if (instance->statusCallback != NULL)
407 // instance->statusCallback(se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
414 SCARD_DEBUG("unknown message : [%d], [%d], [%p], [%p], [%p]", message, result, data, userContext, instance);
420 } /* namespace smartcard_service_api */