Fix Svace issue
[platform/core/connectivity/smartcard-plugin-nfc.git] / NFCTerminal.cpp
index f47a4b9..e142769 100644 (file)
@@ -1,27 +1,28 @@
 /*
-* 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"
@@ -45,43 +46,48 @@ void __attribute__ ((destructor)) lib_fini()
 {
 }
 
-/* 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()
@@ -96,31 +102,95 @@ namespace smartcard_service_api
                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;
@@ -128,311 +198,165 @@ namespace smartcard_service_api
 
        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());
+                                       response.assign(resp, resp_len);
 
-#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();
-
-                                       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;
+                       uint8_t *temp = NULL;
+                       uint32_t temp_len;
 
-               case NET_NFC_MESSAGE_OPEN_INTERNAL_SE :
-                       SCARD_DEBUG("NET_NFC_MESSAGE_OPEN_INTERNAL_SE");
-
-                       if (result == NET_NFC_OK)
+                       rv = nfc_se_get_atr_internal(seHandle, &temp, &temp_len);
+                       if (rv == NFC_ERROR_NONE && temp != NULL)
                        {
-                               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");
-                               }
+                               atr.assign(temp, temp_len);
                        }
                        else
                        {
-                               SCARD_DEBUG_ERR("NET_NFC_MESSAGE_OPEN_INTERNAL_SE returns error [%d]", result);
+                               _ERR("nfc_se_get_atr_internal failed");
                        }
 
-                       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");
-
-                       if (result == NET_NFC_OK)
-                       {
-                               instance->closed = true;
-                       }
-                       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);
-                               }
-                       }
-                       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;
+                       if (temp != NULL)
+                               g_free(temp);
                }
+               else
+               {
+                       _ERR("closed...");
+               }
+
+               _END();
 
-               SCARD_END();
+               return rv;
        }
 } /* namespace smartcard_service_api */
-