Implemented C++/Android API for OCRegisterPersistentStorageHandler()
authorSachin Agrawal <sachin.agrawal@intel.com>
Mon, 13 Jul 2015 18:17:45 +0000 (11:17 -0700)
committerSachin Agrawal <sachin.agrawal@intel.com>
Mon, 13 Jul 2015 20:38:59 +0000 (20:38 +0000)
Add C++ secure sample client and server test app using c++ persistent
storage handler.
Add Android secure sample client app with persistent storage API.

[Patch set 2]: 1. Enhanced Android secure_simpleclient app to choose SVR DB file.
       2. Fixed setting.gradle for android sample.
               3. Add UTC for Persistent Storage in Plaform Config.
[Patch 3]: 1. Fix Sconscript to install SVR DB file for unit test.
[Patch 4]: 1. Fixed jenkins build break.

[Patch 7]: Fixed build issue due linux provisioning client during andriod build.
[Patch 8]: removed secure_simpleclient/server and modified simpleclient/server
[patch 10]: Removed Dialog box for db file selection.
            Modify simpleserver for PS changes.
[Patch 11]: Addressed Review Comments.
[Patch 13]: Rebased to security-basecamp branch
[Patch 14]: Updated Android Server sample to publish non-secure resource
    (otherwise it will break Android client-server non-secure
     test case)

Change-Id: Ica2fc26e65b228a02bc400f87e9780798c19c700
Signed-off-by: Sandeep Sharma <sandeep.s9@samsung.com>
Signed-off-by: Randeep Singh <randeep.s@samsung.com>
Signed-off-by: Sakthivel Samidurai <sakthivel.samidurai@intel.com>
Signed-off-by: Sachin Agrawal <sachin.agrawal@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1491
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
28 files changed:
android/android_api/base/jni/Android.mk
android/android_api/base/jni/JniOcPlatform.cpp
android/android_api/base/jni/JniOcPlatform.h
android/android_api/base/jni/JniOcSecurity.cpp [new file with mode: 0644]
android/android_api/base/jni/JniOcSecurity.h [new file with mode: 0644]
android/android_api/base/src/main/java/org/iotivity/base/OcPlatform.java
android/android_api/base/src/main/java/org/iotivity/base/PlatformConfig.java
android/android_api/base/src/main/java/org/iotivity/base/ResourceProperty.java
android/examples/settings.gradle
android/examples/simpleclient/src/main/AndroidManifest.xml
android/examples/simpleclient/src/main/assets/oic_svr_db_client.json [new file with mode: 0755]
android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/SimpleClient.java
android/examples/simpleclient/src/main/java/org/iotivity/base/examples/simpleclient/StringConstants.java
android/examples/simpleserver/src/main/AndroidManifest.xml
android/examples/simpleserver/src/main/assets/oic_svr_db_server.json [new file with mode: 0755]
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/LightResource.java
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/SimpleServer.java
android/examples/simpleserver/src/main/java/org/iotivity/base/examples/simpleserver/StringConstants.java
resource/csdk/security/provisioning/SConscript
resource/examples/SConscript
resource/examples/oic_svr_db_client.json [new file with mode: 0755]
resource/examples/oic_svr_db_server.json [new file with mode: 0755]
resource/examples/simpleclient.cpp
resource/examples/simpleserver.cpp
resource/include/OCApi.h
resource/src/OCPlatform_impl.cpp
resource/unittests/OCPlatformTest.cpp
resource/unittests/SConscript

index aa2cbae..d5e1f32 100644 (file)
@@ -57,7 +57,8 @@ LOCAL_SRC_FILES :=  JniOcStack.cpp \
                     JniOcResourceResponse.cpp \\r
                     JniOcPlatform.cpp \\r
                     JniOcResource.cpp \\r
-                    JniOcResourceIdentifier.cpp\r
+                    JniOcResourceIdentifier.cpp \
+                    JniOcSecurity.cpp
 \r
 LOCAL_LDLIBS := -llog\r
 LOCAL_STATIC_LIBRARIES := android-oc\r
index 40b5898..10cde35 100644 (file)
@@ -25,6 +25,7 @@
 #include "JniOcResourceHandle.h"\r
 #include "JniOcPresenceHandle.h"\r
 #include "JniOcResourceResponse.h"\r
+#include "JniOcSecurity.h"
 #include "JniUtils.h"\r
 \r
 using namespace OC;\r
