Merge tizen_5.0 codes into tizen_4.0 66/195266/1 accepted/tizen/4.0/unified/20181213.000255 submit/tizen_4.0/20181212.004239
authorDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 12 Dec 2018 04:07:46 +0000 (13:07 +0900)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Wed, 12 Dec 2018 04:07:46 +0000 (13:07 +0900)
Change-Id: If56f871c86a24372cf63fe2ff42055ffbbd72fe6
Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
56 files changed:
android/android_api/base/jni/Android.mk
android/android_api/base/jni/JniListenerManager.h
android/android_api/base/jni/JniOcAccountManager.cpp
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcResource.cpp
android/android_api/base/jni/JniOcResource.h
android/android_api/base/jni/JniOcStack.h
android/android_api/base/jni/JniOnDeleteListener.cpp
android/android_api/base/jni/JniOnDeleteListener.h
android/android_api/base/jni/JniOnGetListener.cpp
android/android_api/base/jni/JniOnGetListener.h
android/android_api/base/jni/JniOnMQSubscribeListener.cpp
android/android_api/base/jni/JniOnMQSubscribeListener.h
android/android_api/base/jni/JniOnMQTopicFoundListener.cpp
android/android_api/base/jni/JniOnMQTopicFoundListener.h
android/android_api/base/jni/JniOnObserveListener.cpp
android/android_api/base/jni/JniOnObserveListener.h
android/android_api/base/jni/JniOnPostListener.cpp
android/android_api/base/jni/JniOnPostListener.h
android/android_api/base/jni/JniOnPutListener.cpp
android/android_api/base/jni/JniOnPutListener.h
packaging/snapshot_history.txt
resource/csdk/connectivity/api/casecurityinterface.h
resource/csdk/connectivity/src/adapter_util/ca_adapter_net_ssl.c
resource/csdk/connectivity/src/bt_le_adapter/caleadapter.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/SConscript
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient_vd.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/tizen/caleserver_vd.c
resource/csdk/security/include/internal/doxmresource.h
resource/csdk/security/include/internal/secureresourcemanager.h
resource/csdk/security/include/oxmverifycommon.h
resource/csdk/security/provisioning/include/internal/ownershiptransfermanager.h
resource/csdk/security/provisioning/include/ocprovisioningmanager.h
resource/csdk/security/provisioning/sample/provisioningclient.c
resource/csdk/security/provisioning/sample/sampleserver_mfg.cpp
resource/csdk/security/provisioning/sample/subownerclient.c
resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/csdk/security/provisioning/src/secureresourceprovider.c
resource/csdk/security/src/credresource.c
resource/csdk/security/src/doxmresource.c
resource/csdk/security/src/pconfresource.c
resource/csdk/security/src/pkix_interface.c
resource/csdk/security/src/pstatresource.c
resource/csdk/security/src/secureresourcemanager.c
resource/csdk/security/src/srmutility.c
resource/csdk/stack/include/ocpresence.h
resource/csdk/stack/include/ocstack.h
resource/csdk/stack/include/octypes.h
resource/csdk/stack/include/oickeepalive.h
resource/csdk/stack/include/payload_logging.h
resource/csdk/stack/src/ocstack.c
resource/csdk/stack/src/oickeepalive.c
resource/src/InProcClientWrapper.cpp
service/easy-setup/mediator/richsdk/android/EasySetupCore/src/main/jni/JniJvm.h

index 4210502..683620c 100644 (file)
@@ -67,6 +67,7 @@ LOCAL_STATIC_LIBRARIES := libandroid-ca
 LOCAL_LDLIBS := -llog
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/connectivity/api
 LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/c_common
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/stack/include
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
index 8965e85..6912424 100644 (file)
 #define _JniListenerManager
 
 class JniOcResource;
-#ifdef WITH_CLOUD
-class JniOcAccountManager;
-#endif
 
 template <class T>
 class JniListenerManager
 {
 public:
-    T* addListener(JNIEnv* env, jobject jListener, JniOcResource* owner)
+    T* addListener(JNIEnv* env, jobject jListener, RemoveListenerCallback removeListener)
     {
         T *onEventListener = nullptr;
 
@@ -57,7 +54,7 @@ public:
 
         if (!onEventListener)
         {
-            onEventListener = new T(env, jListener, owner);
+            onEventListener = new T(env, jListener, removeListener);
             jobject jgListener = env->NewGlobalRef(jListener);
 
             if (jgListener)
@@ -80,53 +77,6 @@ public:
         return onEventListener;
     }
 
-#ifdef WITH_CLOUD
-    T* addListener(JNIEnv* env, jobject jListener, JniOcAccountManager* owner)
-    {
-        T *onEventListener = nullptr;
-
-        m_mapMutex.lock();
-
-        for (auto it = m_listenerMap.begin(); it != m_listenerMap.end(); ++it)
-        {
-            if (env->IsSameObject(jListener, it->first))
-            {
-                auto refPair = it->second;
-                onEventListener = refPair.first;
-                refPair.second++;
-                it->second = refPair;
-                m_listenerMap.insert(*it);
-                LOGD("OnEventListener: ref. count is incremented");
-                break;
-            }
-        }
-
-        if (!onEventListener)
-        {
-            onEventListener = new T(env, jListener, owner);
-            jobject jgListener = env->NewGlobalRef(jListener);
-
-            if (jgListener)
-            {
-                m_listenerMap.insert(
-                        std::pair<jobject,
-                        std::pair<T*, int>>(jgListener, std::pair<T*, int>(onEventListener, 1)));
-            }
-            else
-            {
-                LOGD("OnEventListener: Failed to create global listener ref.");
-                delete onEventListener;
-                m_mapMutex.unlock();
-                return nullptr;
-            }
-            LOGD("OnEventListener: new listener");
-        }
-
-        m_mapMutex.unlock();
-        return onEventListener;
-    }
-#endif
-
     void removeListener(JNIEnv* env, jobject jListener)
     {
         m_mapMutex.lock();
index 2d7e861..141f493 100644 (file)
@@ -86,22 +86,30 @@ JniOcAccountManager* JniOcAccountManager::getJniOcAccountManagerPtr(JNIEnv *env,
 
 JniOnGetListener* JniOcAccountManager::addOnGetListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onGetManager.addListener(env, jListener, this);
+    return this->m_onGetManager.addListener(env, jListener,
+                                            std::bind(&JniOcAccountManager::removeOnGetListener, this,
+                                            std::placeholders::_1, std::placeholders::_2));
 }
 
 JniOnPostListener* JniOcAccountManager::addOnPostListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onPostManager.addListener(env, jListener, this);
+    return this->m_onPostManager.addListener(env, jListener,
+                                             std::bind(&JniOcAccountManager::removeOnPostListener, this,
+                                             std::placeholders::_1, std::placeholders::_2));
 }
 
 JniOnDeleteListener* JniOcAccountManager::addOnDeleteListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onDeleteManager.addListener(env, jListener, this);
+    return this->m_onDeleteManager.addListener(env, jListener,
+                                               std::bind(&JniOcAccountManager::removeOnDeleteListener, this,
+                                               std::placeholders::_1, std::placeholders::_2));
 }
 
 JniOnObserveListener* JniOcAccountManager::addOnObserveListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onObserveManager.addListener(env, jListener, this);
+    return this->m_onObserveManager.addListener(env, jListener,
+                                                std::bind(&JniOcAccountManager::removeOnObserveListener, this,
+                                                std::placeholders::_1, std::placeholders::_2));
 }
 
 void JniOcAccountManager::removeOnGetListener(JNIEnv* env, jobject jListener)
index 87d08a2..f5f4665 100644 (file)
@@ -351,7 +351,7 @@ JniOnObserveListener* AddOnObserveListener(JNIEnv* env, jobject jListener)
     }
     if (!onObserveListener)
     {
-        onObserveListener = new JniOnObserveListener(env, jListener, (JniOcResource*)nullptr);
+        onObserveListener = new JniOnObserveListener(env, jListener, nullptr);
         jobject jgListener = env->NewGlobalRef(jListener);
         onObserveListenerMap.insert(
             std::pair<jobject, std::pair<JniOnObserveListener*, int>>(
index 9d30ba2..f376cdd 100644 (file)
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
 
-JniOcResource::JniOcResource(std::shared_ptr<OCResource> resource)
-    : m_sharedResource(resource)
-{
-}
+class JniOcResourceImpl : public std::enable_shared_from_this<JniOcResourceImpl>
+{
+public:
+    typedef std::shared_ptr<JniOcResourceImpl> Ptr;
+
+    JniOcResourceImpl(std::shared_ptr<OCResource> &resource);
+    ~JniOcResourceImpl();
+
+    OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+        QualityOfService QoS);
+    OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult get(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult put(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService QoS);
+    OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult put(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult post(JNIEnv* env, const OCRepresentation &representation, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService QoS);
+    OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener);
+    OCStackResult post(JNIEnv* env, const std::string &resourceType, const std::string &resourceInterface,
+        const OCRepresentation &representation, const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS);
+
+    OCStackResult deleteResource(JNIEnv* env, jobject jListener);
+    OCStackResult deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS);
+
+    OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap,
+        jobject jListener);
+    OCStackResult observe(JNIEnv* env, ObserveType observeType, const QueryParamsMap &queryParametersMap,
+        jobject jListener, QualityOfService qos);
+
+    OCStackResult cancelObserve(JNIEnv* env);
+    OCStackResult cancelObserve(JNIEnv* env, QualityOfService qos);
+
+    void setHeaderOptions(const HeaderOptions &headerOptions);
+    void unsetHeaderOptions();
+    std::string host();
+    std::string uri();
+    OCConnectivityType connectivityType() const;
+    bool isObservable();
+    std::vector< std::string >  getResourceTypes() const;
+    std::vector< std::string >  getResourceInterfaces(void) const;
+    OCResourceIdentifier uniqueIdentifier() const;
+    std::string sid() const;
+    std::string deviceName() const;
+
+    JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener);
+    JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener);
+    JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener);
+    JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener);
+    JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener);
+
+    void removeOnGetListener(JNIEnv* env, jobject jListener);
+    void removeOnPutListener(JNIEnv* env, jobject jListener);
+    void removeOnPostListener(JNIEnv* env, jobject jListener);
+    void removeOnDeleteListener(JNIEnv* env, jobject jListener);
+    void removeOnObserveListener(JNIEnv* env, jobject jListener);
+
+    std::shared_ptr<OCResource> getOCResource();
+
+#ifdef WITH_MQ
+    JniOnMQTopicFoundListener* addOnTopicFoundListener(JNIEnv* env, jobject jListener);
+    void removeOnTopicFoundListener(JNIEnv* env, jobject jListener);
+
+    JniOnMQSubscribeListener* addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
+    void removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
+
+    OCStackResult discoveryMQTopics(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                    jobject jListener, QualityOfService QoS);
+    OCStackResult createMQTopic(JNIEnv* env, const OCRepresentation &representation,
+                                const std::string &targetUri,
+                                const QueryParamsMap &queryParametersMap,
+                                jobject jListener, QualityOfService QoS);
+#endif
+#ifdef MQ_SUBSCRIBER
+    OCStackResult subscribeMQTopic(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                   jobject jListener, QualityOfService QoS);
+    OCStackResult unsubscribeMQTopic(QualityOfService QoS);
+    OCStackResult requestMQPublish(JNIEnv* env, const QueryParamsMap &queryParametersMap,
+                                   jobject jListener, QualityOfService QoS);
+#endif
+#ifdef MQ_PUBLISHER
+    OCStackResult publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+                                 const QueryParamsMap &queryParametersMap,
+                                 jobject jListener, QualityOfService QoS);
+#endif
+
+private:
+
+    static void onGetCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                              const int eCode, JniOnGetListener *listener,
+                              std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onPutCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                              const int eCode, JniOnPutListener *listener,
+                              std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onPostCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                               const int eCode, JniOnPostListener *listener,
+                               std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onDeleteCallback(const HeaderOptions& opts,
+                                 const int eCode, JniOnDeleteListener *listener,
+                                 std::weak_ptr<JniOcResourceImpl> weakRef);
+
+    static void onObserveCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                  const int eCode, const int& sequenceNumber,
+                                  JniOnObserveListener *listener,
+                                  std::weak_ptr<JniOcResourceImpl> weakRef);
+
+
+    JniListenerManager<JniOnGetListener> m_onGetManager;
+    JniListenerManager<JniOnPutListener> m_onPutManager;
+    JniListenerManager<JniOnPostListener> m_onPostManager;
+    JniListenerManager<JniOnDeleteListener> m_onDeleteManager;
+    JniListenerManager<JniOnObserveListener> m_onObserveManager;
+#ifdef WITH_MQ
+    JniListenerManager<JniOnMQTopicFoundListener> m_onFoundTopicResourceManager;
+    JniListenerManager<JniOnMQSubscribeListener> m_onSubcribeTopicManager;
+#endif
+
+    std::shared_ptr<OCResource> m_sharedResource;
+};
 
-JniOcResource::~JniOcResource()
+JniOcResourceImpl::JniOcResourceImpl(std::shared_ptr<OCResource> &resource)
+    : m_sharedResource(resource) {}
+
+JniOcResourceImpl::~JniOcResourceImpl()
 {
-    LOGD("~JniOcResource()");
+    LOGD("~JniOcResourceImpl()");
 
     m_sharedResource = nullptr;
 
@@ -58,36 +191,44 @@ JniOcResource::~JniOcResource()
     }
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
+void JniOcResourceImpl::onGetCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnGetListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Get callback called on deleted object\n");
+        return;
+    }
+
+    listener->onGetCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](
-        const HeaderOptions& opts,
-        const OCRepresentation& rep,
-        const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(queryParametersMap, getCallback);
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
     QualityOfService QoS)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts, const OCRepresentation& rep,
-        const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(queryParametersMap, getCallback, QoS);
 }
 
-OCStackResult JniOcResource::get(
+OCStackResult JniOcResourceImpl::get(
     JNIEnv* env,
     const std::string &resourceType,
     const std::string &resourceInterface,
@@ -96,206 +237,238 @@ OCStackResult JniOcResource::get(
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap,
         getCallback);
 }
 
-OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::get(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const QueryParamsMap &queryParametersMap,
     jobject jListener, QualityOfService QoS)
 {
     JniOnGetListener *onGetListener = addOnGetListener(env, jListener);
 
-    GetCallback getCallback = [onGetListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onGetListener->onGetCallback(opts, rep, eCode);
-    };
+    GetCallback getCallback = std::bind(JniOcResourceImpl::onGetCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onGetListener,
+                                        shared_from_this());
 
     return m_sharedResource->get(resourceType, resourceInterface, queryParametersMap,
         getCallback, QoS);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+void JniOcResourceImpl::onPutCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnPutListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Put callback called on deleted object\n");
+        return;
+    }
+
+    listener->onPutCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(representation, queryParametersMap, putCallback);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(representation, queryParametersMap, putCallback, QoS);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(resourceType, resourceInterface, representation,
         queryParametersMap, putCallback);
 }
 
-OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::put(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPutListener *onPutListener = addOnPutListener(env, jListener);
 
-    PutCallback putCallback = [onPutListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPutListener->onPutCallback(opts, rep, eCode);
-    };
+    PutCallback putCallback = std::bind(JniOcResourceImpl::onPutCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPutListener,
+                                        shared_from_this());
 
     return m_sharedResource->put(resourceType, resourceInterface, representation,
         queryParametersMap, putCallback, QoS);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+void JniOcResourceImpl::onPostCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, JniOnPostListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Post callback called on deleted object\n");
+        return;
+    }
+
+    listener->onPostCallback(opts, rep, eCode);
+}
+
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(representation, queryParametersMap, postCallback);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(representation, queryParametersMap, postCallback, QoS);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(resourceType, resourceInterface, representation,
         queryParametersMap, postCallback);
 }
 
-OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+OCStackResult JniOcResourceImpl::post(JNIEnv* env, const std::string &resourceType,
     const std::string &resourceInterface, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->post(resourceType, resourceInterface, representation,
         queryParametersMap, postCallback, QoS);
 }
 
-OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::onDeleteCallback(const HeaderOptions& opts,
+                                      const int eCode, JniOnDeleteListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Delete callback called on deleted object\n");
+        return;
+    }
+
+    listener->onDeleteCallback(opts, eCode);
+}
+
+OCStackResult JniOcResourceImpl::deleteResource(JNIEnv* env, jobject jListener)
 {
     JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener);
 
-    DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts,
-        const int eCode)
-    {
-        onDeleteListener->onDeleteCallback(opts, eCode);
-    };
+    DeleteCallback deleteCallback = std::bind(JniOcResourceImpl::onDeleteCallback, std::placeholders::_1,
+                                        std::placeholders::_2, onDeleteListener,
+                                        shared_from_this());
 
     return m_sharedResource->deleteResource(deleteCallback);
 }
 
-OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
+OCStackResult JniOcResourceImpl::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
 {
     JniOnDeleteListener *onDeleteListener = addOnDeleteListener(env, jListener);
 
-    DeleteCallback deleteCallback = [onDeleteListener](const HeaderOptions& opts, const int eCode)
-    {
-        onDeleteListener->onDeleteCallback(opts, eCode);
-    };
+    DeleteCallback deleteCallback = std::bind(JniOcResourceImpl::onDeleteCallback, std::placeholders::_1,
+                                        std::placeholders::_2, onDeleteListener,
+                                        shared_from_this());
 
     return m_sharedResource->deleteResource(deleteCallback, QoS);
 }
 
-OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+void JniOcResourceImpl::onObserveCallback(const HeaderOptions& opts, const OCRepresentation& rep,
+                                      const int eCode, const int& sequenceNumber,
+                                      JniOnObserveListener *listener,
+                                      std::weak_ptr<JniOcResourceImpl> weakRef)
+{
+    auto obj = weakRef.lock();
+       if (!obj)
+    {
+        LOGD("Observe callback called on deleted object\n");
+        return;
+    }
+
+    listener->onObserveCallback(opts, rep, eCode, sequenceNumber);
+}
+
+OCStackResult JniOcResourceImpl::observe(JNIEnv* env, ObserveType observeType,
     const QueryParamsMap &queryParametersMap, jobject jListener)
 {
     JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener);
 
-    ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
-    {
-        onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber);
-    };
+    ObserveCallback observeCallback = std::bind(JniOcResourceImpl::onObserveCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3,
+                                        std::placeholders::_4, onObserveListener,
+                                        shared_from_this());
 
     return m_sharedResource->observe(observeType, queryParametersMap, observeCallback);
 }
 
-OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+OCStackResult JniOcResourceImpl::observe(JNIEnv* env, ObserveType observeType,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnObserveListener *onObserveListener = addOnObserveListener(env, jListener);
 
-    ObserveCallback observeCallback = [onObserveListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
-    {
-        onObserveListener->onObserveCallback(opts, rep, eCode, sequenceNumber);
-    };
+    ObserveCallback observeCallback = std::bind(JniOcResourceImpl::onObserveCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3,
+                                        std::placeholders::_4, onObserveListener,
+                                        shared_from_this());
 
     return m_sharedResource->observe(observeType, queryParametersMap, observeCallback, QoS);
 }
 
-OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
+OCStackResult JniOcResourceImpl::cancelObserve(JNIEnv* env, QualityOfService qos)
 {
     // In Low case, after delete the callback and send empty message when client receive the notify.
     // But TCP does not support EMPTY message.
@@ -306,178 +479,197 @@ OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
     return m_sharedResource->cancelObserve(qos);
 }
 
-void JniOcResource::setHeaderOptions(const HeaderOptions &headerOptions)
+void JniOcResourceImpl::setHeaderOptions(const HeaderOptions &headerOptions)
 {
     m_sharedResource->setHeaderOptions(headerOptions);
 }
 
-void JniOcResource::unsetHeaderOptions()
+void JniOcResourceImpl::unsetHeaderOptions()
 {
     m_sharedResource->unsetHeaderOptions();
 }
 
-std::string JniOcResource::host()
+std::string JniOcResourceImpl::host()
 {
     return m_sharedResource->host();
 }
 
-std::string JniOcResource::uri()
+std::string JniOcResourceImpl::uri()
 {
     return m_sharedResource->uri();
 }
 
-OCConnectivityType JniOcResource::connectivityType() const
+OCConnectivityType JniOcResourceImpl::connectivityType() const
 {
     return m_sharedResource->connectivityType();
 }
 
-bool JniOcResource::isObservable()
+bool JniOcResourceImpl::isObservable()
 {
     return m_sharedResource->isObservable();
 }
 
-std::vector< std::string > JniOcResource::getResourceTypes() const
+std::vector< std::string > JniOcResourceImpl::getResourceTypes() const
 {
     return m_sharedResource->getResourceTypes();
 }
 
-std::vector< std::string > JniOcResource::getResourceInterfaces(void) const
+std::vector< std::string > JniOcResourceImpl::getResourceInterfaces(void) const
 {
     return m_sharedResource->getResourceInterfaces();
 }
 
-OCResourceIdentifier JniOcResource::uniqueIdentifier() const
+OCResourceIdentifier JniOcResourceImpl::uniqueIdentifier() const
 {
     return m_sharedResource->uniqueIdentifier();
 }
 
-std::string JniOcResource::sid() const
+std::string JniOcResourceImpl::sid() const
 {
     return m_sharedResource->sid();
 }
 
-std::string JniOcResource::deviceName() const
+std::string JniOcResourceImpl::deviceName() const
 {
     return m_sharedResource->deviceName();
 }
 
-JniOnGetListener* JniOcResource::addOnGetListener(JNIEnv* env, jobject jListener)
+JniOnGetListener* JniOcResourceImpl::addOnGetListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onGetManager.addListener(env, jListener, this);
+    return this->m_onGetManager.addListener(env, jListener,
+                                            std::bind(&JniOcResourceImpl::removeOnGetListener, this,
+                                            std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnPutListener* JniOcResource::addOnPutListener(JNIEnv* env, jobject jListener)
+JniOnPutListener* JniOcResourceImpl::addOnPutListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onPutManager.addListener(env, jListener, this);
+    return this->m_onPutManager.addListener(env, jListener,
+                                            std::bind(&JniOcResourceImpl::removeOnPutListener, this,
+                                            std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnPostListener* JniOcResource::addOnPostListener(JNIEnv* env, jobject jListener)
+JniOnPostListener* JniOcResourceImpl::addOnPostListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onPostManager.addListener(env, jListener, this);
+    return this->m_onPostManager.addListener(env, jListener,
+                                             std::bind(&JniOcResourceImpl::removeOnPostListener, this,
+                                             std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnDeleteListener* JniOcResource::addOnDeleteListener(JNIEnv* env, jobject jListener)
+JniOnDeleteListener* JniOcResourceImpl::addOnDeleteListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onDeleteManager.addListener(env, jListener, this);
+    return this->m_onDeleteManager.addListener(env, jListener,
+                                               std::bind(&JniOcResourceImpl::removeOnDeleteListener, this,
+                                               std::placeholders::_1, std::placeholders::_2));
 }
 
-JniOnObserveListener* JniOcResource::addOnObserveListener(JNIEnv* env, jobject jListener)
+JniOnObserveListener* JniOcResourceImpl::addOnObserveListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onObserveManager.addListener(env, jListener, this);
+    return this->m_onObserveManager.addListener(env, jListener,
+                                                std::bind(&JniOcResourceImpl::removeOnObserveListener, this,
+                                                std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnGetListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnGetListener(JNIEnv* env, jobject jListener)
 {
     this->m_onGetManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnPutListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnPutListener(JNIEnv* env, jobject jListener)
 {
     this->m_onPutManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnPostListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnPostListener(JNIEnv* env, jobject jListener)
 {
     this->m_onPostManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnDeleteListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnDeleteListener(JNIEnv* env, jobject jListener)
 {
     this->m_onDeleteManager.removeListener(env, jListener);
 }
 
-void JniOcResource::removeOnObserveListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnObserveListener(JNIEnv* env, jobject jListener)
 {
     this->m_onObserveManager.removeListener(env, jListener);
 }
 
 #ifdef WITH_MQ
-JniOnMQTopicFoundListener* JniOcResource::addOnTopicFoundListener(JNIEnv* env, jobject jListener)
+JniOnMQTopicFoundListener* JniOcResourceImpl::addOnTopicFoundListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onFoundTopicResourceManager.addListener(env, jListener, this);
+    return this->m_onFoundTopicResourceManager.addListener(env, jListener,
+                                                           std::bind(&JniOcResource::removeOnTopicFoundListener, this,
+                                                           std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnTopicFoundListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnTopicFoundListener(JNIEnv* env, jobject jListener)
 {
     this->m_onFoundTopicResourceManager.removeListener(env, jListener);
 }
 
-JniOnMQSubscribeListener* JniOcResource::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
+JniOnMQSubscribeListener* JniOcResourceImpl::addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
 {
-    return this->m_onSubcribeTopicManager.addListener(env, jListener, this);
+    return this->m_onSubcribeTopicManager.addListener(env, jListener,
+                                                      std::bind(&JniOcResource::removeOnMQTopicSubscribeListener, this
+                                                      std::placeholders::_1, std::placeholders::_2));
 }
 
-void JniOcResource::removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
+void JniOcResourceImpl::removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener)
 {
     this->m_onSubcribeTopicManager.removeListener(env, jListener);
 }
 #endif
 
-std::shared_ptr<OCResource> JniOcResource::getOCResource()
+std::shared_ptr<OCResource> JniOcResourceImpl::getOCResource()
 {
     return this->m_sharedResource;
 }
 
-JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz)
-{
-    JniOcResource *resource = GetHandle<JniOcResource>(env, thiz);
-    if (env->ExceptionCheck())
-    {
-        LOGE("Failed to get native handle from OcResource");
-    }
-    if (!resource)
-    {
-        ThrowOcException(JNI_NO_NATIVE_POINTER, "");
-    }
-    return resource;
-}
-
 #ifdef WITH_MQ
-OCStackResult JniOcResource::discoveryMQTopics(JNIEnv* env,
+OCStackResult JniOcResourceImpl::discoveryMQTopics(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQTopicFoundListener *onTopicFoundListener = addOnTopicFoundListener(env, jListener);
 
-    MQTopicCallback findCallback = [onTopicFoundListener](const int& eCode,
-            const std::string& uri, std::shared_ptr<OCResource> resource)
+    MQTopicCallback findCallback = std::bind([](const int& eCode,
+                                                const std::string& uri, std::shared_ptr<OCResource> resource,
+                                                JniOnMQTopicFoundListener *listener,
+                                                std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onTopicFoundListener->foundTopicCallback(eCode, uri, resource);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Topic callback called on deleted object\n");
+            return;
+        }
+        listener->foundTopicCallback(eCode, uri, resource);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+       onTopicFoundListener, shared_from_this());
 
     return m_sharedResource->discoveryMQTopics(queryParametersMap, findCallback, QoS);
 }
 
-OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
+OCStackResult JniOcResourceImpl::createMQTopic(JNIEnv* env,
     const OCRepresentation &representation, const std::string &targetUri,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQTopicFoundListener *onTopicCreatedListener = addOnTopicFoundListener(env, jListener);
 
-    MQTopicCallback createCallback = [onTopicCreatedListener](const int& eCode,
-            const std::string& uri, std::shared_ptr<OCResource> resource)
+    MQTopicCallback createCallback = std::bind([](const int& eCode,
+                                                  const std::string& uri,
+                                                  std::shared_ptr<OCResource> resource,
+                                                  JniOnMQTopicFoundListener *listener,
+                                                  std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onTopicCreatedListener->createdTopicCallback(eCode, uri, resource);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Topic callback called on deleted object\n");
+            return;
+        }
+        listener->createdTopicCallback(eCode, uri, resource);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3,
+       onTopicCreatedListener, shared_from_this());
 
     return m_sharedResource->createMQTopic(representation, targetUri,
                                            queryParametersMap,
@@ -485,57 +677,290 @@ OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
 }
 #endif
 #ifdef MQ_SUBSCRIBER
-OCStackResult JniOcResource::subscribeMQTopic(JNIEnv* env,
+OCStackResult JniOcResourceImpl::subscribeMQTopic(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnMQSubscribeListener *onSubscribeListener = addOnMQTopicSubscribeListener(env, jListener);
 
-    ObserveCallback subscribeCallback = [onSubscribeListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int& eCode, const int& sequenceNumber)
+    ObserveCallback subscribeCallback = std::bind([](const HeaderOptions& opts,
+                                                     const OCRepresentation& rep, const int& eCode,
+                                                     const int& sequenceNumber,
+                                                     JniOnMQSubscribeListener *listener,
+                                                     std::weak_ptr<JniOcResourceImpl> weakRef)
     {
-        onSubscribeListener->onSubscribeCallback(opts, rep, eCode, sequenceNumber);
-    };
+        auto obj = weakRef.lock();
+           if (!obj)
+        {
+            LOGD("Subscribe MQ callback called on deleted object\n");
+            return;
+        }
+        listener->onSubscribeCallback(opts, rep, eCode, sequenceNumber);
+    }, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4,
+       onSubscribeListener, shared_from_this());
 
     return m_sharedResource->subscribeMQTopic(ObserveType::Observe, queryParametersMap,
                                               subscribeCallback, QoS);
 }
 
-OCStackResult JniOcResource::unsubscribeMQTopic(QualityOfService QoS)
+OCStackResult JniOcResourceImpl::unsubscribeMQTopic(QualityOfService QoS)
 {
     return m_sharedResource->unsubscribeMQTopic(QoS);
 }
 
-OCStackResult JniOcResource::requestMQPublish(JNIEnv* env,
+OCStackResult JniOcResourceImpl::requestMQPublish(JNIEnv* env,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->requestMQPublish(queryParametersMap, postCallback, QoS);
 }
 #endif
 #ifdef MQ_PUBLISHER
-OCStackResult JniOcResource::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+OCStackResult JniOcResourceImpl::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
     const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
 {
     JniOnPostListener *onPostListener = addOnPostListener(env, jListener);
 
-    PostCallback postCallback = [onPostListener](const HeaderOptions& opts,
-        const OCRepresentation& rep, const int eCode)
-    {
-        onPostListener->onPostCallback(opts, rep, eCode);
-    };
+    PostCallback postCallback = std::bind(JniOcResourceImpl::onPostCallback, std::placeholders::_1,
+                                        std::placeholders::_2, std::placeholders::_3, onPostListener,
+                                        shared_from_this());
 
     return m_sharedResource->publishMQTopic(representation, queryParametersMap,
                                             postCallback, QoS);
 }
 #endif
 
+
+JniOcResource::JniOcResource(std::shared_ptr<OCResource> &resource)
+{
+    m_impl = std::make_shared<JniOcResourceImpl>(resource);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->get(env, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
+    QualityOfService QoS)
+{
+    return m_impl->get(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::get(
+    JNIEnv* env,
+    const std::string &resourceType,
+    const std::string &resourceInterface,
+    const QueryParamsMap &queryParametersMap,
+    jobject jListener)
+{
+    return m_impl->get(env, resourceType, resourceInterface, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::get(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const QueryParamsMap &queryParametersMap,
+    jobject jListener, QualityOfService QoS)
+{
+    return m_impl->get(env, resourceType, resourceInterface, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->put(env, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->put(env, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->put(env, resourceType, resourceInterface, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::put(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->put(env, resourceType, resourceInterface, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->post(env, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->post(env, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->post(env, resourceType, resourceInterface, representation, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::post(JNIEnv* env, const std::string &resourceType,
+    const std::string &resourceInterface, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->post(env, resourceType, resourceInterface, representation, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener)
+{
+    return m_impl->deleteResource(env, jListener);
+}
+
+OCStackResult JniOcResource::deleteResource(JNIEnv* env, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->deleteResource(env, jListener, QoS);
+}
+
+OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+    const QueryParamsMap &queryParametersMap, jobject jListener)
+{
+    return m_impl->observe(env, observeType, queryParametersMap, jListener);
+}
+
+OCStackResult JniOcResource::observe(JNIEnv* env, ObserveType observeType,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->observe(env, observeType, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::cancelObserve(JNIEnv* env, QualityOfService qos)
+{
+    return m_impl->cancelObserve(env, qos);
+}
+
+void JniOcResource::setHeaderOptions(const HeaderOptions &headerOptions)
+{
+    m_impl->setHeaderOptions(headerOptions);
+}
+
+void JniOcResource::unsetHeaderOptions()
+{
+    m_impl->unsetHeaderOptions();
+}
+
+std::string JniOcResource::host()
+{
+    return m_impl->host();
+}
+
+std::string JniOcResource::uri()
+{
+    return m_impl->uri();
+}
+
+OCConnectivityType JniOcResource::connectivityType() const
+{
+    return m_impl->connectivityType();
+}
+
+bool JniOcResource::isObservable()
+{
+    return m_impl->isObservable();
+}
+
+std::vector< std::string > JniOcResource::getResourceTypes() const
+{
+    return m_impl->getResourceTypes();
+}
+
+std::vector< std::string > JniOcResource::getResourceInterfaces(void) const
+{
+    return m_impl->getResourceInterfaces();
+}
+
+OCResourceIdentifier JniOcResource::uniqueIdentifier() const
+{
+    return m_impl->uniqueIdentifier();
+}
+
+std::string JniOcResource::sid() const
+{
+    return m_impl->sid();
+}
+
+std::string JniOcResource::deviceName() const
+{
+    return m_impl->deviceName();
+}
+
+std::shared_ptr<OCResource> JniOcResource::getOCResource()
+{
+    return m_impl->getOCResource();
+}
+
+JniOcResource* JniOcResource::getJniOcResourcePtr(JNIEnv *env, jobject thiz)
+{
+    JniOcResource *resource = GetHandle<JniOcResource>(env, thiz);
+    if (env->ExceptionCheck())
+    {
+        LOGE("Failed to get native handle from OcResource");
+    }
+    if (!resource)
+    {
+        ThrowOcException(JNI_NO_NATIVE_POINTER, "");
+    }
+    return resource;
+}
+
+#ifdef WITH_MQ
+OCStackResult JniOcResource::discoveryMQTopics(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->discoveryMQTopics(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::createMQTopic(JNIEnv* env,
+    const OCRepresentation &representation, const std::string &targetUri,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->createMQTopic(env, representation, targetUri, queryParametersMap, jListener, QoS);
+}
+#endif
+#ifdef MQ_SUBSCRIBER
+OCStackResult JniOcResource::subscribeMQTopic(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->subscribeMQTopic(env, queryParametersMap, jListener, QoS);
+}
+
+OCStackResult JniOcResource::unsubscribeMQTopic(QualityOfService QoS)
+{
+    return m_impl->unsubscribeMQTopic(QoS);
+}
+
+OCStackResult JniOcResource::requestMQPublish(JNIEnv* env,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return  m_impl->requestMQPublish(env, queryParametersMap, jListener, QoS);
+}
+#endif
+#ifdef MQ_PUBLISHER
+OCStackResult JniOcResource::publishMQTopic(JNIEnv* env, const OCRepresentation &representation,
+    const QueryParamsMap &queryParametersMap, jobject jListener, QualityOfService QoS)
+{
+    return m_impl->publishMQTopic(env, representation, queryParametersMap, jListener, QoS);
+}
+#endif
+
 /*
 * Class:     org_iotivity_base_OcResource
 * Method:    get
index e05da82..5ed1e39 100644 (file)
 
 using namespace OC;
 
+class JniOcResourceImpl;
 class JniOcResource
 {
 public:
-    JniOcResource(std::shared_ptr<OCResource> resource);
-    ~JniOcResource();
+    JniOcResource(std::shared_ptr<OCResource> &resource);
+    ~JniOcResource() = default;
 
     OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener);
     OCStackResult get(JNIEnv* env, const QueryParamsMap &queryParametersMap, jobject jListener,
@@ -94,29 +95,11 @@ public:
     std::string sid() const;
     std::string deviceName() const;
 
-    JniOnGetListener* addOnGetListener(JNIEnv* env, jobject jListener);
-    JniOnPutListener* addOnPutListener(JNIEnv* env, jobject jListener);
-    JniOnPostListener* addOnPostListener(JNIEnv* env, jobject jListener);
-    JniOnDeleteListener* addOnDeleteListener(JNIEnv* env, jobject jListener);
-    JniOnObserveListener* addOnObserveListener(JNIEnv* env, jobject jListener);
-
-    void removeOnGetListener(JNIEnv* env, jobject jListener);
-    void removeOnPutListener(JNIEnv* env, jobject jListener);
-    void removeOnPostListener(JNIEnv* env, jobject jListener);
-    void removeOnDeleteListener(JNIEnv* env, jobject jListener);
-    void removeOnObserveListener(JNIEnv* env, jobject jListener);
-
     std::shared_ptr<OCResource> getOCResource();
 
     static JniOcResource* getJniOcResourcePtr(JNIEnv *env, jobject thiz);
 
 #ifdef WITH_MQ
-    JniOnMQTopicFoundListener* addOnTopicFoundListener(JNIEnv* env, jobject jListener);
-    void removeOnTopicFoundListener(JNIEnv* env, jobject jListener);
-
-    JniOnMQSubscribeListener* addOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
-    void removeOnMQTopicSubscribeListener(JNIEnv* env, jobject jListener);
-
     OCStackResult discoveryMQTopics(JNIEnv* env, const QueryParamsMap &queryParametersMap,
                                     jobject jListener, QualityOfService QoS);
     OCStackResult createMQTopic(JNIEnv* env, const OCRepresentation &representation,
@@ -138,17 +121,7 @@ public:
 #endif
 
 private:
-    JniListenerManager<JniOnGetListener> m_onGetManager;
-    JniListenerManager<JniOnPutListener> m_onPutManager;
-    JniListenerManager<JniOnPostListener> m_onPostManager;
-    JniListenerManager<JniOnDeleteListener> m_onDeleteManager;
-    JniListenerManager<JniOnObserveListener> m_onObserveManager;
-#ifdef WITH_MQ
-    JniListenerManager<JniOnMQTopicFoundListener> m_onFoundTopicResourceManager;
-    JniListenerManager<JniOnMQSubscribeListener> m_onSubcribeTopicManager;
-#endif
-
-    std::shared_ptr<OCResource> m_sharedResource;
+    std::shared_ptr<JniOcResourceImpl> m_impl;
 };
 
 /* DO NOT EDIT THIS FILE BEYOND THIS LINE - it is machine generated */
index db5ea1e..cc530d6 100644 (file)
@@ -163,7 +163,8 @@ extern jmethodID g_mid_OcOicSecPdAcl_get_periods;
 extern jmethodID g_mid_OcOicSecPdAcl_get_recurrences;
 
 
-typedef void(*RemoveListenerCallback)(JNIEnv* env, jobject jListener);
+//typedef void(*RemoveListenerCallback)(JNIEnv* env, jobject jListener);
+typedef std::function<void(JNIEnv* env, jobject jListener)> RemoveListenerCallback;
 
 static jfieldID GetHandleField(JNIEnv *env, jobject jobj)
 {
index bb0f5db..31749c5 100644 (file)
 #include "JniOnDeleteListener.h"
 #include "JniOcResource.h"
 #include "JniUtils.h"
-#ifdef WITH_CLOUD
-#include "JniOcAccountManager.h"
-#endif
 
-JniOnDeleteListener::JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcResource* owner)
-    : m_ownerResource(owner)
+JniOnDeleteListener::JniOnDeleteListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
-#ifdef WITH_CLOUD
-    m_ownerAccountManager = nullptr;
-#endif
 }
 
-#ifdef WITH_CLOUD
-JniOnDeleteListener::JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner)
-    : m_ownerAccountManager(owner)
-{
-    m_jwListener = env->NewWeakGlobalRef(jListener);
-    m_ownerResource = nullptr;
-}
-#endif
-
 JniOnDeleteListener::~JniOnDeleteListener()
 {
     if (m_jwListener)
@@ -158,33 +143,11 @@ void JniOnDeleteListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnDeleteListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnDeleteListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnDeleteListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnDeleteListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnDeleteListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnDeleteListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
     }
 }
index 9354232..4a2be30 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-#ifdef WITH_CLOUD
-class JniOcAccountManager;
-#endif
-
 class JniOnDeleteListener
 {
 public:
-    JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcResource* owner);
-#ifdef WITH_CLOUD
-    JniOnDeleteListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner);
-#endif
+
+    JniOnDeleteListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnDeleteListener();
 
     void onDeleteCallback(const HeaderOptions&, const int eCode);
 
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
-#ifdef WITH_CLOUD
-    JniOcAccountManager* m_ownerAccountManager;
-#endif
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index 9a801f1..b8d2273 100644 (file)
 #include "JniOcResource.h"
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
-#ifdef WITH_CLOUD
-#include "JniOcAccountManager.h"
-#endif
 
-JniOnGetListener::JniOnGetListener(JNIEnv *env, jobject jListener, JniOcResource* owner)
-    : m_ownerResource(owner)
+JniOnGetListener::JniOnGetListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
-#ifdef WITH_CLOUD
-    m_ownerAccountManager = nullptr;
-#endif
 }
 
-#ifdef WITH_CLOUD
-JniOnGetListener::JniOnGetListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner)
-    : m_ownerAccountManager(owner)
-{
-    m_jwListener = env->NewWeakGlobalRef(jListener);
-    m_ownerResource = nullptr;
-}
-#endif
-
 JniOnGetListener::~JniOnGetListener()
 {
     LOGD("~JniOnGetListener");
@@ -184,33 +169,11 @@ void JniOnGetListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnGetListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnGetListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnGetListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnGetListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnGetListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnGetListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
     }
 }
index abffaa0..09b4d7b 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-#ifdef WITH_CLOUD
-class JniOcAccountManager;
-#endif
-
 class JniOnGetListener
 {
 public:
-    JniOnGetListener(JNIEnv *env, jobject listener, JniOcResource* resource);
-#ifdef WITH_CLOUD
-    JniOnGetListener(JNIEnv *env, jobject listener, JniOcAccountManager* resource);
-#endif
+
+    JniOnGetListener(JNIEnv *env, jobject listener, RemoveListenerCallback removeListener);
     ~JniOnGetListener();
     void onGetCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
 
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
-#ifdef WITH_CLOUD
-    JniOcAccountManager* m_ownerAccountManager;
-#endif
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index 705f644..fdcbfb6 100644 (file)
@@ -25,8 +25,8 @@
 
 JniOnMQSubscribeListener::JniOnMQSubscribeListener(JNIEnv *env,
                                                    jobject jListener,
-                                                   JniOcResource* owner)
-    : m_ownerResource(owner)
+                                                   RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
 }
@@ -198,11 +198,11 @@ void JniOnMQSubscribeListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-        m_ownerResource->removeOnMQTopicSubscribeListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-        m_ownerResource->removeOnMQTopicSubscribeListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
     }
 }
index 6b7c059..c4929b4 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-
 class JniOnMQSubscribeListener
 {
 public:
-    JniOnMQSubscribeListener(JNIEnv *env, jobject jListener, JniOcResource* owner);
+    JniOnMQSubscribeListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnMQSubscribeListener();
     void onSubscribeCallback(const HeaderOptions headerOptions, const OCRepresentation& rep,
         const int& eCode, const int& sequenceNumber);
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index 6fb1845..8888ee9 100644 (file)
@@ -24,8 +24,8 @@
 #include "JniUtils.h"
 
 JniOnMQTopicFoundListener::JniOnMQTopicFoundListener(JNIEnv *env, jobject jListener,
-                                                     JniOcResource* owner)
-    : m_ownerResource(owner)
+                                                     RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
 }
@@ -255,11 +255,11 @@ void JniOnMQTopicFoundListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-        m_ownerResource->removeOnTopicFoundListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-        m_ownerResource->removeOnTopicFoundListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
     }
 }
index 45b73a0..3dda033 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-
 class JniOnMQTopicFoundListener
 {
 public:
-    JniOnMQTopicFoundListener(JNIEnv *env, jobject jListener, JniOcResource* owner);
+    JniOnMQTopicFoundListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnMQTopicFoundListener();
 
     void foundTopicCallback(const int eCode, const std::string& uri,
@@ -39,7 +37,7 @@ public:
 
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv* env);
 };
 
index 060b19e..ce27374 100644 (file)
 #include "JniOcResource.h"
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
-#ifdef WITH_CLOUD
-#include "JniOcAccountManager.h"
-#endif
 
 #define CA_OBSERVE_MAX_SEQUENCE_NUMBER 0xFFFFFF
 
-JniOnObserveListener::JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcResource* owner)
-    : m_ownerResource(owner)
+JniOnObserveListener::JniOnObserveListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
-#ifdef WITH_CLOUD
-    m_ownerAccountManager = nullptr;
-#endif
 }
 
-#ifdef WITH_CLOUD
-JniOnObserveListener::JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner)
-    : m_ownerAccountManager(owner)
-{
-    m_jwListener = env->NewWeakGlobalRef(jListener);
-    m_ownerResource = nullptr;
-}
-#endif
-
 JniOnObserveListener::~JniOnObserveListener()
 {
     if (m_jwListener)
@@ -166,18 +151,7 @@ void JniOnObserveListener::onObserveCallback(const HeaderOptions headerOptions,
             env->DeleteLocalRef(jHeaderOptionList);
             jthrowable ex = env->ExceptionOccurred();
             env->ExceptionClear();
-#ifndef WITH_CLOUD
-            m_ownerResource->removeOnObserveListener(env, m_jwListener);
-#else
-            if (nullptr != m_ownerResource)
-            {
-                m_ownerResource->removeOnObserveListener(env, m_jwListener);
-            }
-            if (nullptr != m_ownerAccountManager)
-            {
-                m_ownerAccountManager->removeOnObserveListener(env, m_jwListener);
-            }
-#endif
+            m_removeListener(env, m_jwListener);
             env->Throw((jthrowable)ex);
         }
 
@@ -213,34 +187,12 @@ void JniOnObserveListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnObserveListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnObserveListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnObserveListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnObserveListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnObserveListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnObserveListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
     }
 }
 
index 3fc478d..38b0b18 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-#ifdef WITH_CLOUD
-class JniOcAccountManager;
-#endif
-
 class JniOnObserveListener
 {
 public:
-    JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcResource* owner);
-#ifdef WITH_CLOUD
-    JniOnObserveListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner);
-#endif
+    JniOnObserveListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnObserveListener();
     void onObserveCallback(const HeaderOptions headerOptions, const OCRepresentation& rep,
         const int& eCode, const int& sequenceNumber);
     jweak getJWListener();
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
-#ifdef WITH_CLOUD
-    JniOcAccountManager* m_ownerAccountManager;
-#endif
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index 62f6e96..b11c376 100644 (file)
 #include "JniOcResource.h"
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
-#ifdef WITH_CLOUD
-#include "JniOcAccountManager.h"
-#endif
 
-JniOnPostListener::JniOnPostListener(JNIEnv *env, jobject jListener, JniOcResource* owner)
-    : m_ownerResource(owner)
+JniOnPostListener::JniOnPostListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
-#ifdef WITH_CLOUD
-    m_ownerAccountManager = nullptr;
-#endif
 }
 
-#ifdef WITH_CLOUD
-JniOnPostListener::JniOnPostListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner)
-    : m_ownerAccountManager(owner)
-{
-    m_jwListener = env->NewWeakGlobalRef(jListener);
-    m_ownerResource = nullptr;
-}
-#endif
-
 JniOnPostListener::~JniOnPostListener()
 {
     if (m_jwListener)
@@ -183,33 +168,11 @@ void JniOnPostListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnPostListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnPostListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnPostListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-#ifndef WITH_CLOUD
-        m_ownerResource->removeOnPostListener(env, m_jwListener);
-#else
-        if (nullptr != m_ownerResource)
-        {
-            m_ownerResource->removeOnPostListener(env, m_jwListener);
-        }
-        if (nullptr != m_ownerAccountManager)
-        {
-            m_ownerAccountManager->removeOnPostListener(env, m_jwListener);
-        }
-#endif
+        m_removeListener(env, m_jwListener);
     }
 }
index bf3387c..c4e30f1 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-#ifdef WITH_CLOUD
-class JniOcAccountManager;
-#endif
-
 class JniOnPostListener
 {
 public:
-    JniOnPostListener(JNIEnv *env, jobject jListener, JniOcResource* owner);
-#ifdef WITH_CLOUD
-    JniOnPostListener(JNIEnv *env, jobject jListener, JniOcAccountManager* owner);
-#endif
+    JniOnPostListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnPostListener();
 
     void onPostCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
 
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
-#ifdef WITH_CLOUD
-    JniOcAccountManager* m_ownerAccountManager;
-#endif
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index 5e2dd4a..6a4d147 100644 (file)
@@ -24,8 +24,8 @@
 #include "JniOcRepresentation.h"
 #include "JniUtils.h"
 
-JniOnPutListener::JniOnPutListener(JNIEnv *env, jobject jListener, JniOcResource* owner)
-    : m_ownerResource(owner)
+JniOnPutListener::JniOnPutListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener)
+    : m_removeListener(removeListener)
 {
     m_jwListener = env->NewWeakGlobalRef(jListener);
 }
@@ -168,11 +168,11 @@ void JniOnPutListener::checkExAndRemoveListener(JNIEnv* env)
     {
         jthrowable ex = env->ExceptionOccurred();
         env->ExceptionClear();
-        m_ownerResource->removeOnPutListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
         env->Throw((jthrowable)ex);
     }
     else
     {
-        m_ownerResource->removeOnPutListener(env, m_jwListener);
+        m_removeListener(env, m_jwListener);
     }
 }
index 80057e1..e8fccaf 100644 (file)
 
 using namespace OC;
 
-class JniOcResource;
-
 class JniOnPutListener
 {
 public:
-    JniOnPutListener(JNIEnv *env, jobject jListener, JniOcResource* resource);
+    JniOnPutListener(JNIEnv *env, jobject jListener, RemoveListenerCallback removeListener);
     ~JniOnPutListener();
-
     void onPutCallback(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode);
 
+
+
 private:
     jweak m_jwListener;
-    JniOcResource* m_ownerResource;
+    RemoveListenerCallback m_removeListener;
     void checkExAndRemoveListener(JNIEnv *env);
 };
 
index d308bea..b983120 100755 (executable)
@@ -1,3 +1,21 @@
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1359
+   
+commit_info_2018-12-05.txt
+commit_id: 1929cb2f5ba51de21343857dc30dcefa370a6f80
+---------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1358
+
+commit_info_2018-11-28.txt
+
+commit_id: 80cddcb478a802a2d7b6705eeb0624caca15d660 
+---------------------------------------------------------------------------------------------------------------------------------
+http://suprem.sec.samsung.net/jira/browse/CONPRO-1357
+
+commit_info_2018-11-22.txt
+
+commit_id: b5974992e15c5b95e6db4c8f3c905adc9d1560f9 
+---------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1349
 
 commit_info_2018-11-02.txt
@@ -74,13 +92,13 @@ http://suprem.sec.samsung.net/jira/browse/CONPRO-1279
 
 commit_info_2018-04-18.txt
 
-commit_id: 285875048bda46b6ac1a742c25849d70234d7cd1
+commit_id: 285875048bda46b6ac1a742c25849d70234d7cd1 
 ----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1275
 
 commit_info_2018-04-12.txt
 
-commit_id: 22079af2bd0f22a80b98c3b17469c3b8ed601ede
+commit_id: 22079af2bd0f22a80b98c3b17469c3b8ed601ede 
 ----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1268
 
@@ -104,19 +122,19 @@ http://suprem.sec.samsung.net/jira/browse/CONPRO-1247
 
 commit_info_2018-03-07.txt
 
-commit_id: 2a37bbe4849a4d147ed4a7e148b78ab40eb181aa 
+commit_id: 2a37bbe4849a4d147ed4a7e148b78ab40eb181aa
 ----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1243
 
 commit_info_2018-02-28.txt
 
-commit_id: e5ace7ad29ce01019f79c00bdb3bdbd16f5fbf49 
+commit_id: e5ace7ad29ce01019f79c00bdb3bdbd16f5fbf49
 ----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1237
 
 commit_info_2018-02-21.txt
 
-commit_id: aa7649f561c5e2d806aa4bd6aa94d258da6f7433 
+commit_id: aa7649f561c5e2d806aa4bd6aa94d258da6f7433
 ----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1230
 
@@ -160,29 +178,6 @@ commit_info_2018-01-04.txt
 
 commit_id: a0593f6d08f74d736d39523f93b16077a5f6e659
 ----------------------------------------------------------------------------------------------------------------------------------
-http://suprem.sec.samsung.net/jira/browse/CONPRO-1176
-
-[CONPRO-1176] iotivity crash during CAReceiveMessage
-
- - manually patched from below pull request because of VD PVR schedule
-
- - https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/215
-----------------------------------------------------------------------------------------------------------------------------------
-[CONPRO-1172] allocates too much memory
-
- - rollback a patch to solve segmentation fault issue
-
- - https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/206(rollback)
-----------------------------------------------------------------------------------------------------------------------------------
-http://suprem.sec.samsung.net/jira/browse/CONPRO-1172
-
-[CONPRO-1172] allocates too much memory
-
- - manually patched from below 2 pull requests because of VD PVR schedule
-
- - https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/206
- - https://github.sec.samsung.net/RS7-IOTIVITY/IoTivity/pull/209
-----------------------------------------------------------------------------------------------------------------------------------
 http://suprem.sec.samsung.net/jira/browse/CONPRO-1169
 
 commit_info_2017-12-20.txt
index 736541d..c891460 100644 (file)
@@ -33,6 +33,7 @@
 #endif //__WITH_DTLS__ or __WITH_TLS__
 #include "cacommon.h"
 #include "byte_array.h"
+#include "octypes.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -73,6 +74,24 @@ typedef enum
 }CASslEkcbProtocol_t;
 
 /**
+ *@enum CACertificateVerificationStatus_t
+ * type of certificate status info to be used when invoking
+ * certificate verification status info callback
+ */
+typedef enum
+{
+    CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL = 0,
+    CA_CERTIFICATE_VERIFY_NO_CERT,
+    CA_CERTIFICATE_VERIFY_FAILED
+} CACertificateVerificationStatus_t;
+
+/**
+ * Callback function type for certificate verification status.
+ * @param[in]   status      Certificate verification status info.
+ */
+typedef void (*CertificateVerificationCallback_t)(CACertificateVerificationStatus_t status);
+
+/**
  * This internal callback is used by CA layer to
  * retrieve PSK credentials from SRM.
  *
@@ -354,6 +373,16 @@ typedef void (*SslExportKeysCallback_t)(const unsigned char* masterSecret,
 CAResult_t CASetSslExportKeysCallback(SslExportKeysCallback_t exportKeysCb,
                                       CASslEkcbProtocol_t protocol, CASslEkcbRole_t role);
 
+/**
+ * API to set certificate verification callback.
+ */
+void CAsetCertificateVerificationCallback(CertificateVerificationCallback_t noCertCallback);
+
+/**
+ * API to unset certificate verification callback.
+ */
+void CAunsetCertificateVerificationCallback();
+
 #endif //__WITH_TLS__ or __WITH_DTLS__
 
 
index 9b117cd..187d23c 100644 (file)
@@ -36,6 +36,7 @@
 #include "ocrandom.h"
 #include "byte_array.h"
 #include "octhread.h"
+#include "octypes.h"
 #include "timer.h"
 
 
@@ -519,6 +520,11 @@ static CAgetCredentialTypesHandler g_getCredentialTypesCallback = NULL;
 static CAgetPkixInfoHandler g_getPkixInfoCallback = NULL;
 
 /**
+ * Callback to inform in case of client's certificate absence
+ */
+static CertificateVerificationCallback_t g_CertificateVerificationCallback = NULL;
+
+/**
  * @var g_setupPkContextCallback
  *
  * @brief callback to setup PK context handler for H/W based Public Key Infrastructure
@@ -614,6 +620,20 @@ void CAsetCredentialTypesCallback(CAgetCredentialTypesHandler credTypesCallback)
     OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
 }
 
+void CAsetCertificateVerificationCallback(CertificateVerificationCallback_t certVerifyStatusCallback)
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    g_CertificateVerificationCallback = certVerifyStatusCallback;
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+}
+
+void CAunsetCertificateVerificationCallback()
+{
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+    g_CertificateVerificationCallback = NULL;
+    OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+}
+
 static int GetAdapterIndex(CATransportAdapter_t adapter)
 {
     switch (adapter)
@@ -2340,7 +2360,6 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
         return CA_STATUS_FAILED;
     }
 
-
     SslEndPoint_t * peer = GetSslPeer(&sep->endpoint);
     if (NULL == peer)
     {
@@ -2426,6 +2445,22 @@ CAResult_t CAdecryptSsl(const CASecureEndpoint_t *sep, uint8_t *data, uint32_t d
                 void * userIdPos = NULL;
                 const mbedtls_x509_crt * peerCert = mbedtls_ssl_get_peer_cert(&peer->ssl);
                 ret = (NULL == peerCert ? -1 : 0);
+                if (g_CertificateVerificationCallback)
+                {
+                    uint32_t flags = mbedtls_ssl_get_verify_result(&peer->ssl);
+                    if (!flags)
+                    {
+                        g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL);
+                    }
+                    else if (MBEDTLS_X509_BADCERT_MISSING == flags)
+                    {
+                        g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_NO_CERT);
+                    }
+                    else
+                    {
+                        g_CertificateVerificationCallback(CA_CERTIFICATE_VERIFY_FAILED);
+                    }
+                }
                 //SSL_CHECK_FAIL(peer, ret, "Failed to retrieve cert", 1,
                 //                            CA_STATUS_FAILED, MBEDTLS_SSL_ALERT_MSG_NO_CERT);
                 if (0 == ret)
index 94b4f6e..2a6c02d 100755 (executable)
@@ -1180,8 +1180,11 @@ static void CALEServerSendDataThread(void *threadData)
         return;
     }
 
-#if defined(__ANDROID__)
+#if defined(__TIZEN__) || defined(__ANDROID__)
     // get MTU size
+    OIC_LOG_V(INFO, CALEADAPTER_TAG, "Get MTU size using API");
+
+
     g_mtuSize = CALEServerGetMtuSize(bleData->remoteEndpoint->addr);
 #endif
     OIC_LOG_V(INFO, CALEADAPTER_TAG, "MTU size [%d]", g_mtuSize);
index 01c8248..3d59fdb 100644 (file)
@@ -27,7 +27,7 @@ if 'MCD' in division:
                'caleutil.c',
                'calenwmonitor.c']
 elif 'VD' in division:
-    src_files = [ 'caleclient.c',
+    src_files = [ 'caleclient_vd.c',
                'caleserver_vd.c',
                'caleutil.c',
                'calenwmonitor_vd.c']
index 87c47b8..6884a8e 100644 (file)
@@ -1539,3 +1539,36 @@ exit:
     OIC_LOG(DEBUG, TAG, "OUT ");
     return CA_STATUS_OK;
 }
+
+bool CALEClientIsConnected(const char* address)
+{
+    (void)address;
+    //@Todo
+    return true;
+}
+
+uint16_t CALEClientGetMtuSize(const char* address)
+{
+    VERIFY_NON_NULL_RET(address, TAG, "address is null", CA_DEFAULT_BLE_MTU_SIZE);
+    //@Todo
+    //it should be implemented after update Tizen 3.0
+    return CA_DEFAULT_BLE_MTU_SIZE;
+}
+
+CAResult_t CALEClientSetMtuSize(const char* address, uint16_t mtuSize)
+{
+    (void)mtuSize;
+
+    VERIFY_NON_NULL(address, TAG, "address is null");
+    //@Todo
+    //it should be implemented after update Tizen 3.0
+    return CA_NOT_SUPPORTED;
+}
+
+CAResult_t CALEClientSendNegotiationMessage(const char* address)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEClientSendNegotiationMessage(%s)", address);
+    //@Todo
+    //it will be implemented when tizen public 3.0 is released.
+    return CA_NOT_SUPPORTED;
+}
\ No newline at end of file
index e967513..f3aac22 100644 (file)
@@ -79,6 +79,8 @@ void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s
  */
 void CAStartTimerThread(void *data);
 
+void CALEClientScanThread();
+
 /**
  * Used to initialize all required mutex variable for Gatt Client implementation.
  *
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient_vd.c b/resource/csdk/connectivity/src/bt_le_adapter/tizen/caleclient_vd.c
new file mode 100644 (file)
index 0000000..2e2ea1e
--- /dev/null
@@ -0,0 +1,1542 @@
+/* ****************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* 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.
+*
+******************************************************************/
+
+#include "caleclient.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <gio/gio.h>
+
+#include "octhread.h"
+#include "uarraylist.h"
+#include "caqueueingthread.h"
+#include "caadapterutils.h"
+#include "cagattservice.h"
+#include "oic_string.h"
+#include "oic_malloc.h"
+
+/**
+ * Logging tag for module name.
+ */
+#define TAG "OIC_CA_LE_CLIENT"
+
+#define MICROSECS_PER_SEC 1000000
+#define WAIT_TIME_WRITE_CHARACTERISTIC 10 * MICROSECS_PER_SEC
+
+//For custom uuid ble server
+#define CA_GATT_CUSTOM_UUID "4209"
+#define CA_GATT_CUSTOM_UUID2 "4204"
+#define CUSTOM_UUID_LEN 4
+
+static const int samsung_code = 117;
+
+uint64_t const TIMEOUT = 30 * MICROSECS_PER_SEC;
+
+/**
+ * Flag to check if scanning is in progress
+ */
+static bool g_isScanningInProgress = false;
+
+/**
+ * Mutex to synchronize access to g_isScanningInProgress
+ */
+static oc_mutex g_isScanningInProgressMutex = NULL;
+
+/**
+ * Flag to check if connection is in progress
+ */
+static bool g_isConnectionInProgress = false;
+
+/**
+ * Mutex to synchronize access to g_isConnectionInProgress
+ */
+static oc_mutex g_isConnectionInProgressMutex = NULL;
+
+/**
+ * Flag to check if multicast is already in progress.
+ */
+static bool g_isMulticastInProgress = false;
+
+/**
+ * Flag to check if unicast scan is in progress
+ */
+static bool g_isUnicastScanInProgress = false;
+
+/**
+ * Mutex to synchronize access to g_isMulticastInProgress
+ * and g_isUnicastScanInProgress
+ */
+static oc_mutex g_scanMutex = NULL;
+
+/**
+ * Pending multicast data list to be sent.
+ */
+static u_arraylist_t *g_multicastDataList = NULL;
+
+/**
+ * Mutex to synchronize the access to Pending multicast data list.
+ */
+static oc_mutex g_multicastDataListMutex = NULL;
+
+/**
+ * Condition to start the timer for scanning.
+ */
+static oc_cond g_startTimerCond = NULL;
+
+/**
+ * Condition for scanning Time interval.
+ */
+static oc_cond g_scanningTimeCond = NULL;
+
+/**
+ * This contains the list of OIC services a client connect tot.
+ */
+static LEServerInfoList *g_LEServerList = NULL;
+
+/**
+ * Mutex to synchronize access to BleServiceList.
+ */
+static oc_mutex g_LEServerListMutex = NULL;
+
+/**
+ * Boolean variable to keep the state of the GATT Client.
+ */
+static bool g_isLEGattClientStarted = false;
+
+/**
+ * Mutex to synchronize access to the requestResponse callback to be called
+ * when the data needs to be sent from GATTClient.
+ */
+static oc_mutex g_LEReqRespClientCbMutex = NULL;
+
+/**
+ * Mutex to synchronize access to the requestResponse callback to be called
+ * when the data needs to be sent from GATTClient.
+ */
+static oc_mutex g_LEClientConnectMutex = NULL;
+
+/**
+ * Mutex to synchronize the calls to be done to the platform from GATTClient
+ * interfaces from different threads.
+ */
+static oc_mutex g_LEClientStateMutex = NULL;
+
+/**
+ * Mutex to synchronize the task to be pushed to thread pool.
+ */
+static oc_mutex g_LEClientThreadPoolMutex = NULL;
+
+/**
+ * Mutex to synchronize the task to write characteristic one packet after another.
+ */
+static oc_mutex g_threadWriteCharacteristicMutex = NULL;
+
+/**
+ * Condition for Writing characteristic.
+ */
+static oc_cond g_threadWriteCharacteristicCond = NULL;
+
+/**
+ * Flag to check status of write characteristic.
+ */
+static bool g_isSignalSetFlag = false;
+
+/**
+ * Maintains the callback to be notified on receival of network packets from other
+ *           BLE devices
+ */
+static CABLEDataReceivedCallback g_LEClientDataReceivedCallback = NULL;
+
+/**
+ * callback to update the error to le adapter
+ */
+static CABLEErrorHandleCallback g_clientErrorCallback;
+
+/**
+ * gmainLoop to manage the threads to receive the callback from the platfrom.
+ */
+static GMainLoop *g_eventLoop = NULL;
+
+/**
+ * Reference to threadpool
+ */
+static ca_thread_pool_t g_LEClientThreadPool = NULL;
+
+void CALEGattCharacteristicChangedCb(bt_gatt_h characteristic,
+                                     char *value,
+                                     int valueLen, void *userData)
+{
+    (void)characteristic;
+
+    OIC_LOG(DEBUG, TAG, "IN");
+    OIC_LOG_V(DEBUG, TAG, "Changed characteristic value length [%d]", valueLen);
+
+    oc_mutex_lock(g_LEReqRespClientCbMutex);
+    if (NULL == g_LEClientDataReceivedCallback)
+    {
+        OIC_LOG(ERROR, TAG, "Request response callback is not set");
+        oc_mutex_unlock(g_LEReqRespClientCbMutex);
+        return;
+    }
+
+    uint32_t sentLength = 0;
+    g_LEClientDataReceivedCallback(userData, (uint8_t *)value, valueLen, &sentLength);
+
+    OIC_LOG_V(DEBUG, TAG, "Recv data Length is %d", sentLength);
+
+    oc_mutex_unlock(g_LEReqRespClientCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CALEGattCharacteristicWriteCb(int result, bt_gatt_h reqHandle, void *userData)
+{
+    (void)reqHandle;
+    (void)userData;
+
+    OIC_LOG(DEBUG, TAG, "IN ");
+
+    if (BT_ERROR_NONE != result)
+    {
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           false, "writeChar failure");
+
+        OIC_LOG(ERROR, TAG, "Write failed Need Retry ");
+        //Need to Implement retry mechanism
+    }
+    else
+    {
+        oc_mutex_lock(g_threadWriteCharacteristicMutex);
+        OIC_LOG(DEBUG, TAG, "g_isSignalSetFlag is set true and signal");
+        g_isSignalSetFlag = true;
+        oc_cond_signal(g_threadWriteCharacteristicCond);
+        oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+        CALogSendStateInfo(CA_ADAPTER_GATT_BTLE, "", 0, -1,
+                           true, "writeChar success");
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT ");
+}
+
+CAResult_t CALEGattInitiateConnection(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_isConnectionInProgressMutex);
+    if (g_isConnectionInProgress)
+    {
+        oc_mutex_unlock(g_isConnectionInProgressMutex);
+        OIC_LOG(DEBUG, TAG, "Connection already in progress, cannot initiate new connection");
+        return CA_STATUS_FAILED;
+    }
+    g_isConnectionInProgress = true;
+    oc_mutex_unlock(g_isConnectionInProgressMutex);
+
+    // Pause the scanning
+    CALEGattStopDeviceScanning();
+
+    OIC_LOG_V(DEBUG, TAG,
+              "Trying to do Gatt connection to [%s]", remoteAddress);
+
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
+    if (NULL == g_LEClientThreadPool)
+    {
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
+        return CA_STATUS_FAILED;
+    }
+
+    char *addr = OICStrdup(remoteAddress);
+    if (NULL == addr)
+    {
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        OIC_LOG(ERROR, TAG, "OICStrdup failed");
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t res = ca_thread_pool_add_task(g_LEClientThreadPool, CAGattConnectThread, addr, NULL);
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "ca_thread_pool_add_task failed with ret [%d]", res);
+        OICFree(addr);
+        return CA_STATUS_FAILED;
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEGattConnectionStateChanged(bool connected, const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN ");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
+
+    if (!connected)
+    {
+        OIC_LOG_V(DEBUG, TAG, "DisConnected from [%s] ", remoteAddress);
+        oc_mutex_lock(g_LEServerListMutex);
+        CARemoveLEServerInfoFromList(&g_LEServerList, remoteAddress);
+        oc_mutex_unlock(g_LEServerListMutex);
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, TAG, "Connected to [%s] ", remoteAddress);
+
+        oc_mutex_lock(g_isConnectionInProgressMutex);
+        g_isConnectionInProgress = false;
+        oc_mutex_unlock(g_isConnectionInProgressMutex);
+
+
+        // TODO:Disabling scanning for now.Need to check.
+        /*oc_mutex_lock(g_scanMutex);
+        if (g_isMulticastInProgress || g_isUnicastScanInProgress)
+        {
+            CAResult_t ret = CALEGattStartDeviceScanning();
+            if (CA_STATUS_OK != ret)
+            {
+                OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
+            }
+        }
+        oc_mutex_unlock(g_scanMutex);
+*/
+        LEServerInfo *serverInfo = NULL;
+        oc_mutex_lock(g_LEServerListMutex);
+        if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
+        {
+            oc_mutex_unlock(g_LEServerListMutex);
+            OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
+            return;
+        }
+
+        serverInfo->status = LE_STATUS_CONNECTED;
+        oc_mutex_unlock(g_LEServerListMutex);
+
+        oc_mutex_lock(g_LEClientThreadPoolMutex);
+        if (NULL == g_LEClientThreadPool)
+        {
+            oc_mutex_unlock(g_LEClientThreadPoolMutex);
+            OIC_LOG(ERROR, TAG, "g_LEClientThreadPool is NULL");
+            return;
+        }
+
+        char *addr = OICStrdup(remoteAddress);
+        if (NULL == addr)
+        {
+            oc_mutex_unlock(g_LEClientThreadPoolMutex);
+            OIC_LOG(ERROR, TAG, "addr is NULL");
+            return;
+        }
+
+        CAResult_t ret = ca_thread_pool_add_task(g_LEClientThreadPool, CADiscoverLEServicesThread,
+                                                 addr, NULL);
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, TAG, "ca_thread_pool_add_task failed with ret [%d]", ret);
+            OICFree(addr);
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+static bool CALEIsHaveServiceImpl(bt_adapter_le_device_scan_result_info_s *scanInfo,
+                                  const char *service_uuid,
+                                  bt_adapter_le_packet_type_e pkt_type)
+{
+    bool ret = false;
+    char **uuids = NULL;
+    int count = 0;
+    int result = 0;
+
+    result = bt_adapter_le_get_scan_result_service_uuids(scanInfo,
+             pkt_type, &uuids, &count);
+    if (result == BT_ERROR_NONE && NULL != uuids)
+    {
+        for (int i = 0; i < count; i++)
+        {
+            if (0 == strcasecmp(uuids[i], service_uuid))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Service[%s] Found in %s",
+                          uuids[i], scanInfo->remote_address);
+                ret = true;
+            }else if(0 == strncasecmp(uuids[i], service_uuid,CUSTOM_UUID_LEN))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Custom Service[%s] Found in %s",
+                          uuids[i], scanInfo->remote_address);
+                ret = true;
+            }
+            OICFree(uuids[i]);
+        }
+        OICFree(uuids);
+    }
+
+    if(ret == false){
+        char *man_data = NULL;
+        int man_data_len;
+        int man_id;
+        result = bt_adapter_le_get_scan_result_manufacturer_data(scanInfo,
+        pkt_type, &man_id, &man_data, &man_data_len);
+
+        if (result == BT_ERROR_NONE && NULL != man_data)
+        {
+            char *compare_man_data = OICMalloc((man_data_len*2)+1);
+            int pos =0;
+            for(int i=0;i<man_data_len;i++){
+                pos += sprintf(compare_man_data+pos, "%.2x", man_data[i]);
+            }
+            compare_man_data[man_data_len]='\0';
+            if (man_id == samsung_code && 0 == strncasecmp(compare_man_data, service_uuid, CUSTOM_UUID_LEN))
+            {
+                OIC_LOG_V(DEBUG, TAG, "Manufacture Data[%s] Found in %s",
+                                       compare_man_data, scanInfo->remote_address);
+                ret = true;
+            }
+            OICFree(compare_man_data);
+            OICFree(man_data);
+        }
+    }
+    return ret;
+}
+
+static bool CALEIsHaveService(bt_adapter_le_device_scan_result_info_s *scanInfo,
+                              const char *service_uuid)
+{
+    return
+        // For arduino servers, scan response will give the UUIDs advertised.
+        CALEIsHaveServiceImpl(scanInfo, service_uuid,
+                              BT_ADAPTER_LE_PACKET_SCAN_RESPONSE) ||
+        // For android/tizen servers, advertising packet will give the UUIDs.
+        CALEIsHaveServiceImpl(scanInfo, service_uuid,
+                              BT_ADAPTER_LE_PACKET_ADVERTISING);
+}
+
+void CALEAdapterScanResultCb(int result, bt_adapter_le_device_scan_result_info_s *scanInfo,
+                             void *userData)
+{
+    (void)userData;
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_VOID(scanInfo, TAG, "scanInfo");
+    VERIFY_NON_NULL_VOID(scanInfo->remote_address, TAG, "scanInfo->remote_address");
+
+    OIC_LOG_V(DEBUG, TAG, "Remote Address [%s]", scanInfo->remote_address);
+    OIC_LOG_V(DEBUG, TAG, "Scan Result [%d]", result);
+    OIC_LOG_V(DEBUG, TAG,
+              " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
+              scanInfo->adv_data_len, scanInfo->scan_data_len, scanInfo->rssi,
+              scanInfo->address_type);
+
+    // Check if scanning was stopped (since this callback is
+    // being triggered even after stopping the scan)
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (!g_isScanningInProgress)
+    {
+        oc_mutex_unlock(g_isScanningInProgressMutex);
+        OIC_LOG(DEBUG, TAG, "Scanning not in progress, so ignoring callback");
+        return;
+    }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
+
+    if (CALEIsHaveService(scanInfo, CA_GATT_SERVICE_UUID) ||
+        CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID)||
+        CALEIsHaveService(scanInfo, CA_GATT_CUSTOM_UUID2))
+    {
+        OIC_LOG_V(DEBUG, TAG, "Device [%s] supports OIC or custom service", scanInfo->remote_address);
+
+        LEServerInfo *serverInfo = NULL;
+        oc_mutex_lock(g_LEServerListMutex);
+        CAResult_t ret = CAGetLEServerInfo(g_LEServerList, scanInfo->remote_address, &serverInfo);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(DEBUG, TAG,
+                      "Newly discovered device with address [%s] ", scanInfo->remote_address);
+
+            char *addr = OICStrdup(scanInfo->remote_address);
+            if (NULL == addr)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Device address is NULL");
+                return;
+            }
+            serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
+            if (NULL == serverInfo)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Calloc failed");
+                OICFree(addr);
+                return;
+            }
+            serverInfo->remoteAddress = addr;
+            serverInfo->status = LE_STATUS_DISCOVERED;
+
+            if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", scanInfo->remote_address);
+                CAFreeLEServerInfo(serverInfo);
+                return;
+            }
+        }else {
+            OIC_LOG_V(DEBUG, TAG,
+                      "Device Present with address [%s] ", scanInfo->remote_address);
+
+            if(serverInfo->status == LE_STATUS_UNICAST_PENDING){
+                bt_gatt_client_h clientHandle = NULL;
+                int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
+                if (BT_ERROR_NONE != ret || NULL == clientHandle)
+                {
+                    OIC_LOG_V(ERROR, TAG,
+                              "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
+                    CALEGattDisConnect(serverInfo->remoteAddress);
+                    oc_mutex_unlock(g_LEServerListMutex);
+                    return ;
+                }
+                serverInfo->clientHandle = clientHandle;
+
+                serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
+                if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
+                {
+                    OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
+                    serverInfo->status = LE_STATUS_DISCOVERED;
+                    CADestroyLEDataList(&serverInfo->pendingDataList);
+                    oc_mutex_unlock(g_LEServerListMutex);
+                    return ;
+                 }
+             }
+         }
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetLEClientThreadPoolHandle(ca_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
+    g_LEClientThreadPool = handle;
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetLEReqRespClientCallback(CABLEDataReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_LEReqRespClientCbMutex);
+
+    g_LEClientDataReceivedCallback = callback;
+
+    oc_mutex_unlock(g_LEReqRespClientCbMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CASetBLEClientErrorHandleCallback(CABLEErrorHandleCallback callback)
+{
+    g_clientErrorCallback = callback;
+}
+
+CAResult_t CAStartLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_LEClientStateMutex);
+    if (true  == g_isLEGattClientStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Client is already running!!");
+        oc_mutex_unlock(g_LEClientStateMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    CAResult_t  result = CALEGattSetCallbacks();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "CABleGattSetCallbacks Failed");
+        oc_mutex_unlock(g_LEClientStateMutex);
+        CATerminateLEGattClient();
+        return CA_STATUS_FAILED;
+    }
+
+    g_isLEGattClientStarted = true;
+    oc_mutex_unlock(g_LEClientStateMutex);
+
+    oc_mutex_lock(g_LEClientThreadPoolMutex);
+    if (NULL == g_LEClientThreadPool)
+    {
+        OIC_LOG(ERROR, TAG, "gBleServerThreadPool is NULL");
+        CATerminateGattClientMutexVariables();
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    result = ca_thread_pool_add_task(g_LEClientThreadPool, CAStartTimerThread,
+                                     NULL, NULL);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
+        CATerminateGattClientMutexVariables();
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    result= ca_thread_pool_add_task(g_LEClientThreadPool, CALEClientScanThread,
+                                    NULL, NULL);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "ca_thread_pool_add_task failed");
+        CATerminateGattClientMutexVariables();
+        oc_mutex_unlock(g_LEClientThreadPoolMutex);
+        return CA_STATUS_FAILED;
+    }
+    oc_mutex_unlock(g_LEClientThreadPoolMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEClientScanThread()
+{
+    oc_mutex_lock(g_scanMutex);
+    if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
+    {
+        CAResult_t result = CALEGattStartDeviceScanning();
+        if (CA_STATUS_OK != result)
+        {
+            oc_mutex_unlock(g_scanMutex);
+            OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
+            return ;
+        }
+        g_isUnicastScanInProgress = true;
+        // Start Timer
+        oc_cond_signal(g_startTimerCond);
+    }
+    else
+    {
+        g_isUnicastScanInProgress = true;
+        // Reset Timer
+        oc_cond_signal(g_scanningTimeCond);
+    }
+    oc_mutex_unlock(g_scanMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return ;
+}
+
+void CAStartTimerThread(void *data)
+{
+    (void)data;
+
+    OIC_LOG(DEBUG, TAG, "IN");
+    while (g_isLEGattClientStarted)
+    {
+        oc_mutex_lock(g_scanMutex);
+        if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
+        {
+            OIC_LOG(DEBUG, TAG, "waiting....");
+            oc_cond_wait(g_startTimerCond, g_scanMutex);
+            OIC_LOG(DEBUG, TAG, "Wake up");
+        }
+
+        // Timed conditional wait for stopping the scan.
+        OCWaitResult_t ret = oc_cond_wait_for(g_scanningTimeCond, g_scanMutex,
+                                              TIMEOUT);
+        if (OC_WAIT_TIMEDOUT == ret)
+        {
+            OIC_LOG(DEBUG, TAG, "Scan is timed Out");
+            // Call stop scan.
+            CALEGattStopDeviceScanning();
+
+            if (g_isMulticastInProgress)
+            {
+                oc_mutex_lock(g_multicastDataListMutex);
+                // Clear the data list and device list.
+                u_arraylist_destroy(g_multicastDataList);
+                g_multicastDataList = NULL;
+                oc_mutex_unlock(g_multicastDataListMutex);
+                g_isMulticastInProgress = false;
+            }
+            g_isUnicastScanInProgress = false;
+        }
+        oc_mutex_unlock(g_scanMutex);
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAStopLEGattClient()
+{
+    OIC_LOG(DEBUG,  TAG, "IN");
+
+    oc_mutex_lock(g_LEClientStateMutex);
+
+    if (false == g_isLEGattClientStarted)
+    {
+        OIC_LOG(ERROR, TAG, "Gatt Client is not running to stop");
+        oc_mutex_unlock(g_LEClientStateMutex);
+        return;
+    }
+
+    CALEGattUnSetCallbacks();
+
+    CALEGattStopDeviceScanning();
+
+    g_isLEGattClientStarted = false;
+
+    // Signal the conditions waiting in Start timer.
+    oc_cond_signal(g_startTimerCond);
+    oc_cond_signal(g_scanningTimeCond);
+
+    // Destroy the multicast data list and device list if not empty.
+    if (NULL != g_multicastDataList)
+    {
+        oc_mutex_lock(g_multicastDataListMutex);
+        u_arraylist_destroy(g_multicastDataList);
+        g_multicastDataList = NULL;
+        oc_mutex_unlock(g_multicastDataListMutex);
+    }
+
+    oc_mutex_lock(g_LEServerListMutex);
+    CAFreeLEServerList(g_LEServerList);
+    g_LEServerList = NULL;
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
+    oc_cond_signal(g_threadWriteCharacteristicCond);
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+    GMainContext  *context_event_loop = NULL;
+    // Required for waking up the thread which is running in gmain loop
+    if (NULL != g_eventLoop)
+    {
+        context_event_loop = g_main_loop_get_context(g_eventLoop);
+    }
+    if (context_event_loop)
+    {
+        OIC_LOG_V(DEBUG,  TAG, "g_eventLoop context %p", (void *)context_event_loop);
+        g_main_context_wakeup(context_event_loop);
+
+        // Kill g main loops and kill threads.
+        g_main_loop_quit(g_eventLoop);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TAG, "g_eventLoop context is NULL");
+    }
+
+    oc_mutex_unlock(g_LEClientStateMutex);
+
+    OIC_LOG(DEBUG,  TAG, "OUT");
+}
+
+CAResult_t CAInitializeLEGattClient()
+{
+    OIC_LOG(DEBUG, TAG, "Initialize GATT Client");
+    CAResult_t res = CAInitGattClientMutexVariables();
+    if (CA_STATUS_OK != res)
+    {
+        OIC_LOG(ERROR, TAG, "CAInitGattClientMutexVariables failed!");
+        CATerminateGattClientMutexVariables();
+        return CA_STATUS_FAILED;
+    }
+    return res;
+}
+
+void CATerminateLEGattClient()
+{
+    OIC_LOG(DEBUG,  TAG, "IN");
+
+    CATerminateGattClientMutexVariables();
+
+    OIC_LOG(DEBUG,  TAG, "OUT");
+}
+
+CAResult_t CAInitGattClientMutexVariables()
+{
+    OIC_LOG(DEBUG,  TAG, "IN");
+    if (NULL == g_LEClientStateMutex)
+    {
+        g_LEClientStateMutex = oc_mutex_new();
+        if (NULL == g_LEClientStateMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEServerListMutex)
+    {
+        g_LEServerListMutex = oc_mutex_new();
+        if (NULL == g_LEServerListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEReqRespClientCbMutex)
+    {
+        g_LEReqRespClientCbMutex = oc_mutex_new();
+        if (NULL == g_LEReqRespClientCbMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEClientThreadPoolMutex)
+    {
+        g_LEClientThreadPoolMutex = oc_mutex_new();
+        if (NULL == g_LEClientThreadPoolMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_LEClientConnectMutex)
+    {
+        g_LEClientConnectMutex = oc_mutex_new();
+        if (NULL == g_LEClientConnectMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_isScanningInProgressMutex)
+    {
+        g_isScanningInProgressMutex = oc_mutex_new();
+        if (NULL == g_isScanningInProgressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_isConnectionInProgressMutex)
+    {
+        g_isConnectionInProgressMutex = oc_mutex_new();
+        if (NULL == g_isConnectionInProgressMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_multicastDataListMutex)
+    {
+        g_multicastDataListMutex = oc_mutex_new();
+        if (NULL == g_multicastDataListMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_scanMutex)
+    {
+        g_scanMutex = oc_mutex_new();
+        if (NULL == g_scanMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadWriteCharacteristicMutex)
+    {
+        g_threadWriteCharacteristicMutex = oc_mutex_new();
+        if (NULL == g_threadWriteCharacteristicMutex)
+        {
+            OIC_LOG(ERROR, TAG, "oc_mutex_new has failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_startTimerCond)
+    {
+        g_startTimerCond = oc_cond_new();
+        if (NULL == g_startTimerCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_scanningTimeCond)
+    {
+        g_scanningTimeCond = oc_cond_new();
+        if (NULL == g_scanningTimeCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == g_threadWriteCharacteristicCond)
+    {
+        g_threadWriteCharacteristicCond = oc_cond_new();
+        if (NULL == g_threadWriteCharacteristicCond)
+        {
+            OIC_LOG(ERROR, TAG, "oc_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG,  TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CATerminateGattClientMutexVariables()
+{
+    OIC_LOG(DEBUG,  TAG, "IN");
+
+    oc_mutex_free(g_LEClientStateMutex);
+    g_LEClientStateMutex = NULL;
+
+    oc_mutex_free(g_LEServerListMutex);
+    g_LEServerListMutex = NULL;
+
+    oc_mutex_free(g_LEReqRespClientCbMutex);
+    g_LEReqRespClientCbMutex = NULL;
+
+    oc_mutex_free(g_LEClientConnectMutex);
+    g_LEClientConnectMutex = NULL;
+
+    oc_mutex_free(g_LEClientThreadPoolMutex);
+    g_LEClientThreadPoolMutex = NULL;
+
+    oc_mutex_free(g_isScanningInProgressMutex);
+    g_isScanningInProgressMutex = NULL;
+
+    oc_mutex_free(g_isConnectionInProgressMutex);
+    g_isConnectionInProgressMutex = NULL;
+
+    oc_mutex_free(g_multicastDataListMutex);
+    g_multicastDataListMutex = NULL;
+
+    oc_mutex_free(g_scanMutex);
+    g_scanMutex = NULL;
+
+    oc_mutex_free(g_threadWriteCharacteristicMutex);
+    g_threadWriteCharacteristicMutex = NULL;
+
+    oc_cond_free(g_startTimerCond);
+    g_startTimerCond = NULL;
+
+    oc_cond_free(g_scanningTimeCond);
+    g_scanningTimeCond = NULL;
+
+    oc_cond_free(g_threadWriteCharacteristicCond);
+    g_threadWriteCharacteristicCond = NULL;
+    g_isSignalSetFlag = false;
+
+    OIC_LOG(DEBUG,  TAG, "OUT");
+}
+
+CAResult_t CALEGattSetCallbacks()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEGattUnSetCallbacks()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    bt_gatt_unset_connection_state_changed_cb();
+
+    oc_mutex_lock(g_LEServerListMutex);
+    LEServerInfoList *curNode = g_LEServerList;
+    while (curNode)
+    {
+        LEServerInfo *serverInfo = curNode->serverInfo;
+        if (serverInfo->status >= LE_STATUS_SERVICES_DISCOVERED)
+        {
+            bt_gatt_client_unset_characteristic_value_changed_cb(serverInfo->readChar);
+        }
+        curNode = curNode->next;
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEGattStartDeviceScanning()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (!g_isScanningInProgress)
+    {
+        int ret = bt_adapter_le_start_scan(CALEAdapterScanResultCb, NULL);
+        if (BT_ERROR_NONE != ret)
+        {
+            oc_mutex_unlock(g_isScanningInProgressMutex);
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_start_scan failed[%s]",
+                      CALEGetErrorMsg(ret));
+            return CA_STATUS_FAILED;
+        }
+        g_isScanningInProgress = true;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "Ignore, scanning already in progress");
+    }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CALEGattStopDeviceScanning()
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    oc_mutex_lock(g_isScanningInProgressMutex);
+    if (g_isScanningInProgress)
+    {
+        int ret = bt_adapter_le_stop_scan();
+        if (BT_ERROR_NONE != ret)
+        {
+            oc_mutex_unlock(g_isScanningInProgressMutex);
+            OIC_LOG_V(ERROR, TAG, "bt_adapter_le_stop_scan failed[%s]",
+                      CALEGetErrorMsg(ret));
+            return;
+        }
+        g_isScanningInProgress = false;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "Ignore, scanning not in progress");
+    }
+    oc_mutex_unlock(g_isScanningInProgressMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+void CAGattConnectThread (void *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN ");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
+
+    char *address  = (char *)remoteAddress;
+
+    OIC_LOG_V(DEBUG, TAG, "remote address is [%s]", address);
+
+    CAResult_t result = CALEGattConnect(address);
+
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_connect failed for [%s]", address);
+    }
+
+    OICFree(address);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEGattConnect(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, TAG,
+                        "remote address is NULL", CA_STATUS_FAILED);
+
+    oc_mutex_lock(g_LEClientConnectMutex);
+    CAResult_t result = CA_STATUS_OK;
+
+    int ret = bt_gatt_connect(remoteAddress, false);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_connect Failed with ret value [%s] ",
+                  CALEGetErrorMsg(ret));
+        oc_mutex_unlock(g_LEClientConnectMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    oc_mutex_unlock(g_LEClientConnectMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return result;
+}
+
+CAResult_t CALEGattDisConnect(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, TAG,
+                        "remote address is NULL", CA_STATUS_FAILED);
+
+    int ret = bt_gatt_disconnect(remoteAddress);
+
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TAG, "bt_gatt_disconnect Failed with ret value [%s] ",
+                  CALEGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToGattServerImpl(LEServerInfo *serverInfo,
+        const uint8_t *data, const uint32_t dataLen)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(serverInfo, TAG, "Server Info is NULL");
+
+    CALEGattStopDeviceScanning();
+
+    OIC_LOG_V(DEBUG, TAG, "Updating the data of length [%d] to [%s] ", dataLen,
+              serverInfo->remoteAddress);
+
+    int result = bt_gatt_set_value(serverInfo->writeChar, (char *)data, dataLen);
+
+    if (BT_ERROR_NONE != result)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_set_value Failed with return val [%s]",
+                  CALEGetErrorMsg(result));
+        goto exit;
+    }
+
+    result = bt_gatt_client_write_value(serverInfo->writeChar, CALEGattCharacteristicWriteCb,
+                                        NULL);
+    if (BT_ERROR_NONE != result)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_client_write_value Failed with return val [%s]",
+                  CALEGetErrorMsg(result));
+        goto exit;
+    }
+
+    // wait for callback for write Characteristic with success to sent data
+    OIC_LOG_V(DEBUG, TAG, "callback flag is %d", g_isSignalSetFlag);
+    oc_mutex_lock(g_threadWriteCharacteristicMutex);
+    if (!g_isSignalSetFlag)
+    {
+        OIC_LOG(DEBUG, TAG, "wait for callback to notify writeCharacteristic is success");
+        if (OC_WAIT_SUCCESS != oc_cond_wait_for(g_threadWriteCharacteristicCond,
+                                                g_threadWriteCharacteristicMutex,
+                                                WAIT_TIME_WRITE_CHARACTERISTIC))
+        {
+            g_isSignalSetFlag = false;
+            oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+            OIC_LOG(ERROR, TAG, "there is no response. write has failed");
+            goto exit;
+        }
+    }
+    // reset flag set by writeCharacteristic Callback
+    g_isSignalSetFlag = false;
+    oc_mutex_unlock(g_threadWriteCharacteristicMutex);
+
+    oc_mutex_lock(g_scanMutex);
+    if (g_isMulticastInProgress || g_isUnicastScanInProgress)
+    {
+        if (CA_STATUS_OK != CALEGattStartDeviceScanning())
+        {
+            OIC_LOG(ERROR, TAG, "Could not start device scanning");
+        }
+    }
+    oc_mutex_unlock(g_scanMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+
+exit:
+    oc_mutex_lock(g_scanMutex);
+    if (g_isMulticastInProgress || g_isUnicastScanInProgress)
+    {
+        if (CA_STATUS_OK != CALEGattStartDeviceScanning())
+        {
+            OIC_LOG(ERROR, TAG, "Could not start device scanning");
+        }
+    }
+    oc_mutex_unlock(g_scanMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_FAILED;
+}
+
+void CADiscoverLEServicesThread(void *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_VOID(remoteAddress, TAG, "remote address is NULL");
+
+    char *address  = (char *)remoteAddress;
+
+    CAResult_t result = CALEGattDiscoverServices(address);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG(ERROR, TAG, "CALEGattDiscoverServices failed");
+    }
+
+    OICFree(address);
+    OIC_LOG(DEBUG, TAG, "OUT");
+}
+
+CAResult_t CALEGattDiscoverServices(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, TAG,
+                        "remote address is NULL", CA_STATUS_FAILED);
+
+    LEServerInfo *serverInfo = NULL;
+    oc_mutex_lock(g_LEServerListMutex);
+    if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
+    {
+        oc_mutex_unlock(g_LEServerListMutex);
+        OIC_LOG_V(ERROR, TAG, "Could not get server info for [%s]", remoteAddress);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    bt_gatt_h serviceHandle = NULL;
+    int32_t ret = bt_gatt_client_get_service(serverInfo->clientHandle, CA_GATT_SERVICE_UUID, &serviceHandle);
+    if (BT_ERROR_NONE != ret || NULL == serviceHandle)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_client_get_service Failed with ret value [%s] ", CALEGetErrorMsg(ret));
+        bt_gatt_client_destroy(serverInfo->clientHandle);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    // Server will read data on this characteristic.
+    bt_gatt_h writeChrHandle = NULL;
+    ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_REQUEST_CHRC_UUID,
+            &writeChrHandle);
+    if (BT_ERROR_NONE != ret || NULL == writeChrHandle)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
+                  CALEGetErrorMsg(ret));
+        bt_gatt_client_destroy(serverInfo->clientHandle);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    // Server will notify data on this characteristic.
+    bt_gatt_h readChrHandle = NULL;
+    ret = bt_gatt_service_get_characteristic(serviceHandle, CA_GATT_RESPONSE_CHRC_UUID,
+            &readChrHandle);
+    if (BT_ERROR_NONE != ret || NULL == readChrHandle)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_service_get_characteristic Failed with ret value [%s] ",
+                  CALEGetErrorMsg(ret));
+        bt_gatt_client_destroy(serverInfo->clientHandle);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    //TODO: This data has to be freed while unsetting the callback.
+    char *addr = OICStrdup(remoteAddress);
+    if (NULL == addr)
+    {
+        OIC_LOG(ERROR, TAG, "addr is NULL");
+        bt_gatt_client_destroy(serverInfo->clientHandle);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_client_set_characteristic_value_changed_cb(readChrHandle,
+            CALEGattCharacteristicChangedCb,
+            (void *)addr);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TAG,
+                  "bt_gatt_client_set_characteristic_value_changed_cb Failed with ret value [%s]",
+                  CALEGetErrorMsg(ret));
+        bt_gatt_client_destroy(serverInfo->clientHandle);
+        CALEGattDisConnect(remoteAddress);
+        return CA_STATUS_FAILED;
+    }
+
+    serverInfo->serviceHandle = serviceHandle;
+    serverInfo->readChar = readChrHandle;
+    serverInfo->writeChar = writeChrHandle;
+    serverInfo->status = LE_STATUS_SERVICES_DISCOVERED;
+
+    while (serverInfo->pendingDataList)
+    {
+        LEData *leData = serverInfo->pendingDataList->data;
+        if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(
+                serverInfo, leData->data, leData->dataLength))
+        {
+            OIC_LOG_V(ERROR, TAG, "Failed to send pending data to [%s]",
+                      serverInfo->remoteAddress);
+
+            CADestroyLEDataList(&serverInfo->pendingDataList);
+            break;
+        }
+        CARemoveLEDataFromList(&serverInfo->pendingDataList);
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToGattServer(const char *remoteAddress,
+        const uint8_t *data, const uint32_t dataLen,
+        CALETransferType_t type, const int32_t position)
+{
+    OIC_LOG(DEBUG, TAG, "IN");
+
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
+
+    if (0 >= dataLen)
+    {
+        OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    LEServerInfo *serverInfo = NULL;
+    oc_mutex_lock(g_LEServerListMutex);
+    if (LE_UNICAST == type)
+    {
+        if (CA_STATUS_OK != CAGetLEServerInfo(g_LEServerList, remoteAddress, &serverInfo))
+        {
+            OIC_LOG_V(DEBUG, TAG,
+                      "Device with address [%s] not yet found, initiating scan",
+                      remoteAddress);
+
+            char *addr = OICStrdup(remoteAddress);
+            if (NULL == addr)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Device address is NULL");
+                return CA_STATUS_FAILED;
+            }
+            serverInfo = (LEServerInfo *)OICCalloc(1, sizeof(LEServerInfo));
+            if (NULL == serverInfo)
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Calloc failed");
+                OICFree(addr);
+                return CA_STATUS_FAILED;
+            }
+            serverInfo->remoteAddress = addr;
+            serverInfo->status = LE_STATUS_UNICAST_PENDING;
+
+            if (CA_STATUS_OK != CAAddLEServerInfoToList(&g_LEServerList, serverInfo))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG_V(ERROR, TAG, "Could not add [%s] to server list", remoteAddress);
+                CAFreeLEServerInfo(serverInfo);
+                return CA_STATUS_FAILED;
+            }
+
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
+
+            oc_mutex_lock(g_scanMutex);
+            if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
+            {
+                CAResult_t result = CALEGattStartDeviceScanning();
+                if (CA_STATUS_OK != result)
+                {
+                    oc_mutex_unlock(g_scanMutex);
+                    OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning failed");
+                    return CA_STATUS_FAILED;
+                }
+                g_isUnicastScanInProgress = true;
+                // Start Timer
+                oc_cond_signal(g_startTimerCond);
+            }
+            else
+            {
+                g_isUnicastScanInProgress = true;
+                // Reset Timer
+                oc_cond_signal(g_scanningTimeCond);
+            }
+            oc_mutex_unlock(g_scanMutex);
+
+        }
+
+        if (serverInfo->status == LE_STATUS_DISCOVERED)
+        {
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
+
+            bt_gatt_client_h clientHandle = NULL;
+            int32_t ret = bt_gatt_client_create(serverInfo->remoteAddress, &clientHandle);
+            if (BT_ERROR_NONE != ret || NULL == clientHandle)
+            {
+                OIC_LOG_V(ERROR, TAG,
+                          "bt_gatt_client_create Failed with ret value [%s] ", CALEGetErrorMsg(ret));
+                CALEGattDisConnect(serverInfo->remoteAddress);
+                return CA_STATUS_FAILED;
+            }
+            serverInfo->clientHandle = clientHandle;
+
+            serverInfo->status = LE_STATUS_CONNECTION_INITIATED;
+            if (CA_STATUS_OK != CALEGattInitiateConnection(serverInfo->remoteAddress))
+            {
+                OIC_LOG_V(ERROR, TAG, "Could not initiate connection to [%s]", serverInfo->remoteAddress);
+                serverInfo->status = LE_STATUS_DISCOVERED;
+                CADestroyLEDataList(&serverInfo->pendingDataList);
+                oc_mutex_unlock(g_LEServerListMutex);
+                return CA_STATUS_FAILED;
+            }
+        }
+        else if (serverInfo->status < LE_STATUS_SERVICES_DISCOVERED)
+        {
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                oc_mutex_unlock(g_LEServerListMutex);
+                OIC_LOG(ERROR, TAG, "Could not add data to pending list");
+                return CA_STATUS_FAILED;
+            }
+        }
+        else
+        {
+            if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
+            {
+                OIC_LOG_V(ERROR, TAG, "Could not update characteristic to gatt server [%s]",
+                          serverInfo->remoteAddress);
+                oc_mutex_unlock(g_LEServerListMutex);
+                return CA_STATUS_FAILED;
+            }
+        }
+    }
+    else if (LE_MULTICAST == type)
+    {
+        OIC_LOG(ERROR, TAG, "LE_MULTICAST type Not used");
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
+    OIC_LOG(DEBUG, TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAUpdateCharacteristicsToAllGattServers(const uint8_t *data, uint32_t dataLen)
+{
+    OIC_LOG(DEBUG,  TAG, "IN");
+
+    VERIFY_NON_NULL(data, TAG, "data is NULL");
+
+    if (0 >= dataLen)
+    {
+        OIC_LOG(ERROR, TAG, "dataLen is less than or equal zero. Invalid input !");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    oc_mutex_lock(g_LEServerListMutex);
+    LEServerInfoList *curNode = g_LEServerList;
+    while (curNode)
+    {
+        LEServerInfo *serverInfo = curNode->serverInfo;
+        if (serverInfo->status == LE_STATUS_SERVICES_DISCOVERED)
+        {
+            if (CA_STATUS_OK != CAUpdateCharacteristicsToGattServerImpl(serverInfo, data, dataLen))
+            {
+                OIC_LOG_V(ERROR, TAG, "Failed to update characteristics to gatt server [%s]",
+                          serverInfo->remoteAddress);
+            }
+        }
+        else if (serverInfo->status != LE_STATUS_INVALID)
+        {
+            if (CA_STATUS_OK != CAAddLEDataToList(&serverInfo->pendingDataList, data, dataLen))
+            {
+                OIC_LOG(ERROR, TAG, "Failed to add to pending list");
+            }
+        }
+        curNode = curNode->next;
+    }
+    oc_mutex_unlock(g_LEServerListMutex);
+
+    // Add the data to pending list.
+    LEData *multicastData = (LEData *)OICCalloc(1, sizeof(LEData));
+    if (NULL == multicastData)
+    {
+        OIC_LOG(ERROR, TAG, "Calloc failed");
+        goto exit;
+    }
+    multicastData->data = OICCalloc(1, dataLen);
+    if (NULL == multicastData->data)
+    {
+        OIC_LOG(ERROR, TAG, "Calloc failed");
+        goto exit;
+    }
+    memcpy(multicastData->data, data, dataLen);
+    multicastData->dataLength = dataLen;
+
+    oc_mutex_lock(g_multicastDataListMutex);
+    if (NULL == g_multicastDataList)
+    {
+        g_multicastDataList = u_arraylist_create();
+    }
+    u_arraylist_add(g_multicastDataList, (void *)multicastData);
+    oc_mutex_unlock(g_multicastDataListMutex);
+
+    // Start the scanning, if not started, else reset timer
+    oc_mutex_lock(g_scanMutex);
+    if (!g_isMulticastInProgress && !g_isUnicastScanInProgress)
+    {
+        CAResult_t result = CALEGattStartDeviceScanning();
+        if (CA_STATUS_OK != result)
+        {
+            oc_mutex_unlock(g_scanMutex);
+            OIC_LOG(ERROR, TAG, "CALEGattStartDeviceScanning Failed");
+            goto exit;
+        }
+        g_isMulticastInProgress = true;
+        // Start the timer by signalling it
+        oc_cond_signal(g_startTimerCond);
+    }
+    else
+    {
+        g_isMulticastInProgress = true;
+        // Reset timer
+        oc_cond_signal(g_scanningTimeCond);
+    }
+    oc_mutex_unlock(g_scanMutex);
+
+exit:
+    OIC_LOG(DEBUG, TAG, "OUT ");
+    return CA_STATUS_OK;
+}
index 6a52aed..f1a5f6e 100755 (executable)
@@ -859,10 +859,6 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
 
     if (read)
     {
-        g_gattReadCharPath = charPath;
-    }
-    else
-    {
         char desc_value[2] = {0, 0};  // Notification enabled.
         bt_gatt_h descriptor = NULL;
         permissions = BT_GATT_PERMISSION_READ | BT_GATT_PERMISSION_WRITE;
@@ -887,6 +883,9 @@ CAResult_t CAAddNewCharacteristicsToGattServer(const bt_gatt_h svcPath, const ch
                       CALEGetErrorMsg(ret));
             return CA_STATUS_FAILED;
         }
+        g_gattReadCharPath = charPath;
+    }
+    else{
         g_gattWriteCharPath = charPath;
     }
 
index d42dd73..1000f86 100644 (file)
@@ -202,7 +202,6 @@ OCStackResult RemoveSubOwner(const OicUuid_t* subOwner);
  */
 OCStackResult SetNumberOfSubOwner(size_t maxSubOwner);
 
-
 #ifdef __cplusplus
 }
 #endif
index cc9c531..15bb37d 100644 (file)
@@ -91,7 +91,7 @@ typedef bool (*SPResponseCallback) (const CAEndpoint_t *object,
                                     const CAResponseInfo_t *responseInfo);
 
 /**
- * Function to register provisoning API's response callback.
+ * Function to register provisioning API's response callback.
  *
  * @param respHandler response handler callback.
  */
index c26852b..bab6aa2 100644 (file)
@@ -61,6 +61,11 @@ typedef OCStackResult (*UserConfirmCallback)(void * ctx);
 typedef OCStackResult (*InputStateCallback)(void * ctx);
 
 /**
+ * Function pointer to notify user selected OXM
+ */
+typedef void (*InformOxmSelectedCallback_t)(OicSecOxm_t oxmSel);
+
+/**
  * Context for displaying verification PIN
  */
 typedef struct DisplayNumContext
@@ -124,6 +129,16 @@ void* UnsetInputStateCB();
 void SetVerifyOption(VerifyOptionBitmask_t verifyOption);
 
 /**
+ * Set notify selected OXM callback
+ */
+void SetInformOxmSelCB(InformOxmSelectedCallback_t informOxmSelCB);
+
+/**
+ * Set notify selected OXM callback
+ */
+void UnsetInformOxmSelCB();
+
+/**
  * Call the Callback for Verifying Ownership Transfer process.
  */
 OCStackResult VerifyOwnershipTransfer(uint8_t mutualVerifNum[MUTUAL_VERIF_NUM_LEN],
index b8f34c9..a7f2eb6 100644 (file)
@@ -81,6 +81,11 @@ typedef OCStackResult (*OTMCreateSecureSession)(OTMContext_t* otmCtx);
 typedef OCStackResult (*OTMCreatePayloadCallback)(OTMContext_t* otmCtx, uint8_t **payload,\r
                                                   size_t *size);\r
 \r
+/*\r
+ * Callback for selecting OTM.\r
+ */\r
+typedef OicSecOxm_t (*OTMSelectMethodCallback)(const OicSecOxm_t* otmList, const uint32_t len);\r
+\r
 /**\r
  * Required callback for performing ownership transfer\r
  */\r
@@ -90,6 +95,7 @@ struct OTMCallbackData
     OTMCreateSecureSession createSecureSessionCB;\r
     OTMCreatePayloadCallback createSelectOxmPayloadCB;\r
     OTMCreatePayloadCallback createOwnerTransferPayloadCB;\r
+    OTMSelectMethodCallback selectOTMCB;\r
 };\r
 \r
 /**\r
index 50c00fb..483afa2 100644 (file)
@@ -582,6 +582,16 @@ OCStackResult OCSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMethod
  */\r
 OCStackResult OCSetPeerCertCallback(void *ctx, PeerCertCallback peerCertCallback);\r
 \r
+/*\r
+ * Set selecting OTM callback.\r
+ */\r
+void SetSelectOTMCB(OTMSelectMethodCallback selectOTMcb);\r
+\r
+/*\r
+ * Unset selecting OTM callback.\r
+ */\r
+void UnsetSelectOTMCB();\r
+\r
 #endif // __WITH_DTLS__ || __WITH_TLS__\r
 \r
 \r
index d391770..301a625 100644 (file)
@@ -1303,6 +1303,11 @@ OCStackResult notifyInputStateCB(void * ctx)
     return OC_STACK_OK;
 }
 
+OicSecOxm_t selectOTMcb(const OicSecOxm_t* otmList, const uint32_t len)
+{
+    return otmList[len-1];
+}
+
 #ifdef MULTIPLE_OWNER
 static int changeMultipleOwnershipTrnasferMode(void)
 {
@@ -2522,6 +2527,7 @@ int main()
     SetDisplayNumCB(NULL, displayNumCB);
     SetUserConfirmCB(NULL, confirmNumCB);
     SetInputStateCB(NULL, notifyInputStateCB);
+    SetSelectOTMCB(selectOTMcb);
 
     // set callback for checking peer certificate information
     OCSetPeerCertCallback(NULL, peerCertCallback);
index 90ed672..a1923fe 100644 (file)
@@ -46,6 +46,7 @@
 #include "pkix_interface.h"
 #include "hw_emul/hw_interface.h"
 #include "oxmverifycommon.h"
+#include "casecurityinterface.h"
 
 #define TAG "SAMPLE_MANUFACTURER_CERT"
 
@@ -434,6 +435,28 @@ OCStackResult confirmCB(void * ctx)
     return OC_STACK_OK;
 }
 
+void confirmNoCertCB(CACertificateVerificationStatus_t status)
+{
+    if (CA_CERTIFICATE_VERIFY_SUCCESS_MUTUAL == status)
+    {
+        printf("   > Peer certificate verification successful");
+    }
+    else if (CA_CERTIFICATE_VERIFY_NO_CERT == status)
+    {
+        printf("   > Peer has not provided certificate\n");
+    }
+    else if (CA_CERTIFICATE_VERIFY_FAILED == status)
+    {
+        printf("   > Peer certificate verification failed\n");
+    }
+    return;
+}
+
+void informOxmSelCB(OicSecOxm_t oxmSel)\r
+{\r
+    printf("   > OXM selected: 0x%x\n", oxmSel);\r
+}\r
+\r
 FILE* server_fopen(const char *path, const char *mode)
 {
     (void)path;
@@ -477,6 +500,8 @@ int main(int argc, char **argv)
     OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
 
     SetUserConfirmCB(NULL, confirmCB);
+    SetInformOxmSelCB(informOxmSelCB);
+    CAsetCertificateVerificationCallback(confirmNoCertCB);
 
     OCRegisterPersistentStorageHandler(&ps);
 
index ac24a22..cf14101 100644 (file)
@@ -179,7 +179,7 @@ static void LedCB(void *ctx, OCDoHandle UNUSED,
             printf("Received OC_STACK_OK from server\n");
             if(clientResponse->payload)
             {
-                printf("Response ===================> %s\n", clientResponse->payload);
+                printf("Response ===================> %p\n", clientResponse->payload);
             }
         }
         else if(OC_STACK_RESOURCE_CHANGED == clientResponse->result)
index 326376b..a483e7a 100644 (file)
@@ -104,6 +104,8 @@ static uint8_t g_OxmAllowStatus[OXM_IDX_COUNT] = {ALLOWED_OXM, ALLOWED_OXM, ALLO
                                                   NOT_ALLOWED_OXM};
 #endif
 
+static OTMSelectMethodCallback g_selectOTMCB = NULL;
+
 OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
 {
     OCStackResult res = OC_STACK_INVALID_PARAM;
@@ -180,6 +182,18 @@ exit:
     return res;
 }
 
+void SetSelectOTMCB(OTMSelectMethodCallback selectOTMcb)
+{
+    g_selectOTMCB = selectOTMcb;
+    return;
+}
+
+void UnsetSelectOTMCB()
+{
+    g_selectOTMCB = NULL;
+    return;
+}
+
 /**
  * Internal API to convert OxM value to index of oxm allow table.
  */
@@ -237,6 +251,11 @@ OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMetho
     {
         case SUPER_OWNER:
         {
+            if (g_selectOTMCB)
+            {
+                uint32_t methNum = 0;
+                OicSecOxm_t list[10] = {0};
+
             for (size_t i = 0; i < numberOfMethods; i++)
             {
                 selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
@@ -245,19 +264,45 @@ OCStackResult OTMSelectOwnershipTransferMethod(const OicSecOxm_t *supportedMetho
                     OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
                     continue;
                 }
-#ifdef MULTIPLE_OWNER
+    #ifdef MULTIPLE_OWNER
+                    if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
+                       OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
+    #else
+
+                    if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
+    #endif //MULTIPLE_OWNER
+                    {
+                        list[methNum] = supportedMethods[i];
+                        methNum++;
+                    }
+                }
+                *selectedMethod = g_selectOTMCB(list, methNum);
+                isOxmSelected = true;
+            }
+            else
+            {
+                for (size_t i = 0; i < numberOfMethods; i++)
+                {
+                    selectedOxmIdx = GetOxmAllowTableIdx(supportedMethods[i]);
+                    if (OXM_IDX_COUNT <= selectedOxmIdx)
+                    {
+                        OIC_LOG(WARNING, TAG, "Invalid oxm index to access OxM allow table");
+                        continue;
+                    }
+    #ifdef MULTIPLE_OWNER
                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx] &&
                    OXM_IDX_PRECONFIG_PIN != selectedOxmIdx)
-#else
+    #else
 
                 if (ALLOWED_OXM == g_OxmAllowStatus[selectedOxmIdx])
-#endif //MULTIPLE_OWNER
+    #endif //MULTIPLE_OWNER
                 {
                     *selectedMethod  = supportedMethods[i];
                     isOxmSelected = true;
                 }
             }
         }
+        }
         break;
 #ifdef MULTIPLE_OWNER
         case SUB_OWNER:
@@ -2144,7 +2189,7 @@ static OCStackResult StartOwnershipTransfer(void* ctx, OCProvisionDev_t* selecte
         SetResult(otmCtx, res);
         return res;
     }
-    OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
+    OIC_LOG_V(DEBUG, TAG, "Selected provisioning method = %d", selectedDevice->doxm->oxmSel);
 
     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
     if(OC_STACK_OK != res)
@@ -2197,7 +2242,7 @@ static OCStackResult StartCustomOwnershipTransfer(void* ctx, OCProvisionDev_t* s
 
     //Select the OxM to performing ownership transfer
     selectedDevice->doxm->oxmSel = method;
-    OIC_LOG_V(DEBUG, TAG, "Selected provisoning method = %d", selectedDevice->doxm->oxmSel);
+    OIC_LOG_V(DEBUG, TAG, "Selected provisioning method = %d", selectedDevice->doxm->oxmSel);
 
     res = OTMSetOTCallback(selectedDevice->doxm->oxmSel, &otmCtx->otmCallback);
     if(OC_STACK_OK != res)
index d77300b..6804381 100644 (file)
@@ -568,7 +568,7 @@ OCStackResult SRPSaveTrustCertChain(uint8_t *trustCertChain, size_t chainSize,
     // because we use 3 Cert, 6K is enough size for saving Certs.
     if (6144 <= chainSize)
     {
-        OIC_LOG_V(ERROR, TAG, "chainSize(%lu) is invalid", chainSize);
+        OIC_LOG_V(ERROR, TAG, "chainSize(%u) is invalid", chainSize);
         return OC_STACK_INVALID_PARAM;
     }
 
index d3ac759..b105de9 100644 (file)
@@ -1169,7 +1169,7 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
     OIC_LOG_BUFFER(DEBUG, TAG, cred->subject.id, sizeof(cred->subject.id));
     if (cred->privateData.data)
     {
-        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %lu", cred->privateData.len);
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : privateData len: %u", cred->privateData.len);
         OIC_LOG_BUFFER(DEBUG, TAG, cred->privateData.data, cred->privateData.len);
     }
 #if defined(__WITH_DTLS__) || defined(__WITH_TLS__)
@@ -1179,13 +1179,13 @@ OicSecCred_t * GenerateCredential(const OicUuid_t * subject, OicSecCredType_t cr
     }
     if (cred->publicData.data)
     {
-        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %lu", cred->publicData.len);
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : publicData len: %u", cred->publicData.len);
         OIC_LOG_BUFFER(DEBUG, TAG, cred->publicData.data, cred->publicData.len);
 
     }
     if (cred->optionalData.data)
     {
-        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %lu", cred->optionalData.len);
+        OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData len: %u", cred->optionalData.len);
         OIC_LOG_BUFFER(DEBUG, TAG, cred->optionalData.data, cred->optionalData.len);
         OIC_LOG_V(DEBUG, TAG, "GenerateCredential : optionalData revstat: %d", cred->optionalData.revstat);
     }
index 3128723..4fbd45c 100644 (file)
@@ -95,6 +95,7 @@ static OicSecDoxm_t        *gDoxm = NULL;
 static oc_mutex            g_mutexDoxm = NULL;
 static bool                g_isDoxmNull = false;
 static OCResourceHandle    gDoxmHandle = NULL;
+static InformOxmSelectedCallback_t g_InformOxmSelectedCallback = NULL;
 
 static OicSecOxm_t gOicSecDoxmJustWorks = OIC_JUST_WORKS;
 static OicSecDoxm_t gDefaultDoxm =
@@ -1081,6 +1082,20 @@ static bool ValidateOxmsel(const OicSecOxm_t *supportedMethods,
     return isValidOxmsel;
 }
 
+void SetInformOxmSelCB(InformOxmSelectedCallback_t informOxmSelCB)
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    g_InformOxmSelectedCallback = informOxmSelCB;
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
+void UnsetInformOxmSelCB()
+{
+    OIC_LOG_V(DEBUG, TAG, "In %s", __func__);
+    g_InformOxmSelectedCallback = NULL;
+    OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
+}
+
 static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRequest)
 {
     OIC_LOG (DEBUG, TAG, "Doxm EntityHandle  processing POST request");
@@ -1240,6 +1255,10 @@ static OCEntityHandlerResult HandleDoxmPostRequest(OCEntityHandlerRequest * ehRe
                     ehRet = OC_EH_NOT_ACCEPTABLE;
                     goto exit;
                 }
+                if (g_InformOxmSelectedCallback)
+                {
+                    g_InformOxmSelectedCallback(newDoxm->oxmSel);
+                }
 
 #if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
                 if (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0)
index da0b9c0..3404a16 100644 (file)
@@ -401,7 +401,7 @@ OCStackResult PconfToCBORPayload(const OicSecPconf_t *pconf,uint8_t **payload,si
     }
 
     //DeviceId -- Mandatory
-    //There may not be devicd id if caller is provisoning tool
+    //There may not be devicd id if caller is provisioning tool
     cborEncoderResult = cbor_encode_text_string(&pconfMap, OIC_JSON_DEVICE_ID_NAME,
             strlen(OIC_JSON_DEVICE_ID_NAME));
     VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to encode device id");
index 919608d..6a487a9 100644 (file)
@@ -32,6 +32,8 @@
 
 #define TAG "OIC_SRM_PKIX_INTERFACE"
 
+#define ECC256_SIG_LEN 32+4
+
 static HWPkixContext_t gHwPkixCtx = {
     .getHwKeyContext = NULL,
     .freeHwKeyContext = NULL,
@@ -165,6 +167,7 @@ void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
                 if(NULL == derCrtBufTmp)
                 {
                     OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
+                    OICFree(certCopy);
                     goto exit;
                 }
 
@@ -195,8 +198,8 @@ void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
         * | tag (INTEGER) | length (1B) | value (r or s in integer)  |
         * +---------------+-------------+----------------------------+
         */
-        uint8_t r_buf[32 + 4]; // for ECC 256 sign
-        uint8_t s_buf[32 + 4];
+        uint8_t r_buf[ECC256_SIG_LEN]; // for ECC 256 sign
+        uint8_t s_buf[ECC256_SIG_LEN];
         uint32_t r_len = 0;
         uint32_t s_len = 0;
         size_t sign_len = 0;
@@ -237,7 +240,7 @@ void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
             {
                 r_len = sign_ptr[1] + 2; // including header itself
             }
-            if (r_len > deviceCert.sig.len)
+            if (r_len > deviceCert.sig.len || r_len > ECC256_SIG_LEN)
             {
                 OIC_LOG_V(ERROR, TAG, "signature length check error #1 : %d", ret);
                 goto exit;
@@ -254,7 +257,7 @@ void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
             {
                 s_len = sign_ptr[1] + 2; // including header itself
             }
-            if (s_len + r_len > deviceCert.sig.len)
+            if (s_len + r_len > deviceCert.sig.len || s_len > ECC256_SIG_LEN)
             {
                 OIC_LOG_V(ERROR, TAG, "signature length check error #2 : %d", ret);
                 goto exit;
@@ -341,7 +344,7 @@ void CheckInvalidDERSignature(uint8_t *crtBuf, size_t *crtBufLen)
 exit:
     mbedtls_x509_crt_free(&deviceCert);
     OICFree(derCrtBufTmp);
-    OIC_LOG_V(DEBUG, TAG, "Cert chain length = %lu", *crtBufLen);
+    OIC_LOG_V(DEBUG, TAG, "Cert chain length = %u", *crtBufLen);
     OIC_LOG_V(DEBUG, TAG, "Out %s", __func__);
 }
 
@@ -378,7 +381,7 @@ static bool GetPkixInfoFromHw(PkiInfo_t * inf)
         // check and fix invalid cert signature
         CheckInvalidDERSignature(inf->crt.data, &inf->crt.len);
 
-        OIC_LOG_V(INFO, TAG, "Cert chain length = %lu", inf->crt.len);
+        OIC_LOG_V(INFO, TAG, "Cert chain length = %u", inf->crt.len);
         OIC_LOG_V(INFO, TAG, "Out %s", __func__);
         return true;
     }
index e32c86c..4a4c107 100644 (file)
@@ -907,7 +907,15 @@ exit:
  */
 bool GetPstatIsop()
 {
-    return gPstat->isOp;
+    if(NULL != gPstat)
+    {
+        return gPstat->isOp;
+    }
+    else
+    {
+        //In case of gPstat is NULL
+        return false;
+    }
 }
 
 OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
index a054e73..8c1963e 100644 (file)
@@ -60,7 +60,7 @@ static SPResponseCallback gSPResponseHandler = NULL;
 PEContext_t g_policyEngineContext;
 
 /**
- * Function to register provisoning API's response callback.
+ * Function to register provisioning API's response callback.
  * @param respHandler response handler callback.
  */
 void SRMRegisterProvisioningResponseHandler(SPResponseCallback respHandler)
index 96953c9..e54095d 100644 (file)
@@ -27,6 +27,7 @@
 #include "oic_string.h"
 #include "base64.h"
 #include "doxmresource.h"
+#include "credresource.h"
 #include "pstatresource.h"
 #include "cacommon.h"
 #include "casecurityinterface.h"
@@ -338,6 +339,7 @@ void InvokeOtmEventHandler(const char* addr, uint16_t port,
             //Restore Pkix handler to initial state
             CAregisterPkixInfoHandler(GetPkixInfo);
             CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
+            CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
             break;
         default:
             OIC_LOG_V(ERROR, TAG, "Unknow OTM event : %d", event);
index 8213152..2c497ef 100644 (file)
@@ -21,8 +21,6 @@
 #ifndef OCPRESENCE_H_
 #define OCPRESENCE_H_
 
-#ifdef WITH_PRESENCE
-
 /**
  * The OCPresenceTrigger enum delineates the three spec-compliant modes for
  * "Trigger." These enum values are then mapped to  strings
@@ -41,5 +39,3 @@ typedef enum
     OC_PRESENCE_TRIGGER_DELETE = 2
 } OCPresenceTrigger;
 #endif
-
-#endif
index 897d770..96bae43 100644 (file)
@@ -245,7 +245,6 @@ OCStackResult OCCancel(OCDoHandle handle,
  */
 OCStackResult OCRegisterPersistentStorageHandler(OCPersistentStorage* persistentStorageHandler);
 
-#ifdef WITH_PRESENCE
 /**
  * When operating in  OCServer or  OCClientServer mode,
  * this API will start sending out presence notifications to clients via multicast.
@@ -277,8 +276,6 @@ OCStackResult OCStartPresence(const uint32_t ttl);
  */
 
 OCStackResult OCStopPresence();
-#endif // WITH_PRESENCE
-
 
 /**
  * This function sets default device entity handler.
@@ -903,6 +900,14 @@ OCStackResult OCGetKey(unsigned char* key);
  */
 OCStackResult OCSetOtmEventHandler(void *ctx, OCOtmEventHandler cb);
 
+ /**
+ * Gets the bool state of "isOp" property on the pstat resource
+ * @param isOp a pointer to be assigned to isop property
+ * @return Returns ::OC_STACK_OK.
+ */
+
+OCStackResult OCGetDeviceOperationalState(bool* isOp);
+
 #ifdef __cplusplus
 }
 #endif // __cplusplus
index df6df44..1a5797b 100644 (file)
@@ -79,12 +79,8 @@ extern "C" {
 /** KeepAlive URI.*/
 #define OC_RSRVD_KEEPALIVE_URI                "/oic/ping"
 
-#ifdef WITH_PRESENCE
-/** Presence */
-
 /** Presence URI through which the OIC devices advertise their presence.*/
 #define OC_RSRVD_PRESENCE_URI                 "/oic/ad"
-#endif // WITH_PRESENCE
 
 /** Presence URI through which the OIC devices advertise their device presence.*/
 #define OC_RSRVD_DEVICE_PRESENCE_URI         "/oic/prs"
@@ -95,7 +91,6 @@ extern "C" {
 /** Separator for multiple query string.*/
 #define OC_QUERY_SEPARATOR                    "&;"
 
-#ifdef WITH_PRESENCE
 /**
  *  OC_DEFAULT_PRESENCE_TTL_SECONDS sets the default time to live (TTL) for presence.
  */
@@ -123,8 +118,6 @@ extern "C" {
 /** To delete.*/
 #define OC_RSRVD_TRIGGER_DELETE         "delete"
 
-#endif // WITH_PRESENCE
-
 /**
  *  Attributes used to form a proper OIC conforming JSON message.
  */
@@ -151,10 +144,8 @@ extern "C" {
 /** To represent resource type.*/
 #define OC_RSRVD_RESOURCE_TYPE          "rt"
 
-#ifdef WITH_PRESENCE
 /** To represent resource type with presence.*/
 #define OC_RSRVD_RESOURCE_TYPE_PRESENCE "oic.wk.ad"
-#endif
 
 /** To represent resource type with device.*/
 #define OC_RSRVD_RESOURCE_TYPE_DEVICE   "oic.wk.d"
@@ -844,11 +835,9 @@ typedef enum
     /** Register observe request for all notifications, including stale notifications.*/
     OC_REST_OBSERVE_ALL    = (1 << 5),
 
-#ifdef WITH_PRESENCE
     /** Subscribe for all presence notifications of a particular resource.*/
     OC_REST_PRESENCE       = (1 << 7),
 
-#endif
     /** Allows OCDoResource caller to do discovery.*/
     OC_REST_DISCOVER       = (1 << 8)
 } OCMethod;
@@ -1029,11 +1018,9 @@ typedef enum
     OC_STACK_NOT_ALLOWED_OXM,
 
     /** Insert all new error codes here!.*/
-#ifdef WITH_PRESENCE
     OC_STACK_PRESENCE_STOPPED = 128,
     OC_STACK_PRESENCE_TIMEOUT,
     OC_STACK_PRESENCE_DO_NOT_HANDLE,
-#endif
 
     /** Request is denied by the user*/
     OC_STACK_USER_DENIED_REQ,
@@ -1313,10 +1300,8 @@ typedef enum
     PAYLOAD_TYPE_REPRESENTATION,
     /** The payload is an OCSecurityPayload */
     PAYLOAD_TYPE_SECURITY,
-#ifdef WITH_PRESENCE
     /** The payload is an OCPresencePayload */
     PAYLOAD_TYPE_PRESENCE
-#endif
 } OCPayloadType;
 
 /**
@@ -1454,7 +1439,6 @@ typedef struct
     size_t payloadSize;
 } OCSecurityPayload;
 
-#ifdef WITH_PRESENCE
 typedef struct
 {
     OCPayload base;
@@ -1463,7 +1447,6 @@ typedef struct
     OCPresenceTrigger trigger;
     char* resourceType;
 } OCPresencePayload;
-#endif
 
 /**
  * Incoming requests handled by the server. Requests are passed in as a parameter to the
index d813665..9aeeeac 100644 (file)
@@ -65,7 +65,8 @@ OCStackResult OCFindKeepAliveResource(OCDoHandle *handle, const char *remoteAddr
  *                          the consumer.  A NULL handle is permitted in the event where the caller
  *                          has no use for the return value.
  * @param remoteAddr        The target device address to discovery a resource.
- * @param payload           Encoded request payload.
+ * @param payload           Encoded request payload.This API takes ownership of payload passed as input,
+ *                          so whenever it returns, payload memory is de-allocated.
  * @param cbData            Asynchronous callback function that is invoked by the stack when
  *                          discovery or resource interaction is received. The discovery could be
  *                          related to filtered/scoped/particular resource. The callback is
index 59696c3..3faf0ad 100644 (file)
@@ -50,10 +50,8 @@ extern "C"
     #define OIC_LOG_PAYLOAD(level, payload) OCPayloadLog((level),(payload))
     #define UUID_SIZE (16)
 
-#ifdef WITH_PRESENCE
 const char *convertTriggerEnumToString(OCPresenceTrigger trigger);
 OCPresenceTrigger convertTriggerStringToEnum(const char * triggerStr);
-#endif
 
 INLINE_API void OCPayloadLogRep(LogLevel level, OCRepPayload* payload);
 
@@ -274,7 +272,6 @@ INLINE_API void OCPayloadLogDiscovery(LogLevel level, OCDiscoveryPayload* payloa
     }
 }
 
-#ifdef WITH_PRESENCE
 INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload)
 {
     OIC_LOG(level, PL_TAG, "Payload Type: Presence");
@@ -283,7 +280,6 @@ INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload)
     OIC_LOG_V(level, PL_TAG, "\tTrigger:%s", convertTriggerEnumToString(payload->trigger));
     OIC_LOG_V(level, PL_TAG, "\tResource Type:%s", payload->resourceType);
 }
-#endif // WITH_PRESENCE
 
 INLINE_API void OCPayloadLogSecurity(LogLevel level, OCSecurityPayload* payload)
 {
index b6e30e6..8f77cf7 100755 (executable)
@@ -151,9 +151,6 @@ static const char COAP_TCP_SCHEME[] = "coap+tcp:";
 static const char COAPS_TCP_SCHEME[] = "coaps+tcp:";
 static const char CORESPEC[] = "core";
 
-CAAdapterStateChangedCB g_adapterHandler = NULL;
-CAConnectionStateChangedCB g_connectionHandler = NULL;
-
 #if defined(__WITH_DTLS__) || defined (__WITH_TLS__)
 static OCOtmEventHandler_t g_otmEventHandler = {NULL, NULL};
 #endif
@@ -5500,19 +5497,14 @@ OCStackResult OCGetHeaderOption(OCHeaderOption* ocHdrOpt, size_t numOptions, uin
 void OCDefaultAdapterStateChangedHandler(CATransportAdapter_t adapter, bool enabled)
 {
     OIC_LOG(DEBUG, TAG, "OCDefaultAdapterStateChangedHandler");
-    if (g_adapterHandler)
-    {
-        g_adapterHandler(adapter, enabled);
-    }
+    
+    OC_UNUSED(adapter);
+    OC_UNUSED(enabled);
 }
 
 void OCDefaultConnectionStateChangedHandler(const CAEndpoint_t *info, bool isConnected)
 {
     OIC_LOG(DEBUG, TAG, "OCDefaultConnectionStateChangedHandler");
-    if (g_connectionHandler)
-    {
-       g_connectionHandler(info, isConnected);
-    }
 
     /*
      * If the client observes one or more resources over a reliable connection,
@@ -5578,6 +5570,17 @@ OCStackResult OCGetDeviceOwnedState(bool *isOwned)
     return ret;
 }
 
+OCStackResult OCGetDeviceOperationalState(bool* isOp)
+{
+    if(NULL != isOp)
+    {
+        *isOp = GetPstatIsop();
+        return OC_STACK_OK;
+    }
+
+    return OC_STACK_ERROR;
+}
+
 void OCClearCallBackList()
 {
     DeleteClientCBList();
index 1340b70..7c29f72 100644 (file)
@@ -59,6 +59,9 @@ static const uint64_t USECS_PER_SEC = 1000000;
 #define VERIFY_NON_NULL_V(arg) { if (!arg) {OIC_LOG_V(FATAL, TAG, "%s is NULL", #arg);\
     goto exit;} }
 
+#define VERIFY_NON_NULL_EXIT(arg, logLevel, retVal) { if (!(arg)) { OIC_LOG((logLevel), \
+             TAG, #arg " is NULL"); ret = retVal; goto exit; } }
+
 /**
  * The KeepAlive table entries are removed
  * if it can't receive response message within 60 seconds.
@@ -276,10 +279,11 @@ OCStackResult OCFindKeepAliveResource(OCDoHandle *handle, const char *remoteAddr
 OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
                                      OCPayload *payload, OCCallbackData *cbData)
 {
-    VERIFY_NON_NULL(remoteAddr, FATAL, OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_PARAM);
-    VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
-    VERIFY_NON_NULL(payload, FATAL, OC_STACK_INVALID_CALLBACK);
+    OCStackResult ret;
+    VERIFY_NON_NULL_EXIT(remoteAddr, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_EXIT(cbData, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_EXIT(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+    VERIFY_NON_NULL_EXIT(payload, FATAL, OC_STACK_INVALID_CALLBACK);
 
     OIC_LOG(DEBUG, TAG, "SendKeepAliveRequest IN");
 
@@ -292,15 +296,17 @@ OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
     if (result != OC_STACK_OK)
     {
         OIC_LOG_V(DEBUG, TAG, "Unable to parse uri: %s", remoteAddr);
+        OCPayloadDestroy(payload);
         return OC_STACK_ERROR;
     }
 
-    VERIFY_NON_NULL(devAddr, FATAL, OC_STACK_INVALID_PARAM);
+    VERIFY_NON_NULL_EXIT(devAddr, FATAL, OC_STACK_INVALID_PARAM);
 
     if (!(devAddr->adapter & OC_ADAPTER_TCP))
     {
         OIC_LOG_V(DEBUG, TAG, "Not supported connectivity type");
         OICFree(devAddr);
+        OCPayloadDestroy(payload);
         return OC_STACK_ERROR;
     }
 
@@ -320,6 +326,7 @@ OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
             oc_mutex_unlock(g_mutexObjectList);
             OIC_LOG(ERROR, TAG, "Failed to add new KeepAlive entry");
             OICFree(devAddr);
+            OCPayloadDestroy(payload);
             return OC_STACK_ERROR;
         }
     }
@@ -334,6 +341,7 @@ OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
             oc_mutex_unlock(g_mutexObjectList);
             OIC_LOG(ERROR, TAG, "Already sent a ping request to remote device");
             OICFree(devAddr);
+            OCPayloadDestroy(payload);
             return OC_STACK_ERROR;
         }
         entry->interval = interval;
@@ -381,6 +389,10 @@ OCStackResult OCSendKeepAliveRequest(OCDoHandle *handle, const char *remoteAddr,
     OIC_LOG(DEBUG, TAG, "SendKeepAliveRequest OUT");
     OICFree(devAddr);
     return result;
+
+exit:
+    OCPayloadDestroy(payload);
+    return (ret);
 }
 
 OCStackResult OCHandleKeepAliveResponse(const CAEndpoint_t *endPoint, const OCPayload *payload)
index 41bb8fa..75b7b46 100644 (file)
@@ -1823,10 +1823,6 @@ namespace OC
             std::lock_guard<std::recursive_mutex> lock(*cLock);
             OCRepPayload *payload = rep.getPayload();
             result = OCSendKeepAliveRequest (nullptr, host.c_str(), (OCPayload*)payload, &cbdata);
-            if (result != OC_STACK_OK)
-            {
-                OCRepPayloadDestroy(payload);
-            }
         }
         else
         {
index ce8111b..30a5a64 100755 (executable)
@@ -65,8 +65,6 @@ extern jmethodID g_mid_CloudPropProvisioningStatus_ctor;
 extern jmethodID g_mid_Integer_ctor;
 extern jmethodID g_mid_OcRepresentation_N_ctor_bool;
 
-typedef void(*RemoveListenerCallback)(JNIEnv *env, jobject jListener);
-
 /**
  * @brief Get the native handle field
  */