add stop API of base stack in android.
authorjihwan.seo <jihwan.seo@samsung.com>
Tue, 25 Oct 2016 09:58:52 +0000 (18:58 +0900)
committerAshok Babu Channa <ashok.channa@samsung.com>
Mon, 5 Dec 2016 10:11:31 +0000 (10:11 +0000)
since some user application want to use IoTivity more dynamically.
stop API of IoTivity should be provided effeciently.

Change-Id: Ie9ebb874b9b1d49703d5023a972cff5c630acaf3
Signed-off-by: jihwan.seo <jihwan.seo@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/13649
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Larry Sachs <larry.j.sachs@intel.com>
Reviewed-by: Jaehong Jo <jaehong.jo@samsung.com>
Reviewed-by: Ashok Babu Channa <ashok.channa@samsung.com>
17 files changed:
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcPlatform.h
android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java
resource/csdk/stack/src/ocstack.c
resource/include/IClientWrapper.h
resource/include/IServerWrapper.h
resource/include/InProcClientWrapper.h
resource/include/InProcServerWrapper.h
resource/include/OCPlatform.h
resource/include/OCPlatform_impl.h
resource/include/OutOfProcClientWrapper.h
resource/include/OutOfProcServerWrapper.h
resource/include/StringConstants.h
resource/src/InProcClientWrapper.cpp
resource/src/InProcServerWrapper.cpp
resource/src/OCPlatform.cpp
resource/src/OCPlatform_impl.cpp

index 8f76dc8..07f6d3e 100644 (file)
@@ -578,6 +578,56 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
 
 /*
 * Class:     org_iotivity_base_OcPlatform
+* Method:    stop
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stop
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.stop");
+
+    try {
+        OCStackResult result = OCPlatform::stop();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to stop ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    start
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_start
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.start");
+
+    try {
+        OCStackResult result = OCPlatform::start();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to start ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
 * Method:    notifyAllObservers0
 * Signature: (Lorg/iotivity/base/OcResourceHandle;)V
 */
