replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / android / android_api / base / jni / JniOcPlatform.cpp
index 8f76dc8..87d08a2 100644 (file)
@@ -24,6 +24,7 @@
 #include "JniOcResourceHandle.h"
 #include "JniOcPresenceHandle.h"
 #include "JniOcResourceResponse.h"
+#include "JniOcRepresentation.h"
 #include "JniOcSecurity.h"
 #include "JniOcDirectPairDevice.h"
 #include "JniUtils.h"
@@ -34,6 +35,8 @@
 #include "JniOcAccountManager.h"
 #endif
 
+#define AES_KEY_SIZE 32
+
 using namespace OC;
 
 JniOnResourceFoundListener* AddOnResourceFoundListener(JNIEnv* env, jobject jListener)
@@ -537,19 +540,92 @@ void RemoveOnDirectPairingListener(JNIEnv* env, jobject jListener)
     directPairingListenerMapLock.unlock();
 }
 
+#ifdef TCP_ADAPTER
+JniKeepAliveListener* AddKeepAliveListener(JNIEnv* env, jobject jListener)
+{
+    JniKeepAliveListener *KeepAliveListener = nullptr;
+
+    KeepAliveListenerMapLock.lock();
+
+    for (auto it = KeepAliveListenerMap.begin(); it !=
+        KeepAliveListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            KeepAliveListener = refPair.first;
+            refPair.second++;
+            it->second = refPair;
+            KeepAliveListenerMap.insert(*it);
+            LOGD("KeepAliveListener: ref. count incremented");
+            break;
+        }
+    }
+    if (!KeepAliveListener)
+    {
+         KeepAliveListener = new JniKeepAliveListener(env, jListener, RemoveKeepAliveListener);
+         jobject jgListener = env->NewGlobalRef(jListener);
+         KeepAliveListenerMap.insert(std::pair<jobject, std::pair<JniKeepAliveListener*, int>>(
+            jgListener,
+            std::pair<JniKeepAliveListener*, int>(KeepAliveListener, 1)));
+         LOGI("KeepAliveListener: new listener");
+    }
+    KeepAliveListenerMapLock.unlock();
+    return KeepAliveListener;
+}
+#endif
+#ifdef TCP_ADAPTER
+void RemoveKeepAliveListener(JNIEnv* env, jobject jListener)
+{
+    KeepAliveListenerMapLock.lock();
+    bool isFound = false;
+    for (auto it = KeepAliveListenerMap.begin(); it !=
+        KeepAliveListenerMap.end(); ++it)
+    {
+        if (env->IsSameObject(jListener, it->first))
+        {
+            auto refPair = it->second;
+            if (refPair.second > 1)
+            {
+                refPair.second--;
+                it->second = refPair;
+                KeepAliveListenerMap.insert(*it);
+                LOGI("KeepAliveListener: ref.count decremented");
+            }
+            else
+            {
+                env->DeleteGlobalRef(it->first);
+                JniKeepAliveListener* listener = refPair.first;
+                delete listener;
+                KeepAliveListenerMap.erase(it);
+                LOGI("KeepAliveListener is removed");
+            }
+            isFound = true;
+            break;
+        }
+    }
+    if (!isFound)
+    {
+        ThrowOcException(JNI_EXCEPTION, "KeepAliveListener not found");
+    }
+    KeepAliveListenerMapLock.unlock();
+}
+#endif
 /*
 * Class:     org_iotivity_base_OcPlatform
 * Method:    configure
-* Signature: (IILjava/lang/String;II)V
+* Signature: (IILjava/lang/String;IILjava/lang/String;I)V
 */
 JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
 (JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort,
-                                                                 jint jQOS, jstring jDbPath)
+ jint jQOS, jstring jDbPath, jstring jDbPathDefault , jstring jRescueDBPath, jint jkeySize,
+jbyteArray data, jint jTransport)
 {
     LOGI("OcPlatform_configure");
 
     std::string ipAddress;
-    std::string dbfile;
+    std::string dbfile, defaultPath, rescuePath;
+    static unsigned char *aesKey = NULL;
     if (jIpAddress)
     {
         ipAddress = env->GetStringUTFChars(jIpAddress, nullptr);
@@ -559,6 +635,39 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         dbfile = env->GetStringUTFChars(jDbPath, nullptr);
         JniOcSecurity::StoreDbPath(dbfile);
     }
+    //Either we have both paths or neither of them.
+    if ((jDbPathDefault && !jRescueDBPath) || (!jDbPathDefault && jRescueDBPath))
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "path cannot be null");
+        return;
+    }
+
+    if (!jDbPathDefault && !jRescueDBPath)
+    {
+        LOGI("Secure SVR DB feature not enable!!");
+    }
+    else
+    {
+        aesKey = (unsigned char*)calloc(1, sizeof(unsigned char) * AES_KEY_SIZE);
+        defaultPath = env->GetStringUTFChars(jDbPathDefault, nullptr);
+        rescuePath = env->GetStringUTFChars(jRescueDBPath, nullptr);
+        OC::JniOcSecurity::StoreDefault_DbPath(defaultPath, rescuePath, (int)jkeySize);
+
+        jbyte* key = env->GetByteArrayElements(data, 0);
+        jsize arrayLength = env->GetArrayLength(data);
+        if(arrayLength != AES_KEY_SIZE)
+        {
+            ThrowOcException(OC_STACK_INVALID_PARAM, "key size mismatch");
+        }
+        else
+        {
+            for(int i=0;i < AES_KEY_SIZE; i++)
+            {
+                aesKey[i]=(jbyte)key[i];
+            }
+        }
+
+    }
     uint16_t port = 0;
     if (jPort > 0)
     {
@@ -570,10 +679,66 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         JniUtils::getModeType(env, jModeType),
         ipAddress,
         port,
+        JniUtils::getOCTransportAdapter(jTransport),
         JniUtils::getQOS(env, static_cast<int>(jQOS)),
-        JniOcSecurity::getOCPersistentStorage()
+        aesKey,
+        JniOcSecurity::getOCPersistentStorage(),
+        JniOcSecurity::getOCPersistentStorageEnc(),
+        JniOcSecurity::getOCPersistentStorageRescue()
     };
