ANDROID_RELEASE="release"
else:
ANDROID_RELEASE="debug"
+ANDROID_SECURED = env.get('SECURED')
os.environ['ANDROID_HOME'] = env.get('ANDROID_HOME')
os.environ['ANDROID_NDK_HOME'] = env.get('ANDROID_NDK')
return target, [source, env.get('BUILD_DIR') + 'liboc.so', env.get('BUILD_DIR') + 'liboc_logger.so']
jdk_env = Environment(ENV=os.environ)
-jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PTARGET_ARCH=%s -PRELEASE=%s --stacktrace' %(ANDROID_TARGET_ARCH, ANDROID_RELEASE), emitter = ensure_libs)
+jdk_env['BUILDERS']['Gradle'] = Builder(action = env.get('ANDROID_GRADLE') + ' build -b' + os.getcwd()+'/build.gradle -PSECURED=%s -PTARGET_ARCH=%s -PRELEASE=%s --stacktrace' %(ANDROID_SECURED, ANDROID_TARGET_ARCH, ANDROID_RELEASE), emitter = ensure_libs)
jdk_env['BUILD_DIR'] = env.get('BUILD_DIR')
jdk_env.Gradle(target="base/objs", source="base/src/main/java/org/iotivity/base/OcResource.java")
//for windows use 'ndk-build.cmd'\r
//def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd')\r
def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')\r
- commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE"\r
+ commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", "SECURE=$SECURED"
} else {\r
println '##################'\r
println 'Skipping NDK build'\r
LOCAL_PATH := $(call my-dir)\r
TARGET_ARCH_ABI := $(APP_ABI)\r
+SECURED := $(SECURE)
\r
include $(CLEAR_VARS)\r
OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)\r
LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so\r
include $(PREBUILT_SHARED_LIBRARY)\r
\r
+ifeq ($(SECURED), 1)
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
+LOCAL_MODULE := libandroid-ocprovision
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocprovision.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../out/android/$(APP_ABI)/$(APP_OPTIM)
+LOCAL_MODULE := libandroid-ocpmapi
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocpmapi.a
+include $(PREBUILT_STATIC_LIBRARY)
+endif
+
include $(CLEAR_VARS)\r
OIC_SRC_PATH := ../../../resource\r
LOCAL_MODULE := libca-interface\r
JniOcResource.cpp \\r
JniOcResourceIdentifier.cpp \
JniOcSecurity.cpp
+ifeq ($(SECURED), 1)
+LOCAL_SRC_FILES += JniOcSecureResource.cpp \
+ JniOcProvisioning.cpp \
+ JniSecureUtils.cpp \
+ JniProvisionResultListner.cpp \
+ JniPinCheckListener.cpp
+endif
\r
LOCAL_LDLIBS := -llog\r
LOCAL_STATIC_LIBRARIES := android-oc\r
LOCAL_STATIC_LIBRARIES += android-oc_logger\r
LOCAL_STATIC_LIBRARIES += android-ca\r
LOCAL_STATIC_LIBRARIES += android_cpp11_compat\r
+ifeq ($(SECURED), 1)
+LOCAL_STATIC_LIBRARIES += android-ocprovision
+LOCAL_STATIC_LIBRARIES += android-ocpmapi
+endif
\r
LOCAL_CPPFLAGS += -std=c++0x\r
LOCAL_CPP_FEATURES := rtti exceptions\r
LOCAL_C_INCLUDES := $(OIC_SRC_PATH)/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/c_common\r
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/c_common/oic_string/include
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/stack/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/ocsocket/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/oc_logger/include\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../extlibs/boost/boost_1_58_0\r
LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/../build_common/android/compatibility\r
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include/oxm/
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/provisioning/include/internal
+LOCAL_C_INCLUDES += $(OIC_SRC_PATH)/csdk/security/include
include $(BUILD_SHARED_LIBRARY)\r
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcProvisioning.h"
+#include "JniPinCheckListener.h"
+
+using namespace OC;
+namespace PH = std::placeholders;
+
+static JniPinCheckListener *PinListener = nullptr;
+
+void Callback(char *buf, size_t size)
+{
+ if (PinListener)
+ {
+ PinListener->PinCallback(buf, size);
+ }
+ else
+ {
+ LOGE("PinListener is null");
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: ownershipTransferCDdata
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_ownershipTransferCBdata
+ (JNIEnv *env, jobject thiz, jint OxmType, jobject jListener)
+{
+ LOGD("OcProvisioning_ownershipTransferCBdata");
+ OCStackResult result = OC_STACK_ERROR;
+
+ try
+ {
+ OTMCallbackData_t CBData = {0};
+ if (OIC_JUST_WORKS == (OicSecOxm_t)OxmType)
+ {
+ CBData.loadSecretCB = LoadSecretJustWorksCallback;
+ CBData.createSecureSessionCB = CreateSecureSessionJustWorksCallback;
+ CBData.createSelectOxmPayloadCB = CreateJustWorksSelectOxmPayload;
+ CBData.createOwnerTransferPayloadCB = CreateJustWorksOwnerTransferPayload;
+
+ result = OCSecure::setOwnerTransferCallbackData((OicSecOxm_t)OxmType,
+ &CBData, NULL);
+ }
+ if (OIC_RANDOM_DEVICE_PIN == (OicSecOxm_t)OxmType)
+ {
+ if (jListener)
+ {
+ delete PinListener;
+ PinListener = new JniPinCheckListener(env, jListener);
+ CBData.loadSecretCB = InputPinCodeCallback;
+ CBData.createSecureSessionCB = CreateSecureSessionRandomPinCallbak;
+ CBData.createSelectOxmPayloadCB = CreatePinBasedSelectOxmPayload;
+ CBData.createOwnerTransferPayloadCB = CreatePinBasedOwnerTransferPayload;
+ result = OCSecure::setOwnerTransferCallbackData((OicSecOxm_t)OxmType,
+ &CBData, Callback);
+ }
+ else
+ {
+ result = OC_STACK_ERROR;
+ }
+ }
+
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcProvisioning_ownershipTransferCDdata");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+* Class: org_iotivity_base_OcProvisioning
+* Method: discoverUnownedDevices
+* Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+*/
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_discoverUnownedDevices1
+ (JNIEnv *env, jclass clazz, jint timeout)
+{
+ LOGI("OcProvisioning_discoverUnownedDevices");
+ DeviceList_t list;
+
+ try
+ {
+ OCStackResult result = OCSecure::discoverUnownedDevices((unsigned short)timeout, list);
+
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "Failed to discover Unowned devices");
+ return nullptr;
+ }
+
+ return JniSecureUtils::convertDeviceVectorToJavaArray(env, list);
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: provisionInit
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionInit
+ (JNIEnv *env, jclass calzz, jstring jdbPath)
+{
+ LOGI("OcProvisioning_provisionInit");
+ char *dbpath;
+
+ if (!jdbPath)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "SVR db path cannot be null");
+ return;
+ }
+
+ try
+ {
+ dbpath = (char*)env->GetStringUTFChars(jdbPath, NULL);
+ OCStackResult result = OCSecure::provisionInit(env->GetStringUTFChars(jdbPath, NULL));
+
+ if (OC_STACK_OK != result)
+ {
+ env->ReleaseStringUTFChars(jdbPath, (const char*)dbpath);
+ ThrowOcException(result, "Failed to Init Provisioning Manager");
+ return;
+ }
+ env->ReleaseStringUTFChars(jdbPath, (const char*)dbpath);
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: discoverOwnedDevices
+ * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_discoverOwnedDevices1
+ (JNIEnv *env, jclass clazz , jint timeout)
+{
+ LOGI("OcProvisioning_discoverOwnedDevices");
+ DeviceList_t list;
+
+ try
+ {
+ OCStackResult result = OCSecure::discoverOwnedDevices((unsigned short)timeout, list);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "Failed to discover Owned devices");
+ return nullptr;
+ }
+
+ return JniSecureUtils::convertDeviceVectorToJavaArray(env, list);
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: getDevicestatusLists
+ * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_getDeviceStatusList1
+ (JNIEnv *env, jclass clazz, jint timeout)
+{
+ LOGI("OcProvisioning_getDeviceStatusList");
+ DeviceList_t ownedDevList, unownedDevList;
+
+ try
+ {
+ OCStackResult result = OCSecure::getDevInfoFromNetwork((unsigned short)timeout,
+ ownedDevList, unownedDevList);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "Failed to get Device Status List");
+ return nullptr;
+ }
+ ownedDevList.insert(ownedDevList.end(), unownedDevList.begin(), unownedDevList.end());
+ return JniSecureUtils::convertDeviceVectorToJavaArray(env, ownedDevList);
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(OC_STACK_ERROR, e.reason().c_str());
+ }
+}
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcStack.h"
+#include "OCProvisioningManager.h"
+#include "JniSecureUtils.h"
+#include "oxmjustworks.h"
+#include "oxmrandompin.h"
+#include <jni.h>
+#include <mutex>
+
+#ifndef _Included_org_iotivity_base_OcProvisioning
+#define _Included_org_iotivity_base_OcProvisioning
+
+using namespace OC;
+
+/* DO NOT EDIT THIS FILE - it is machine generated */
+/* Header for class org_iotivity_base_OcProvisioning */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: ownershipTransferCDdata
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_ownershipTransferCBdata
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: discoverUnownedDevices
+ * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_discoverUnownedDevices1
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: provisionInit
+ * Signature: (Ljava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcProvisioning_provisionInit
+ (JNIEnv *, jclass, jstring);
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: discoverOwnedDevices
+ * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_discoverOwnedDevices1
+ (JNIEnv *, jclass, jint);
+
+/*
+ * Class: org_iotivity_base_OcProvisioning
+ * Method: getDevicestatusLists
+ * Signature: (I)[Lorg/iotivity/base/OcSecureResource;
+ */
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_base_OcProvisioning_getDeviceStatusList1
+ (JNIEnv *, jclass, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcSecureResource.h"
+#include "JniSecureUtils.h"
+namespace PH = std::placeholders;
+
+JniOcSecureResource::JniOcSecureResource(std::shared_ptr<OCSecureResource> device)
+ : m_sharedSecureResource(device)
+{}
+
+JniOcSecureResource::~JniOcSecureResource()
+{
+ LOGD("~JniOcSecureResource()");
+ m_sharedSecureResource = nullptr;
+}
+
+std::string JniOcSecureResource::getIpAddr()
+{
+ return m_sharedSecureResource->getDevAddr();
+}
+
+std::string JniOcSecureResource::getDeviceID()
+{
+ return m_sharedSecureResource->getDeviceID();
+}
+
+int JniOcSecureResource::getDeviceStatus()
+{
+ return m_sharedSecureResource->getDeviceStatus();
+}
+
+bool JniOcSecureResource::getOwnedStatus()
+{
+ return m_sharedSecureResource->getOwnedStatus();
+}
+
+OCSecureResource* JniOcSecureResource::getDevicePtr()
+{
+ return m_sharedSecureResource.get();
+}
+
+JniOcSecureResource* JniOcSecureResource::getJniOcSecureResourcePtr(JNIEnv *env, jobject thiz)
+{
+ JniOcSecureResource *secureResource = GetHandle<JniOcSecureResource>(env, thiz);
+ if (env->ExceptionCheck())
+ {
+ LOGE("Failed to get native handle from OcSecureResource");
+ }
+ if (!secureResource)
+ {
+ ThrowOcException(JNI_NO_NATIVE_POINTER, "");
+ }
+ return secureResource;
+}
+
+JniProvisionResultListner* JniOcSecureResource::AddProvisionResultListener(JNIEnv* env,
+ jobject jListener)
+{
+ JniProvisionResultListner *resultListener = NULL;
+ resultMapLock.lock();
+
+ for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
+ {
+ if (env->IsSameObject(jListener, it->first))
+ {
+ auto refPair = it->second;
+ resultListener = refPair.first;
+ refPair.second++;
+ it->second = refPair;
+ resultMap.insert(*it);
+ LOGD("Provision resultListener: ref. count incremented");
+ break;
+ }
+ }
+ if (!resultListener)
+ {
+ resultListener = new JniProvisionResultListner(env, jListener,
+ RemoveCallback(std::bind(&JniOcSecureResource::RemoveProvisionResultListener,
+ this, PH::_1, PH::_2)));
+ jobject jgListener = env->NewGlobalRef(jListener);
+
+ resultMap.insert(std::pair < jobject, std::pair < JniProvisionResultListner*,
+ int >> (jgListener, std::pair<JniProvisionResultListner*, int>(resultListener, 1)));
+ LOGD("Provision resultListener: new listener");
+ }
+ resultMapLock.unlock();
+ return resultListener;
+}
+
+void JniOcSecureResource::RemoveProvisionResultListener(JNIEnv* env, jobject jListener)
+{
+ resultMapLock.lock();
+
+ for (auto it = resultMap.begin(); it != resultMap.end(); ++it)
+ {
+ if (env->IsSameObject(jListener, it->first))
+ {
+ auto refPair = it->second;
+ if (refPair.second > 1)
+ {
+ refPair.second--;
+ it->second = refPair;
+ resultMap.insert(*it);
+ LOGI("Provision resultListener: ref. count decremented");
+ }
+ else
+ {
+ env->DeleteGlobalRef(it->first);
+ JniProvisionResultListner* listener = refPair.first;
+ delete listener;
+ resultMap.erase(it);
+ LOGI("Provision resultListener removed");
+ }
+ break;
+ }
+ }
+ resultMapLock.unlock();
+}
+
+OCStackResult JniOcSecureResource::doOwnershipTransfer(JNIEnv* env, jobject jListener)
+{
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+
+ ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
+ {
+ resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::OWNERSHIPTRANSFER);
+ };
+
+ return m_sharedSecureResource->doOwnershipTransfer(resultCallback);
+}
+
+OCStackResult JniOcSecureResource::getLinkedDevices(JNIEnv *env, UuidList_t &uuidList)
+{
+ return m_sharedSecureResource->getLinkedDevices(uuidList);
+}
+
+OCStackResult JniOcSecureResource::removeDevice(JNIEnv* env, jint timeout, jobject jListener)
+{
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+
+ ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
+ {
+ resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::REMOVEDEVICE);
+ };
+
+ return m_sharedSecureResource->removeDevice((int)timeout, resultCallback);
+}
+
+OCStackResult JniOcSecureResource::unlinkDevices(JNIEnv* env, jobject _device2, jobject jListener)
+{
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+
+ ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
+ {
+ resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::UNLINKDEVICES);
+ };
+
+ JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
+ if (!device2)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ return m_sharedSecureResource->unlinkDevices(*device2->getDevicePtr(), resultCallback);
+}
+
+OCStackResult JniOcSecureResource::provisionCredentials(JNIEnv* env, jint type, jint keySize,
+ jobject _device2, jobject jListener)
+{
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+
+ ResultCallBack resultCallback = [resultListener](PMResultList_t *result, int hasError)
+ {
+ resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::PROVISIONCREDENTIALS);
+ };
+
+ JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
+ if (!device2)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ Credential cred((OicSecCredType_t)type, keySize);
+
+ return m_sharedSecureResource->provisionCredentials(cred, *device2->getDevicePtr(),
+ resultCallback);
+}
+
+OCStackResult JniOcSecureResource::provisionACL(JNIEnv* env, jobject _acl, jobject jListener)
+{
+ OCStackResult ret;
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+ OicSecAcl_t *acl = new OicSecAcl_t;
+ acl->next = nullptr;
+ if (!acl)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl, acl))
+ {
+ delete acl;
+ return OC_STACK_ERROR;
+ }
+
+ ResultCallBack resultCallback = [acl, resultListener](PMResultList_t *result, int hasError)
+ {
+ delete acl;
+ resultListener->ProvisionResultCallback(result, hasError, ListenerFunc::PROVISIONACL);
+ };
+ ret = m_sharedSecureResource->provisionACL(acl, resultCallback);
+
+ if (ret != OC_STACK_OK)
+ {
+ delete acl;
+
+ }
+ return ret;
+}
+
+OCStackResult JniOcSecureResource::provisionPairwiseDevices(JNIEnv* env, jint type, jint keySize,
+ jobject _acl1, jobject _device2, jobject _acl2, jobject jListener)
+{
+ OCStackResult ret;
+
+ JniProvisionResultListner *resultListener = AddProvisionResultListener(env, jListener);
+ JniOcSecureResource *device2 = JniOcSecureResource::getJniOcSecureResourcePtr(env, _device2);
+ if (!device2)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ Credential cred((OicSecCredType_t)type, keySize);
+
+ OicSecAcl_t *acl1 = nullptr;
+ OicSecAcl_t *acl2 = nullptr;
+
+ if (_acl1)
+ {
+ acl1 = new OicSecAcl_t;
+ if (!acl1)
+ {
+ return OC_STACK_NO_MEMORY;
+ }
+
+ if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl1, acl1))
+ {
+ delete acl1;
+ return OC_STACK_ERROR;
+ }
+ acl1->next = nullptr;
+ }
+
+ if (_acl2)
+ {
+ acl2 = new OicSecAcl_t;
+ if (!acl2)
+ {
+ delete acl1;
+ return OC_STACK_NO_MEMORY;
+ }
+
+ if (OC_STACK_OK != JniSecureUtils::convertJavaACLToOCAcl(env, _acl2, acl2))
+ {
+ delete acl2;
+ return OC_STACK_ERROR;
+ }
+ acl2->next = nullptr;
+ }
+
+ ResultCallBack resultCallback = [acl1, acl2, resultListener](PMResultList_t *result,
+ int hasError)
+ {
+ delete acl1;
+ delete acl2;
+ resultListener->ProvisionResultCallback(result, hasError,
+ ListenerFunc::PROVISIONPAIRWISEDEVICES);
+ };
+
+
+ ret = m_sharedSecureResource->provisionPairwiseDevices(cred, acl1,
+ *device2->getDevicePtr(), acl2, resultCallback);
+ if (ret != OC_STACK_OK)
+ {
+ delete acl1;
+ delete acl2;
+ }
+ return ret;
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: doOwnershipTransfer
+ * Signature: (Lorg/iotivity/base/OcSecureResource/doOwnershipTransferListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_doOwnershipTransfer
+(JNIEnv *env, jobject thiz, jobject jListener)
+{
+ LOGD("OcSecureResource_doOwnershipTransfer");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->doOwnershipTransfer(env, jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_doOwnershipTransfer");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: removeDevice
+ * Signature: (ILorg/iotivity/base/OcSecureResource/removeDevice;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_removeDevice
+(JNIEnv *env, jobject thiz, jint timeout, jobject jListener)
+{
+ LOGD("OcSecureResource_removeDevice");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->removeDevice(env, timeout, jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_removeDevice");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: unlinkDevices
+ * Signature: (Lorg/iotivity/base/OcSecureResource/unlinkDevices;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_unlinkDevices
+(JNIEnv *env, jobject thiz, jobject device2, jobject jListener)
+{
+ LOGD("OcSecureResource_unlinkDevices");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->unlinkDevices(env, device2, jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_unlinkDevices");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionCredentials1
+ * Signature: (Lorg/iotivity/base/OcSecureResource/provisionCredentials;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionCredentials1
+(JNIEnv *env, jobject thiz, jint type, jint keySize, jobject device2, jobject jListener)
+{
+ LOGD("OcSecureResource_provisionCredentials");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->provisionCredentials(env, type, keySize, device2,
+ jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_provisionCredentials");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionACL
+ * Signature: (Lorg/iotivity/base/OcSecureResource/provisionACL;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionACL
+(JNIEnv *env, jobject thiz, jobject acl, jobject jListener)
+{
+ LOGD("OcSecureResource_provisionACL");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->provisionACL(env, acl, jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_provisionACL");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionPairwiseDevices1
+ * Signature: (Lorg/iotivity/base/OcSecureResource/provisionPairwiseDevices;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionPairwiseDevices1
+(JNIEnv *env, jobject thiz, jint type, jint keySize, jobject acl1, jobject device2,
+ jobject acl2, jobject jListener)
+{
+ LOGD("OcSecureResource_provisionPairwiseDevices");
+ if (!jListener)
+ {
+ ThrowOcException(OC_STACK_INVALID_PARAM, "provisionResultListener cannot be null");
+ return;
+ }
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->provisionPairwiseDevices(env, type, keySize,
+ acl1, device2, acl2, jListener);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_provisionPairwiseDevices");
+ return;
+ }
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getLinkedDevices
+ * Signature: ()Ljava/util/List;
+ */
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcSecureResource_getLinkedDevices
+(JNIEnv *env, jobject thiz)
+{
+ LOGD("OcSecureResource_getLinkedDevices");
+ UuidList_t uuidList;
+
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return nullptr;
+ }
+
+ try
+ {
+ OCStackResult result = secureResource->getLinkedDevices(env, uuidList);
+ if (OC_STACK_OK != result)
+ {
+ ThrowOcException(result, "OcSecureResource_getLinkedDevices");
+ return nullptr;
+ }
+ return JniSecureUtils::convertUUIDVectorToJavaStrList(env, uuidList);
+ }
+ catch (OCException& e)
+ {
+ LOGE("%s", e.reason().c_str());
+ ThrowOcException(e.code(), e.reason().c_str());
+ }
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getIpAddr
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getIpAddr
+ (JNIEnv *env, jobject thiz)
+{
+ LOGD("OcSecureResource_getIpAddr");
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return nullptr;
+ }
+
+ return env->NewStringUTF(secureResource->getIpAddr().c_str());
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getDeviceID
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getDeviceID
+ (JNIEnv *env , jobject thiz)
+{
+ LOGD("OcSecureResource_getDeviceID");
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return nullptr;
+ }
+
+ return env->NewStringUTF(secureResource->getDeviceID().c_str());
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: deviceStatus
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_deviceStatus
+ (JNIEnv *env, jobject thiz)
+{
+ LOGD("OcSecureResource_deviceStatus");
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return -1;
+ }
+
+ return secureResource->getDeviceStatus();
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: ownedStatus
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_ownedStatus
+ (JNIEnv *env, jobject thiz)
+{
+ LOGD("OcSecureResource_ownedStatus");
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ if (!secureResource)
+ {
+ return -1;
+ }
+
+ return secureResource->getOwnedStatus();
+}
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: dispose
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_dispose
+ (JNIEnv *env, jobject thiz)
+{
+ LOGD("OcSecureResource_dispose");
+ JniOcSecureResource *secureResource = JniOcSecureResource::getJniOcSecureResourcePtr(env, thiz);
+ delete secureResource;
+}
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcStack.h"
+#include "JniProvisionResultListner.h"
+#include "OCProvisioningManager.h"
+#include <mutex>
+
+#ifndef _Included_org_iotivity_base_OcSecureResource
+#define _Included_org_iotivity_base_OcSecureResource
+
+using namespace OC;
+
+class JniOcSecureResource
+{
+ public:
+ JniOcSecureResource(std::shared_ptr<OCSecureResource> secureresource);
+ ~JniOcSecureResource();
+
+ static JniOcSecureResource* getJniOcSecureResourcePtr(JNIEnv *env, jobject thiz);
+ std::string getDeviceID(void);
+ std::string getIpAddr(void);
+ int getDeviceStatus(void);
+ bool getOwnedStatus(void);
+ OCSecureResource* getDevicePtr();
+
+ JniProvisionResultListner* AddProvisionResultListener(JNIEnv* env, jobject jListener);
+ void RemoveProvisionResultListener(JNIEnv* env, jobject jListener);
+
+ OCStackResult doOwnershipTransfer(JNIEnv* env, jobject jListener);
+ OCStackResult getLinkedDevices(JNIEnv *env, UuidList_t &uuidList);
+ OCStackResult provisionACL(JNIEnv* env, jobject acl, jobject jListener);
+ OCStackResult provisionPairwiseDevices(JNIEnv* env, jint type, jint keySize,
+ jobject acl1, jobject device2, jobject acl2, jobject jListener);
+ OCStackResult provisionCredentials(JNIEnv* env, jint type, jint keySize,
+ jobject device2, jobject jListener);
+ OCStackResult unlinkDevices(JNIEnv* env, jobject device2, jobject jListener);
+ OCStackResult removeDevice(JNIEnv* env, jint timeout, jobject jListener);
+
+ private:
+
+ std::map<jobject, std::pair<JniProvisionResultListner*, int>> resultMap;
+ std::mutex resultMapLock;
+ std::shared_ptr<OCSecureResource> m_sharedSecureResource;
+};
+
+/* DO NOT EDIT THIS FILE BEYOND THIS LINE - it is machine generated */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: doOwnershipTransfer
+ * Signature: (Lorg/iotivity/base/OcSecureResource/DoOwnershipTransferListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_doOwnershipTransfer
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: removeDevice
+ * Signature: (ILorg/iotivity/base/OcSecureResource/RemoveDeviceListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_removeDevice
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: unlinkDevices
+ * Signature: (Ljava/lang/Object;Lorg/iotivity/base/OcSecureResource/UnlinkDevicesListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_unlinkDevices
+ (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionCredentials1
+ * Signature: (IILjava/lang/Object;Lorg/iotivity/base/OcSecureResource/ProvisionCredentialsListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionCredentials1
+ (JNIEnv *, jobject, jint, jint, jobject, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionACL
+ * Signature: (Ljava/lang/Object;Lorg/iotivity/base/OcSecureResource/ProvisionAclListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionACL
+ (JNIEnv *, jobject, jobject, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: provisionPairwiseDevices1
+ * Signature: (IILjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Lorg/iotivity/base/OcSecureResource/ProvisionPairwiseDevicesListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_provisionPairwiseDevices1
+ (JNIEnv *, jobject, jint, jint, jobject, jobject, jobject, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getLinkedDevices
+ * Signature: ()Ljava/util/List;
+ */
+JNIEXPORT jobject JNICALL Java_org_iotivity_base_OcSecureResource_getLinkedDevices
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getIpAddr
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getIpAddr
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: getDeviceID
+ * Signature: ()Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_org_iotivity_base_OcSecureResource_getDeviceID
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: deviceStatus
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_deviceStatus
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: ownedStatus
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_iotivity_base_OcSecureResource_ownedStatus
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_iotivity_base_OcSecureResource
+ * Method: dispose
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcSecureResource_dispose
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
jclass g_cls_OcHeaderOption = nullptr;
jclass g_cls_ObservationInfo = nullptr;
jclass g_cls_OcResourceIdentifier = nullptr;
+jclass g_cls_OcProvisionResult = nullptr;
+jclass g_cls_OcSecureResource = nullptr;
+jclass g_cls_OcOicSecAcl = nullptr;
jmethodID g_mid_Integer_ctor = nullptr;
jmethodID g_mid_Double_ctor = nullptr;
jmethodID g_mid_ObservationInfo_N_ctor = nullptr;
jmethodID g_mid_OcPresenceStatus_get = nullptr;
jmethodID g_mid_OcResourceIdentifier_N_ctor = nullptr;
+jmethodID g_mid_OcProvisionResult_ctor = nullptr;
+jmethodID g_mid_OcSecureResource_ctor = nullptr;
+
+jmethodID g_mid_OcOicSecAcl_get_subject = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_resources_cnt = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_resources = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_permission = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_periods_cnt = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_periods = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_recurrences = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_owners_cnt = nullptr;
+jmethodID g_mid_OcOicSecAcl_get_owners = nullptr;
jobject getOcException(JNIEnv* env, const char* file, const char* functionName,
const int line, const int code, const char* message)
g_mid_OcResourceIdentifier_N_ctor = env->GetMethodID(g_cls_OcResourceIdentifier, "<init>", "(J)V");
if (!g_mid_OcResourceIdentifier_N_ctor) return JNI_ERR;
+ //OcSecureResource
+ clazz = env->FindClass("org/iotivity/base/OcSecureResource");
+ if (!clazz) return JNI_ERR;
+ g_cls_OcSecureResource = (jclass)env->NewGlobalRef(clazz);
+ env->DeleteLocalRef(clazz);
+ g_mid_OcSecureResource_ctor = env->GetMethodID(g_cls_OcSecureResource, "<init>", "(J)V");
+ if (!g_mid_OcSecureResource_ctor) return JNI_ERR;
+
+ //ProvisionResult
+ clazz = env->FindClass("org/iotivity/base/ProvisionResult");
+ if (!clazz) return JNI_ERR;
+ g_cls_OcProvisionResult = (jclass)env->NewGlobalRef(clazz);
+ env->DeleteLocalRef(clazz);
+ g_mid_OcProvisionResult_ctor = env->GetMethodID(g_cls_OcProvisionResult, "<init>", "(Ljava/lang/String;I)V");
+ if (!g_mid_OcProvisionResult_ctor) return JNI_ERR;
+
+ //OicSecAcl
+ clazz = env->FindClass("org/iotivity/base/OicSecAcl");
+ if (!clazz) return JNI_ERR;
+ g_cls_OcOicSecAcl = (jclass)env->NewGlobalRef(clazz);
+ env->DeleteLocalRef(clazz);
+
+ g_mid_OcOicSecAcl_get_subject = env->GetMethodID(g_cls_OcOicSecAcl, "getSubject", "()Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_subject) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_resources_cnt = env->GetMethodID(g_cls_OcOicSecAcl, "getResourcesCount", "()I");
+ if (!g_mid_OcOicSecAcl_get_resources_cnt) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_resources = env->GetMethodID(g_cls_OcOicSecAcl, "getResources", "(I)Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_resources) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_permission = env->GetMethodID(g_cls_OcOicSecAcl, "getPermission", "()I");
+ if (!g_mid_OcOicSecAcl_get_permission) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_periods_cnt = env->GetMethodID(g_cls_OcOicSecAcl, "getPeriodsCount", "()I");
+ if (!g_mid_OcOicSecAcl_get_periods_cnt) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_periods = env->GetMethodID(g_cls_OcOicSecAcl, "getPeriods", "(I)Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_periods) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_recurrences = env->GetMethodID(g_cls_OcOicSecAcl, "getRecurrences", "(I)Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_recurrences) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_owners_cnt = env->GetMethodID(g_cls_OcOicSecAcl, "getOwnersCount", "()I");
+ if (!g_mid_OcOicSecAcl_get_owners_cnt) return JNI_ERR;
+
+ g_mid_OcOicSecAcl_get_owners = env->GetMethodID(g_cls_OcOicSecAcl, "getOwners", "(I)Ljava/lang/String;");
+ if (!g_mid_OcOicSecAcl_get_owners) return JNI_ERR;
+
return JNI_CURRENT_VERSION;
}
env->DeleteGlobalRef(g_cls_OcHeaderOption);
env->DeleteGlobalRef(g_cls_ObservationInfo);
env->DeleteGlobalRef(g_cls_OcResourceIdentifier);
+ env->DeleteGlobalRef(g_cls_OcSecureResource);
+ env->DeleteGlobalRef(g_cls_OcProvisionResult);
+ env->DeleteGlobalRef(g_cls_OcOicSecAcl);
}
\ No newline at end of file
extern jclass g_cls_OcHeaderOption;
extern jclass g_cls_ObservationInfo;
extern jclass g_cls_OcResourceIdentifier;
+extern jclass g_cls_OcProvisionResult;
+extern jclass g_cls_OcSecureResource;
+extern jclass g_cls_OcOicSecAcl;
extern jmethodID g_mid_Integer_ctor;
extern jmethodID g_mid_Double_ctor;
extern jmethodID g_mid_ObservationInfo_N_ctor;
extern jmethodID g_mid_OcPresenceStatus_get;
extern jmethodID g_mid_OcResourceIdentifier_N_ctor;
+extern jmethodID g_mid_OcProvisionResult_ctor;
+extern jmethodID g_mid_OcSecureResource_ctor;
+extern jmethodID g_mid_OcOicSecAcl_get_subject;
+extern jmethodID g_mid_OcOicSecAcl_get_resources_cnt;
+extern jmethodID g_mid_OcOicSecAcl_get_resources;
+extern jmethodID g_mid_OcOicSecAcl_get_permission;
+extern jmethodID g_mid_OcOicSecAcl_get_periods_cnt;
+extern jmethodID g_mid_OcOicSecAcl_get_periods;
+extern jmethodID g_mid_OcOicSecAcl_get_recurrences;
+extern jmethodID g_mid_OcOicSecAcl_get_owners_cnt;
+extern jmethodID g_mid_OcOicSecAcl_get_owners;
typedef void(*RemoveListenerCallback)(JNIEnv* env, jobject jListener);
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniPinCheckListener.h"
+#include "oic_string.h"
+
+JniPinCheckListener::JniPinCheckListener(JNIEnv *env, jobject jListener)
+{
+ m_jListener = env->NewGlobalRef(jListener);
+}
+
+JniPinCheckListener::~JniPinCheckListener()
+{
+ LOGI("~JniPinCheckListener()");
+ if (m_jListener)
+ {
+ jint ret;
+ JNIEnv *env = GetJNIEnv(ret);
+ if (NULL == env) return;
+ env->DeleteWeakGlobalRef(m_jListener);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ }
+}
+
+void JniPinCheckListener::PinCallback(char *pinBuf, size_t bufSize)
+{
+ jint ret;
+
+ JNIEnv *env = GetJNIEnv(ret);
+ if (NULL == env) return;
+
+ jclass clsL = env->GetObjectClass(m_jListener);
+
+ if (!clsL)
+ {
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+
+ jmethodID midL = env->GetMethodID(clsL, "pinCallbackListener", "()Ljava/lang/String;");
+ if (!midL)
+ {
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+ jstring jpin = (jstring)env->CallObjectMethod(m_jListener, midL);
+ if (env->ExceptionCheck())
+ {
+ LOGE("Java exception is thrown");
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+
+ char *str = (char*)env->GetStringUTFChars(jpin, NULL);
+ OICStrcpy(pinBuf, bufSize, str);
+ env->ReleaseStringUTFChars(jpin, str);
+
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+}
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcStack.h"
+#include "OCProvisioningManager.h"
+
+#ifndef _Included_org_iotivity_base_PinCheckListener
+#define _Included_org_iotivity_base_PinCheckListener
+
+typedef std::function<void(JNIEnv* env, jobject jListener)> RemoveCallback;
+class JniPinCheckListener
+{
+ public:
+ JniPinCheckListener(JNIEnv *, jobject);
+ ~JniPinCheckListener();
+
+ void PinCallback(char*, size_t);
+ private:
+ jobject m_jListener;
+};
+#endif
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniProvisionResultListner.h"
+#include "JniOcSecureResource.h"
+#include "JniSecureUtils.h"
+
+JniProvisionResultListner::JniProvisionResultListner(JNIEnv *env, jobject jListener,
+ RemoveCallback removeProvisionResultListener)
+{
+ m_jwListener = env->NewWeakGlobalRef(jListener);
+ m_removeProvisionResultListener = removeProvisionResultListener;
+}
+
+JniProvisionResultListner::~JniProvisionResultListner()
+{
+ LOGI("~JniProvisionResultListner()");
+ if (m_jwListener)
+ {
+ jint ret;
+ JNIEnv *env = GetJNIEnv(ret);
+ if (NULL == env) return;
+ env->DeleteWeakGlobalRef(m_jwListener);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ }
+}
+
+void JniProvisionResultListner::ProvisionResultCallback(PMResultList_t *result, int hasError,
+ ListenerFunc func)
+{
+ jint ret;
+ JNIEnv *env = GetJNIEnv(ret);
+ if (NULL == env) return;
+
+ jobject jListener = env->NewLocalRef(m_jwListener);
+ if (!jListener)
+ {
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+
+ jclass clsL = env->GetObjectClass(jListener);
+
+ if (!clsL)
+ {
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+
+
+ jobject jResultList = JniSecureUtils::convertProvisionresultVectorToJavaList(env, result);
+ if (!jResultList)
+ {
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+
+ std::string calledFunc;
+ switch (func)
+ {
+ case ListenerFunc::OWNERSHIPTRANSFER:
+ {
+ calledFunc = "doOwnershipTransferListener";
+ }
+ break;
+ case ListenerFunc::PROVISIONACL:
+ {
+ calledFunc = "provisionAclListener";
+ }
+ break;
+ case ListenerFunc::PROVISIONCREDENTIALS:
+ {
+ calledFunc = "provisionCredentialsListener";
+ }
+ break;
+ case ListenerFunc::UNLINKDEVICES:
+ {
+ calledFunc = "unlinkDevicesListener";
+ }
+ break;
+ case ListenerFunc::REMOVEDEVICE:
+ {
+ calledFunc = "removeDeviceListener";
+ }
+ break;
+ case ListenerFunc::PROVISIONPAIRWISEDEVICES:
+ {
+ calledFunc = "provisionPairwiseDevicesListener";
+ }
+ break;
+ default:
+ {
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ }
+ return;
+ }
+
+ jmethodID midL = env->GetMethodID(clsL, calledFunc.c_str(), "(Ljava/util/List;I)V");
+ if (!midL)
+ {
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+ return;
+ }
+ env->CallVoidMethod(jListener, midL, jResultList, (jint)hasError);
+ if (env->ExceptionCheck())
+ {
+ LOGE("Java exception is thrown");
+ }
+
+ checkExAndRemoveListener(env);
+ if (JNI_EDETACHED == ret) g_jvm->DetachCurrentThread();
+}
+
+void JniProvisionResultListner::checkExAndRemoveListener(JNIEnv* env)
+{
+ if (env->ExceptionCheck())
+ {
+ jthrowable ex = env->ExceptionOccurred();
+ env->ExceptionClear();
+ m_removeProvisionResultListener(env, m_jwListener);
+ env->Throw((jthrowable)ex);
+ }
+ else
+ {
+ m_removeProvisionResultListener(env, m_jwListener);
+ }
+}
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 <jni.h>
+#include "JniOcStack.h"
+#include "OCProvisioningManager.h"
+
+#ifndef _Included_org_iotivity_base_OcProvisioning_JniProvisionResultListner
+#define _Included_org_iotivity_base_OcProvisioning_JniProvisionResultListner
+
+typedef std::function<void(JNIEnv* env, jobject jListener)> RemoveCallback;
+
+enum class ListenerFunc
+{
+ OWNERSHIPTRANSFER = 1,
+ PROVISIONACL,
+ PROVISIONCREDENTIALS,
+ UNLINKDEVICES,
+ REMOVEDEVICE,
+ PROVISIONPAIRWISEDEVICES
+};
+
+class JniProvisionResultListner
+{
+ public:
+ JniProvisionResultListner(JNIEnv *env, jobject jListener,
+ RemoveCallback removeProvisionResultListener);
+ ~JniProvisionResultListner();
+
+ void ProvisionResultCallback(OC::PMResultList_t *result, int hasError, ListenerFunc func);
+
+ private:
+ RemoveCallback m_removeProvisionResultListener;
+ jweak m_jwListener;
+ void checkExAndRemoveListener(JNIEnv* env);
+};
+#endif
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniSecureUtils.h"
+#include "JniOcSecureResource.h"
+#include "base64.h"
+
+jobject JniSecureUtils::convertProvisionresultVectorToJavaList(JNIEnv *env, const OC::PMResultList_t *result)
+{
+ jobject jResultList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
+ if (!jResultList)
+ {
+ return nullptr;
+ }
+
+ for (size_t i = 0; i < result->size(); ++i)
+ {
+ jobject jresult = env->NewObject(
+ g_cls_OcProvisionResult,
+ g_mid_OcProvisionResult_ctor,
+ env->NewStringUTF((char*)result->at(i).deviceId.id),
+ static_cast<jint>(result->at(i).res)
+ );
+ if (!jresult)
+ {
+ return nullptr;
+ }
+
+ env->CallBooleanMethod(jResultList, g_mid_LinkedList_add_object, jresult);
+ if (env->ExceptionCheck())
+ {
+ return nullptr;
+ }
+ env->DeleteLocalRef(jresult);
+ }
+ return jResultList;
+}
+
+jobjectArray JniSecureUtils::convertDeviceVectorToJavaArray(JNIEnv *env,
+ std::vector<std::shared_ptr<OC::OCSecureResource>> &deviceListVector)
+{
+ jsize len = static_cast<jsize>(deviceListVector.size());
+ jobjectArray devArr = env->NewObjectArray(len, g_cls_OcSecureResource, NULL);
+
+ if (!devArr)
+ {
+ return nullptr;
+ }
+
+ for (jsize i = 0; i < len; ++i)
+ {
+ JniOcSecureResource *device = new JniOcSecureResource(deviceListVector[i]);
+ jobject jDevice = env->NewObject(g_cls_OcSecureResource, g_mid_OcSecureResource_ctor);
+
+ SetHandle<JniOcSecureResource>(env, jDevice, device);
+ if (!jDevice)
+ {
+ return nullptr;
+ }
+
+ env->SetObjectArrayElement(devArr, i, jDevice);
+ if (env->ExceptionCheck())
+ {
+ return nullptr;
+ }
+ env->DeleteLocalRef(jDevice);
+ }
+ return devArr;
+}
+
+std::string JniSecureUtils::convertUUIDtoStr(OicUuid_t uuid)
+{
+ std::ostringstream deviceId("");
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {0,};
+ uint32_t outLen = 0;
+ B64Result b64Ret = B64_OK;
+
+ b64Ret = b64Encode(uuid.id, sizeof(uuid.id), base64Buff,
+ sizeof(base64Buff), &outLen);
+
+ deviceId << base64Buff;
+ return deviceId.str();
+}
+
+void JniSecureUtils::convertStrToUUID(char *str, OicUuid_t &uuid)
+{
+ unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
+ uint32_t outLen = 0;
+ B64Result b64Ret = B64_OK;
+
+ b64Ret = b64Decode(str, strlen(str), base64Buff, sizeof(base64Buff), &outLen);
+ memcpy(uuid.id, base64Buff, outLen);
+}
+
+jobject JniSecureUtils::convertUUIDVectorToJavaStrList(JNIEnv *env, UuidList_t &vector)
+{
+ jobject jList = env->NewObject(g_cls_LinkedList, g_mid_LinkedList_ctor);
+ if (!jList)
+ {
+ return nullptr;
+ }
+ for (size_t i = 0; i < vector.size(); ++i)
+ {
+ jstring jStr = env->NewStringUTF((convertUUIDtoStr(vector[i])).c_str());
+ if (!jStr)
+ {
+ return nullptr;
+ }
+ env->CallBooleanMethod(jList, g_mid_LinkedList_add_object, jStr);
+ if (env->ExceptionCheck())
+ {
+ return nullptr;
+ }
+ env->DeleteLocalRef(jStr);
+ }
+ return jList;
+}
+
+OCStackResult JniSecureUtils::convertJavaACLToOCAcl(JNIEnv *env, jobject in, OicSecAcl_t *acl)
+{
+ jstring jData;
+ jvalue args[1];
+
+ jData = (jstring) env->CallObjectMethod(in, g_mid_OcOicSecAcl_get_subject);
+ if (!jData || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ char *str = (char*) env->GetStringUTFChars(jData, 0);
+ convertStrToUUID(str, acl->subject);
+ env->ReleaseStringUTFChars(jData, str);
+
+ jint jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_resources_cnt);
+ if (!jCount || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->resourcesLen = jCount;
+ acl->resources = new char*[jCount];
+ for (jint i = 0; i < jCount; ++i)
+ {
+ args[0].i = i;
+ jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecAcl_get_resources, args);
+ if (!jData || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->resources[i] = (char*) env->GetStringUTFChars(jData, 0);
+ }
+
+ jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_permission);
+ if (env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->permission = jCount;
+ jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_periods_cnt);
+ if (env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->prdRecrLen = jCount;
+ acl->periods = new char*[jCount];
+ for (jint i = 0; i < jCount; ++i)
+ {
+ args[0].i = i;
+ jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecAcl_get_periods, args);
+ if (!jData || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->periods[i] = (char*) env->GetStringUTFChars(jData, 0);
+ }
+
+ acl->recurrences = new char*[jCount]; //TODO:Period Len and Reccurence len is same
+ for (jint i = 0; i < jCount; ++i)
+ {
+ args[0].i = i;
+ jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecAcl_get_recurrences, args);
+ if (!jData || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->recurrences[i] = (char*) env->GetStringUTFChars(jData, 0);
+ }
+
+ jCount = (jint) env->CallIntMethod(in, g_mid_OcOicSecAcl_get_owners_cnt);
+ if (!jCount || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ acl->ownersLen = jCount;
+ acl->owners = new OicUuid_t[acl->ownersLen];
+ if (!acl->owners)
+ {
+ return OC_STACK_ERROR;
+ }
+
+ for (jint i = 0; i < jCount; ++i)
+ {
+ args[0].i = i;
+ jData = (jstring) env->CallObjectMethodA(in, g_mid_OcOicSecAcl_get_owners, args);
+ if (!jData || env->ExceptionCheck())
+ {
+ return OC_STACK_ERROR;
+ }
+
+ str = (char*) env->GetStringUTFChars(jData, 0);
+ convertStrToUUID(str, acl->owners[i]);
+ env->ReleaseStringUTFChars(jData, str);
+ }
+ return OC_STACK_OK;
+}
--- /dev/null
+/*
+* //******************************************************************
+* //
+* // Copyright 2015 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 "JniOcStack.h"
+#include "OCProvisioningManager.h"
+
+class JniSecureUtils
+{
+ private:
+ static std::string convertUUIDtoStr(OicUuid_t uuid);
+ static void convertStrToUUID(char *str, OicUuid_t &uuid);
+ public:
+ static jobject convertProvisionresultVectorToJavaList(JNIEnv *,
+ const OC::PMResultList_t *);
+ static jobjectArray convertDeviceVectorToJavaArray(JNIEnv *env,
+ std::vector<std::shared_ptr<OC::OCSecureResource>>& deviceListVector);
+ static jobject convertUUIDVectorToJavaStrList(JNIEnv *env, OC::UuidList_t &vector);
+ static OCStackResult convertJavaACLToOCAcl(JNIEnv *env, jobject in, OicSecAcl_t *out);
+};
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.security.InvalidParameterException;
+import java.util.EnumSet;
+
+public enum CredType {
+
+ NO_SECURITY_MODE (0),
+
+ SYMMETRIC_PAIR_WISE_KEY (1 << 0),
+
+ SYMMETRIC_GROUP_KEY (1 << 1),
+
+ ASYMMETRIC_KEY (1 << 2),
+
+ SIGNED_ASYMMETRIC_KEY (1 << 3),
+
+ PIN_PASSWORD (1 << 4),
+
+ ASYMMETRIC_ENCRYPTION_KEY (1 << 5),
+
+ ;
+ private int value;
+
+ private CredType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+
+ public static EnumSet<CredType> convertToEnumSet(int value) {
+ EnumSet<CredType> typeSet = null;
+
+ for (CredType v : values()) {
+ if (0 != (value & v.getValue())) {
+ if (null == typeSet) {
+ typeSet = EnumSet.of(v);
+ } else {
+ typeSet.add(v);
+ }
+ }
+ }
+
+ if (null == typeSet || typeSet.isEmpty()) {
+ throw new InvalidParameterException("Unexpected CredType value:" + value);
+ }
+
+ return typeSet;
+ }
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+public enum DeviceStatus {
+ ON(0),
+ OFF(1),
+ INVALID(-1);
+
+ private int value;
+
+ private DeviceStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+
+ public static DeviceStatus convertDeviceStatus(int value) {
+
+ if (0 == value)
+ {
+ return DeviceStatus.ON;
+ }
+ else if (1 == value)
+ {
+ return DeviceStatus.OFF;
+ }
+ else
+ {
+ return DeviceStatus.INVALID;
+ }
+ }
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+public enum KeySize {
+ OWNER_PSK_LENGTH_128 (128/8),
+ OWNER_PSK_LENGTH_256 (256/8),;
+
+ private int value;
+
+ private KeySize(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * OcProvisionig represents functions corresponding to the provisioing of
+ * resources.
+ */
+public class OcProvisioning {
+
+ /**
+ * Method to Intialize Provisioning Manager.This will load the provisioning
+ * Manager's persistent database.
+ *
+ * @param dbPath dbPath file path of the sqlite3 db.
+ * @throws OcException
+ */
+ public static native void provisionInit(String dbPath) throws OcException;
+
+ /**
+ * Method to Discover un-owned devices in its subnet.Un-owned devices need
+ * to be owned by calling ownershipTransferCBdata.
+ *
+ * @param timeout Timeout in sec.Time to listen for responses before
+ * returining the Array.
+ * @return Array of OcSecureResource class objects.
+ * @throws OcException
+ */
+ public static List<OcSecureResource> discoverUnownedDevices(int timeout) throws OcException {
+ return Arrays.asList(OcProvisioning.discoverUnownedDevices1(timeout));
+ }
+ private static native OcSecureResource[] discoverUnownedDevices1(int timeout) throws OcException;
+
+ /**
+ * Method to Discover owned devices in its subnet.
+ *
+ * @param timeout Timeout in sec.Time to listen for responses before
+ * returining the Array.
+ * @return Array of OcSecureResource class objects.
+ * @throws OcException
+ */
+ public static List<OcSecureResource> discoverOwnedDevices(int timeout) throws OcException {
+ return Arrays.asList(OcProvisioning.discoverOwnedDevices1(timeout));
+ }
+ private static native OcSecureResource[] discoverOwnedDevices1(int timeout) throws OcException;
+
+ /**
+ * API for registering Ownership transfer methods for a particular
+ * transfer Type
+ *
+ * @param type OxmType ownership transfer type.
+ * @throws OcException
+ */
+ public static void SetownershipTransferCBdata(OxmType type,
+ PinCallbackListener pinCallbackListener) throws OcException
+ {
+ OcProvisioning.ownershipTransferCBdata(type.getValue(), pinCallbackListener);
+ }
+
+ private static native void ownershipTransferCBdata(int oxmType, PinCallbackListener pinCallbackListener);
+
+ public static interface PinCallbackListener {
+ public String pinCallbackListener();
+ }
+
+ /**
+ * Method to get Array of owned and un-owned devices in the current subnet.
+ *
+ * @param timeout timeout in sec for the API to return.
+ * @retrun Array of OcSecureResource class objects.
+ * be provisioned.
+ * @throws OcException
+ */
+ public static List<OcSecureResource> getDeviceStatusList(int timeout) throws OcException {
+ return Arrays.asList(OcProvisioning.getDeviceStatusList1(timeout));
+ }
+ private static native OcSecureResource[] getDeviceStatusList1(int timeout) throws OcException;
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.util.List;
+import java.util.EnumSet;
+import java.util.Map;
+
+public class OcSecureResource {
+
+ private OcSecureResource(long nativeHandle) {
+ this.mNativeHandle = nativeHandle;
+ }
+
+ /**
+ * Method to Start Ownership Transfer of an un-owned device.
+ *
+ * @param DoOwnershipTransferListener Callback function, which will be called after
+ * completion of ownership Transfer.
+ * @throws OcException
+ */
+ public native void doOwnershipTransfer(DoOwnershipTransferListener doOwnershipTransferListener)
+ throws OcException;
+
+ /**
+ * Method removes device credential from all devices in subnet
+ *
+ * @param timeout
+ * @param RemoveDeviceListener Callback function, which will be called after
+ * completion of removing device.
+ * @throws OcException
+ */
+ public native void removeDevice(int timeout, RemoveDeviceListener removeDeviceListener)
+ throws OcException;
+
+ /**
+ * Method removes the credential & relationship between the two devices.
+ *
+ * @param jobject Second device
+ * @param UnlinkDevicesListener Callback function, which will be called after
+ * completion of removing device.
+ * @throws OcException
+ */
+ public native void unlinkDevices(Object device2, UnlinkDevicesListener unlinkDevicesListener)
+ throws OcException;
+
+ /**
+ * Method removes the credential & relationship between the two devices.
+ *
+ * @param EnumSet<CredType> OR'ed Cred Types
+ * @param KeySize keySize
+ * @param Object Second device
+ * @param ProvisionCredentialsListener Callback function, which will be called after
+ * completion of removing device.
+ * @throws OcException
+ */
+ public void provisionCredentials(EnumSet<CredType> credTypeSet, KeySize keysize, Object device2,
+ ProvisionCredentialsListener provisionCredentialsListener) throws OcException {
+ int credTypeInt = 0;
+
+ for (CredType credType : CredType.values()) {
+ if (credTypeSet.contains(credType))
+ credTypeInt |= credType.getValue();
+ }
+ this.provisionCredentials1(credTypeInt, keysize.getValue(),
+ device2, provisionCredentialsListener);
+ }
+ private native void provisionCredentials1(int type, int keySize, Object device2,
+ ProvisionCredentialsListener provisionCredentialsListener)
+ throws OcException;
+
+ /**
+ * Method send ACL information to resource.
+ *
+ * @param jobject Acl
+ * @param ProvisionAclListener Callback function, which will be called after
+ * completion of removing device.
+ * @throws OcException
+ */
+ public native void provisionACL(Object acl, ProvisionAclListener provisionACLListener)
+ throws OcException;
+
+
+ /**
+ * Method provisions credentials between two devices and ACLs for the devices who
+ * act as a server.
+ *
+ * @param EnumSet<CredType> OR'ed Cred Types
+ * @param KeySize keySize
+ * @param Object First acl
+ * @param Object Second device
+ * @param Object Second acl
+ * @param ProvisionPairwiseDevicesListener Callback function, which will be called after
+ * completion of removing device.
+ * @throws OcException
+ */
+ public void provisionPairwiseDevices(EnumSet<CredType> credTypeSet, KeySize keysize, Object acl1,
+ Object device2, Object acl2,
+ ProvisionPairwiseDevicesListener provisionPairwiseDevicesListener) throws OcException {
+ int credTypeInt = 0;
+
+ for (CredType credType : CredType.values()) {
+ if (credTypeSet.contains(credType))
+ credTypeInt |= credType.getValue();
+ }
+ this.provisionPairwiseDevices1(credTypeInt, keysize.getValue(), acl1, device2,
+ acl2, provisionPairwiseDevicesListener);
+ }
+ private native void provisionPairwiseDevices1(int type, int keySize, Object acl1,
+ Object device2, Object acl2,
+ ProvisionPairwiseDevicesListener provisionPairwiseDevicesListener) throws OcException;
+
+ /**
+ * doOwnershipTransferListener can be registered with doOwnershipTransfer
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface DoOwnershipTransferListener {
+ public void doOwnershipTransferListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /**
+ * removeDeviceListener can be registered with removeDeviceListener
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface RemoveDeviceListener {
+ public void removeDeviceListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /**
+ * unlinkDevicesListener can be registered with unlinkDevicesListener
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface UnlinkDevicesListener {
+ public void unlinkDevicesListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /**
+ * provisionCredentialsListener can be registered with provisionCredentialsListener
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface ProvisionCredentialsListener {
+ public void provisionCredentialsListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /**
+ * provisionAclListener can be registered with provisionAclListener
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface ProvisionAclListener {
+ public void provisionAclListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /**
+ * provisionPairwiseDevicesListener can be registered with provisionPairwiseDevicesListener
+ * call.
+ * Listener notified asynchronously.
+ */
+ public interface ProvisionPairwiseDevicesListener {
+ public void provisionPairwiseDevicesListener(List<ProvisionResult> provisionResultList,
+ int hasError);
+ }
+
+ /** Method to get List of device ID of devices linked with invoking device.
+ *
+ * @return Sring List List of device id's of linked devices.
+ */
+ public native List<String> getLinkedDevices();
+
+ /**
+ * Method to get IP address of sercure discovered device.
+ * @return Stringified IP address.
+ */
+ public native String getIpAddr();
+
+ /**
+ * Method to get device id of a device.
+ * @return Device ID of the selected device.
+ */
+ public native String getDeviceID();
+
+ /**
+ * Method to get device status (ON/OFF) of a device.
+ * @return ON/OFF
+ */
+
+ public DeviceStatus getDeviceStatus() throws OcException {
+ return DeviceStatus.convertDeviceStatus(this.deviceStatus());
+ }
+ public native int deviceStatus() throws OcException;
+
+ /**
+ * Method to get device ownership (OWNED/UNOWNED) status.
+ * @return OWNED/UNOWNED
+ */
+
+ public OwnedStatus getOwnedStatus() throws OcException {
+ return OwnedStatus.convertOwnedStatus(this.ownedStatus());
+ }
+ public native int ownedStatus() throws OcException;
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ dispose();
+ }
+
+ private native void dispose();
+
+ private long mNativeHandle;
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Arrays;
+
+public class OicSecAcl implements Serializable {
+
+ private String subject;
+ private int permission;
+ private List<String> resources;
+ private List<String> periods;
+ private List<String> recurrences;
+ private List<String> owners;
+
+ public OicSecAcl(String subject, List<String> recurrences, List<String> periods, int permission,
+ List<String> resources, List<String> owners) {
+ this.subject = subject;
+ this.recurrences = recurrences;
+ this.periods = periods;
+ this.permission = permission;
+ this.resources = resources;
+ this.owners = owners;
+ }
+
+ public String getSubject() {
+ return this.subject;
+ }
+
+ public void setSubject(String subject) {
+ this.subject = subject;
+ }
+
+ public List<String> getOwners() {
+ return owners;
+ }
+
+ public void setOwners(List<String> owners) {
+ this.owners = owners;
+ }
+
+ public List<String> getRecurrences() {
+ return recurrences;
+ }
+
+ public void setRecurrences(List<String> recurrences) {
+ this.recurrences = recurrences;
+ }
+
+ public List<String> getPeriods() {
+ return periods;
+ }
+
+ public void setPeriods(List<String> periods) {
+ this.periods = periods;
+ }
+
+ public int getPermission() {
+ return this.permission;
+ }
+
+ public void setPermission(int permission) {
+ this.permission = permission;
+ }
+
+ public List<String> getResources() {
+ return resources;
+ }
+
+ public void setResources(List<String> resources) {
+ this.resources = resources;
+ }
+
+ public int getResourcesCount() {
+ return this.resources.size();
+ }
+
+ public String getResources(int i) {
+ return this.resources.get(i);
+ }
+
+ public int getPeriodsCount() {
+ return this.periods.size();
+ }
+
+ public String getPeriods(int i) {
+ return this.periods.get(i);
+ }
+
+ public String getRecurrences(int i) {
+ return this.recurrences.get(i);
+ }
+
+ public int getOwnersCount() {
+ return this.owners.size();
+ }
+
+ public String getOwners(int i) {
+ return this.owners.get(i);
+ }
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+public enum OwnedStatus {
+ OWNED(0),
+ UNOWNED(1),
+ INVALID(-1);
+
+ private int value;
+
+ private OwnedStatus(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+
+ public static OwnedStatus convertOwnedStatus(int value) {
+
+ if (0 == value)
+ {
+ return OwnedStatus.UNOWNED;
+ }
+ else if (1 == value)
+ {
+ return OwnedStatus.OWNED;
+ }
+ else
+ {
+ return OwnedStatus.INVALID;
+ }
+ }
+}
--- /dev/null
+/*
+ * //******************************************************************
+ * //
+ * // Copyright 2015 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.
+ * //
+ * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+ */
+
+package org.iotivity.base;
+
+public enum OxmType {
+ OIC_JUST_WORKS(0),
+ OIC_MODE_SWITCH(1),
+ OIC_RANDOM_DEVICE_PIN(2),
+ OIC_PRE_PROVISIONED_DEVICE_PIN(3),
+ OIC_PRE_PROVISION_STRONG_CREDENTIAL(4),
+ OIC_OXM_COUNT(5);
+
+ private int value;
+
+ private OxmType(int value) {
+ this.value = value;
+ }
+
+ public int getValue() {
+ return this.value;
+ }
+}
--- /dev/null
+/* *****************************************************************
+ *
+ * Copyright 2015 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.
+ *
+ * *****************************************************************/
+package org.iotivity.base;
+
+public class ProvisionResult {
+
+ private String mDeviceId;
+ private int mResult;
+
+ public ProvisionResult(String deviceId, int result)
+ {
+ this.mDeviceId = deviceId;
+ this.mResult = result;
+ }
+
+ public String getDevId()
+ {
+ return this.mDeviceId;
+ }
+ public int getResult()
+ {
+ return this.mResult;
+ }
+}
--- /dev/null
+apply plugin: 'com.android.application'\r
+\r
+android {\r
+ compileSdkVersion 21\r
+ buildToolsVersion "21.1.2"\r
+\r
+ defaultConfig {\r
+ applicationId "org.iotivity.base.examples.provisioningclient"\r
+ minSdkVersion 19\r
+ targetSdkVersion 21\r
+ versionCode 1\r
+ versionName "1.0"\r
+ }\r
+ buildTypes {\r
+ release {\r
+ minifyEnabled false\r
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\r
+ }\r
+ }\r
+}\r
+\r
+dependencies {\r
+ compile 'com.android.support:appcompat-v7:21.0.3'\r
+}\r
--- /dev/null
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/sri/Android/Sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="examples" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+ <component name="FacetManager">
+ <facet type="android-gradle" name="Android-Gradle">
+ <configuration>
+ <option name="GRADLE_PROJECT_PATH" value=":secureprovisionclient" />
+ </configuration>
+ </facet>
+ <facet type="android" name="Android">
+ <configuration>
+ <option name="SELECTED_BUILD_VARIANT" value="debug" />
+ <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
+ <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
+ <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
+ <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
+ <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
+ <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+ <option name="ALLOW_USER_CONFIGURATION" value="false" />
+ <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
+ <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
+ <option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
+ <option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
+ </configuration>
+ </facet>
+ </component>
+ <component name="NewModuleRootManager" inherit-compiler-output="false">
+ <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+ <output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
+ <exclude-output />
+ <content url="file://$MODULE_DIR$">
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
+ <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
+ <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
+ <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
+ </content>
+ <orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
+ <orderEntry type="sourceFolder" forTests="false" />
+ <orderEntry type="library" exported="" name="appcompat-v7-21.0.3" level="project" />
+ <orderEntry type="library" exported="" name="iotivity-armeabi-base-debug-" level="project" />
+ <orderEntry type="library" exported="" name="support-annotations-21.0.3" level="project" />
+ <orderEntry type="library" exported="" name="support-v4-21.0.3" level="project" />
+ <orderEntry type="module" module-name="message" exported="" />
+ </component>
+</module>
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="org.iotivity.base.examples.provisioningclient" >
+
+ <application
+ android:allowBackup="true"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:theme="@style/AppTheme" >
+ <activity
+ android:name=".ProvisioningClient"
+ android:label="@string/app_name" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
--- /dev/null
+{
+ "acl": [
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/res",
+ "/oic/d",
+ "/oic/p",
+ "/oic/res/types/d",
+ "/oic/ad",
+ "/oic/sec/acl"
+ ],
+ "perms": 2,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/sec/doxm",
+ "/oic/sec/pstat"
+ ],
+ "perms": 2,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }
+ ],
+ "pstat": {
+ "isop": true,
+ "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
+ "ch": 0,
+ "cm": 0,
+ "tm": 0,
+ "om": 3,
+ "sm": [3]
+ },
+ "doxm": {
+ "oxm": [0],
+ "oxmsel": 0,
+ "owned": true,
+ "deviceid": "MjIyMjIyMjIyMjIyMjIyMg==",
+ "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+ },
+ "cred": [{
+ "credid": 1,
+ "sub": "MTExMTExMTExMTExMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }]
+}
--- /dev/null
+
+package org.iotivity.base.examples.provisioningclient;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+
+import org.iotivity.base.ModeType;
+
+import org.iotivity.base.OcException;
+
+import org.iotivity.base.OcPlatform;
+
+
+import org.iotivity.base.PlatformConfig;
+import org.iotivity.base.QualityOfService;
+import org.iotivity.base.ServiceType;
+import org.iotivity.base.OcProvisioning;
+import org.iotivity.base.OcSecureResource;
+import org.iotivity.base.ProvisionResult;
+import org.iotivity.base.OxmType;
+import org.iotivity.base.OicSecAcl;
+import org.iotivity.base.CredType;
+import org.iotivity.base.KeySize;
+import org.iotivity.base.DeviceStatus;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.EnumSet;
+
+
+import java.util.List;
+
+
+public class ProvisioningClient extends Activity implements
+ OcSecureResource.DoOwnershipTransferListener,
+ OcSecureResource.ProvisionPairwiseDevicesListener {
+ private static final String TAG = "Provisioning Client: ";
+ OcProvisioning.PinCallbackListener pinCallbackListener =
+ new OcProvisioning.PinCallbackListener() {
+ @Override
+ public String pinCallbackListener() {
+
+ Log.d(TAG, "Inside Pin Callback ");
+ return "";
+
+ }
+ };
+ OcSecureResource.ProvisionAclListener provisionAclListener =
+ new OcSecureResource.ProvisionAclListener() {
+ @Override
+ public void provisionAclListener(List<ProvisionResult> provisionResults,
+ int hasError) {
+
+ Log.d(TAG, "Inside ProvisionAclListener ");
+
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage("Error: ACL Provision failed !!");
+ } else {
+ logMessage("ACL Provision Done !!");
+ new DeviceRevocationAsyncTask().execute();
+ }
+
+ }
+ };
+ OcSecureResource.ProvisionCredentialsListener provisionCredentialsListener =
+ new OcSecureResource.ProvisionCredentialsListener() {
+ @Override
+ public void provisionCredentialsListener(List<ProvisionResult> provisionResults,
+ int hasError) {
+
+ Log.d(TAG, "Inside ProvisionCredentialsListener ");
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage("Error: Provision Credentials failed !!");
+ } else {
+ logMessage("Provision Credentials Done !!");
+ new ProvisionACLAsyncTask().execute();
+ }
+
+
+ }
+ };
+ OcSecureResource.UnlinkDevicesListener unlinkDevicesListener =
+ new OcSecureResource.UnlinkDevicesListener() {
+ @Override
+ public void unlinkDevicesListener(List<ProvisionResult> provisionResults,
+ int hasError) {
+ Log.d(TAG, "Inside unlinkDevicesListener ");
+
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage("Error: UnLinking device !!");
+ } else {
+ logMessage("Unlink Done !!");
+ new ProvisionCredentialAsyncTask().execute();
+ }
+
+ }
+ };
+
+ OcSecureResource.RemoveDeviceListener removeDeviceListener =
+ new OcSecureResource.RemoveDeviceListener() {
+ @Override
+ public void removeDeviceListener(List<ProvisionResult> provisionResults,
+ int hasError) {
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage("Error: Remove Fail !!");
+ } else {
+ logMessage("Remove Device done !!");
+ }
+ }
+ };
+ private static final int BUFFER_SIZE = 1024;
+ int unownedDevCount = StringConstants.NUMBER_ZERO;
+ private String filePath = "";
+ private OcSecureResource newSecureResource;
+ private List<OcSecureResource> deviceList;
+ private List<OcSecureResource> ownedDeviceList;
+ //for display
+ private TextView mEventsTextView;
+
+ /**
+ * configure OIC platform and call findResource
+ */
+ private void initOICStack() {
+
+ //create platform config
+ PlatformConfig cfg = new PlatformConfig(
+ this,
+ ServiceType.IN_PROC,
+ ModeType.CLIENT_SERVER,
+ "0.0.0.0", // bind to all available interfaces
+ 0,
+ QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+ OcPlatform.Configure(cfg);
+
+ try {
+ /*
+ * Initialize DataBase
+ */
+
+ String sqlDbPath = getFilesDir().getAbsolutePath().replace("files", "databases") +
+ File.separator;
+
+ File file = new File(sqlDbPath);
+ //check files directory exists
+ if (!(file.isDirectory())) {
+ file.mkdirs();
+ Log.d(TAG, "Sql db directory created at " + sqlDbPath);
+ }
+ Log.d(TAG, "Sql db directory exists at " + sqlDbPath);
+
+ OcProvisioning.provisionInit(sqlDbPath + StringConstants.OIC_SQL_DB_FILE);
+ } catch (OcException e) {
+ logMessage(TAG + "provisionInit error: " + e.getMessage());
+ Log.e(TAG, e.getMessage());
+ }
+
+ new DiscoveryOTTransferAsyncTask().execute();
+ }
+
+ @Override
+ synchronized public void doOwnershipTransferListener(List<ProvisionResult> ProvisionResultList,
+ int hasError) {
+
+ ProvisionResult pResult = ProvisionResultList.get(0);
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage(TAG + "Ownership Transfer Failed for " + pResult.getDevId());
+ } else {
+ logMessage(TAG + "Ownership Transfer Successful for "
+ + pResult.getDevId());
+ unownedDevCount--;
+ }
+
+ if (unownedDevCount == 0) { //When done with Ownership Transfer
+ new OwnedDiscoveryAsyncTask().execute();
+ }
+ }
+
+ private void doPairwiseProvisioning() {
+ try {
+ logMessage(TAG + "Pairwise Provisioning b/w " + ownedDeviceList.get(0).getDeviceID()
+ + " and " + ownedDeviceList.get(1).getDeviceID());
+ newSecureResource = ownedDeviceList.get(0);
+ OcSecureResource newSecureResource2 = ownedDeviceList.get(1);
+ List<String> resources = new ArrayList<String>();
+ List<String> owners = new ArrayList<String>();
+ List<String> periods = new ArrayList<String>();
+ List<String> recurrences = new ArrayList<String>();
+ recurrences.add("Daily");
+ resources.add("*");
+ owners.add("adminDeviceUUID0");
+ periods.add("01-01-15");
+ OicSecAcl acl1 = new OicSecAcl(newSecureResource.getDeviceID(), recurrences, periods,
+ 31, resources, owners);
+ OicSecAcl acl2 = new OicSecAcl(newSecureResource2.getDeviceID(), recurrences, periods,
+ 31, resources, owners);
+ newSecureResource.provisionPairwiseDevices(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
+ KeySize.OWNER_PSK_LENGTH_128, acl1, newSecureResource2, acl2, this);
+
+ } catch (Exception e) {
+ logMessage(TAG + "Pairwise Provisioning error: " + e.getMessage());
+ Log.e(TAG, e.getMessage());
+ }
+ }
+
+ @Override
+ public void provisionPairwiseDevicesListener(List<ProvisionResult> ProvisionResultList,
+ int hasError) {
+ if (hasError == StringConstants.ERROR_CODE) {
+ logMessage(TAG + "provisionPairwiseDevices Failed");
+ } else {
+ for (int i = 0; i < ProvisionResultList.size(); i++) {
+ ProvisionResult pResult = ProvisionResultList.get(i);
+ logMessage(TAG + "provisionPairwiseDevices Result for "
+ + pResult.getDevId() + "is " + pResult.getResult());
+ }
+ new GetLinkedDevicesAsyncTask().execute();
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_secure_provision_client);
+ mEventsTextView = new TextView(this);
+ mEventsTextView.setGravity(Gravity.BOTTOM);
+ mEventsTextView.setMovementMethod(new ScrollingMovementMethod());
+ LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
+ layout.addView(mEventsTextView, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)
+ );
+
+ filePath = getFilesDir().getPath() + "/"; // data/data/<package>/files/
+ //copy json when application runs first time
+ SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);
+ if (isFirstRun) {
+ copyJsonFromAsset();
+ SharedPreferences.Editor editor = wmbPreference.edit();
+ editor.putBoolean("FIRSTRUN", false);
+ editor.commit();
+ }
+ initOICStack();
+ }
+
+ /**
+ * Copy svr db json file from assets folder to app data files dir
+ */
+ private void copyJsonFromAsset() {
+ InputStream inputStream = null;
+ OutputStream outputStream = null;
+ int length;
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ try {
+ inputStream = getAssets().open(StringConstants.OIC_CLIENT_JSON_DB_FILE);
+ File file = new File(filePath);
+ //check files directory exists
+ if (!(file.exists() && file.isDirectory())) {
+ file.mkdirs();
+ }
+ outputStream = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);
+
+ while ((length = inputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, length);
+ }
+
+
+ } catch (NullPointerException e) {
+ logMessage(TAG + "Null pointer exception " + e.getMessage());
+ Log.e(TAG, e.getMessage());
+ } catch (FileNotFoundException e) {
+ logMessage(TAG + "Json svr db file not found " + e.getMessage());
+ Log.e(TAG, e.getMessage());
+ } catch (IOException e) {
+ logMessage(TAG + StringConstants.OIC_CLIENT_JSON_DB_FILE + " file copy failed");
+ Log.e(TAG, e.getMessage());
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+ if (outputStream != null) {
+ try {
+ outputStream.close();
+ } catch (IOException e) {
+ Log.e(TAG, e.getMessage());
+ }
+ }
+ }
+ }
+
+ public void logMessage(String text) {
+ logMsg(text);
+ }
+
+ public void logMsg(final String text) {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ Message msg = new Message();
+ msg.obj = text;
+ mEventsTextView.append(text);
+ mEventsTextView.append("\n\n");
+ }
+ });
+ Log.i(TAG, text);
+
+ Intent intent = new Intent(getPackageName());
+ intent.putExtra(StringConstants.MESSAGE, text);
+ sendBroadcast(intent);
+ }
+
+ private class DiscoveryOTTransferAsyncTask extends AsyncTask<Void, String, String> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ try {
+ /**
+ * Discover Un-owned devices
+ */
+
+ publishProgress(TAG + "Discovering Unowned Devices");
+ deviceList = new ArrayList<OcSecureResource>();
+ deviceList = OcProvisioning.discoverUnownedDevices(5);
+
+
+ if (deviceList.size() > 0) {
+ unownedDevCount = deviceList.size();
+ for (int i = 0; i < deviceList.size(); i++) {
+ publishProgress(TAG + "Un-owned Discovered Device " + (i + 1) + "= " +
+ deviceList.get(i).getDeviceID());
+ }
+
+
+ try {
+
+ OcProvisioning.SetownershipTransferCBdata(OxmType.OIC_JUST_WORKS,
+ pinCallbackListener);
+
+ for (int i = 0; i < deviceList.size(); i++) {
+ publishProgress(TAG + "Doing Ownership Transfer for " +
+ deviceList.get(i).getDeviceID());
+ deviceList.get(i).doOwnershipTransfer(ProvisioningClient.this);
+ }
+ } catch (OcException e) {
+ publishProgress(TAG + "Ownership Transfer error: " + e.getMessage());
+ return "Ownership Transfer error: " + e.getMessage();
+
+ }
+
+
+ } else {
+ publishProgress(TAG + "No un-owned devices present");
+ }
+
+ } catch (OcException e) {
+ publishProgress(TAG + "Un-owned discovery error: " + e.getMessage());
+ return "Un-owned discovery error: " + e.getMessage();
+
+ }
+ return "success";
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+ @Override
+ protected void onPostExecute(String s) {
+ super.onPostExecute(s);
+ }
+ }
+
+ private class ProvisionACLAsyncTask extends AsyncTask<Void, String, Void> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+
+
+ if (ownedDeviceList.size() > 1) {
+ OcSecureResource ocSecureResource = ownedDeviceList.get(0);
+
+ OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
+
+ publishProgress(TAG + "ACL Provision for " + ocSecureResource.getDeviceID());
+
+ List<String> resources = new ArrayList<String>();
+ List<String> owners = new ArrayList<String>();
+ List<String> periods = new ArrayList<String>();
+ List<String> recurrences = new ArrayList<String>();
+ recurrences.add("Daily");
+ resources.add("*");
+ owners.add("adminDeviceUUID0");
+ periods.add("01-01-15");
+
+ OicSecAcl aclObject = new OicSecAcl(ocSecureResourceDest.getDeviceID(),
+ recurrences, periods, 31, resources, owners);
+
+
+ ocSecureResource.provisionACL(aclObject, provisionAclListener);
+
+ } else {
+ publishProgress(TAG + "No Owned devices present");
+ }
+
+ } catch (Exception e) {
+ publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
+
+
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+
+ }
+
+ private class ProvisionCredentialAsyncTask extends AsyncTask<Void, String, Void> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+
+ if (ownedDeviceList.size() > 1) {
+
+ OcSecureResource ocSecureResource = ownedDeviceList.get(0);
+ OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
+ publishProgress(TAG + "ProvisionCredential for " +
+ ocSecureResource.getDeviceID() + " with " +
+ ocSecureResourceDest.getDeviceID());
+
+
+ int credential_type = StringConstants.CREDENTIAL_TYPE; //symmetrical
+ int psk_length = StringConstants.OWNER_PSK_LENGTH_128;
+
+ ocSecureResource.provisionCredentials(EnumSet.of(CredType.SYMMETRIC_PAIR_WISE_KEY),
+ KeySize.OWNER_PSK_LENGTH_128,
+ ocSecureResourceDest, provisionCredentialsListener);
+
+
+ } else {
+ publishProgress(TAG + "Cannot perform credentials between devices");
+ }
+
+ } catch (Exception e) {
+ publishProgress(TAG + "ProvisionACL error: " + e.getMessage());
+
+
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+
+ }
+
+ private class GetLinkedDevicesAsyncTask extends AsyncTask<Void, String, String> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ try {
+
+ if (ownedDeviceList.size() > 1) {
+
+ OcSecureResource ocSecureResource = ownedDeviceList.get(0);
+ publishProgress(TAG + "Get linked devices of " + ocSecureResource.getDeviceID());
+
+
+ List<String> linkedDevices= ocSecureResource.getLinkedDevices();
+ if(linkedDevices.size() >0 )
+ {
+ for (int i = 0; i < linkedDevices.size(); i++) {
+ publishProgress(TAG + "Linked Devices "+
+ + (i + 1) + "= " + linkedDevices.get(i)
+ );
+ }
+ }
+ else
+ {
+ publishProgress(TAG + "No linked Devices found");
+ }
+ } else {
+ publishProgress(TAG + "Cannot perform linked devices");
+ }
+
+ } catch (Exception e) {
+ publishProgress(TAG + "getLinked device error: " + e.getMessage());
+ return "failed";
+
+
+ }
+ return "success";
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+
+ @Override
+ protected void onPostExecute(String s) {
+
+ if ("success".equals(s)) {
+ new ProvisionUnlinkAsyncTask().execute();
+
+ }
+
+
+ }
+
+ }
+
+
+ private class ProvisionUnlinkAsyncTask extends AsyncTask<Void, String, Void> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+
+ if (ownedDeviceList.size() > 1) {
+
+ OcSecureResource ocSecureResource = ownedDeviceList.get(0);
+ OcSecureResource ocSecureResourceDest = ownedDeviceList.get(1);
+ publishProgress(TAG + "Un linking " + ocSecureResource.getDeviceID() +
+ " with " + ocSecureResourceDest.getDeviceID());
+
+ ocSecureResource.unlinkDevices(ocSecureResourceDest, unlinkDevicesListener);
+
+
+ } else {
+ publishProgress(TAG + "Cannot perform unlink devices");
+ }
+
+ } catch (Exception e) {
+ publishProgress(TAG + "Unlink error: " + e.getMessage());
+
+
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+
+ }
+
+
+ private class DeviceRevocationAsyncTask extends AsyncTask<Void, String, Void> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+
+ if (ownedDeviceList.size() > 0) {
+
+ OcSecureResource ocSecureResource = ownedDeviceList.get(0);
+
+ publishProgress(TAG + "Removing " + ocSecureResource.getDeviceID());
+
+ ocSecureResource.removeDevice(20, removeDeviceListener);
+
+
+ } else {
+ publishProgress(TAG + "Cannot remove");
+ }
+
+ } catch (Exception e) {
+ publishProgress(TAG + "Remove Device error: " + e.getMessage());
+
+
+ }
+ return null;
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+
+ }
+
+ private class OwnedDiscoveryAsyncTask extends AsyncTask<Void, String, String> {
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ }
+
+ @Override
+ protected String doInBackground(Void... params) {
+ try {
+ publishProgress(TAG + "Initiate Owned device Discovery");
+
+ ownedDeviceList = OcProvisioning.discoverOwnedDevices(10);
+
+ if (ownedDeviceList.size() > 0) {
+ for (int i = 0; i < ownedDeviceList.size(); i++) {
+ publishProgress(TAG + "Owned Discovered Device " + (i + 1) + "= " +
+ ownedDeviceList.get(i).getDeviceID()
+ + "\nIP Address= " + ownedDeviceList.get(i).getIpAddr()
+ + "\nOwned Status= " + ownedDeviceList.get(i).getOwnedStatus()
+ + "\nDevice Status= " + ((ownedDeviceList.get(i).
+ getDeviceStatus() == DeviceStatus.ON) ? "ON" : "OFF")
+ );
+ }
+ } else {
+ publishProgress(TAG + "No Owned devices present");
+ }
+
+ } catch (OcException e) {
+ publishProgress(TAG + "Owned device Discovery error: " + e.getMessage());
+ return "Owned device Discovery error: " + e.getMessage();
+
+ }
+ return "success";
+ }
+
+ @Override
+ protected void onProgressUpdate(String... values) {
+ logMessage(values[0]);
+ }
+
+ @Override
+ protected void onPostExecute(String s) {
+
+ if (ownedDeviceList.size() > 1 && "success".equals(s)) {
+ doPairwiseProvisioning();
+
+ }
+
+
+ }
+
+ }
+
+ /**
+ * to display on Server Message on Client screen
+ */
+ public class MessageReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String message = intent.getStringExtra(StringConstants.MESSAGE);
+ logMessage(message);
+ }
+ }
+}
--- /dev/null
+package org.iotivity.base.examples.provisioningclient;
+
+public interface StringConstants {
+
+ public static final int NUMBER_ZERO = 0;
+ public static final int ERROR_CODE = 1;
+ public static final String OIC_CLIENT_JSON_DB_FILE = "oic_svr_db_client.json";
+ public static final String MESSAGE = "message";
+ public static final String OIC_SQL_DB_FILE = "Pdm.db";
+ public static final int CREDENTIAL_TYPE=1;
+ public static final int OWNER_PSK_LENGTH_128=128/8;
+}
--- /dev/null
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
+ android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingRight="@dimen/activity_horizontal_margin"
+ android:paddingTop="@dimen/activity_vertical_margin"
+ android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
+ android:label="@string/app_name">
+
+ <LinearLayout
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"
+ android:id="@+id/linearLayout" >
+ </LinearLayout>
+</RelativeLayout>
+
--- /dev/null
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools" tools:context=".SecureProvisionClientActivity">
+ <item android:id="@+id/action_settings" android:title="@string/action_settings"
+ android:orderInCategory="100" android:showAsAction="never" />
+</menu>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="AppTheme" parent="android:Theme.Material.Light">
+ </style>
+</resources>
--- /dev/null
+<resources>
+ <!-- Example customization of dimensions originally defined in res/values/dimens.xml
+ (such as screen margins) for screens with more than 820dp of available width. This
+ would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
+ <dimen name="activity_horizontal_margin">64dp</dimen>
+</resources>
--- /dev/null
+<resources>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>
--- /dev/null
+<resources>
+ <string name="app_name">Provisioning Client</string>
+
+ <string name="hello_world">Hello world!</string>
+ <string name="action_settings">Settings</string>
+</resources>
--- /dev/null
+<resources>
+
+ <!-- Base application theme. -->
+ <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+ <!-- Customize your theme here. -->
+ </style>
+
+</resources>
-include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient', ':guiclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':iotivity-armeabi-base-debug'
+include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient', ':guiclient', ':secureprovisionclient', ':presenceserver', ':presenceclient', ':devicediscoveryclient', ':devicediscoveryserver', ':iotivity-armeabi-base-debug'
'../../oc_logger/include',
'../connectivity/lib/libcoap-4.1.1',
'../connectivity/external/inc',
+ '../connectivity/common/inc',
'../connectivity/inc',
'../connectivity/api',
'../security/include',
- '../security/include/internal',
+ '../security/include/internal'
])
if target_os not in ['arduino', 'windows', 'winrt']:
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
+ OCSRM_SRC + 'amsmgr.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
OCSRM_SRC + 'resourcemanager.c',
OCSRM_SRC + 'aclresource.c',
OCSRM_SRC + 'amaclresource.c',
+ OCSRM_SRC + 'amsmgr.c',
OCSRM_SRC + 'pstatresource.c',
OCSRM_SRC + 'doxmresource.c',
OCSRM_SRC + 'credresource.c',
libocsrm_env.InstallTarget(libocsrm, 'libocsrm')
libocsrm_env.UserInstallTargetLib(libocsrm, 'libocsrm')
-if target_os == 'linux' and env.get('SECURED') == '1':
+if target_os in ['linux', 'android'] and env.get('SECURED') == '1':
SConscript('provisioning/SConscript')
*/
char* BinToAclJSON(const OicSecAcl_t * acl);
+
/**
* This function deletes ACL data.
*
*/
void DeleteACLList(OicSecAcl_t* acl);
+
+/**
+ * This function installs a new ACL.
+ * @param newJsonStr JSON string representing a new ACL.
+ *
+ * @retval OC_STACK_OK for Success, otherwise some error value
+ */
+OCStackResult InstallNewACL(const char* newJsonStr);
+
+
#ifdef __cplusplus
}
#endif
void DeInitAmaclResource();
/**
- * This method is used by PolicyEngine to retrieve Amacl for a Subject.
+ * This method is used by PolicyEngine to retrieve amsId for the resource.
+ * If the Amacl is found for the given resource then populate the parameter
+ * amsId with Amacl resource amss id.
*
- * @param subjectId ID of the subject for which Amacl is required.
- * @param savePtr is used internally by @ref GetAmaclResourceData to maintain index between
- * successive calls for same subjectId.
+ * @param resource resource for which AMS service is required.
+ * @param amsId ID of the ams service for the given resource
*
- * @retval reference to @ref OicSecAmacl_t if Amacl is found, else NULL
+ * @retval
+ * OC_STACK_OK If Amacl found for the resource
+ * OC_STACK_ERROR If no Amacl found for the resource
*
- * @note On the first call to @ref GetAmaclResourceData, savePtr should point to NULL
*/
-const OicSecAmacl_t* GetAmaclResourceData(const OicUuid_t* subjectId, OicSecAmacl_t **savePtr);
+OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsId);
/**
* This function converts Amacl data into JSON format.
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef IOTVT_SRM_AMSMGR_H
+#define IOTVT_SRM_AMSMGR_H
+
+#include "ocstack.h"
+#include "logger.h"
+#include "policyengine.h"
+#include "securevirtualresourcetypes.h"
+#include "cainterface.h"
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct PEContext PEContext_t;
+/**
+ * @brief The AMS context..
+ */
+typedef struct AmsMgrContext
+{
+ OicUuid_t amsDeviceId; /**< DeviceID of the oic.sec.ams service. */
+ CAEndpoint_t *endpoint;
+ CARequestInfo_t *requestInfo;
+} AmsMgrContext_t;
+
+
+/**
+ * @brief This method updates AmsMgr context's endpoint & requestInfo
+ *
+ * @param context Policy engine context.
+ * @param endpoint CA Endpoint info of the requester
+ * @param requestInfo CA RequestInfo of the requester
+ */
+OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
+ const CARequestInfo_t *requestInfo);
+
+/**
+ *
+ * This method is called by PolicyEngine to Discover AMS service.
+ * It sends muticast discovery request such as
+ * /oic/sec/doxm?deviceid="AMSSrvcDeviceID" to discover AMS service
+ * with deviceId="AMSSrvcDeviceID"
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send multicast discovery request.
+ * OC_STACK_ERROR If unable to successfully send multicast discovery request due to error.
+ *
+ */
+OCStackResult DiscoverAmsService(PEContext_t *context);
+
+
+/**
+ *
+ * This method sends unicast request to retrieve the secured port info of the
+ * discovered AMS service. It sends unicast discovery request such as
+ * /oic/res?rt="oic.sec.doxm" to the discovered AMS service
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send unicast discovery request
+ * OC_STACK_ERROR If unable to successfully send unicast discovery request due to error
+ *
+ */
+OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
+ OCConnectivityType connType);
+
+
+/**
+ *
+ * This method sends unicast request to AMS service to get ACL for
+ * the Subject and/or Resource. It sends unicast request such as
+ * /oic/sec/acl?sub="subjectId";rsrc="/a/led" to get the ACL for
+ * the subject & resource
+ *
+ * @param context Policy engine context.
+ *
+ * @retval
+ * OC_STACK_OK If able to successfully send unicast ACL request
+ * OC_STACK_ERROR If unable to successfully send unicast ACL request due to error
+ *
+ */
+OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
+ uint16_t securedPort);
+
+
+/*
+ * Cleanup CARequestInfo_t object
+ * @param requestInfo pointer to RequestInfo_t object
+ */
+void FreeCARequestInfo(CARequestInfo_t *requestInfo);
+
+
+/*
+ * This method is used by Policy engine to checks Amacl resource.
+ * If Amacl is found then it fills up context->amsMgrContext->amsDeviceId
+ * with amsID of the Amacl else leaves it empty.
+ *
+ * @param context Policy engine context.
+ *
+ * @return true if AMacl for the resource is found
+ * false if AMacl for the resource is not found
+ */
+bool FoundAmaclForRequest(PEContext_t *context);
+
+
+/*
+ * This method is used by Policy engine to process AMS request
+ * *
+ * @param context Policy engine context.
+ *
+ * @return None
+ */
+void ProcessAMSRequest(PEContext_t *context);
+
+#endif //IOTVT_SRM_AMSMGR_H
#include "logger.h"
#include "securevirtualresourcetypes.h"
#include "cainterface.h"
+#include "amsmgr.h"
#include <stdlib.h>
#include <stdint.h>
+typedef struct AmsMgrContext AmsMgrContext_t;
+
typedef enum PEState
{
- STOPPED = 0,
- AWAITING_REQUEST,
- BUSY
+ STOPPED = 0, //Policy engine state machine is not running
+ AWAITING_REQUEST, //Can process new request
+ AWAITING_AMS_RESPONSE, //Can't process new request; waiting for AMS response
+ BUSY //Can't process new request as processing other requests
} PEState_t;
+
typedef struct PEContext
{
PEState_t state;
- OicUuid_t *subject;
- char *resource;
+ OicUuid_t subject;
+ char resource[MAX_URI_LENGTH];
uint16_t permission;
bool matchingAclFound;
+ bool amsProcessing;
SRMAccessResponse_t retVal;
+ AmsMgrContext_t *amsMgrContext;
} PEContext_t;
/**
*/
uint16_t GetPermissionFromCAMethod_t(const CAMethod_t method);
+
+/*
+ * This method reset Policy Engine context to default state and update
+ * it's state to @param state.
+ *
+ * @param context Policy engine context.
+ * @param state Set Policy engine state to this.
+ *
+ * @return none
+ */
+void SetPolicyEngineState(PEContext_t *context, const PEState_t state);
+
#endif //IOTVT_SRM_PE_H
#ifndef SECURITYRESOURCEMANAGER_H_
#define SECURITYRESOURCEMANAGER_H_
+#include "securevirtualresourcetypes.h"
+
#ifdef __cplusplus
extern "C" {
#endif
*/
bool SRMIsSecurityResourceURI(const char* uri);
+/**
+ * @brief Sends Response
+ * @param resposeVal SRMAccessResponse_t value
+ * @return NONE
+ */
+void SRMSendResponse(SRMAccessResponse_t responseVal);
+
+
#ifdef __cplusplus
}
#endif
#define RESOURCE_NOT_FOUND_DEF (1 << 4)
#define POLICY_ENGINE_ERROR_DEF (1 << 5)
#define INVALID_PERIOD_DEF (1 << 6)
+#define ACCESS_WAITING_DEF (1 << 7)
+#define AMS_SERVICE_DEF (1 << 8)
#define REASON_MASK_DEF (INSUFFICIENT_PERMISSION_DEF | \
INVALID_PERIOD_DEF | \
SUBJECT_NOT_FOUND_DEF | \
| RESOURCE_NOT_FOUND_DEF,
ACCESS_DENIED_POLICY_ENGINE_ERROR = ACCESS_DENIED_DEF
| POLICY_ENGINE_ERROR_DEF,
+ ACCESS_WAITING_FOR_AMS = ACCESS_WAITING_DEF
+ | AMS_SERVICE_DEF,
+ ACCESS_DENIED_AMS_SERVICE_ERROR = ACCESS_DENIED
+ | AMS_SERVICE_DEF
} SRMAccessResponse_t;
/**
}
return false;
}
+
/*
* This method removes ACE for the subject and resource from the ACL
*
ParseQueryIterInit((unsigned char *)query, &parseIter);
+
while(GetNextQuery(&parseIter))
{
if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
*savePtr = NULL;
return NULL;
}
+
+
+OCStackResult InstallNewACL(const char* newJsonStr)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ // Convert JSON ACL data into binary. This will also validate the ACL data received.
+ OicSecAcl_t* newAcl = JSONToAclBin(newJsonStr);
+
+ if (newAcl)
+ {
+ // Append the new ACL to existing ACL
+ LL_APPEND(gAcl, newAcl);
+
+ // Convert ACL data into JSON for update to persistent storage
+ char *jsonStr = BinToAclJSON(gAcl);
+ if (jsonStr)
+ {
+ cJSON *jsonAcl = cJSON_Parse(jsonStr);
+ OICFree(jsonStr);
+
+ if (jsonAcl)
+ {
+ ret = UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl);
+ }
+ cJSON_Delete(jsonAcl);
+ }
+ }
+
+ return ret;
+}
DeleteAmaclList(gAmacl);
gAmacl = NULL;
}
+
+
+OCStackResult AmaclGetAmsDeviceId(const char *resource, OicUuid_t *amsDeviceId)
+{
+ OicSecAmacl_t *amacl = NULL;
+
+ VERIFY_NON_NULL(TAG, resource, ERROR);
+ VERIFY_NON_NULL(TAG, amsDeviceId, ERROR);
+
+ LL_FOREACH(gAmacl, amacl)
+ {
+ for(size_t i = 0; i < amacl->resourcesLen; i++)
+ {
+ if (strncmp((amacl->resources[i]), resource, strlen(amacl->resources[i])) == 0)
+ {
+ //Returning the ID of the first AMS service for the resource
+ memcpy(amsDeviceId, &amacl->amss[0], sizeof(*amsDeviceId));
+ return OC_STACK_OK;
+ }
+ }
+ }
+
+exit:
+ return OC_STACK_ERROR;
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH 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 "oic_malloc.h"
+#include "amsmgr.h"
+#include "resourcemanager.h"
+#include "securevirtualresourcetypes.h"
+#include "srmresourcestrings.h"
+#include "logger.h"
+#include "ocrandom.h"
+#include "aclresource.h"
+#include "amaclresource.h"
+#include "srmutility.h"
+#include "base64.h"
+#include "secureresourcemanager.h"
+#include "doxmresource.h"
+#include "policyengine.h"
+#include "oic_string.h"
+#include "caremotehandler.h"
+#include <string.h>
+
+#define TAG "SRM-AMSMGR"
+
+
+ //Callback for AMS service multicast discovery request.
+static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+//Callback for unicast secured port discovery request.
+static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+//Callback for unicast ACL request
+static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse);
+
+
+OCStackResult DiscoverAmsService(PEContext_t *context)
+{
+ OC_LOG(INFO, TAG, "IN DiscoverAmsService");
+
+ OCStackResult ret = OC_STACK_ERROR;
+ const char DOXM_DEVICEID_QUERY_FMT[] = "%s?%s=%s";
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ OCCallbackData cbData = {.context=NULL};
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+ uint32_t outLen = 0;
+ B64Result b64Ret;
+
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ b64Ret = b64Encode(context->amsMgrContext->amsDeviceId.id,
+ sizeof(context->amsMgrContext->amsDeviceId.id), base64Buff, sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+ snprintf(uri, sizeof(uri), DOXM_DEVICEID_QUERY_FMT, OIC_RSRC_DOXM_URI,
+ OIC_JSON_DEVICE_ID_NAME, base64Buff);
+
+ cbData.cb = &AmsMgrDiscoveryCallback;
+ cbData.context = (void*)context;
+
+ /* TODO
+ * If no good response was received for this discovery request,
+ * PE would be blocked forever waiting for AMS service to respond with the ACE.
+ * Need logic to reset the PE state and send ACCESS_DENIED response,
+ * when discovery response from AMS service is not received within certain time.
+ */
+ OC_LOG_V(INFO, TAG,"AMS Manager Sending Multicast Discovery with URI = %s", uri);
+ ret = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL,
+ CT_DEFAULT, OC_LOW_QOS, &cbData, NULL, 0);
+
+exit:
+ OC_LOG(INFO, TAG, "Leaving DiscoverAmsService");
+ return ret;
+}
+
+
+static OCStackApplicationResult AmsMgrDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG_V(INFO, TAG, "%s Begin", __func__ );
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type)||
+ (OC_STACK_OK != clientResponse->result))
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ (void)handle;
+ PEContext_t *context = (PEContext_t *) ctx;
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid PE State ", __func__);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ OicSecDoxm_t *doxm = NULL;
+ OC_LOG_V(INFO, TAG, "Doxm DeviceId Discovery response = %s\n",
+ ((OCSecurityPayload*)clientResponse->payload)->securityData);
+ doxm = JSONToDoxmBin(((OCSecurityPayload*)clientResponse->payload)->securityData);
+
+ //As doxm is NULL amsmgr can't test if response from trusted AMS service
+ //so keep the transaction.
+ if(NULL == doxm)
+ {
+ OC_LOG_V(ERROR, TAG, "%s : Unable to convert JSON to Binary",__func__);
+ return OC_STACK_KEEP_TRANSACTION;
+ }
+
+ OicUuid_t deviceId = {.id={}};
+ memcpy(&deviceId, &doxm->deviceID, sizeof(deviceId));
+ OICFree(doxm);
+
+ /* TODO : By assuming that the first response received is the actual
+ * AMS service, a 'bad device' can cause DoS attack.
+ */
+ if (memcmp(&context->amsMgrContext->amsDeviceId, &deviceId,
+ sizeof(context->amsMgrContext->amsDeviceId)) == 0)
+ {
+ OC_LOG(INFO, TAG, "AMS Manager Sending unicast discovery to get secured port info");
+ //Sending Unicast discovery to get secure port information
+ if(OC_STACK_OK == SendUnicastSecurePortDiscovery(context, &clientResponse->devAddr,
+ clientResponse->connType))
+ {
+ context->retVal = ACCESS_WAITING_FOR_AMS;
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult SendUnicastSecurePortDiscovery(PEContext_t *context,OCDevAddr *devAddr,
+ OCConnectivityType connType)
+{
+ OC_LOG(INFO, TAG, "IN SendUnicastSecurePortDiscovery");
+
+ const char RES_DOXM_QUERY_FMT[] = "%s?%s=%s";
+ OCCallbackData cbData = {.context=NULL};
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ snprintf(uri, sizeof(uri), RES_DOXM_QUERY_FMT, OC_RSRVD_WELL_KNOWN_URI,
+ OC_RSRVD_RESOURCE_TYPE, OIC_RSRC_TYPE_SEC_DOXM);
+
+ cbData.cb = &SecurePortDiscoveryCallback;
+ cbData.context = context;
+
+ OC_LOG_V(INFO, TAG, "AMS Manager Sending Unicast Discovery with URI = %s", uri);
+
+ return OCDoResource(NULL, OC_REST_DISCOVER, uri, devAddr, NULL,
+ connType, OC_LOW_QOS, &cbData, NULL, 0);
+}
+
+static OCStackApplicationResult SecurePortDiscoveryCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG(INFO, TAG, "In SecurePortDiscoveryCallback");
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_DISCOVERY != clientResponse->payload->type)||
+ (OC_STACK_OK != clientResponse->result))
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid Response ", __func__);
+ SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ PEContext_t *context = (PEContext_t *) ctx;
+ (void)handle;
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid PE State ", __func__);
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ OCResourcePayload* resPayload = ((OCDiscoveryPayload*)clientResponse->payload)->resources;
+
+ //Verifying if the ID of the sender is an AMS service that this device trusts.
+ if(memcmp(context->amsMgrContext->amsDeviceId.id, resPayload->sid,
+ sizeof(context->amsMgrContext->amsDeviceId.id)) != 0)
+ {
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ if (resPayload && resPayload->secure)
+ {
+ if(OC_STACK_OK == SendAclReq(context, &clientResponse->devAddr, clientResponse->connType,
+ resPayload->port))
+ {
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+ }
+ OC_LOG(INFO, TAG, "Can not find secure port information");
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult SendAclReq(PEContext_t *context, OCDevAddr *devAddr, OCConnectivityType connType,
+ uint16_t securedPort)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+ const char GET_ACE_QUERY_FMT[] = "%s?%s=%s;%s=%s";
+ char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
+ uint32_t outLen = 0;
+ char uri[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {};
+ OCCallbackData cbData = {.context=NULL};
+ OCDevAddr destAddr = {.adapter = OC_ADAPTER_IP};
+ B64Result b64Ret;
+
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ VERIFY_NON_NULL(TAG, devAddr, ERROR);
+
+ b64Ret = b64Encode(context->subject.id, sizeof(context->subject.id),
+ base64Buff, sizeof(base64Buff), &outLen);
+ VERIFY_SUCCESS(TAG, B64_OK == b64Ret, ERROR);
+
+ snprintf(uri, sizeof(uri), GET_ACE_QUERY_FMT, OIC_RSRC_ACL_URI,
+ OIC_JSON_SUBJECT_NAME, base64Buff,
+ OIC_JSON_RESOURCES_NAME, context->resource);
+
+ cbData.cb = &AmsMgrAclReqCallback;
+ cbData.context = context;
+
+ destAddr = *devAddr;
+ //update port info
+ destAddr.flags = (OCTransportFlags)(destAddr.flags | OC_FLAG_SECURE);
+ destAddr.port = securedPort;
+
+ OC_LOG_V(INFO, TAG, "AMS Manager Sending Unicast ACL request with URI = %s", uri);
+ ret = OCDoResource(NULL, OC_REST_GET, uri, &destAddr, NULL,
+ connType, OC_LOW_QOS, &cbData, NULL, 0);
+
+exit:
+ OC_LOG_V(INFO, TAG, "%s returns %d ", __func__, ret);
+ return ret;
+}
+
+
+static OCStackApplicationResult AmsMgrAclReqCallback(void *ctx, OCDoHandle handle,
+ OCClientResponse * clientResponse)
+{
+ OC_LOG_V(INFO, TAG, "%s Begin", __func__ );
+
+ (void)handle;
+ PEContext_t *context = (PEContext_t *) ctx;
+ SRMAccessResponse_t rsps;
+
+ if (!ctx ||
+ !clientResponse ||
+ !clientResponse->payload||
+ (PAYLOAD_TYPE_SECURITY != clientResponse->payload->type) ||
+ (clientResponse->result != OC_STACK_OK))
+ {
+ SRMSendResponse(ACCESS_DENIED_AMS_SERVICE_ERROR);
+ goto exit;
+ }
+
+ if (context->state != AWAITING_AMS_RESPONSE)
+ {
+ OC_LOG_V(ERROR, TAG, "%s Invalid State ", __func__);
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+ // Verify before installing ACL if the ID of the sender of this ACL is an AMS
+ //service that this device trusts.
+ rsps = ACCESS_DENIED;
+ if((UUID_LENGTH == clientResponse->identity.id_length) &&
+ memcmp(context->amsMgrContext->amsDeviceId.id, clientResponse->identity.id,
+ sizeof(context->amsMgrContext->amsDeviceId.id)) == 0)
+ {
+ OCStackResult ret =
+ InstallNewACL(((OCSecurityPayload*)clientResponse->payload)->securityData);
+ VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
+
+ OC_LOG_V(INFO, TAG, "%s : Calling checkPermission", __func__);
+ rsps = CheckPermission(context, &context->subject, context->resource, context->permission);
+ VERIFY_SUCCESS(TAG, (true == IsAccessGranted(rsps)), ERROR);
+
+ OC_LOG_V(INFO, TAG, "%sAccess granted, Calling SRMCallCARequestHandler", __func__);
+ context->retVal = ACCESS_GRANTED;
+ SRMSendResponse(context->retVal);
+ return OC_STACK_DELETE_TRANSACTION;
+ }
+
+exit:
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ SRMSendResponse(context->retVal);
+ FreeCARequestInfo(context->amsMgrContext->requestInfo);
+ OICFree(context->amsMgrContext->endpoint);
+ return OC_STACK_DELETE_TRANSACTION;
+}
+
+
+OCStackResult UpdateAmsMgrContext(PEContext_t *context, const CAEndpoint_t *endpoint,
+ const CARequestInfo_t *requestInfo)
+{
+ OCStackResult ret = OC_STACK_ERROR;
+
+ //The AmsMgr context endpoint and requestInfo will be free from ,
+ //AmsMgrAclReqCallback function
+ if(context->amsMgrContext->endpoint)
+ {
+ OICFree(context->amsMgrContext->endpoint);
+ context->amsMgrContext->endpoint = NULL;
+ }
+ context->amsMgrContext->endpoint = (CAEndpoint_t *)OICCalloc(1, sizeof(CAEndpoint_t ));
+ VERIFY_NON_NULL(TAG, context->amsMgrContext->endpoint, ERROR);
+ *context->amsMgrContext->endpoint = *endpoint;
+
+ if(context->amsMgrContext->requestInfo)
+ {
+ FreeCARequestInfo(context->amsMgrContext->requestInfo);
+ context->amsMgrContext->requestInfo = NULL;
+ }
+ context->amsMgrContext->requestInfo = CACloneRequestInfo(requestInfo);
+ VERIFY_NON_NULL(TAG, context->amsMgrContext->requestInfo, ERROR);
+ ret = OC_STACK_OK;
+exit:
+ return ret;
+}
+
+void FreeCARequestInfo(CARequestInfo_t *requestInfo)
+{
+ OICFree(requestInfo->info.token);
+ OICFree(requestInfo->info.options);
+ OICFree(requestInfo->info.payload);
+ OICFree(requestInfo->info.resourceUri);
+ OICFree(requestInfo);
+}
+
+
+//This method checks for Amacl resource. If Amacl is found then it fills up
+//context->amsMgrContext->amsDeviceId with amsID of the Amacl else leaves it empty.
+bool FoundAmaclForRequest(PEContext_t *context)
+{
+ OC_LOG_V(INFO, TAG, "%s:no ACL found. Searching for AMACL",__func__);
+
+ bool ret = false;
+ VERIFY_NON_NULL(TAG, context, ERROR);
+ memset(&context->amsMgrContext->amsDeviceId, 0, sizeof(context->amsMgrContext->amsDeviceId));
+
+ //Call amacl resource function to get the AMS service deviceID for the resource
+ if(OC_STACK_OK == AmaclGetAmsDeviceId(context->resource, &context->amsMgrContext->amsDeviceId))
+ {
+ OC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s",
+ __func__, context->resource);
+ ret = true;
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "%s:AMACL found for the requested resource %s",
+ __func__, context->resource);
+ ret = false;
+ }
+
+ exit:
+ return ret;
+}
+
+
+void ProcessAMSRequest(PEContext_t *context)
+{
+ OicUuid_t emptyUuid = {.id={}};
+ OC_LOG_V(INFO, TAG, "Entering %s", __func__);
+ if(NULL != context)
+ {
+ if((false == context->matchingAclFound) && (false == context->amsProcessing))
+ {
+ context->amsProcessing = true;
+
+ //Checking if context AMS deviceId is empty
+ if(memcmp(&context->amsMgrContext->amsDeviceId, &emptyUuid, sizeof(OicUuid_t)) != 0 )
+ {
+ if(OC_STACK_OK == DiscoverAmsService(context))
+ {
+ context->retVal = ACCESS_WAITING_FOR_AMS;
+ }
+ else
+ {
+ context->retVal = ACCESS_DENIED_AMS_SERVICE_ERROR;
+ }
+ }
+ }
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "Leaving %s(context is NULL)", __func__);
+ }
+
+ if(ACCESS_WAITING_FOR_AMS == context->retVal )
+ {
+ OC_LOG_V(INFO, TAG, "Leaving %s(WAITING_FOR_AMS)", __func__);
+ }
+}
#include "oic_malloc.h"
#include "policyengine.h"
+#include "amsmgr.h"
#include "resourcemanager.h"
#include "securevirtualresourcetypes.h"
#include "srmresourcestrings.h"
return true;
}
-
/**
* Set the state and clear other stateful context vars.
*/
void SetPolicyEngineState(PEContext_t *context, const PEState_t state)
{
// Clear stateful context variables.
- OICFree(context->subject);
- context->subject = NULL;
- OICFree(context->resource);
- context->resource = NULL;
+ memset(&context->subject, 0, sizeof(context->subject));
+ memset(&context->resource, 0, sizeof(context->resource));
context->permission = 0x0;
context->matchingAclFound = false;
+ context->amsProcessing = false;
context->retVal = ACCESS_DENIED_POLICY_ENGINE_ERROR;
+ memset(context->amsMgrContext, 0, sizeof(AmsMgrContext_t));
// Set state.
context->state = state;
if(OC_STACK_OK == GetDoxmDevOwnerId(&owner))
{
- retVal = UuidCmp(context->subject, &owner);
+ retVal = UuidCmp(&context->subject, &owner);
}
return retVal;
}
+
+inline static bool IsRequestSubjectEmpty(PEContext_t *context)
+{
+ OicUuid_t emptySubject = {.id={}};
+ return (memcmp(&context->subject, &emptySubject, sizeof(OicUuid_t)) == 0) ?
+ true : false;
+}
+
+
/**
* Bitwise check to see if 'permission' contains 'request'.
* @param permission The allowed CRUDN permission.
{
size_t length = 0;
- // Free any existing subject.
- OICFree(context->subject);
- // Copy the subjectId into context.
- context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, context->subject, ERROR);
- memcpy(context->subject, subjectId, sizeof(OicUuid_t));
+ memcpy(&context->subject, subjectId, sizeof(OicUuid_t));
// Copy the resource string into context.
length = strlen(resource) + 1;
if(0 < length)
{
- OICFree(context->resource);
- context->resource = (char*)OICMalloc(length);
- VERIFY_NON_NULL(TAG, context->resource, ERROR);
strncpy(context->resource, resource, length);
context->resource[length - 1] = '\0';
}
// Assign the permission field.
context->permission = requestedPermission;
-
-exit:
- return;
}
+
/**
* Check whether 'resource' is getting accessed within the valid time period.
* @param acl The ACL to check.
return false;
}
+
/**
* Find ACLs containing context->subject.
* Search each ACL for requested resource.
- * If resource found, check for context->permission.
+ * If resource found, check for context->permission and period validity.
+ * If the ACL is not found locally and AMACL for the resource is found
+ * then sends the request to AMS service for the ACL
* Set context->retVal to result from first ACL found which contains
* correct subject AND resource.
*
// Start out assuming subject not found.
context->retVal = ACCESS_DENIED_SUBJECT_NOT_FOUND;
+
+ // Loop through all ACLs with a matching Subject searching for the right
+ // ACL for this request.
do
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): getting ACL...");
- currentAcl = GetACLResourceData(context->subject, &savePtr);
+ OC_LOG_V(INFO, TAG, ("%s: getting ACL..."),__func__);
+ currentAcl = GetACLResourceData(&context->subject, &savePtr);
+
if(NULL != currentAcl)
{
// Found the subject, so how about resource?
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- found ACL matching subject.");
+ OC_LOG_V(INFO, TAG, ("%s:found ACL matching subject"),__func__);
+
+ // Subject was found, so err changes to Rsrc not found for now.
context->retVal = ACCESS_DENIED_RESOURCE_NOT_FOUND;
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Searching for resource...");
+ OC_LOG_V(INFO, TAG, ("%s:Searching for resource..."),__func__);
if(IsResourceInAcl(context->resource, currentAcl))
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- found matching resource in ACL.");
+ OC_LOG_V(INFO, TAG, ("%s:found matching resource in ACL"),__func__);
context->matchingAclFound = true;
// Found the resource, so it's down to valid period & permission.
if(IsAccessWithinValidTime(currentAcl))
{
context->retVal = ACCESS_DENIED_INSUFFICIENT_PERMISSION;
- if(IsPermissionAllowingRequest(currentAcl->permission, \
- context->permission))
+ if(IsPermissionAllowingRequest(currentAcl->permission, context->permission))
{
context->retVal = ACCESS_GRANTED;
}
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- no ACL found matching subject .");
+ OC_LOG_V(INFO, TAG, ("%s:no ACL found matching subject for resource %s"),__func__, context->resource);
}
}
while((NULL != currentAcl) && (false == context->matchingAclFound));
if(IsAccessGranted(context->retVal))
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(ACCESS_GRANTED)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(ACCESS_GRANTED)"), __func__);
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(ACCESS_DENIED)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(ACCESS_DENIED)"), __func__);
}
}
else
{
- OC_LOG(INFO, TAG, "ProcessAccessRequest(): \
- Leaving ProcessAccessRequest(context is NULL)");
+ OC_LOG_V(INFO, TAG, ("%s:Leaving ProcessAccessRequest(context is NULL)"), __func__);
}
-
}
/**
VERIFY_NON_NULL(TAG, resource, ERROR);
// Each state machine context can only be processing one request at a time.
- // Therefore if the context is not in AWAITING_REQUEST state, return error.
- // Otherwise, change to BUSY state and begin processing request.
- if(AWAITING_REQUEST == context->state)
+ // Therefore if the context is not in AWAITING_REQUEST or AWAITING_AMS_RESPONSE
+ // state, return error. Otherwise, change to BUSY state and begin processing request.
+ if(AWAITING_REQUEST == context->state || AWAITING_AMS_RESPONSE == context->state)
{
- SetPolicyEngineState(context, BUSY);
- CopyParamsToContext(context, subjectId, resource, requestedPermission);
+ if(AWAITING_REQUEST == context->state)
+ {
+ SetPolicyEngineState(context, BUSY);
+ CopyParamsToContext(context, subjectId, resource, requestedPermission);
+ }
+
// Before doing any processing, check if request coming
// from DevOwner and if so, always GRANT.
if(IsRequestFromDevOwner(context))
}
else
{
+ OicUuid_t saveSubject = {.id={}};
+ bool isSubEmpty = IsRequestSubjectEmpty(context);
+
ProcessAccessRequest(context);
+
// If matching ACL not found, and subject != wildcard, try wildcard.
if((false == context->matchingAclFound) && \
- (false == IsWildCardSubject(context->subject)))
+ (false == IsWildCardSubject(&context->subject)))
{
- OICFree(context->subject);
- context->subject = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
- VERIFY_NON_NULL(TAG, context->subject, ERROR);
- memcpy(context->subject, &WILDCARD_SUBJECT_ID,
- sizeof(OicUuid_t));
+ //Saving subject for Amacl check
+ memcpy(&saveSubject, &context->subject,sizeof(OicUuid_t));
+
+ //Setting context subject to WILDCARD_SUBJECT_ID
+ //TODO: change ProcessAccessRequest method signature to
+ //ProcessAccessRequest(context, subject) so that context
+ //subject is not tempered.
+ memset(&context->subject, 0, sizeof(context->subject));
+ memcpy(&context->subject, &WILDCARD_SUBJECT_ID,sizeof(OicUuid_t));
ProcessAccessRequest(context); // TODO anonymous subj can result
// in confusing err code return.
}
+
+ //No local ACE found for the request so checking Amacl resource
+ if(ACCESS_GRANTED != context->retVal)
+ {
+ //If subject is not empty then restore the original subject
+ //else keep the subject to WILDCARD_SUBJECT_ID
+ if(!isSubEmpty)
+ {
+ memcpy(&context->subject, &saveSubject, sizeof(OicUuid_t));
+ }
+
+ //FoundAmaclForRequest method checks for Amacl and fills up
+ //context->amsMgrContext->amsDeviceId with the AMS deviceId
+ //if Amacl was found for the requested resource.
+ if(FoundAmaclForRequest(context))
+ {
+ ProcessAMSRequest(context);
+ }
+ }
}
}
else
// Capture retVal before resetting state for next request.
retVal = context->retVal;
- SetPolicyEngineState(context, AWAITING_REQUEST);
+
+ //Change the state of PE to "AWAITING_AMS_RESPONSE", if waiting
+ //for response from AMS service else to "AWAITING_REQUEST"
+ if(ACCESS_WAITING_FOR_AMS == retVal)
+ {
+ OC_LOG(INFO, TAG, ("Setting PE State to AWAITING_AMS_RESPONSE"));
+ context->state = AWAITING_AMS_RESPONSE;
+ }
+ else if(!context->amsProcessing)
+ {
+ OC_LOG(INFO, TAG, ("Resetting PE context and PE State to AWAITING_REQUEST"));
+ SetPolicyEngineState(context, AWAITING_REQUEST);
+ }
exit:
return retVal;
*/
OCStackResult InitPolicyEngine(PEContext_t *context)
{
+ context->amsMgrContext = (AmsMgrContext_t *)OICMalloc(sizeof(AmsMgrContext_t));
if(NULL != context)
{
SetPolicyEngineState(context, AWAITING_REQUEST);
{
SetPolicyEngineState(context, STOPPED);
}
-
+ OICFree(context->amsMgrContext);
return;
}
#include "ocstack.h"
#include "logger.h"
#include "cainterface.h"
-#include "secureresourcemanager.h"
#include "resourcemanager.h"
#include "credresource.h"
#include "policyengine.h"
+#include "srmutility.h"
+#include "amsmgr.h"
#include "oic_string.h"
+#include "oic_malloc.h"
+#include "securevirtualresourcetypes.h"
+#include "secureresourcemanager.h"
#include "srmresourcestrings.h"
#define TAG "SRM"
{
gSPResponseHandler = respHandler;
}
+
+
+static void SRMSendUnAuthorizedAccessresponse(PEContext_t *context)
+{
+ CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
+ memcpy(&responseInfo.info, &(context->amsMgrContext->requestInfo->info),
+ sizeof(responseInfo.info));
+ responseInfo.info.payload = NULL;
+ responseInfo.result = CA_UNAUTHORIZED_REQ;
+ if (CA_STATUS_OK != CASendResponse(context->amsMgrContext->endpoint, &responseInfo))
+ {
+ OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+ }
+ else
+ {
+ OC_LOG(INFO, TAG, "Succeed in sending response to a unauthorized request!");
+ }
+}
+
+
+void SRMSendResponse(SRMAccessResponse_t responseVal)
+{
+ OC_LOG(INFO, TAG, "Sending response to remote device");
+
+ if (IsAccessGranted(responseVal) && gRequestHandler)
+ {
+ OC_LOG_V(INFO, TAG, "%s : Access granted. Passing Request to RI layer", __func__);
+ if (!g_policyEngineContext.amsMgrContext->endpoint ||
+ !g_policyEngineContext.amsMgrContext->requestInfo)
+ {
+ OC_LOG_V(ERROR, TAG, "%s : Invalid arguments", __func__);
+ SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
+ goto exit;
+ }
+ gRequestHandler(g_policyEngineContext.amsMgrContext->endpoint,
+ g_policyEngineContext.amsMgrContext->requestInfo);
+ }
+ else
+ {
+ OC_LOG_V(INFO, TAG, "%s : ACCESS_DENIED.", __func__);
+ SRMSendUnAuthorizedAccessresponse(&g_policyEngineContext);
+ }
+
+exit:
+ //Resting PE state to AWAITING_REQUEST
+ SetPolicyEngineState(&g_policyEngineContext, AWAITING_REQUEST);
+}
+
+
/**
* @brief Handle the request from the SRM.
* @param endPoint [IN] Endpoint object from which the response is received.
int position = 0;
if (uri)
{
+ //Skip query and pass the resource uri
position = uri - requestInfo->info.resourceUri;
}
- if (position > MAX_URI_LENGTH)
+ else
+ {
+ position = strlen(requestInfo->info.resourceUri);
+ }
+ if (MAX_URI_LENGTH < position || 0 > position)
{
- OC_LOG(ERROR, TAG, "URI length is too long");
+ OC_LOG(ERROR, TAG, "Incorrect URI length");
return;
}
SRMAccessResponse_t response = ACCESS_DENIED;
- if (position > 0)
+ char newUri[MAX_URI_LENGTH + 1];
+ OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
+
+ //New request are only processed if the policy engine state is AWAITING_REQUEST.
+ if(AWAITING_REQUEST == g_policyEngineContext.state)
{
- char newUri[MAX_URI_LENGTH + 1];
- OICStrcpyPartial(newUri, MAX_URI_LENGTH + 1, requestInfo->info.resourceUri, position);
- //Skip query and pass the newUri.
- response = CheckPermission(&g_policyEngineContext, &subjectId,
- newUri,
- GetPermissionFromCAMethod_t(requestInfo->method));
+ OC_LOG_V(INFO, TAG, "Processing request with uri, %s for method, %d",
+ requestInfo->info.resourceUri, requestInfo->method);
+ response = CheckPermission(&g_policyEngineContext, &subjectId, newUri,
+ GetPermissionFromCAMethod_t(requestInfo->method));
}
else
{
- //Pass resourceUri if there is no query info.
- response = CheckPermission(&g_policyEngineContext, &subjectId,
- requestInfo->info.resourceUri,
- GetPermissionFromCAMethod_t(requestInfo->method));
+ OC_LOG_V(INFO, TAG, "PE state %d. Ignoring request with uri, %s for method, %d",
+ g_policyEngineContext.state, requestInfo->info.resourceUri, requestInfo->method);
}
+
if (IsAccessGranted(response) && gRequestHandler)
{
return (gRequestHandler(endPoint, requestInfo));
}
- // Form a 'access deny' or 'Error' response and send to peer
+ // Form a 'Error', 'slow response' or 'access deny' response and send to peer
CAResponseInfo_t responseInfo = {.result = CA_EMPTY};
memcpy(&responseInfo.info, &(requestInfo->info), sizeof(responseInfo.info));
responseInfo.info.payload = NULL;
- if (!gRequestHandler)
+
+ VERIFY_NON_NULL(TAG, gRequestHandler, ERROR);
+
+ if(ACCESS_WAITING_FOR_AMS == response)
{
- responseInfo.result = CA_INTERNAL_SERVER_ERROR;
+ OC_LOG(INFO, TAG, "Sending slow response");
+
+ UpdateAmsMgrContext(&g_policyEngineContext, endPoint, requestInfo);
+ responseInfo.result = CA_EMPTY;
+ responseInfo.info.type = CA_MSG_ACKNOWLEDGE;
}
else
{
* CA_UNAUTHORIZED_REQ or CA_FORBIDDEN_REQ depending
* upon SRMAccessResponseReasonCode_t
*/
+ OC_LOG(INFO, TAG, "Sending for regular response");
responseInfo.result = CA_UNAUTHORIZED_REQ;
}
{
OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
}
+ return;
+exit:
+ responseInfo.result = CA_INTERNAL_SERVER_ERROR;
+ if (CA_STATUS_OK != CASendResponse(endPoint, &responseInfo))
+ {
+ OC_LOG(ERROR, TAG, "Failed in sending response to a unauthorized request!");
+ }
}
/**
*/
void SRMErrorHandler(const CAEndpoint_t *endPoint, const CAErrorInfo_t *errorInfo)
{
- OC_LOG(INFO, TAG, "Received error from remote device");
+ OC_LOG_V(INFO, TAG, "Received error from remote device with result, %d for request uri, %s",
+ errorInfo->result, errorInfo->info.resourceUri);
if (gErrorHandler)
{
gErrorHandler(endPoint, errorInfo);
{
DeInitPolicyEngine(&g_peContext);
EXPECT_EQ(STOPPED, g_peContext.state);
- EXPECT_EQ(NULL, g_peContext.subject);
- EXPECT_EQ(NULL, g_peContext.resource);
EXPECT_EQ((uint16_t)0, g_peContext.permission);
EXPECT_FALSE(g_peContext.matchingAclFound);
EXPECT_EQ(ACCESS_DENIED_POLICY_ENGINE_ERROR, g_peContext.retVal);
--- /dev/null
+Testing AMS service:
+1. Copy subjectID ("NDQ0NDMzMzMyMjIyMTExMQ==") of ACE with resource "/a/led" from AMS service
+ database file, "oic_amss_db.json" into client Doxm resource deviceID located in file
+ "oic_svr_client.json".
+2. Start ocserverbasicops
+3. start ocamsservice
+4. Start occlientbasicops
+
+
+Expected Result:
+1. New ACE with subjectID="NDQ0NDMzMzMyMjIyMTExMQ==" and rsrc="/a/led/" will be appended to the
+ server ACL resource in file "oic_svr_db_server.json".
+2. GET request made by occlientbasicops will be received successfully
+3. PUT reuest will received with result "OC_STACK_UNAUTHORIZED_REQ"
ocserverbasicops = samples_env.Program('ocserverbasicops', ['common.cpp', 'ocserverbasicops.cpp'])
occlientbasicops = samples_env.Program('occlientbasicops', ['common.cpp', 'occlientbasicops.cpp'])
+ocamsservice = samples_env.Program('ocamsservice', ['common.cpp', 'ocamsservice.cpp'])
-Alias("samples", [ocserverbasicops, occlientbasicops])
+Alias("samples", [ocserverbasicops, occlientbasicops, ocamsservice])
env.AppendTarget('samples')
sec_samples_src_dir + 'oic_svr_db_server.json'))
samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
sec_samples_src_dir + 'oic_svr_db_client.json'))
+samples_env.Alias("install", samples_env.Install( sec_samples_build_dir,
+ sec_samples_src_dir + 'oic_amss_db.json'))
--- /dev/null
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <pthread.h>
+#include "ocstack.h"
+#include "logger.h"
+#include "common.h"
+
+#define TAG PCF("SRM-AMSS")
+
+int gQuitFlag = 0;
+
+//AMS service database, hold AMS service Identity and
+//the PSK credentials of trusted devices
+static char AMSS_DB_FILE[] = "oic_amss_db.json";
+
+/* SIGINT handler: set gQuitFlag to 1 for graceful termination */
+void handleSigInt(int signum)
+{
+ if (signum == SIGINT)
+ {
+ gQuitFlag = 1;
+ }
+}
+
+FILE* service_fopen(const char *path, const char *mode)
+{
+ (void)path;
+ return fopen(AMSS_DB_FILE, mode);
+}
+
+int main(int /*argc*/, char* /*argv*/[])
+{
+ struct timespec timeout;
+
+ OC_LOG(DEBUG, TAG, "OCAMS service is starting...");
+
+ // Initialize Persistent Storage for SVR database
+ OCPersistentStorage ps = { service_fopen, fread, fwrite, fclose, unlink };
+ OCRegisterPersistentStorageHandler(&ps);
+
+ if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack init error");
+ return 0;
+ }
+
+ timeout.tv_sec = 0;
+ timeout.tv_nsec = 100000000L;
+
+ // Break from loop with Ctrl-C
+ OC_LOG(INFO, TAG, "Entering ocamsservice main loop...");
+ signal(SIGINT, handleSigInt);
+ while (!gQuitFlag)
+ {
+ if (OCProcess() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ return 0;
+ }
+ nanosleep(&timeout, NULL);
+ }
+
+ OC_LOG(INFO, TAG, "Exiting ocamsservice main loop...");
+
+ if (OCStop() != OC_STACK_OK)
+ {
+ OC_LOG(ERROR, TAG, "OCStack process error");
+ }
+
+ return 0;
+}
--- /dev/null
+{
+ "acl": [
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/res",
+ "/oic/d",
+ "/oic/p",
+ "/oic/res/types/d",
+ "/oic/ad",
+ "/oic/sec/acl",
+ "/oic/sec/amacl"
+ ],
+ "perms": 2,
+ "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+ },
+ {
+ "sub": "Kg==",
+ "rsrc": [
+ "/oic/sec/doxm",
+ "/oic/sec/pstat"
+ ],
+ "perms": 2,
+ "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+ },
+ {
+ "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+ "rsrc": ["/oic/sec/acl",
+ "/oic/sec/cred"],
+ "perms": 8,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
+ "rsrc": ["/a/led"],
+ "perms": 6,
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }
+ ],
+ "pstat": {
+ "isop": true,
+ "deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
+ "ch": 0,
+ "cm": 0,
+ "tm": 0,
+ "om": 3,
+ "sm": [3]
+ },
+ "doxm": {
+ "oxm": [0],
+ "oxmsel": 0,
+ "sct": 1,
+ "owned": true,
+ "deviceid": "MTkxOTE5MTkxOTE5MTkxOQ==",
+ "ownr": "YWRtaW5EZXZpY2VVVUlEAA=="
+ },
+ "cred": [{
+ "credid": 1,
+ "sub": "MTExMTExMTExMTExMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }]
+}
"ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
}
],
+ "amacl": [{
+ "rsrc" : ["/a/led"],
+ "amss" : ["MTkxOTE5MTkxOTE5MTkxOQ=="],
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ }],
"pstat": {
"isop": true,
"deviceid": "ZGV2aWNlaWQAAAAAABhanw==",
"credtyp": 1,
"pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
"ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "credid": 4,
+ "sub": "NDQ0NDMzMzMyMjIyMTExMQ==",
+ "credtyp": 1,
+ "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+ },
+ {
+ "credid": 5,
+ "sub": "MTkxOTE5MTkxOTE5MTkxOQ==",
+ "credtyp": 1,
+ "pvdata": "QkJCQkJCQkJCQkJCQkJCQg==",
+ "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
}]
}
# Note: 'pthread' is in libc for android. On other platform, if use
# new gcc(>4.9?) it isn't required, otherwise, it's required
if target_os != 'android':
- examples_env.AppendUnique(LIBS = ['-lpthread'])
+ examples_env.AppendUnique(LIBS = ['-lpthread', '-ldl'])
examples_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
examples_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
])
provisiontests_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall', '-pthread'])
-provisiontests_env.AppendUnique(LIBS = ['-lpthread'])
+provisiontests_env.AppendUnique(LIBS = ['-lpthread', '-ldl'])
provisiontests_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
provisiontests_env.AppendUnique(LIBPATH = [src_dir + '/extlibs/gtest/gtest-1.7.0/lib/.libs'])
provisiontests_env.PrependUnique(LIBS = [