presenceMapLock.unlock();
}
+JniOnObserveListener* AddOnObserveListener(JNIEnv* env, jobject jListener)
+{
+ JniOnObserveListener *onObserveListener = nullptr;
+
+ observeMapLock.lock();
+
+ for (auto it = onObserveListenerMap.begin(); it != onObserveListenerMap.end(); ++it)
+ {
+ if (env->IsSameObject(jListener, it->first))
+ {
+ auto refPair = it->second;
+ onObserveListener = refPair.first;
+ refPair.second++;
+ it->second = refPair;
+ onObserveListenerMap.insert(*it);
+ LOGD("OnObserveListener: ref. count incremented");
+ break;
+ }
+ }
+ if (!onObserveListener)
+ {
+ onObserveListener = new JniOnObserveListener(env, jListener, nullptr);
+ jobject jgListener = env->NewGlobalRef(jListener);
+ onObserveListenerMap.insert(
+ std::pair<jobject, std::pair<JniOnObserveListener*, int>>(
+ jgListener,
+ std::pair<JniOnObserveListener*, int>(onObserveListener, 1)));
+ LOGI("OnObserveListener: new listener");
+ }
+ observeMapLock.unlock();
+ return onObserveListener;
+}
+
+void RemoveOnObserveListener(JNIEnv* env, jobject jListener)
+{
+ observeMapLock.lock();
+ bool isFound = false;
+ for (auto it = onObserveListenerMap.begin(); it != onObserveListenerMap.end(); ++it)
+ {
+ if (env->IsSameObject(jListener, it->first))
+ {
+ auto refPair = it->second;
+ if (refPair.second > 1)
+ {
+ refPair.second--;
+ it->second = refPair;
+ onObserveListenerMap.insert(*it);
+ LOGI("OnObserveListener: ref. count decremented");
+ }
+ else
+ {
+ env->DeleteGlobalRef(it->first);
+ JniOnObserveListener* listener = refPair.first;
+ delete listener;
+ onObserveListenerMap.erase(it);
+ LOGI("OnObserveListener is removed");
+ }
+ isFound = true;
+ break;
+ }
+ }
+ if (!isFound)
+ {
+ ThrowOcException(JNI_EXCEPTION, "OnObserveListener not found");
+ }
+ observeMapLock.unlock();
+}
+
JniOnDPDevicesFoundListener* AddOnDPDevicesFoundListener(JNIEnv* env, jobject jListener)
{
JniOnDPDevicesFoundListener *onDPDeviceListener = nullptr;
{
RemoveOnPresenceListener(env, jwOnPresenceListener);
}
+ jweak jwOnObserveListener =
+ jniPresenceHandle->getJniOnObserveListener()->getJWListener();
+ if (jwOnObserveListener)
+ {
+ RemoveOnObserveListener(env, jwOnObserveListener);
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+* Class: org_iotivity_base_OcPlatform
+* Method: subscribeDevicePresence0
+* Signature: (Ljava/lang/String;[Ljava/lang/String;I
+Lorg/iotivity/base/OcResource/OnObserveListener;)Lorg/iotivity/base/OcPresenceHandle;
+*/
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribeDevicePresence0(
+ JNIEnv *env,
+ jclass clazz,
+ jstring jHost,
+ jobjectArray jDiArray,
+ jint jConnectivityType,
+ jobject jListener)
+{
+ LOGD("OcPlatform_subscribeDevicePresence0");
+#ifdef WITH_CLOUD
+ std::string host;
+ if (jHost)
+ {
+ host = env->GetStringUTFChars(jHost, nullptr);
+ }
+
+ if (!jDiArray)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "device id List cannot be null");
+ return nullptr;
+ }
+
+ std::vector<std::string> di;
+ JniUtils::convertJavaStrArrToStrVector(env, jDiArray, di);
+
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "onObserveListener cannot be null");
+ return nullptr;
+ }
+
+ 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);
+ };
+
+ OCPlatform::OCPresenceHandle presenceHandle;
+ try
+ {
+ OCStackResult result = OCPlatform::subscribeDevicePresence(
+ presenceHandle,
+ host,
+ di,
+ static_cast<OCConnectivityType>(jConnectivityType),
+ observeCallback);
+
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "subscribe device presence has failed");
+ }
}
catch (OCException& e)
{
LOGE("%s", e.reason().c_str());
ThrowOcException(e.code(), e.reason().c_str());
+ return nullptr;
+ }
+
+ JniOcPresenceHandle* jniPresenceHandle =
+ new JniOcPresenceHandle(onObserveListener, presenceHandle);
+ jlong jhandle = reinterpret_cast<jlong>(jniPresenceHandle);
+ jobject jPresenceHandle =
+ env->NewObject(g_cls_OcPresenceHandle, g_mid_OcPresenceHandle_N_ctor, jhandle);
+ if (!jPresenceHandle)
+ {
+ LOGE("Failed to create OcPresenceHandle");
+ delete jniPresenceHandle;
}
+ return jPresenceHandle;
+#else
+ ThrowOcException(JNI_EXCEPTION, "Not support");
+ return nullptr;
+#endif
}
/*
jstring jHost,
jint jConnectivityType,
jobjectArray jResourceHandleArray,
- jint jQoS,
- jobject jListener)
+ jobject jListener,
+ jint jQoS)
{
LOGD("OcPlatform_publishResourceToRD");
#ifdef RD_CLIENT
jstring jHost,
jint jConnectivityType,
jobjectArray jResourceHandleArray,
- jint jQoS,
- jobject jListener)
+ jobject jListener,
+ jint jQoS)
{
LOGD("OcPlatform_deleteResourceFromRD");
#ifdef RD_CLIENT
#include "JniOnDPDevicesFoundListener.h"
#include "JniOnDirectPairingListener.h"
#include "JniOnPresenceListener.h"
+#include "JniOnObserveListener.h"
#include "JniOnPublishResourceListener.h"
#include "JniOnDeleteResourceListener.h"
#include <mutex>
JniOnPresenceListener* AddOnPresenceListener(JNIEnv* env, jobject jListener);
void RemoveOnPresenceListener(JNIEnv* env, jobject jListener);
+JniOnObserveListener* AddOnObserveListener(JNIEnv* env, jobject jListener);
+void RemoveOnObserveListener(JNIEnv* env, jobject jListener);
+
JniOnDPDevicesFoundListener* AddOnDPDevicesFoundListener(JNIEnv* env, jobject jListener);
void RemoveOnDPDevicesFoundListener(JNIEnv* env, jobject jListener);
std::map<jobject, std::pair<JniOnDeviceInfoListener*, int>> onDeviceInfoListenerMap;
std::map<jobject, std::pair<JniOnPlatformInfoListener*, int>> onPlatformInfoListenerMap;
std::map<jobject, std::pair<JniOnPresenceListener*, int>> onPresenceListenerMap;
+std::map<jobject, std::pair<JniOnObserveListener*, int>> onObserveListenerMap;
std::map<jobject, std::pair<JniOnDPDevicesFoundListener*, int>> onDPDevicesFoundListenerMap;
std::map<jobject, std::pair<JniOnDirectPairingListener*, int>> directPairingListenerMap;
std::map<jobject, std::pair<JniOnPublishResourceListener*, int>> onPublishResourceListenerMap;
std::mutex deviceInfoMapLock;
std::mutex platformInfoMapLock;
std::mutex presenceMapLock;
+std::mutex observeMapLock;
std::mutex dpDevicesFoundListenerMapLock;
std::mutex directPairingListenerMapLock;
std::mutex publishResourceListenerMapLock;
/*
* Class: org_iotivity_base_OcPlatform
+ * Method: subscribeDevicePresence0
+ * Signature: (Ljava/lang/String;[Ljava/lang/String;I
+ * Lorg/iotivity/base/OcResource/OnObserveListener;)Lorg/iotivity/base/OcPresenceHandle;
+ */
+ JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcPlatform_subscribeDevicePresence0
+ (JNIEnv *, jclass, jstring, jobjectArray, jint, jobject);
+
+ /*
+ * Class: org_iotivity_base_OcPlatform
* Method: constructResourceObject0
* Signature: (Ljava/lang/String;Ljava/lang/String;IZ[Ljava/lang/String;[Ljava/lang/String;)Lorg/iotivity/base/OcResource;
*/
{
}
+JniOcPresenceHandle::JniOcPresenceHandle(JniOnObserveListener* jniListener, OCPresenceHandle presenceHandle)
+ : m_jniObserveListener(jniListener), m_presenceHandle(presenceHandle)
+{
+}
+
JniOcPresenceHandle::~JniOcPresenceHandle()
{
LOGD("~JniOcPresenceHandle()");
return this->m_jniListener;
}
+JniOnObserveListener* JniOcPresenceHandle::getJniOnObserveListener()
+{
+ return this->m_jniObserveListener;
+}
+
/*
* Class: org_iotivity_base_OcPresenceHandle
* Method: dispose
* //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
*/
#include "JniOcStack.h"
+#include "JniOnObserveListener.h"
#include "JniOnPresenceListener.h"
#include "OCPlatform.h"
public:
JniOcPresenceHandle(JniOnPresenceListener* jniListener, OCPresenceHandle presenceHandle);
+ JniOcPresenceHandle(JniOnObserveListener* jniListener, OCPresenceHandle presenceHandle);
~JniOcPresenceHandle();
JniOcPresenceHandle(const JniOcPresenceHandle &) = delete;
void operator=(const JniOcPresenceHandle &) = delete;
OCPresenceHandle getOCPresenceHandle();
JniOnPresenceListener* getJniOnPresenceListener();
+ JniOnObserveListener* getJniOnObserveListener();
private:
JniOnPresenceListener* m_jniListener;
+ JniOnObserveListener* m_jniObserveListener;
OCPresenceHandle m_presenceHandle;
};
m_ownerResource->removeOnObserveListener(env, m_jwListener);
}
}
+
+jweak JniOnObserveListener::getJWListener()
+{
+ return this->m_jwListener;
+}
~JniOnObserveListener();
void onObserveCallback(const HeaderOptions headerOptions, const OCRepresentation& rep,
const int& eCode, const int& sequenceNumber);
+ jweak getJWListener();
private:
jweak m_jwListener;
JniOcResource* m_ownerResource;
OcPresenceHandle ocPresenceHandle) throws OcException;
/**
+ * Subscribes to a server's device presence change events.
+ *
+ * @param host The IP address/addressable name of the server to subscribe to.
+ * @param di Vector which can have the devices id.
+ * @param connectivityTypeSet Set of connectivity types, e.g. IP.
+ * @param onObserveListener The handler method will be invoked with a map
+ * of attribute name and values.
+ * @return a handle object that can be used to identify this subscription request.
+ * It can be used to unsubscribe from these events in the future.
+ * @throws OcException if failure.
+ */
+ public static OcPresenceHandle subscribeDevicePresence(
+ String host,
+ List<String> di,
+ EnumSet<OcConnectivityType> connectivityTypeSet,
+ OcResource.OnObserveListener onObserveListener) throws OcException {
+ OcPlatform.initCheck();
+ int connTypeInt = 0;
+
+ for (OcConnectivityType connType : OcConnectivityType.values()) {
+ if (connectivityTypeSet.contains(connType))
+ connTypeInt |= connType.getValue();
+ }
+ return OcPlatform.subscribeDevicePresence0(
+ host,
+ di.toArray(new String[di.size()]),
+ connTypeInt,
+ onObserveListener);
+ }
+
+ private static native OcPresenceHandle subscribeDevicePresence0(
+ String host,
+ String[] di,
+ int connectivityType,
+ OcResource.OnObserveListener onObserveListener) throws OcException;
+
+ /**
* Creates a resource proxy object so that get/put/observe functionality can be used without
* discovering the object in advance. Note that the consumer of this method needs to provide
* all of the details required to correctly contact and observe the object. If the consumer