@@ -233,18 +234,25 @@ void RemoveOnPresenceListener(JNIEnv* env, jobject jListener)
 /*\r
 * Class:     org_iotivity_base_OcPlatform\r
 * Method:    configure\r
-* Signature: (IILjava/lang/String;II)V\r
+* Signature: (IILjava/lang/String;IILjava/lang/String;)V
 */\r
 JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure\r
-(JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort, jint jQOS)\r
+(JNIEnv *env, jclass clazz, jint jServiceType, jint jModeType, jstring jIpAddress, jint jPort,
+                                                                 jint jQOS, jstring jDbPath)
 {\r
     LOGI("OcPlatform_configure");\r
 \r
     std::string ipAddress;\r
+    std::string dbfile;
     if (jIpAddress)\r
     {\r
         ipAddress = env->GetStringUTFChars(jIpAddress, NULL);\r
     }\r
+    if (jDbPath)
+    {
+        dbfile = env->GetStringUTFChars(jDbPath, nullptr);
+        JniOcSecurity::StoreDbPath(dbfile);
+    }
     uint16_t port;\r
     if (jPort > 0)\r
     {\r
@@ -255,7 +263,8 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure
         JniUtils::getModeType(env, jModeType),\r
         ipAddress,\r
         port,\r
-        JniUtils::getQOS(env, static_cast<int>(jQOS))\r
+        JniUtils::getQOS(env, static_cast<int>(jQOS)),
+        JniOcSecurity::getOCPersistentStorage()
     };\r
 \r
     OCPlatform::Configure(cfg);\r
@@ -1500,4 +1509,4 @@ JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_sendResponse0
         LOGE("%s", e.reason().c_str());\r
         ThrowOcException(OC_STACK_ERROR, e.reason().c_str());\r
     }\r
