/*
-* Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
/* standard library header */
-#include <stdio.h>
+#include <cstdio>
+#include <cstring>
#include <unistd.h>
-#include <string.h>
#include <sys/time.h>
+#include <glib.h>
/* local header */
+#include "smartcard-types.h"
#include "Debug.h"
#include "TerminalInterface.h"
#include "NFCTerminal.h"
{
}
-/* below trhee functions must be implemented */
-extern "C" EXPORT_API const char *get_name()
+/* below three functions must be implemented */
+extern "C"
+{
+EXPORT_API const char *get_name()
{
return se_name;
}
-extern "C" EXPORT_API void *create_instance()
+EXPORT_API void *create_instance()
{
- return (void *)NFCTerminal::getInstance();
+ int value;
+
+ if (vconf_get_bool(VCONFKEY_NFC_ESE_DISABLE, &value) < 0)
+ return NULL;
+
+ return value ? NULL : (void *)NFCTerminal::getInstance();
}
-extern "C" EXPORT_API void destroy_instance(void *instance)
+EXPORT_API void destroy_instance(void *instance)
{
NFCTerminal *inst = (NFCTerminal *)instance;
+
if (inst == NFCTerminal::getInstance())
{
inst->finalize();
}
else
{
- SCARD_DEBUG_ERR("instance is invalid : getInstance [%p], instance [%p]", NFCTerminal::getInstance(), instance);
+ _ERR("instance is invalid : getInstance [%p], instance [%p]",
+ NFCTerminal::getInstance(), instance);
}
}
+}
namespace smartcard_service_api
{
- NFCTerminal::NFCTerminal():Terminal()
+ NFCTerminal::NFCTerminal() : Terminal(), seHandle(NULL),
+ present(false), referred(0)
{
- seHandle = NULL;
- closed = true;
name = (char *)se_name;
- if (initialize())
- {
- /* TODO : disable nfc library temporary */
-// open();
- }
+ initialize();
}
NFCTerminal *NFCTerminal::getInstance()
finalize();
}
+ void NFCTerminal::onActivationChanged(bool activated, void *userData)
+ {
+ NFCTerminal *instance = (NFCTerminal *)userData;
+
+ _ERR("nfc state changed [%s]", activated ? "activated" : "deactivated");
+
+ if (activated == true) {
+ if (instance->present == false) {
+ if (instance->open() == true) {
+ instance->present = true;
+ instance->close();
+
+ if (instance->statusCallback != NULL) {
+ instance->statusCallback(
+ instance->getName(),
+ NOTIFY_SE_AVAILABLE,
+ SCARD_ERROR_OK,
+ NULL);
+ }
+ } else {
+ _ERR("ese open failed");
+ }
+ } else {
+ /* okay */
+ }
+ } else {
+ if (instance->present == true) {
+ instance->present = false;
+
+ if (instance->isClosed() == false) {
+ int ret;
+
+ /* close now */
+ ret = nfc_se_close_secure_element_internal(
+ instance->seHandle);
+ if (ret != NFC_ERROR_NONE) {
+ _ERR("nfc_se_close_secure_element failed [%d]", ret);
+ }
+
+ instance->seHandle = NULL;
+ instance->closed = true;
+ instance->referred = 0;
+ }
+
+ if (instance->statusCallback != NULL) {
+ instance->statusCallback(
+ instance->getName(),
+ NOTIFY_SE_NOT_AVAILABLE,
+ SCARD_ERROR_OK,
+ NULL);
+ }
+ } else {
+ /* okay */
+ }
+ }
+ }
+
bool NFCTerminal::initialize()
{
- int ret = 0;
+ int ret;
+
+ if (initialized == true)
+ return initialized;
- if (initialized == false)
+ ret = nfc_manager_initialize();
+ if (ret == NFC_ERROR_NONE)
{
-#if 0
- if ((ret = net_nfc_client_initialize()) == NET_NFC_OK)
- {
- if ((ret = net_nfc_set_response_callback(&NFCTerminal::nfcResponseCallback, this)) == NET_NFC_OK)
- {
- SCARD_DEBUG("nfc initialize success");
+ initialized = true;
- initialized = true;
- }
- else
- {
- SCARD_DEBUG_ERR("net_nfc_set_response_callback failed [%d]", ret);
- }
+ ret = nfc_manager_set_activation_changed_cb(
+ &NFCTerminal::onActivationChanged, this);
+ if (ret != NFC_ERROR_NONE) {
+ _ERR("nfc_manager_set_activation_changed_cb failed, [%d]", ret);
}
- else
- {
- SCARD_DEBUG_ERR("net_nfc_initialize failed [%d]", ret);
+
+ if (nfc_manager_is_activated() == true) {
+ if (open() == true) {
+ present = true;
+ close();
+ } else {
+ _ERR("ese open failed");
+ }
+ } else {
+ _ERR("nfc is not activated.");
}
-#endif
+ }
+ else
+ {
+ _ERR("net_nfc_initialize failed [%d]", ret);
}
return initialized;
void NFCTerminal::finalize()
{
- if (isInitialized() && isClosed() == false && seHandle != NULL)
- {
- net_nfc_client_se_close_internal_secure_element_sync(seHandle);
+ int ret;
+
+ if (isClosed() == false) {
+ /* close now */
+ ret = nfc_se_close_secure_element_internal(seHandle);
+ if (ret != NFC_ERROR_NONE) {
+ _ERR("nfc_se_close_secure_element failed [%d]", ret);
+ }
+
+ seHandle = NULL;
+ closed = true;
+ referred = 0;
}
- net_nfc_client_deinitialize();
+ present = false;
+
+ nfc_manager_unset_activation_changed_cb();
+
+ ret = nfc_manager_deinitialize();
+ if (ret == NFC_ERROR_NONE) {
+ initialized = false;
+ } else {
+ _ERR("nfc_manager_deinitialize failed [%d]", ret);
+ }
}
bool NFCTerminal::open()
{
- bool result = true;
- net_nfc_error_e ret;
-
- SCARD_BEGIN();
-
- if (isClosed() == true)
- {
-#if 0
- if ((ret = net_nfc_open_internal_secure_element(NET_NFC_SE_TYPE_ESE, this)) == NET_NFC_OK)
- {
-#ifndef ASYNC
- int rv;
- syncLock();
- if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
- {
-#endif
- SCARD_DEBUG("net_nfc_open_internal_secure_element returns [%d]", ret);
-#ifndef ASYNC
+ int ret;
+
+ _BEGIN();
+
+ if (isInitialized()) {
+ if (referred == 0) {
+ ret = nfc_se_open_secure_element_internal(NFC_SE_TYPE_ESE,
+ &seHandle);
+ if (ret == NFC_ERROR_NONE) {
+ closed = false;
+ referred++;
+ } else {
+ _ERR("nfc_se_open_secure_element_internal failed [%d]", ret);
}
- else
- {
- SCARD_DEBUG_ERR("net_nfc_open_internal_secure_element failed cbResult [%d], rv [%d]", error, rv);
- result = false;
- }
- syncUnlock();
-#endif
+ } else {
+ referred++;
}
- else
- {
- SCARD_DEBUG_ERR("net_nfc_set_secure_element_type failed [%d]", ret);
- result = false;
- }
-#endif
+
+ _DBG("reference count [%d]", referred);
}
- SCARD_END();
+ _END();
- return result;
+ return (isClosed() == false);
}
void NFCTerminal::close()
{
- net_nfc_error_e ret;
+ int ret;
- SCARD_BEGIN();
+ _BEGIN();
- if (isInitialized() && isClosed() == false && seHandle != NULL)
+ if (isInitialized())
{
- if ((ret = net_nfc_client_se_close_internal_secure_element_sync(seHandle)) == NET_NFC_OK)
- {
-#ifndef ASYNC
- int rv;
-
- syncLock();
- if ((rv = waitTimedCondition(3)) == 0 && error == NET_NFC_OK)
- {
-#endif
- SCARD_DEBUG("net_nfc_close_internal_secure_element returns [%d]", ret);
-#ifndef ASYNC
+ if (referred <= 1) {
+ g_usleep(1000000);
+
+ ret = nfc_se_close_secure_element_internal(seHandle);
+ if (ret == NFC_ERROR_NONE) {
+ seHandle = NULL;
+ closed = true;
+ referred = 0;
+ } else {
+ _ERR("nfc_se_close_secure_element_internal failed [%d]", ret);
}
- else
- {
- SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed, error [%d], rv [%d]", error, rv);
- }
- syncUnlock();
-#endif
- }
- else
- {
- SCARD_DEBUG_ERR("net_nfc_close_internal_secure_element failed [%d]", ret);
+ } else {
+ referred--;
}
+
+ _DBG("reference count [%d]", referred);
}
- SCARD_END();
+ _END();
}
- bool NFCTerminal::isClosed()
+ int NFCTerminal::transmitSync(const ByteArray &command, ByteArray &response)
{
- return closed;
- }
+ int rv = SCARD_ERROR_NOT_INITIALIZED;
- int NFCTerminal::transmitSync(ByteArray command, ByteArray &response)
- {
- int rv = 0;
- data_h data;
-
- SCARD_BEGIN();
+ _BEGIN();
if (isClosed() == false)
{
- SCOPE_LOCK(mutex)
+ if (command.size() > 0)
{
- if (command.getLength() > 0)
+ uint8_t *resp = NULL;
+ uint32_t resp_len;
+
+ rv = nfc_se_send_apdu_internal(seHandle,
+ (uint8_t *)command.getBuffer(),
+ command.size(),
+ &resp,
+ &resp_len);
+ if (rv == NFC_ERROR_NONE &&
+ resp != NULL)
{
- SCARD_DEBUG("command : %s", command.toString());
-
-#ifndef ASYNC
- response.releaseBuffer();
-#endif
- net_nfc_create_data(&data, command.getBuffer(), command.getLength());
- net_nfc_client_se_send_apdu_sync(seHandle, data, NULL);
-#ifndef ASYNC
- syncLock();
- rv = waitTimedCondition(3);
-
- if (rv == 0 && error == NET_NFC_OK)
- {
- SCARD_DEBUG("transmit success, length [%d]", response.getLength());
- }
- else
- {
- SCARD_DEBUG_ERR("transmit failed, rv [%d], cbResult [%d]", rv, error);
- }
- syncUnlock();
+ response.assign(resp, resp_len);
- rv = error;
-#endif
- net_nfc_free_data(data);
+ g_free(resp);
}
else
{
- rv = -1;
- }
+ _ERR("nfc_se_send_apdu_internal failed, [%d]", rv);
+ }
+ }
+ else
+ {
+ _ERR("invalid command");
}
}
else
{
- rv = -1;
+ _ERR("closed...");
}
- SCARD_END();
+ _END();
return rv;
}
int NFCTerminal::getATRSync(ByteArray &atr)
{
- int rv = 0;
-
- SCARD_BEGIN();
-
- SCOPE_LOCK(mutex)
- {
- /* TODO : implement nfc first */
- }
-
- SCARD_END();
-
- return rv;
- }
-
- bool NFCTerminal::isSecureElementPresence()
- {
- return (seHandle != NULL);
- }
-
- void NFCTerminal::nfcResponseCallback(net_nfc_message_e message, net_nfc_error_e result, void *data , void *userContext, void *transData)
- {
- NFCTerminal *instance = (NFCTerminal *)userContext;
+ int rv = -1;
- SCARD_BEGIN();
+ _BEGIN();
- if (instance == NULL)
- {
- SCARD_DEBUG_ERR("instance is null");
- return;
- }
-
- switch(message)
+ if (isClosed() == false)
{
- case NET_NFC_MESSAGE_SET_SE :
- SCARD_DEBUG("NET_NFC_MESSAGE_SET_SE");
- break;
-
- case NET_NFC_MESSAGE_GET_SE :
- SCARD_DEBUG("NET_NFC_MESSAGE_GET_SE");
- break;
-
- case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
- SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
-
- if (result == NET_NFC_OK)
- {
- if (data != NULL)
- {
- instance->seHandle = (net_nfc_target_handle_h)data;
- instance->closed = false;
- }
- else
- {
- SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed");
- }
- }
- else
- {
- SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
- }
-
- instance->error = result;
-
-#ifndef ASYNC
- instance->syncLock();
- instance->signalCondition();
- instance->syncUnlock();
-#else
- /* TODO : async process */
-#endif
- break;
-
- case NET_NFC_MESSAGE_CLOSE_INTERNAL_SE :
- SCARD_DEBUG("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE");
+ uint8_t *temp = NULL;
+ uint32_t temp_len;
- if (result == NET_NFC_OK)
+ rv = nfc_se_get_atr_internal(seHandle, &temp, &temp_len);
+ if (rv == NFC_ERROR_NONE && temp != NULL)
{
- instance->closed = true;
+ atr.assign(temp, temp_len);
+ g_free(temp);
}
else
{
- SCARD_DEBUG_ERR("NET_NFC_MESSAGE_CLOSE_INTERNAL_SE failed [%d]", result);
- }
-
- instance->error = result;
-
-#ifndef ASYNC
- instance->syncLock();
- instance->signalCondition();
- instance->syncUnlock();
-#else
- /* TODO : async process */
-#endif
- break;
-
- case NET_NFC_MESSAGE_SEND_APDU_SE :
- {
- data_h resp = (data_h)data;
-
- SCARD_DEBUG("NET_NFC_MESSAGE_SEND_APDU_SE");
-
- if (result == NET_NFC_OK)
- {
- if (resp != NULL)
- {
- SCARD_DEBUG("apdu result length [%d]", net_nfc_get_data_length(resp));
- instance->response.setBuffer(net_nfc_get_data_buffer(resp), net_nfc_get_data_length(resp));
- }
- }
- else
- {
- SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE failed [%d]", result);
- }
-
- instance->error = result;
-
-#ifndef ASYNC
- instance->syncLock();
- instance->signalCondition();
- instance->syncUnlock();
-#else
- /* TODO : async process */
-#endif
- }
- break;
-
- case NET_NFC_MESSAGE_INIT :
- {
- instance->finalize();
-
- /* send notification */
- if (instance->statusCallback != NULL)
- {
- instance->statusCallback((void *)se_name, NOTIFY_SE_AVAILABLE, 0, NULL);
- }
+ _ERR("nfc_se_get_atr_internal failed");
}
- break;
-
- case NET_NFC_MESSAGE_DEINIT :
- {
- instance->initialize();
- if (instance->open() == true)
- {
- /* send notification */
- if (instance->statusCallback != NULL)
- {
- instance->statusCallback((void *)se_name, NOTIFY_SE_NOT_AVAILABLE, 0, NULL);
- }
- }
- }
- break;
-
- default:
- SCARD_DEBUG("unknown message : [%d], [%d], [%p], [%p], [%p]", message, result, data, userContext, instance);
- break;
}
+ else
+ {
+ _ERR("closed...");
+ }
+
+ _END();
- SCARD_END();
+ return rv;
}
} /* namespace smartcard_service_api */
-