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)
#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;
if (!onEventListener)
{
- onEventListener = new T(env, jListener, owner);
+ onEventListener = new T(env, jListener, removeListener);
jobject jgListener = env->NewGlobalRef(jListener);
if (jgListener)
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();
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)
}
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>>(
#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;
}
}
-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,
{
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.
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,
}
#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
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,
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,
#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 */
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)
{
#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)
{
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);
}
}
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);
};
#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");
{
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);
}
}
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);
};
JniOnMQSubscribeListener::JniOnMQSubscribeListener(JNIEnv *env,
jobject jListener,
- JniOcResource* owner)
- : m_ownerResource(owner)
+ RemoveListenerCallback removeListener)
+ : m_removeListener(removeListener)
{
m_jwListener = env->NewWeakGlobalRef(jListener);
}
{
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);
}
}
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);
};
#include "JniUtils.h"
JniOnMQTopicFoundListener::JniOnMQTopicFoundListener(JNIEnv *env, jobject jListener,
- JniOcResource* owner)
- : m_ownerResource(owner)
+ RemoveListenerCallback removeListener)
+ : m_removeListener(removeListener)
{
m_jwListener = env->NewWeakGlobalRef(jListener);
}
{
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);
}
}
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,
private:
jweak m_jwListener;
- JniOcResource* m_ownerResource;
+ RemoveListenerCallback m_removeListener;
void checkExAndRemoveListener(JNIEnv* env);
};
#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)
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);
}
{
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);
}
}
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);
};
#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)
{
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);
}
}
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);
};
#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);
}
{
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);
}
}
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);
};
+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
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
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
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
#endif //__WITH_DTLS__ or __WITH_TLS__
#include "cacommon.h"
#include "byte_array.h"
+#include "octypes.h"
#ifdef __cplusplus
extern "C"
}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.
*
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__
#include "ocrandom.h"
#include "byte_array.h"
#include "octhread.h"
+#include "octypes.h"
#include "timer.h"
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
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)
return CA_STATUS_FAILED;
}
-
SslEndPoint_t * peer = GetSslPeer(&sep->endpoint);
if (NULL == peer)
{
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)
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);
'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']
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
*/
void CAStartTimerThread(void *data);
+void CALEClientScanThread();
+
/**
* Used to initialize all required mutex variable for Gatt Client implementation.
*
--- /dev/null
+/* ****************************************************************
+*
+* 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;
+}
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;
CALEGetErrorMsg(ret));
return CA_STATUS_FAILED;
}
+ g_gattReadCharPath = charPath;
+ }
+ else{
g_gattWriteCharPath = charPath;
}
*/
OCStackResult SetNumberOfSubOwner(size_t maxSubOwner);
-
#ifdef __cplusplus
}
#endif
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.
*/
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
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],
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
OTMCreateSecureSession createSecureSessionCB;\r
OTMCreatePayloadCallback createSelectOxmPayloadCB;\r
OTMCreatePayloadCallback createOwnerTransferPayloadCB;\r
+ OTMSelectMethodCallback selectOTMCB;\r
};\r
\r
/**\r
*/\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
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)
{
SetDisplayNumCB(NULL, displayNumCB);
SetUserConfirmCB(NULL, confirmNumCB);
SetInputStateCB(NULL, notifyInputStateCB);
+ SetSelectOTMCB(selectOTMcb);
// set callback for checking peer certificate information
OCSetPeerCertCallback(NULL, peerCertCallback);
#include "pkix_interface.h"
#include "hw_emul/hw_interface.h"
#include "oxmverifycommon.h"
+#include "casecurityinterface.h"
#define TAG "SAMPLE_MANUFACTURER_CERT"
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;
OCPersistentStorage ps = {server_fopen, fread, fwrite, fclose, unlink, NULL, NULL};
SetUserConfirmCB(NULL, confirmCB);
+ SetInformOxmSelCB(informOxmSelCB);
+ CAsetCertificateVerificationCallback(confirmNoCertCB);
OCRegisterPersistentStorageHandler(&ps);
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)
NOT_ALLOWED_OXM};
#endif
+static OTMSelectMethodCallback g_selectOTMCB = NULL;
+
OCStackResult OTMSetOTCallback(OicSecOxm_t oxm, OTMCallbackData_t* callbacks)
{
OCStackResult res = OC_STACK_INVALID_PARAM;
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.
*/
{
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]);
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:
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)
//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)
// 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;
}
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__)
}
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);
}
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 =
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");
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)
}
//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");
#define TAG "OIC_SRM_PKIX_INTERFACE"
+#define ECC256_SIG_LEN 32+4
+
static HWPkixContext_t gHwPkixCtx = {
.getHwKeyContext = NULL,
.freeHwKeyContext = NULL,
if(NULL == derCrtBufTmp)
{
OIC_LOG (ERROR, TAG, "Failed to allocate memory.");
+ OICFree(certCopy);
goto exit;
}
* | 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;
{
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;
{
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;
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__);
}
// 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;
}
*/
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)
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)
#include "oic_string.h"
#include "base64.h"
#include "doxmresource.h"
+#include "credresource.h"
#include "pstatresource.h"
#include "cacommon.h"
#include "casecurityinterface.h"
//Restore Pkix handler to initial state
CAregisterPkixInfoHandler(GetPkixInfo);
CAregisterGetCredentialTypesHandler(InitCipherSuiteList);
+ CAregisterPskCredentialsHandler(GetDtlsPskCredentials);
break;
default:
OIC_LOG_V(ERROR, TAG, "Unknow OTM event : %d", event);
#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
OC_PRESENCE_TRIGGER_DELETE = 2
} OCPresenceTrigger;
#endif
-
-#endif
*/
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.
*/
OCStackResult OCStopPresence();
-#endif // WITH_PRESENCE
-
/**
* This function sets default device entity handler.
*/
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
/** 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"
/** 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.
*/
/** To delete.*/
#define OC_RSRVD_TRIGGER_DELETE "delete"
-#endif // WITH_PRESENCE
-
/**
* Attributes used to form a proper OIC conforming JSON message.
*/
/** 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"
/** 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;
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,
PAYLOAD_TYPE_REPRESENTATION,
/** The payload is an OCSecurityPayload */
PAYLOAD_TYPE_SECURITY,
-#ifdef WITH_PRESENCE
/** The payload is an OCPresencePayload */
PAYLOAD_TYPE_PRESENCE
-#endif
} OCPayloadType;
/**
size_t payloadSize;
} OCSecurityPayload;
-#ifdef WITH_PRESENCE
typedef struct
{
OCPayload base;
OCPresenceTrigger trigger;
char* resourceType;
} OCPresencePayload;
-#endif
/**
* Incoming requests handled by the server. Requests are passed in as a parameter to the
* 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
#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);
}
}
-#ifdef WITH_PRESENCE
INLINE_API void OCPayloadLogPresence(LogLevel level, OCPresencePayload* payload)
{
OIC_LOG(level, PL_TAG, "Payload Type: Presence");
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)
{
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
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,
return ret;
}
+OCStackResult OCGetDeviceOperationalState(bool* isOp)
+{
+ if(NULL != isOp)
+ {
+ *isOp = GetPstatIsop();
+ return OC_STACK_OK;
+ }
+
+ return OC_STACK_ERROR;
+}
+
void OCClearCallBackList()
{
DeleteClientCBList();
#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.
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");
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;
}
oc_mutex_unlock(g_mutexObjectList);
OIC_LOG(ERROR, TAG, "Failed to add new KeepAlive entry");
OICFree(devAddr);
+ OCPayloadDestroy(payload);
return OC_STACK_ERROR;
}
}
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;
OIC_LOG(DEBUG, TAG, "SendKeepAliveRequest OUT");
OICFree(devAddr);
return result;
+
+exit:
+ OCPayloadDestroy(payload);
+ return (ret);
}
OCStackResult OCHandleKeepAliveResponse(const CAEndpoint_t *endPoint, const OCPayload *payload)
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
{
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
*/