-}
\ No newline at end of file
+}
index 1019147..eb23a8b 100644 (file)
@@ -56,7 +56,7 @@ extern "C" {
     * Signature: (IILjava/lang/String;II)V\r
     */\r
     JNIEXPORT void JNICALL Java_org_iotivity_base_OcPlatform_configure\r
-        (JNIEnv *, jclass, jint, jint, jstring, jint, jint);\r
+        (JNIEnv *, jclass, jint, jint, jstring, jint, jint, jstring);
 \r
     /*\r
     * Class:     org_iotivity_base_OcPlatform\r
diff --git a/android/android_api/base/jni/JniOcSecurity.cpp b/android/android_api/base/jni/JniOcSecurity.cpp
new file mode 100644 (file)
index 0000000..54821ee
--- /dev/null
@@ -0,0 +1,60 @@
+/******************************************************************
+ *
+ * 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 "JniOcSecurity.h"
+#include "JniOcStack.h"
+
+/*
+ * TODO: Persistant Storage Handling should be done by App.
+ * For 0.9.2 , Handling is done at JNI. As of now Plaform Config only
+ * SVR Database fileName(fullpath) is passed.
+ */
+using namespace std;
+namespace PH = std::placeholders;
+namespace OC {
+
+    string& JniOcSecurity::store_path()
+    {
+        static string s_dbPath;
+        return s_dbPath;
+    }
+
+    void JniOcSecurity::StoreDbPath(const string &path)
+    {
+        store_path() = path;
+    }
+
+    OCPersistentStorage* JniOcSecurity::getOCPersistentStorage()
+    {
+        if (store_path().empty())
+        {
+            return nullptr;
+        }
+        static OCPersistentStorage s_ps { &JniOcSecurity::client_open, fread,
+            fwrite, fclose, unlink };
+        return &s_ps;
+    }
+
+    FILE* JniOcSecurity::client_open(const char *path, const char *mode)
+    {
+        LOGI("Opening SVR Database file '%s' with mode '%s'\n", store_path().c_str(), mode);
+        return fopen(store_path().c_str(), mode);
+    }
+}
diff --git a/android/android_api/base/jni/JniOcSecurity.h b/android/android_api/base/jni/JniOcSecurity.h
new file mode 100644 (file)
index 0000000..78293e6
--- /dev/null
@@ -0,0 +1,43 @@
+/******************************************************************
+ *
+ * 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.
+ *
+ ******************************************************************/
+
+#ifndef __JNIOCSECURITY_H
+#define __JNIOCSECURITY_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string>
+#include "octypes.h"
+#include <unistd.h>
+
+namespace OC
+{
+    class JniOcSecurity
+    {
+        private:
+            static FILE* client_open(const char*, const char*);
+        public:
+            static std::string& store_path(void);
+            static void StoreDbPath(const std::string&);
+            static OCPersistentStorage* getOCPersistentStorage(void);
+    };
+}
+#endif //__JNIOCSECURITY_H
index ac17a5b..3d672d0 100644 (file)
@@ -91,7 +91,8 @@ public final class OcPlatform {
                     platformConfig.getModeType().getValue(),\r
                     platformConfig.getIpAddress(),\r
                     platformConfig.getPort(),\r
-                    platformConfig.getQualityOfService().getValue()\r
+                    platformConfig.getQualityOfService().getValue(),
+                    platformConfig.getSvrDbPath()
             );\r
 \r
             sIsPlatformInitialized = true;\r
@@ -102,7 +103,8 @@ public final class OcPlatform {
                                          int modeType,\r
                                          String ipAddress,\r
                                          int port,\r
-                                         int qualityOfService);\r
+                                         int qualityOfService,
+                                         String dbPath);
 \r
     /**\r
      * API for notifying base that resource's attributes have changed.\r
index 7fd9ac0..70d9df3 100644 (file)
@@ -35,6 +35,8 @@ public class PlatformConfig {
     private String mIpAddress;\r
     private int mPort;\r
     private QualityOfService mQualityOfService;\r
+    private String mSvrDbPath; //TODO: Instead of SVRDB file, it should be Persistent Storage.
+                              //this is only for 0.9.2
 \r
     /**\r
      * @param context          app context\r
@@ -47,19 +49,44 @@ public class PlatformConfig {
      *                         if you specify 5683 : client discovery can work even if they don't\r
      *                         specify port\r
      * @param qualityOfService quality of service\r
+     * @param dbPath           Persistant storage file for SVR Database.
      */\r
     public PlatformConfig(Context context,\r
                           ServiceType serviceType,\r
                           ModeType modeType,\r
                           String ipAddress,\r
                           int port,\r
-                          QualityOfService qualityOfService) {\r
+                          QualityOfService qualityOfService,
+                          String dbPath) {
         this.mContext = context;\r
         this.mServiceType = serviceType;\r
         this.mModeType = modeType;\r
         this.mIpAddress = ipAddress;\r
         this.mPort = port;\r
         this.mQualityOfService = qualityOfService;\r
+        this.mSvrDbPath = dbPath;
+    }
+
+    /**
+     * @param context          app context
+     * @param serviceType      indicate IN_PROC or OUT_OF_PROC
+     * @param modeType         indicate whether we want to do server, client or both
+     * @param ipAddress        ip address of server
+     *                         if you specify 0.0.0.0 : it listens on any interface
+     * @param port             port of server
+     *                         if you specifiy 0 : next available random port is used
+     *                         if you specify 5683 : client discovery can work even if they don't
+     *                         specify port
+     * @param qualityOfService quality of service
+     */
+    //Avoid breaking building java samples due to persistent storage SVR DB changes.
+    public PlatformConfig(Context context,
+                          ServiceType serviceType,
+                          ModeType modeType,
+                          String ipAddress,
+                          int port,
+                          QualityOfService qualityOfService) {
+        this(context,serviceType,modeType,ipAddress,port,qualityOfService, "");
     }\r
 \r
     public Context getContext() {\r
@@ -84,5 +111,9 @@ public class PlatformConfig {
 \r
     public QualityOfService getQualityOfService() {\r
         return mQualityOfService;\r
+    }
+
+    public String getSvrDbPath() {
+        return mSvrDbPath;
     }\r
 }\r
index 64345db..778543d 100644 (file)
@@ -23,9 +23,9 @@
 package org.iotivity.base;\r
 \r
 public enum ResourceProperty {\r
-    ACTIVE(1 << 0),\r
-    DISCOVERABLE(1 << 1),\r
-    OBSERVABLE(1 << 2),\r
+    DISCOVERABLE(1 << 0),\r
+    OBSERVABLE(1 << 1),\r
+    ACTIVE(1 << 2),\r
     SLOW(1 << 3),\r
     SECURE(1 << 4);\r
 \r
index bf2b78b..59feebf 100755 (executable)
@@ -1 +1 @@
-include ':simpleserver', ':simpleclient', ':message', ':fridgeserver', ':fridgeclient'
\ No newline at end of file
+include ':simpleserver', ':simpleclient', ':message',':fridgeserver',':fridgeclient'
index 0345054..86dd253 100755 (executable)
@@ -4,6 +4,8 @@
     xmlns:tools="http://schemas.android.com/tools">\r
 \r
     <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 \r
     <application\r
         android:allowBackup="true"\r
diff --git a/android/examples/simpleclient/src/main/assets/oic_svr_db_client.json b/android/examples/simpleclient/src/main/assets/oic_svr_db_client.json
new file mode 100755 (executable)
index 0000000..17dc43f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "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=="]
+       }]
+}
index d2d2620..472d206 100644 (file)
@@ -26,8 +26,11 @@ import android.app.Activity;
 import android.content.BroadcastReceiver;\r
 import android.content.Context;\r
 import android.content.Intent;\r