index cff6800..4a9d134 100644 (file)
@@ -85,6 +85,22 @@ extern "C" {
 
     /*
     * Class:     org_iotivity_base_OcPlatform
+    * Method:    stop
+    * Signature: ()V
+    */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stop
+        (JNIEnv *, jclass);
+
+    /*
+    * Class:     org_iotivity_base_OcPlatform
+    * Method:    start
+    * Signature: ()V
+    */
+    JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_start
+        (JNIEnv *, jclass);
+
+    /*
+    * Class:     org_iotivity_base_OcPlatform
     * Method:    notifyAllObservers0
     * Signature: (Lorg/iotivity/base/OcResourceHandle;)V
     */
index c62e170..0af5565 100644 (file)
@@ -78,6 +78,8 @@ public final class OcPlatform {
     private static volatile boolean sIsPlatformInitialized = false;
     private static QualityOfService sPlatformQualityOfService = QualityOfService.NA;
 
+    private static volatile boolean sIsStopPlatform = false;
+
     private OcPlatform() {
     }
 
@@ -90,6 +92,12 @@ public final class OcPlatform {
      * @param platformConfig platform configuration
      */
     public synchronized static void Configure(PlatformConfig platformConfig) {
+        if (sIsStopPlatform)
+        {
+            OcPlatform.start();
+            sIsStopPlatform = false;
+        }
+
         if (!sIsPlatformInitialized) {
             CaInterface.initialize(platformConfig.getActivity(), platformConfig.getContext());
 
@@ -116,6 +124,27 @@ public final class OcPlatform {
                                          String dbPath);
 
     /**
+     * API for stop all process of the OcPlatform.
+     * All of threads and memory will be terminated by this API.
+     * Iotivity Core can be started again through Configure(PlatformConfig platformConfig) API.
+     * Both Configure and Shutdown API is filtering for duplicated calling even while processing.
+     * <p>
+     * Note: This API is for both server and client side.
+     * </p>
+     */
+    public synchronized static void Shutdown() {
+        if (!sIsStopPlatform)
+        {
+            OcPlatform.stop();
+            sIsStopPlatform = true;
+            sIsPlatformInitialized = false;
+        }
+    }
+
+    private static native void stop();
+    private static native void start();
+
+    /**
      * API for notifying base that resource's attributes have changed.
      * <p>
      * Note: This API is for server side only.
index c89716f..7ff1551 100644 (file)
@@ -2277,7 +2277,7 @@ OCStackResult OCStop()
     }
     else if (stackState != OC_STACK_INITIALIZED)
     {
-        OIC_LOG(ERROR, TAG, "Stack not initialized");
+        OIC_LOG(INFO, TAG, "Stack not initialized");
         return OC_STACK_ERROR;
     }
 
index b453068..d1658c7 100644 (file)
@@ -150,6 +150,10 @@ namespace OC
             const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
             MQTopicCallback& callback, QualityOfService QoS) = 0;
 #endif
+        virtual OCStackResult stop() = 0;
+
+        virtual OCStackResult start() = 0;
+
         virtual ~IClientWrapper(){}
     };
 }
index d49dc1b..112ced6 100644 (file)
@@ -77,6 +77,10 @@ namespace OC
 
         virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value) = 0;
         virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value) = 0;
+
+        virtual OCStackResult stop() = 0;
+
+        virtual OCStackResult start() = 0;
     };
 }
 
index bbf6a38..530b076 100644 (file)
@@ -227,6 +227,9 @@ namespace OC
             MQTopicCallback& callback, QualityOfService QoS);
 #endif
 
+        virtual OCStackResult stop();
+        virtual OCStackResult start();
+
     private:
         void listeningFunc();
         std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
index 0ea25e8..e5dc0cd 100644 (file)
@@ -72,11 +72,16 @@ namespace OC
         virtual OCStackResult setPropertyValue(OCPayloadType type, const std::string& tag, const std::string& value);
         virtual OCStackResult getPropertyValue(OCPayloadType type, const std::string& tag, std::string& value);
 
+        virtual OCStackResult stop();
+
+        virtual OCStackResult start();
+
     private:
         void processFunc();
         std::thread m_processThread;
         bool m_threadRun;
         std::weak_ptr<std::recursive_mutex> m_csdkLock;
+        PlatformConfig  m_cfg;
     };
 }
 
index 9903611..1adcb82 100644 (file)
@@ -50,6 +50,21 @@ namespace OC
         typedef OCDoHandle OCPresenceHandle;
 
         /**
+         * API for stop Base layer including resource and connectivity abstraction.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult stop();
+
+        /**
+         * API for start Base layer including resource and connectivity abstraction.
+         * OCInit will be invoked.
+         *
+         * @return Returns ::OC_STACK_OK if success.
+         */
+        OCStackResult start();
+
+        /**
          * API for notifying base that resource's attributes have changed.
          *
          * @param resourceHandle resource handle of the resource
index 6adefc7..e20dc7d 100644 (file)
@@ -269,8 +269,11 @@ namespace OC
 
         OCStackResult setDeviceId(const OCUUIdentity *myUuid);
 
+        OCStackResult stop();
+        OCStackResult start();
     private:
         PlatformConfig m_cfg;
+        OCMode m_modeType;
 
     private:
         std::unique_ptr<WrapperFactory> m_WrapperInstance;
index c32656c..0fb6fa4 100644 (file)
@@ -32,6 +32,16 @@ namespace OC
                                PlatformConfig /*cfg*/)
         {}
 
+        virtual OCStackResult stop()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
+        virtual OCStackResult start()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult ListenForResource(const std::string& /*servUrl*/,
                                                 const std::string& /*rsrcType*/,
                                                 OCConnectivityType /*connType*/,
index 05d79e4..9f5b21c 100644 (file)
@@ -31,6 +31,16 @@ namespace OC
         OutOfProcServerWrapper(PlatformConfig /*cfg*/)
         {}
 
+        virtual OCStackResult stop()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
+        virtual OCStackResult start()
+        {
+            return OC_STACK_NOTIMPL;
+        }
+
         virtual OCStackResult registerResource(
             OCResourceHandle& /*resourceHandle*/,
             std::string& /*resourceURI*/,
index 4f856c2..177bd1d 100644 (file)
@@ -48,6 +48,7 @@ namespace OC
         static const char UNKNOWN_ERROR[]              = "Unknown Error";
 
         static const char STACK_INIT_ERROR[]           = "Error Initializing Stack";
+        static const char STACK_TERMINATE_ERROR[]      = "Error Terminating Stack";
         static const char NOT_CONFIGURED_AS_SERVER[]   =
                           "Cannot static construct a Server when configured as a client";
         static const char INVALID_PARAM[]              = "Invalid Param";
index ce2fb92..9c63705 100644 (file)
 #include "OCResource.h"
 #include "ocpayload.h"
 #include <OCSerialization.h>
+#include "logger.h"
+
+#define TAG "OIC_CLIENT_WRAPPER"
+
 using namespace std;
 
 namespace OC
@@ -36,7 +40,17 @@ namespace OC
     {
         // if the config type is server, we ought to never get called.  If the config type
         // is both, we count on the server to run the thread and do the initialize
+        start();
+    }
+
+    InProcClientWrapper::~InProcClientWrapper()
+    {
+        stop();
+    }
 
+    OCStackResult InProcClientWrapper::start()
+    {
+        OIC_LOG(INFO, TAG, "start ocplatform");
         if (m_cfg.mode == ModeType::Client)
         {
             OCTransportFlags serverFlags =
@@ -50,25 +64,37 @@ namespace OC
                 throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
             }
 
-            m_threadRun = true;
-            m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+            if (false == m_threadRun)
+            {
+                m_threadRun = true;
+                m_listeningThread = std::thread(&InProcClientWrapper::listeningFunc, this);
+            }
         }
+        return OC_STACK_OK;
     }
 
-    InProcClientWrapper::~InProcClientWrapper()
+    OCStackResult InProcClientWrapper::stop()
     {
+        OIC_LOG(INFO, TAG, "stop ocplatform");
+
         if (m_threadRun && m_listeningThread.joinable())
         {
             m_threadRun = false;
             m_listeningThread.join();
         }
 
-        // only stop if we are the ones who actually called 'init'.  We are counting
+        // only stop if we are the ones who actually called 'start'.  We are counting
         // on the server to do the stop.
         if (m_cfg.mode == ModeType::Client)
         {
-            OCStop();
+            OCStackResult result = OCStop();
+
+            if (OC_STACK_OK != result)
+           {
+               throw InitializeException(OC::InitException::STACK_TERMINATE_ERROR, result);
+           }
         }
+        return OC_STACK_OK;
     }
 
     void InProcClientWrapper::listeningFunc()
index fb26655..cd762e3 100644 (file)
@@ -38,6 +38,9 @@
 #include <oic_malloc.h>
 #include <OCPlatform.h>
 #include <OCUtilities.h>
+#include "logger.h"
+
+#define TAG "OIC_SERVER_WRAPPER"
 
 using namespace std;
 using namespace OC;
@@ -254,19 +257,27 @@ namespace OC
 {
     InProcServerWrapper::InProcServerWrapper(
         std::weak_ptr<std::recursive_mutex> csdkLock, PlatformConfig cfg)
-     : m_csdkLock(csdkLock)
+     : m_csdkLock(csdkLock),
+       m_cfg { cfg }
+    {
+        start();
+    }
+
+    OCStackResult InProcServerWrapper::start()
     {
+        OIC_LOG(INFO, TAG, "start");
+
         OCMode initType;
 
-        if(cfg.mode == ModeType::Server)
+        if(m_cfg.mode == ModeType::Server)
         {
             initType = OC_SERVER;
         }
-        else if (cfg.mode == ModeType::Both)
+        else if (m_cfg.mode == ModeType::Both)
         {
             initType = OC_CLIENT_SERVER;
         }
-        else if (cfg.mode == ModeType::Gateway)
+        else if (m_cfg.mode == ModeType::Gateway)
         {
             initType = OC_GATEWAY;
         }
@@ -277,9 +288,9 @@ namespace OC
         }
 
         OCTransportFlags serverFlags =
-                            static_cast<OCTransportFlags>(cfg.serverConnectivity & CT_MASK_FLAGS);
+                            static_cast<OCTransportFlags>(m_cfg.serverConnectivity & CT_MASK_FLAGS);
         OCTransportFlags clientFlags =
-                            static_cast<OCTransportFlags>(cfg.clientConnectivity & CT_MASK_FLAGS);
+                            static_cast<OCTransportFlags>(m_cfg.clientConnectivity & CT_MASK_FLAGS);
         OCStackResult result = OCInit1(initType, serverFlags, clientFlags);
 
         if(OC_STACK_OK != result)
@@ -287,8 +298,27 @@ namespace OC
             throw InitializeException(OC::InitException::STACK_INIT_ERROR, result);
         }
 
-        m_threadRun = true;
-        m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        if (false == m_threadRun)
+        {
+            m_threadRun = true;
+            m_processThread = std::thread(&InProcServerWrapper::processFunc, this);
+        }
+        return OC_STACK_OK;
+    }
+
+    OCStackResult InProcServerWrapper::stop()
+    {
+        OIC_LOG(INFO, TAG, "stop");
+
+        if(m_processThread.joinable())
+        {
+            m_threadRun = false;
+            m_processThread.join();
+        }
+
+        OCStackResult res = OCStop();
+
+        return res;
     }
 
     void InProcServerWrapper::processFunc()
@@ -626,12 +656,6 @@ namespace OC
 
     InProcServerWrapper::~InProcServerWrapper()
     {
-        if(m_processThread.joinable())
-        {
-            m_threadRun = false;
-            m_processThread.join();
-        }
-
-        OCStop();
+        stop();
     }
 }
index e9e90a1..c41d665 100644 (file)
@@ -37,6 +37,16 @@ namespace OC
             OCPlatform_impl::Configure(config);
         }
 
+        OCStackResult start()
+        {
+            return OCPlatform_impl::Instance().start();
+        }
+
+        OCStackResult stop()
+        {
+            return OCPlatform_impl::Instance().stop();
+        }
+
         OCStackResult setDefaultDeviceEntityHandler(EntityHandler entityHandler)
         {
             return OCPlatform_impl::Instance().setDefaultDeviceEntityHandler(entityHandler);
index a8e8fd3..f23688f 100644 (file)
 #include "OCUtilities.h"
 #include "ocpayload.h"
 
+#include "logger.h"
 #include "oc_logger.hpp"
 
+#define TAG "OIC_PLATFORM"
+
 namespace OC
 {
 
@@ -67,22 +70,105 @@ namespace OC
         return platform;
     }
 
+    OCStackResult OCPlatform_impl::start()
+    {
+        OIC_LOG(INFO, TAG, "start");
+
+        OCStackResult res = OC_STACK_OK;
+        if (OC_CLIENT == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_CLIENT_SERVER == m_modeType || OC_GATEWAY == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::start))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            res = OC_STACK_ERROR;
+        }
+
+        return res;
+    }
+
+    OCStackResult OCPlatform_impl::stop()
+    {
+        OIC_LOG(INFO, TAG, "stop");
+
+        OCStackResult res = OC_STACK_OK;
+        if (OC_CLIENT == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else if (OC_CLIENT_SERVER == m_modeType)
+        {
+            if (OC_STACK_OK != checked_guard(m_client, &IClientWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+
+            if (OC_STACK_OK != checked_guard(m_server, &IServerWrapper::stop))
+            {
+                res = OC_STACK_ERROR;
+            }
+        }
+        else
+        {
+            res = OC_STACK_ERROR;
+        }
+
+        return res;
+    }
+
     void OCPlatform_impl::init(const PlatformConfig& config)
     {
+        OIC_LOG(INFO, TAG, "init");
+
         switch(config.mode)
         {
             case ModeType::Server:
                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
+                m_modeType = OC_SERVER;
                 break;
 
             case ModeType::Client:
                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_modeType = OC_CLIENT;
                 break;
 
             case ModeType::Both:
             case ModeType::Gateway:
                 m_server = m_WrapperInstance->CreateServerWrapper(m_csdkLock, config);
                 m_client = m_WrapperInstance->CreateClientWrapper(m_csdkLock, config);
+                m_modeType = OC_CLIENT_SERVER;
                 break;
          }
     }