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>
/*
* 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
*/
/*
* 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
*/
private static volatile boolean sIsPlatformInitialized = false;
private static QualityOfService sPlatformQualityOfService = QualityOfService.NA;
+ private static volatile boolean sIsStopPlatform = false;
+
private 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());
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.
}
else if (stackState != OC_STACK_INITIALIZED)
{
- OIC_LOG(ERROR, TAG, "Stack not initialized");
+ OIC_LOG(INFO, TAG, "Stack not initialized");
return OC_STACK_ERROR;
}
const QueryParamsMap& queryParams, const HeaderOptions& headerOptions,
MQTopicCallback& callback, QualityOfService QoS) = 0;
#endif
+ virtual OCStackResult stop() = 0;
+
+ virtual OCStackResult start() = 0;
+
virtual ~IClientWrapper(){}
};
}
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;
};
}
MQTopicCallback& callback, QualityOfService QoS);
#endif
+ virtual OCStackResult stop();
+ virtual OCStackResult start();
+
private:
void listeningFunc();
std::string assembleSetResourceUri(std::string uri, const QueryParamsMap& queryParams);
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;
};
}
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
OCStackResult setDeviceId(const OCUUIdentity *myUuid);
+ OCStackResult stop();
+ OCStackResult start();
private:
PlatformConfig m_cfg;
+ OCMode m_modeType;
private:
std::unique_ptr<WrapperFactory> m_WrapperInstance;
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*/,
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*/,
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";
#include "OCResource.h"
#include "ocpayload.h"
#include <OCSerialization.h>
+#include "logger.h"
+
+#define TAG "OIC_CLIENT_WRAPPER"
+
using namespace std;
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 =
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()
#include <oic_malloc.h>
#include <OCPlatform.h>
#include <OCUtilities.h>
+#include "logger.h"
+
+#define TAG "OIC_SERVER_WRAPPER"
using namespace std;
using 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;
}
}
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)
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()
InProcServerWrapper::~InProcServerWrapper()
{
- if(m_processThread.joinable())
- {
- m_threadRun = false;
- m_processThread.join();
- }
-
- OCStop();
+ stop();
}
}
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);
#include "OCUtilities.h"
#include "ocpayload.h"
+#include "logger.h"
#include "oc_logger.hpp"
+#define TAG "OIC_PLATFORM"
+
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;
}
}