+import android.content.SharedPreferences;\r
+import android.content.res.AssetManager;\r
 import android.os.Bundle;\r
 import android.os.Message;\r
+import android.preference.PreferenceManager;\r
 import android.text.method.ScrollingMovementMethod;\r
 import android.util.Log;\r
 import android.widget.LinearLayout;\r
@@ -46,6 +49,12 @@ import org.iotivity.base.PlatformConfig;
 import org.iotivity.base.QualityOfService;\r
 import org.iotivity.base.ServiceType;\r
 \r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
 import java.util.HashMap;\r
 import java.util.List;\r
 \r
@@ -61,13 +70,15 @@ import base.iotivity.org.examples.message.IMessageLogger;
  */\r
 public class SimpleClient extends Activity implements OcPlatform.OnResourceFoundListener,\r
         IMessageLogger {\r
-    private static final String TAG = "SimpleClient: ";\r
+    private static final String TAG = "SimpleClient: ";
 \r
+    private static final int BUFFER_SIZE = 1024;
+    private String filePath = "";\r
     private Light myLight;\r
-    private OcResource curResource;\r
+    private OcResource curResource;
 \r
     //for display\r
-    private TextView mEventsTextView;\r
+    private TextView mEventsTextView;
     private static boolean printOnce = true;\r
 \r
     /**\r
@@ -78,10 +89,10 @@ public class SimpleClient extends Activity implements OcPlatform.OnResourceFound
         PlatformConfig cfg = new PlatformConfig(\r
                 this,\r
                 ServiceType.IN_PROC,\r
-                ModeType.CLIENT,\r
+                ModeType.CLIENT_SERVER,\r
                 "0.0.0.0", // bind to all available interfaces\r
                 0,\r
-                QualityOfService.LOW);\r
+                QualityOfService.LOW, filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);\r
         OcPlatform.Configure(cfg);\r
         try {\r
             /**\r
@@ -111,7 +122,7 @@ public class SimpleClient extends Activity implements OcPlatform.OnResourceFound
             hostAddress = ocResource.getHost();\r
             logMessage(TAG + "Discovered Resource\nUri: " + resourceUri + " \n Host: " + hostAddress);\r
             // get the resource types\r
-            if (resourceUri.equals(StringConstants.RESOURCE_URI0)) {\r
+            if (resourceUri.contains("light")) {\r
                 curResource = ocResource;\r
                 doGetLightRepresentation();\r
             }\r
@@ -416,10 +427,70 @@ public class SimpleClient extends Activity implements OcPlatform.OnResourceFound
                 LinearLayout.LayoutParams.MATCH_PARENT, 0, 1f)\r
         );\r
         myLight = new Light();\r
+        filePath = getFilesDir().getPath() + "/"; //  data/data/<package>/files/\r
+        //copy json when application runs first time\r
+        SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);\r
+        boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);\r
+        if (isFirstRun) {\r
+            copyJsonFromAsset();\r
+            SharedPreferences.Editor editor = wmbPreference.edit();\r
+            editor.putBoolean("FIRSTRUN", false);\r
+            editor.commit();\r
+        }\r
+\r
 \r
         initOICStack();\r
     }\r
+/**\r
+     * Copy svr db json file from assets folder to app data files dir\r
+     */\r
+    private void copyJsonFromAsset() {\r
+        AssetManager assetManager = getAssets();\r
+        InputStream in = null;\r
+        OutputStream out = null;\r
+        try {\r
+            in = assetManager.open(StringConstants.OIC_CLIENT_JSON_DB_FILE);\r
+            File file = new File(filePath);\r
+            //check files directory exists\r
+            if (!(file.exists() && file.isDirectory())) {\r
+                file.mkdirs();\r
+            }\r
+            out = new FileOutputStream(filePath + StringConstants.OIC_CLIENT_JSON_DB_FILE);\r
+            copyFile(in, out);\r
+        } catch (NullPointerException e) {\r
+            logMessage(TAG + "Null pointer exception " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (FileNotFoundException e) {\r
+            logMessage(TAG + "Json svr db file not found " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (IOException e) {\r
+            logMessage(TAG + StringConstants.OIC_CLIENT_JSON_DB_FILE+ " file copy failed");\r
+            Log.e(TAG, e.getMessage());\r
+        } finally {\r
+            if (in != null) {\r
+                try {\r
+                    in.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+            if (out != null) {\r
+                try {\r
+                    out.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+        }\r
+    }\r
 \r
+    private void copyFile(InputStream in, OutputStream out) throws IOException {\r
+        byte[] buffer = new byte[BUFFER_SIZE];\r
+        int read;\r
+        while ((read = in.read(buffer)) != -1) {\r
+            out.write(buffer, 0, read);\r
+        }\r
+    }\r
     @Override\r
     public void logMessage(String text) {\r
         logMsg(text);\r
index f87c387..af163e1 100644 (file)
@@ -1,5 +1,4 @@
 package org.iotivity.base.examples.simpleclient;\r
-\r
 /**\r
  * StringConstant contains the simpleclient specific constant values.  To add another supported\r
  * Resource or Interface type to this app, begin by adding the new strings here, and then\r
@@ -9,6 +8,7 @@ package org.iotivity.base.examples.simpleclient;
 public interface StringConstants {\r
     public static final String RESOURCE_URI0 = "/light0";\r
     public static final String RESOURCE_URI1 = "/light1";\r
+    public static final String OIC_CLIENT_JSON_DB_FILE =  "oic_svr_db_client.json";\r
     public static final String CREATED_URI = "createduri";\r
     public static final String STATE = "state";\r
     public static final String NAME = "name";\r
index 43352f4..0026240 100755 (executable)
@@ -4,6 +4,8 @@
     xmlns:tools="http://schemas.android.com/tools">\r
 \r
     <uses-sdk tools:overrideLibrary="org.iotivity.base"></uses-sdk>\r
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 \r
     <application\r
         android:allowBackup="true"\r
diff --git a/android/examples/simpleserver/src/main/assets/oic_svr_db_server.json b/android/examples/simpleserver/src/main/assets/oic_svr_db_server.json
new file mode 100755 (executable)
index 0000000..6c8c4e4
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        },
+        {
+            "sub": "Kg==",
+            "rsrc": ["/light0", "/light1", "/a/light"],
+            "perms": 6,
+            "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":     "MTExMTExMTExMTExMTExMQ==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index e8414a0..a658663 100644 (file)
@@ -305,4 +305,4 @@ public class LightResource implements IMessageLogger {
         intent.putExtra(StringConstants.MESSAGE, text);\r
         mContext.sendBroadcast(intent);\r
     }\r
-}
\ No newline at end of file
+}\r
index 31b5c6a..b48a9f5 100644 (file)
@@ -36,6 +36,9 @@ import android.view.Menu;
 import android.view.MenuItem;\r
 import android.widget.LinearLayout;\r
 import android.widget.TextView;\r
+import android.content.SharedPreferences;\r
+import android.content.res.AssetManager;\r
+import android.preference.PreferenceManager;\r
 \r
 import org.iotivity.base.ModeType;\r
 import org.iotivity.base.OcPlatform;\r
@@ -44,6 +47,13 @@ import org.iotivity.base.PlatformConfig;
 import org.iotivity.base.QualityOfService;\r
 import org.iotivity.base.ServiceType;\r
 \r
+import java.io.File;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+\r
 import base.iotivity.org.examples.message.IMessageLogger;\r
 \r
 /**\r
@@ -56,6 +66,8 @@ import base.iotivity.org.examples.message.IMessageLogger;
 \r
 public class SimpleServer extends Activity implements IMessageLogger {\r
     private final static String TAG = "SimpleServer: ";\r
+    private static final int BUFFER_SIZE = 1024;
+    private String filePath = "";\r
     private TextView mEventsTextView;\r
     private MessageReceiver mMessageReceiver = new MessageReceiver();\r
 \r
@@ -73,10 +85,72 @@ public class SimpleServer extends Activity implements IMessageLogger {
         OcRepresentation rep = new OcRepresentation();\r
         rep.setValueBool("test", false);\r
         boolean result = rep.getValueBool("test");\r
+        filePath = getFilesDir().getPath() + "/";//  data/data/<package>/files/\r
+        //copy json when application runs first time\r
+        SharedPreferences wmbPreference = PreferenceManager.getDefaultSharedPreferences(this);\r
+        boolean isFirstRun = wmbPreference.getBoolean("FIRSTRUN", true);\r
+        if (isFirstRun) {\r
+            copyJsonFromAsset();\r
+            SharedPreferences.Editor editor = wmbPreference.edit();\r
+            editor.putBoolean("FIRSTRUN", false);\r
+            editor.commit();\r
+        }
 \r
         initOICStack();\r
     }\r
+
+    /**\r
+     * Copy svr db json file from assets folder to app data files dir\r
+     */\r
+    private void copyJsonFromAsset() {\r
+        AssetManager assetManager = getAssets();\r
+\r
+        InputStream in = null;\r
+        OutputStream out = null;\r
+        try {\r
+\r
+            in = assetManager.open(StringConstants.OIC_SERVER_JSON_DB_FILE);\r
+            File file = new File(filePath);\r
+            //check files directory exists\r
+            if (!(file.exists() && file.isDirectory())) {\r
+                file.mkdirs();\r
+            }\r
+            out = new FileOutputStream(filePath + StringConstants.OIC_SERVER_JSON_DB_FILE);\r
+            copyFile(in, out);\r
+        } catch (NullPointerException e) {\r
+            logMessage(TAG + "Null pointer exception " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (FileNotFoundException e) {\r
+            logMessage(TAG + "Json svr db file not found " + e.getMessage());\r
+            Log.e(TAG, e.getMessage());\r
+        } catch (IOException e) {\r
+            logMessage(TAG + StringConstants.OIC_SERVER_JSON_DB_FILE + " file copy failed");\r
+            Log.e(TAG, e.getMessage());\r
+        } finally {\r
+            if (in != null) {\r
+                try {\r
+                    in.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+            if (out != null) {\r
+                try {\r
+                    out.close();\r
+                } catch (IOException e) {\r
+                    Log.e(TAG, e.getMessage());\r
+                }\r
+            }\r
+        }\r
+    }\r
 \r
+    private void copyFile(InputStream in, OutputStream out) throws IOException {\r
+        byte[] buffer = new byte[BUFFER_SIZE];\r
+        int read;\r
+        while ((read = in.read(buffer)) != -1) {\r
+            out.write(buffer, 0, read);\r
+        }\r
+    }\r
     /**\r
      * configure OIC platform and call findResource\r
      */\r
@@ -88,14 +162,15 @@ public class SimpleServer extends Activity implements IMessageLogger {
                 ModeType.SERVER,\r
                 "0.0.0.0", // bind to all available interfaces\r
                 0,\r
-                QualityOfService.LOW);\r
+                QualityOfService.LOW,\r
+                filePath + StringConstants.OIC_SERVER_JSON_DB_FILE);\r
         OcPlatform.Configure(cfg);\r
         // Create instance of lightResource\r
         LightResource myLight = new LightResource(this);\r
         // create and register a resource\r
         myLight.createResource0();\r
     }\r
-\r
+
     public class MessageReceiver extends BroadcastReceiver {\r
         @Override\r
         public void onReceive(Context context, Intent intent) {\r
index 98f33d0..f4836fa 100644 (file)
@@ -11,6 +11,7 @@ public interface StringConstants {
     public static final String RESOURCE_URI0 = "/light0";\r
     public static final String RESOURCE_URI1 = "/light1";\r
     public static final String RESOURCE_TYPENAME = "core.light";\r
+    public static final String OIC_SERVER_JSON_DB_FILE =  "oic_svr_db_server.json";\r
     public static final String RESOURCE_INTERFACE = OcPlatform.DEFAULT_INTERFACE; //resource interface\r
     public static final String CREATED_URI = "createduri";\r
     public static final String STATE = "state";\r
index dea14c7..8b06ed6 100644 (file)
@@ -84,4 +84,6 @@ provisioningserver = provisioning_env.StaticLibrary('ocspapi', provisioning_src)
 
 provisioning_env.InstallTarget(provisioningserver, 'libocspapi')
 
-SConscript('sample/SConscript')
+if target_os in ['linux']:
+       SConscript('sample/SConscript')
+
index 914a5ee..731b203 100644 (file)
@@ -100,4 +100,10 @@ Alias("examples", [simpleserver, simpleclient,
      ])
 env.AppendTarget('examples')
 
-
+src_dir = examples_env.get('SRC_DIR')
+svr_db_src_dir = src_dir + '/resource/examples/'
+svr_db_build_dir = env.get('BUILD_DIR') +'/resource/examples/'
+examples_env.Alias("install", examples_env.Install( svr_db_build_dir,
+                svr_db_src_dir + 'oic_svr_db_client.json'))
+examples_env.Alias("install", examples_env.Install( svr_db_build_dir,
+                svr_db_src_dir + 'oic_svr_db_server.json'))
diff --git a/resource/examples/oic_svr_db_client.json b/resource/examples/oic_svr_db_client.json
new file mode 100755 (executable)
index 0000000..17dc43f
--- /dev/null
@@ -0,0 +1,49 @@
+{
+    "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=="]
+       }]
+}
diff --git a/resource/examples/oic_svr_db_server.json b/resource/examples/oic_svr_db_server.json
new file mode 100755 (executable)
index 0000000..0a8cebe
--- /dev/null
@@ -0,0 +1,55 @@
+{
+    "acl": [
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/res",
+                "/oic/d",
+                "/oic/p",
+                "/oic/res/types/d",
+                "/oic/ad",
+                "/oic/sec/acl"
+                       ],
+                       "perms": 2,
+                       "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+               },
+        {
+            "sub": "Kg==",
+            "rsrc": [
+                "/oic/sec/doxm",
+                "/oic/sec/pstat"
+             ],
+             "perms": 2,
+             "ownrs" : ["MTExMTExMTExMTExMTExMQ=="]
+        },
+        {
+            "sub": "Kg==",
+            "rsrc": ["/a/light"],
+            "perms": 6,
+            "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":     "MTExMTExMTExMTExMTExMQ==",
+               "ownr": "MjIyMjIyMjIyMjIyMjIyMg=="
+       },
+    "cred":    [{
+               "credid": 1,
+               "sub": "MjIyMjIyMjIyMjIyMjIyMg==",
+               "credtyp": 1,
+               "pvdata": "QUFBQUFBQUFBQUFBQUFBQQ==",
+        "ownrs" : ["MjIyMjIyMjIyMjIyMjIyMg=="]
+       }]
+}
index e606908..5278a0b 100644 (file)
@@ -412,10 +412,15 @@ void checkObserverValue(int value)
     }
 }
 
+static FILE* client_open(const char *path, const char *mode)
+{
+    return fopen("./oic_svr_db_client.json", mode);
+}
+
 int main(int argc, char* argv[]) {
 
     std::ostringstream requestURI;
-
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
     try
     {
         printUsage();
@@ -442,10 +447,11 @@ int main(int argc, char* argv[]) {
     // Create PlatformConfig object
     PlatformConfig cfg {
         OC::ServiceType::InProc,
-        OC::ModeType::Client,
+        OC::ModeType::Both,
         "0.0.0.0",
         0,
-        OC::QualityOfService::LowQos
+        OC::QualityOfService::LowQos,
+        &ps
     };
 
     OCPlatform::Configure(cfg);
index f52588b..d89faf2 100644 (file)
@@ -482,10 +482,15 @@ void PrintUsage()
     std::cout << "    4 - Non-secure resource, GET slow response, notify all observers\n";
 }
 
+static FILE* client_open(const char *path, const char *mode)
+{
+    return fopen("./oic_svr_db_server.json", mode);
+}
 
 int main(int argc, char* argv[])
 {
     PrintUsage();
+    OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
 
     if (argc == 1)
     {
@@ -527,7 +532,8 @@ int main(int argc, char* argv[])
         OC::ModeType::Server,
         "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces
         0,         // Uses randomly available port
-        OC::QualityOfService::LowQos
+        OC::QualityOfService::LowQos,
+        &ps
     };
 
     OCPlatform::Configure(cfg);
index a6e9f35..2014ce3 100644 (file)
@@ -112,6 +112,7 @@ namespace OC
     *  ServerConnectivity : default flags for server
     *  ClientConnectivity : default flags for client
     *  QoS        : Quality of Service : CONFIRMABLE or NON CONFIRMABLE.
+    *  ps         : persistant storage Handler structure (open/read/write/close/unlink)
     */
     struct PlatformConfig
     {
@@ -122,6 +123,7 @@ namespace OC
         std::string                ipAddress;   // not used
         uint16_t                   port;        // not used
         QualityOfService           QoS;
+        OCPersistentStorage        *ps;
 
         public:
             PlatformConfig()
@@ -131,34 +133,39 @@ namespace OC
                 clientConnectivity(CT_DEFAULT),
                 ipAddress("0.0.0.0"),
                 port(0),
-                QoS(QualityOfService::NaQos)
+                QoS(QualityOfService::NaQos),
+                ps(nullptr)
         {}
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             OCConnectivityType serverConnectivity_,
             OCConnectivityType clientConnectivity_,
-            const QualityOfService QoS_)
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr)
                 : serviceType(serviceType_),
                 mode(mode_),
                 serverConnectivity(serverConnectivity_),
                 clientConnectivity(clientConnectivity_),
                 ipAddress(""),
                 port(0),
-                QoS(QoS_)
+                QoS(QoS_),
+                ps(ps_)
         {}
             // for backward compatibility
             PlatformConfig(const ServiceType serviceType_,
             const ModeType mode_,
             const std::string& ipAddress_,
             const uint16_t port_,
-            const QualityOfService QoS_)
+            const QualityOfService QoS_,
+            OCPersistentStorage *ps_ = nullptr)
                 : serviceType(serviceType_),
                 mode(mode_),
                 serverConnectivity(CT_DEFAULT),
                 clientConnectivity(CT_DEFAULT),
                 ipAddress(ipAddress_),
                 port(port_),
-                QoS(QoS_)
+                QoS(QoS_),
+                ps(ps_)
         {}
     };
 
index f57ce51..ba470e8 100644 (file)
@@ -56,6 +56,7 @@ namespace OC
 
     void OCPlatform_impl::Configure(const PlatformConfig& config)
     {
+        OCRegisterPersistentStorageHandler(config.ps);
         globalConfig() = config;
     }
 
index e1cb339..86471ba 100644 (file)
@@ -31,7 +31,13 @@ namespace OCPlatformTest
     const std::string gResourceInterface = DEFAULT_INTERFACE;
     const uint8_t gResourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE;
     OCResourceHandle resourceHandle;
+  //OCPersistent Storage Handlers
 
+   static FILE* client_open(const char *path, const char *mode)
+   {
+       std::cout << "<===Opening SVR DB file = './oic_svr_db_client.json' with mode = '"<< mode<<"' "<<std::endl;
+               return fopen("./oic_svr_db_client.json", mode);
+   }
     // Callbacks
     OCEntityHandlerResult entityHandler(std::shared_ptr<OCResourceRequest> request)
     {
@@ -214,6 +220,67 @@ namespace OCPlatformTest
                  resourceHandle, uri, type,
                  gResourceInterface, entityHandler, gResourceProperty));
     }
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureDefaultNULLPersistentStorage)
+    {
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureNULLPersistentStorage)
+    {
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             nullptr
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigurePersistentStorage)
+    {
+        OCPersistentStorage ps {client_open, fread, fwrite, fclose, unlink };
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             &ps
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
+    //PersistentStorageTest
+    TEST(ConfigureTest, ConfigureNULLHandlersPersistentStorage)
+    {
+        OCPersistentStorage ps {client_open, nullptr, nullptr, nullptr, nullptr };
+        PlatformConfig cfg {
+             OC::ServiceType::InProc,
+             OC::ModeType::Both,
+             "0.0.0.0",
+             0,
+             OC::QualityOfService::LowQos,
+             &ps
+         };
+         OCPlatform::Configure(cfg);
+         EXPECT_NO_THROW(OCPlatform::setDefaultDeviceEntityHandler(nullptr));
+     }
+
 
     //RegisterResourceTest
     TEST(RegisterResourceTest, RegisterSingleResource)
@@ -699,5 +766,4 @@ namespace OCPlatformTest
                 OC_MULTICAST_IP, CT_DEFAULT, &presenceHandler));
         EXPECT_EQ(OC_STACK_OK, OCPlatform::unsubscribePresence(presenceHandle));
     }
-
 }
index 3050b78..45c152d 100644 (file)
@@ -90,3 +90,9 @@ if env.get('TEST') == '1':
                ut = unittests_env.Command ('ut', None,
                 [ 'valgrind --leak-check=full --xml=yes --xml-file=resource_unittests_unittests.memcheck ' + out_dir + 'resource/unittests/unittests'])
                AlwaysBuild ('ut')
+
+src_dir = unittests_env.get('SRC_DIR')
+svr_db_src_dir = src_dir + '/resource/examples/'
+svr_db_build_dir = env.get('BUILD_DIR') +'/resource/unittests/'
+unittests_env.Alias("install", unittests_env.Install( svr_db_build_dir,
+                                svr_db_src_dir + 'oic_svr_db_client.json'))