+
     OCPlatform::Configure(cfg);
+
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    stop
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_stop
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.stop");
+
+    try {
+        OCStackResult result = OCPlatform::stop();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to stop ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
+}
+
+/*
+* Class:     org_iotivity_base_OcPlatform
+* Method:    start
+* Signature: ()V
+*/
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_start
+(JNIEnv *env, jclass clazz)
+{
+    LOGI("OcPlatform.start");
+
+    try {
+        OCStackResult result = OCPlatform::start();
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "Failed to start ocplatform");
+            return;
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+    }
 }
 
 /*
@@ -1473,7 +1638,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
             jstring jStr = (jstring)env->GetObjectArrayElement(jDeviceTypes, i);
             if (!jStr)
             {
-                delete deviceInfo.deviceName;
+                delete[] deviceInfo.deviceName;
                 ThrowOcException(OC_STACK_INVALID_PARAM, "device type cannot be null");
                 return;
             }
@@ -1481,7 +1646,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
             OCResourcePayloadAddStringLL(&deviceInfo.types, env->GetStringUTFChars(jStr, nullptr));
             if (env->ExceptionCheck())
             {
-                delete deviceInfo.deviceName;
+                delete[] deviceInfo.deviceName;
                 return;
             }
 
@@ -1498,7 +1663,7 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerDeviceInfo0(
     {
         OCStackResult result = OCPlatform::registerDeviceInfo(deviceInfo);
 
-        delete deviceInfo.deviceName;
+        delete[] deviceInfo.deviceName;
 
         if (OC_STACK_OK != result)
         {
@@ -1619,17 +1784,17 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_registerPlatformInfo0(
         {
             OCStackResult result = OCPlatform::registerPlatformInfo(platformInfo);
 
-            delete platformInfo.platformID;
-            delete platformInfo.manufacturerName;
-            delete platformInfo.manufacturerUrl;
-            delete platformInfo.modelNumber;
-            delete platformInfo.dateOfManufacture;
-            delete platformInfo.platformVersion;
-            delete platformInfo.operatingSystemVersion;
-            delete platformInfo.hardwareVersion;
-            delete platformInfo.firmwareVersion;
-            delete platformInfo.supportUrl;
-            delete platformInfo.systemTime;
+            delete[] platformInfo.platformID;
+            delete[] platformInfo.manufacturerName;
+            delete[] platformInfo.manufacturerUrl;
+            delete[] platformInfo.modelNumber;
+            delete[] platformInfo.dateOfManufacture;
+            delete[] platformInfo.platformVersion;
+            delete[] platformInfo.operatingSystemVersion;
+            delete[] platformInfo.hardwareVersion;
+            delete[] platformInfo.firmwareVersion;
+            delete[] platformInfo.supportUrl;
+            delete[] platformInfo.systemTime;
 
             if (OC_STACK_OK != result)
             {
@@ -2706,3 +2871,118 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_setDeviceId(
         ThrowOcException(e.code(), e.reason().c_str());
     }
 }
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    findKeepAliveResourceImpl
+ * Signature: (Ljava/lang/String;Lorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_findKeepAliveResourceImpl(
+        JNIEnv *env, jclass clazz, jstring jHost, jobject jListener)
+{
+#ifndef TCP_ADAPTER
+    ThrowOcException(OC_STACK_ERROR,
+                     "findKeepAliveResource is not supported. (Please build with WITH_TCP=1 option)");
+    return;
+#else
+    LOGI("OcPlatform_findKeepAliveResource");
+    std::string host;
+    if (!jHost)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "host cannot be null");
+        return;
+    }
+    else
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "onKeepAliveFoundListener cannot be null");
+        return;
+    }
+
+    JniKeepAliveListener *onKeepAliveFoundListener = AddKeepAliveListener(env, jListener);
+
+    KeepAliveCallback KeepAliveCallback = [onKeepAliveFoundListener](const int ret,
+                                                                   const OCRepresentation& rep)
+    {
+        onKeepAliveFoundListener->onKeepAliveListener(ret, rep);
+    };
+
+    try
+    {
+        OCStackResult result = OCPlatform::findKeepAliveResource(host, KeepAliveCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "findKeepAliveResource has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+        return;
+    }
+#endif
+}
+
+/*
+ * Class:     org_iotivity_base_OcPlatform
+ * Method:    sendKeepAliveRequestImpl
+ * Signature: (Ljava/lang/String;ILorg/iotivity/base/OcPlatform/KeepAliveListener;)V
+ */
+JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendKeepAliveRequestImpl(
+        JNIEnv *env, jclass clazz, jstring jHost, jobject jRep, jobject jListener)
+{
+#ifndef TCP_ADAPTER
+    ThrowOcException(OC_STACK_ERROR,
+                     "sendKeepAlive is not supported. (Please build with WITH_TCP=1 option)");
+    return;
+#else
+    LOGI("OcPlatform_sendKeepAliveRequest");
+    std::string host;
+    if (!jHost)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "host cannot be null");
+        return;
+    }
+    else
+    {
+        host = env->GetStringUTFChars(jHost, nullptr);
+    }
+
+    if (!jListener)
+    {
+        ThrowOcException(OC_STACK_INVALID_PARAM, "keepAliveResponseListener cannot be null");
+        return;
+    };
+
+    JniKeepAliveListener *KeepAliveResponseListener = AddKeepAliveListener(env, jListener);
+
+    KeepAliveCallback KeepAliveCallback = [KeepAliveResponseListener](const int ret,
+                                                         const OCRepresentation& rep)
+    {
+        KeepAliveResponseListener->onKeepAliveListener(ret, rep);
+    };
+
+    try
+    {
+        OCRepresentation *rep = JniOcRepresentation::getOCRepresentationPtr(env, jRep);
+        OCStackResult result = OCPlatform::sendKeepAliveRequest(host, *rep, KeepAliveCallback);
+
+        if (OC_STACK_OK != result)
+        {
+            ThrowOcException(result, "sendKeepAliveRequest has failed");
+        }
+    }
+    catch (OCException& e)
+    {
+        LOGE("%s", e.reason().c_str());
+        ThrowOcException(e.code(), e.reason().c_str());
+        return;
+    }
+#endif
+}