Просмотр исходного кода

first commit bridge home server only separated with iotivity_lite full repository.

Trishia 4 лет назад
Родитель
Сommit
260909ff49
71 измененных файлов с 4749 добавлено и 0 удалено
  1. 1 0
      app/.gitignore
  2. 48 0
      app/build.gradle
  3. 3 0
      app/libs/.gitignore
  4. BIN
      app/libs/iotivity-lite.jar
  5. 17 0
      app/proguard-rules.pro
  6. 44 0
      app/src/main/AndroidManifest.xml
  7. 33 0
      app/src/main/aidl/org/iotivity/bridge/homeserver/IRemoteService.aidl
  8. 19 0
      app/src/main/aidl/org/iotivity/bridge/homeserver/IRemoteServiceCallback.aidl
  9. BIN
      app/src/main/assets/idds/bridge_device_IDD.cbor
  10. 303 0
      app/src/main/assets/idds/bridge_device_IDD.json
  11. BIN
      app/src/main/assets/idds/virtual_ocf_device_light_IDD.cbor
  12. 299 0
      app/src/main/assets/idds/virtual_ocf_device_light_IDD.json
  13. 25 0
      app/src/main/assets/pki_certs/ee.pem
  14. 5 0
      app/src/main/assets/pki_certs/key.pem
  15. 8 0
      app/src/main/assets/pki_certs/key_org.pem
  16. 13 0
      app/src/main/assets/pki_certs/rootca1.pem
  17. 11 0
      app/src/main/assets/pki_certs/rootca2.pem
  18. 18 0
      app/src/main/assets/pki_certs/subca1.pem
  19. 21 0
      app/src/main/java/org/iotivity/bridge/homeserver/AlarmReceiver.java
  20. 362 0
      app/src/main/java/org/iotivity/bridge/homeserver/BridgeServer.java
  21. 742 0
      app/src/main/java/org/iotivity/bridge/homeserver/BridgeServerActivity.java
  22. 334 0
      app/src/main/java/org/iotivity/bridge/homeserver/BridgeService.java
  23. 123 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/BridgeInitHandler.java
  24. 136 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/FactoryPresetsHandler.java
  25. 25 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/RandomPinHandler.java
  26. 49 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/DeviceDiscoveryHandler.java
  27. 185 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetCommonResponseHandler.java
  28. 77 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetDeviceAccessCheckResponseHandler.java
  29. 95 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetLight2ResponseHandler.java
  30. 90 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetLightResponseHandler.java
  31. 62 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/ObserveLightResponseHandler.java
  32. 58 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/Post2LightResponseHandler.java
  33. 68 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/PostLightResponseHandler.java
  34. 48 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/PutLightResponseHandler.java
  35. 117 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/ResourceDetailsHelper.java
  36. 32 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/client/StopObserveTriggerHandler.java
  37. 84 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/server/GetBridgeRequestHandler.java
  38. 64 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/server/GetLightRequestHandler.java
  39. 50 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PostBridgeRequestHandler.java
  40. 59 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PostLightRequestHandler.java
  41. 28 0
      app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PutLightRequestHandler.java
  42. 115 0
      app/src/main/java/org/iotivity/bridge/homeserver/model/Bridge.java
  43. 90 0
      app/src/main/java/org/iotivity/bridge/homeserver/model/Light.java
  44. 94 0
      app/src/main/java/org/iotivity/bridge/homeserver/model/VirtualOCFDevice.java
  45. 233 0
      app/src/main/java/org/iotivity/bridge/homeserver/utils/Utils.java
  46. BIN
      app/src/main/jniLibs/arm64-v8a/libiotivity-lite-jni.so
  47. 2 0
      app/src/main/jniLibs/armeabi/.gitignore
  48. BIN
      app/src/main/jniLibs/armeabi/libiotivity-lite-jni.so
  49. BIN
      app/src/main/jniLibs/x86/libiotivity-lite-jni.so
  50. 2 0
      app/src/main/jniLibs/x86_64/.gitignore
  51. BIN
      app/src/main/jniLibs/x86_64/libiotivity-lite-jni.so
  52. 40 0
      app/src/main/res/layout/activity_main.xml
  53. 44 0
      app/src/main/res/layout/resource_multi_line.xml
  54. 32 0
      app/src/main/res/menu/actionbar_actions.xml
  55. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  56. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  57. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  58. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  59. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  60. 6 0
      app/src/main/res/values-w820dp/dimens.xml
  61. 6 0
      app/src/main/res/values/colors.xml
  62. 5 0
      app/src/main/res/values/dimens.xml
  63. 14 0
      app/src/main/res/values/strings.xml
  64. 11 0
      app/src/main/res/values/styles.xml
  65. 25 0
      build.gradle
  66. 17 0
      gradle.properties
  67. BIN
      gradle/wrapper/gradle-wrapper.jar
  68. 6 0
      gradle/wrapper/gradle-wrapper.properties
  69. 160 0
      gradlew
  70. 90 0
      gradlew.bat
  71. 1 0
      settings.gradle

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
+/build

+ 48 - 0
app/build.gradle

@@ -0,0 +1,48 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 28
+    buildToolsVersion '28.0.3'
+    defaultConfig {
+        applicationId "org.iotivity.bridge.homeserver"
+        minSdkVersion 21
+        targetSdkVersion 26
+        versionCode 2
+        versionName "1.0"
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+        debug {
+            jniDebuggable true
+        }
+    }
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ["src/main/jniLibs", "$buildDir/native-libs"]
+        }
+    }
+    splits {
+        abi {
+            enable true
+            reset()
+            include 'x86', 'x86_64', 'armeabi', 'arm64-v8a'
+            universalApk true
+        }
+    }
+}
+
+dependencies {
+    implementation 'com.android.support:support-compat:28.0.0'
+    implementation 'com.android.support:appcompat-v7:28.0.0'
+    //compile fileTree(include: ['*.jar'], dir: 'libs')
+    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+        exclude group: 'com.android.support', module: 'support-annotations'
+    })
+    //compile 'com.android.support:appcompat-v7:24.2.1'
+    //testCompile 'junit:junit:4.12'
+    compile files('libs/iotivity-lite.jar')
+}

+ 3 - 0
app/libs/.gitignore

@@ -0,0 +1,3 @@
+
+*.so
+

BIN
app/libs/iotivity-lite.jar


+ 17 - 0
app/proguard-rules.pro

@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /home/larrys/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 *;
+#}

+ 44 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="org.iotivity.bridge.homeserver">
+
+    <uses-feature android:name="android.hardware.nfc" />
+
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.NFC" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:supportsRtl="true"
+        android:theme="@style/AppTheme">
+
+        <activity
+            android:name=".BridgeServerActivity"
+            android:label="@string/app_name"
+            android:screenOrientation="fullSensor">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <service android:name=".BridgeService"
+            android:exported="true"/>
+
+        <receiver android:name=".AlarmReceiver" />
+
+    </application>
+
+</manifest>

+ 33 - 0
app/src/main/aidl/org/iotivity/bridge/homeserver/IRemoteService.aidl

@@ -0,0 +1,33 @@
+package org.iotivity.bridge.homeserver;
+
+import org.iotivity.bridge.homeserver.IRemoteServiceCallback;
+/**
+ * Example of defining an interface for calling on to a remote service
+ * (running in another process).
+ */
+interface IRemoteService {
+    /**
+     * Often you want to allow a service to call back to its clients.
+     * This shows how to do so, by registering a callback interface with
+     * the service.
+     */
+    void registerCallback(IRemoteServiceCallback cb);
+
+    /**
+     * Remove a previously registered callback interface.
+     */
+    void unregisterCallback(IRemoteServiceCallback cb);
+
+    /**
+     * Request the PID of this service, to do evil things with it.
+     */
+    int getPid();
+
+    /**
+     * This demonstrates the basic types that you can use as parameters
+     * and return values in AIDL.
+     */
+    /*void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
+            double aDouble, String aString);*/
+
+}

+ 19 - 0
app/src/main/aidl/org/iotivity/bridge/homeserver/IRemoteServiceCallback.aidl

@@ -0,0 +1,19 @@
+package org.iotivity.bridge.homeserver;
+
+/**
+ * Example of a callback interface used by IRemoteService to send
+ * synchronous notifications back to its clients.  Note that this is a
+ * one-way interface so the server does not block waiting for the client.
+ */
+
+interface IRemoteServiceCallback {
+    /**
+     * Called when the service has a new value for you.
+     */
+    void lineMessageNotified();
+
+    void messageNotified(String msg);
+
+    void addDeviceNotified();
+
+}

BIN
app/src/main/assets/idds/bridge_device_IDD.cbor


+ 303 - 0
app/src/main/assets/idds/bridge_device_IDD.json

@@ -0,0 +1,303 @@
+{
+  "schemes": [
+    "http"
+  ],
+  "swagger": "2.0",
+  "consumes": [
+    "application/json"
+  ],
+  "paths": {
+    "/bridge/vodlist": {
+      "get": {
+        "description": "This resource describes the VODs that have been onboarded on the Bridge Platform.\n",
+        "responses": {
+          "200": {
+            "schema": {
+              "$ref": "#/definitions/vodlist"
+            },
+            "description": ""
+          }
+        },
+        "parameters": [
+          {
+            "$ref": "#/parameters/interface-r"
+          },
+          {
+            "schema": {
+              "$ref": "#/definitions/vodlist"
+            },
+            "in": "body",
+            "required": true,
+            "name": "body"
+          }
+        ]
+      }
+    },
+    "/oic/p": {
+      "get": {
+        "responses": {
+          "200": {
+            "schema": {
+              "$ref": "#/definitions/Platform"
+            },
+            "description": ""
+          }
+        },
+        "parameters": [
+          {
+            "$ref": "#/parameters/interface-r"
+          }
+        ],
+        "description": ""
+      }
+    }
+  },
+  "definitions": {
+    "vodlist": {
+      "properties": {
+        "n": {
+          "type": "string",
+          "maxLength": 64,
+          "readOnly": true,
+          "description": "Friendly name of the Resource"
+        },
+        "rt": {
+          "minItems": 1,
+          "items": {
+            "enum": [
+              "oic.r.vodlist"
+            ],
+            "type": "string",
+            "maxLength": 64
+          },
+          "description": "Resource Type",
+          "uniqueItems": true,
+          "readOnly": true,
+          "default": [
+            "oic.r.vodlist"
+          ],
+          "type": "array"
+        },
+        "if": {
+          "minItems": 2,
+          "items": {
+            "enum": [
+              "oic.if.r",
+              "oic.if.baseline"
+            ],
+            "type": "string"
+          },
+          "description": "The OCF Interface set supported by this Resource",
+          "uniqueItems": true,
+          "readOnly": true,
+          "type": "array"
+        },
+        "vods": {
+          "description": "Array of information per VOD created by the Bridge",
+          "type": "array",
+          "minItems": 0,
+          "uniqueItems": true,
+          "readOnly": true,
+          "items": {
+            "$ref": "#/definitions/vodentry"
+          }
+        }
+      },
+      "required": [ "vods" ],
+      "type": "object"
+    },
+    "vodentry": {
+      "description": "Information for a VOD created by the Bridge",
+      "type": "object",
+      "properties": {
+        "n": {
+          "type": "string",
+          "maxLength": 64,
+          "readOnly": true,
+          "description": "Friendly name of the Resource"
+        },
+        "di": {
+          "type": "string",
+          "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
+          "readOnly": true,
+          "description": "Format pattern according to IETF RFC 4122."
+        },
+        "econame": {
+          "type": "string",
+          "enum": [ "ABC", "XYZ" ],
+          "readOnly": true,
+          "description": "Ecosystem Name of the Bridged Device which is exposed by this VOD"
+        }
+      },
+      "required": ["n", "di", "econame"]
+      },
+    "Platform": {
+        "properties": {
+          "id": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "if": {
+            "minItems": 2,
+            "items": {
+              "enum": [
+                "oic.if.r",
+                "oic.if.baseline"
+              ],
+              "type": "string",
+              "maxLength": 64
+            },
+            "description": "",
+            "uniqueItems": true,
+            "readOnly": true,
+            "type": "array"
+          },
+          "n": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnmn": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnnct": {
+            "minItems": 1,
+            "items": {
+              "minimum": 1,
+              "type": "integer",
+              "description": ""
+            },
+            "readOnly": true,
+            "type": "array",
+            "description": ""
+          },
+          "mnml": {
+            "format": "uri",
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 256,
+            "description": ""
+          },
+          "mnsel": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnpv": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnfv": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "rt": {
+            "minItems": 1,
+            "items": {
+              "enum": [
+                "oic.wk.p"
+              ],
+              "type": "string",
+              "maxLength": 64
+            },
+            "description": "",
+            "uniqueItems": true,
+            "readOnly": true,
+            "default": [
+              "oic.wk.p"
+            ],
+            "type": "array"
+          },
+          "mnos": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnhw": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "vid": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mnmo": {
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 64,
+            "description": ""
+          },
+          "mndt": {
+            "readOnly": true,
+            "type": "string",
+            "pattern": "^([0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|2[0-9]|1[0-9]|0[1-9])$",
+            "description": ""
+          },
+          "pi": {
+            "readOnly": true,
+            "type": "string",
+            "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
+            "description": ""
+          },
+          "st": {
+            "format": "date-time",
+            "readOnly": true,
+            "type": "string",
+            "description": ""
+          },
+          "mnsl": {
+            "format": "uri",
+            "type": "string",
+            "readOnly": true,
+            "maxLength": 256,
+            "description": ""
+          }
+        },
+        "required": [
+          "pi",
+          "mnmn"
+        ],
+        "type": "object"
+      }
+    },
+  "info": {
+    "version": "20190215",
+    "title": "serverlite24521",
+    "termsOfService": "https://openconnectivityfoundation.github.io/core/DISCLAIMER.md",
+    "license": {
+      "x-copyright": "copyright 2016-2017, 2019 Open Connectivity Foundation, Inc. All rights reserved.",
+      "url": "https://github.com/openconnectivityfoundation/core/blob/e28a9e0a92e17042ba3e83661e4c0fbce8bdc4ba/LICENSE.md",
+      "name": "OCF Data Model License"
+    }
+  },
+  "parameters": {
+    "interface-r": {
+      "enum": [
+        "oic.if.r",
+        "oic.if.baseline"
+      ],
+      "type": "string",
+      "in": "query",
+      "name": "if"
+    }
+  },
+  "produces": [
+    "application/json"
+  ]
+}

BIN
app/src/main/assets/idds/virtual_ocf_device_light_IDD.cbor


+ 299 - 0
app/src/main/assets/idds/virtual_ocf_device_light_IDD.json

@@ -0,0 +1,299 @@
+{
+  "schemes": [
+    "http"
+  ],
+  "swagger": "2.0",
+  "consumes": [
+    "application/json"
+  ],
+  "paths": {
+    "/bridge/light/switch": {
+      "post": {
+        "responses": {
+          "200": {
+            "schema": {
+              "$ref": "#/definitions/BinarySwitch"
+            },
+            "description": ""
+          }
+        },
+        "parameters": [
+          {
+            "$ref": "#/parameters/interface-a"
+          },
+          {
+            "schema": {
+              "$ref": "#/definitions/BinarySwitch"
+            },
+            "in": "body",
+            "required": true,
+            "name": "body"
+          }
+        ],
+        "description": ""
+      },
+      "get": {
+        "responses": {
+          "200": {
+            "schema": {
+              "$ref": "#/definitions/BinarySwitch"
+            },
+            "description": ""
+          }
+        },
+        "parameters": [
+          {
+            "$ref": "#/parameters/interface-a"
+          }
+        ],
+        "description": ""
+      }
+    },
+    "/oic/p": {
+      "get": {
+        "responses": {
+          "200": {
+            "schema": {
+              "$ref": "#/definitions/Platform"
+            },
+            "description": ""
+          }
+        },
+        "parameters": [
+          {
+            "$ref": "#/parameters/interface-r"
+          }
+        ],
+        "description": ""
+      }
+    }
+  },
+  "definitions": {
+    "BinarySwitch": {
+      "properties": {
+        "n": {
+          "type": "string",
+          "maxLength": 64,
+          "readOnly": true,
+          "description": "Friendly name of the Resource"
+        },
+        "rt": {
+          "minItems": 1,
+          "items": {
+            "enum": [
+              "oic.r.switch.binary"
+            ],
+            "type": "string",
+            "maxLength": 64
+          },
+          "description": "",
+          "uniqueItems": true,
+          "readOnly": true,
+          "default": [
+            "oic.r.switch.binary"
+          ],
+          "type": "array"
+        },
+        "if": {
+          "minItems": 2,
+          "items": {
+            "enum": [
+              "oic.if.a",
+              "oic.if.baseline"
+            ],
+            "type": "string"
+          },
+          "description": "",
+          "uniqueItems": true,
+          "readOnly": true,
+          "type": "array"
+        },
+        "value": {
+          "type": "boolean",
+          "description": ""
+        }
+      },
+      "required": [
+        "value"
+      ],
+      "type": "object"
+    },
+    "Platform": {
+      "properties": {
+        "id": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "if": {
+          "minItems": 2,
+          "items": {
+            "enum": [
+              "oic.if.r",
+              "oic.if.baseline"
+            ],
+            "type": "string",
+            "maxLength": 64
+          },
+          "description": "",
+          "uniqueItems": true,
+          "readOnly": true,
+          "type": "array"
+        },
+        "n": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnmn": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnnct": {
+          "minItems": 1,
+          "items": {
+            "minimum": 1,
+            "type": "integer",
+            "description": ""
+          },
+          "readOnly": true,
+          "type": "array",
+          "description": ""
+        },
+        "mnml": {
+          "format": "uri",
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 256,
+          "description": ""
+        },
+        "mnsel": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnpv": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnfv": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "rt": {
+          "minItems": 1,
+          "items": {
+            "enum": [
+              "oic.wk.p"
+            ],
+            "type": "string",
+            "maxLength": 64
+          },
+          "description": "",
+          "uniqueItems": true,
+          "readOnly": true,
+          "default": [
+            "oic.wk.p"
+          ],
+          "type": "array"
+        },
+        "mnos": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnhw": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "vid": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mnmo": {
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 64,
+          "description": ""
+        },
+        "mndt": {
+          "readOnly": true,
+          "type": "string",
+          "pattern": "^([0-9]{4})-(1[0-2]|0[1-9])-(3[0-1]|2[0-9]|1[0-9]|0[1-9])$",
+          "description": ""
+        },
+        "pi": {
+          "readOnly": true,
+          "type": "string",
+          "pattern": "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
+          "description": ""
+        },
+        "st": {
+          "format": "date-time",
+          "readOnly": true,
+          "type": "string",
+          "description": ""
+        },
+        "mnsl": {
+          "format": "uri",
+          "type": "string",
+          "readOnly": true,
+          "maxLength": 256,
+          "description": ""
+        }
+      },
+      "required": [
+        "pi",
+        "mnmn"
+      ],
+      "type": "object"
+    }
+  },
+  "info": {
+    "version": "20190215",
+    "title": "serverlite24521",
+    "termsOfService": "https://openconnectivityfoundation.github.io/core/DISCLAIMER.md",
+    "license": {
+      "x-copyright": "copyright 2016-2017, 2019 Open Connectivity Foundation, Inc. All rights reserved.",
+      "url": "https://github.com/openconnectivityfoundation/core/blob/e28a9e0a92e17042ba3e83661e4c0fbce8bdc4ba/LICENSE.md",
+      "name": "OCF Data Model License"
+    }
+  },
+  "parameters": {
+    "interface-a": {
+      "enum": [
+        "oic.if.a",
+        "oic.if.baseline"
+      ],
+      "type": "string",
+      "in": "query",
+      "name": "if"
+    },
+    "interface-r": {
+      "enum": [
+        "oic.if.r",
+        "oic.if.baseline"
+      ],
+      "type": "string",
+      "in": "query",
+      "name": "if"
+    }
+  },
+  "produces": [
+    "application/json"
+  ]
+}

+ 25 - 0
app/src/main/assets/pki_certs/ee.pem

@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEITCCA8igAwIBAgIJAI0K+3tTsk5iMAoGCCqGSM49BAMCMFsxDDAKBgNVBAoM
+A09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJbmZyYXN0cnVjdHVyZTEnMCUGA1UE
+AwweS3lyaW8gVEVTVCBJbnRlcm1lZGlhdGUgQ0EwMDAyMB4XDTIwMDUxODA5MTYz
+MVoXDTIwMDYxNzA5MTYzMVowZjEMMAoGA1UECgwDT0NGMSIwIAYDVQQLDBlLeXJp
+byBUZXN0IEluZnJhc3RydWN0dXJlMTIwMAYDVQQDDCl1dWlkPWVkNzYzMzBmLTdl
+ZjktNDZmMC01NDUzLWIwNjFiOTExOWRmMDBZMBMGByqGSM49AgEGCCqGSM49AwEH
+A0IABN4PlUPImyPuacE4NGyFeI8hMJAggX2Qr5xeWE0Vnm6NOiZpvuaAmbIO5M+a
+q2Gvv2QZr7Ly01yH72kUG3csnZ2jggJoMIICZDAJBgNVHRMEAjAAMA4GA1UdDwEB
+/wQEAwIDiDApBgNVHSUEIjAgBggrBgEFBQcDAgYIKwYBBQUHAwEGCisGAQQBgt58
+AQYwHQYDVR0OBBYEFN2tpwX3P1/htWoDp89DTd/tTHd0MB8GA1UdIwQYMBaAFBlz
+agQaCwdwT1N5UzaH/Ay6fK4LMIGWBggrBgEFBQcBAQSBiTCBhjBdBggrBgEFBQcw
+AoZRaHR0cDovL3Rlc3Rwa2kua3lyaW8uY29tL29jZi9jYWNlcnRzL0JCRTY0RjlB
+N0VFMzdEMjlBMDVFNEJCNzc1OTVGMzA4QkU0MUVCMDcuY3J0MCUGCCsGAQUFBzAB
+hhlodHRwOi8vdGVzdG9jc3Aua3lyaW8uY29tMF8GA1UdHwRYMFYwVKBSoFCGTmh0
+dHA6Ly90ZXN0cGtpLmt5cmlvLmNvbS9vY2YvY3Jscy9CQkU2NEY5QTdFRTM3RDI5
+QTA1RTRCQjc3NTk1RjMwOEJFNDFFQjA3LmNybDAYBgNVHSAEETAPMA0GCysGAQQB
+g5FWAAECMGoGCisGAQQBg5FWAQAEXDBaMAkCAQICAQACAQAwNgwZMS4zLjYuMS40
+LjEuNTE0MTQuMC4wLjEuMAwZMS4zLjYuMS40LjEuNTE0MTQuMC4wLjIuMAwNQnJp
+ZGdlIFNlcnZlcgwGSU1Tb2Z0MCoGCisGAQQBg5FWAQEEHDAaBgsrBgEEAYORVgEB
+AAYLKwYBBAGDkVYBAQEwMAYKKwYBBAGDkVYBAgQiMCAMDjEuMy42LjEuNC4xLjcx
+DAlEaXNjb3ZlcnkMAzEuMDAKBggqhkjOPQQDAgNHADBEAiBOgJHH0KGCaNJS0Kis
+gR/2z2oOcdyY/vGLnWrj6UFrDAIgUb+vMlVA36casyeKUpz3ddEOTPl8/IAeXcXb
+iSx9lB0=
+-----END CERTIFICATE-----

+ 5 - 0
app/src/main/assets/pki_certs/key.pem

@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEICoMBthEi8SempJoOjvLJovdMcO+FsBmUFEm1jxoZvH3oAoGCCqGSM49
+AwEHoUQDQgAE3g+VQ8ibI+5pwTg0bIV4jyEwkCCBfZCvnF5YTRWebo06Jmm+5oCZ
+sg7kz5qrYa+/ZBmvsvLTXIfvaRQbdyydnQ==
+-----END EC PRIVATE KEY-----

+ 8 - 0
app/src/main/assets/pki_certs/key_org.pem

@@ -0,0 +1,8 @@
+-----BEGIN EC PARAMETERS-----
+BggqhkjOPQMBBw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEICoMBthEi8SempJoOjvLJovdMcO+FsBmUFEm1jxoZvH3oAoGCCqGSM49
+AwEHoUQDQgAE3g+VQ8ibI+5pwTg0bIV4jyEwkCCBfZCvnF5YTRWebo06Jmm+5oCZ
+sg7kz5qrYa+/ZBmvsvLTXIfvaRQbdyydnQ==
+-----END EC PRIVATE KEY-----

+ 13 - 0
app/src/main/assets/pki_certs/rootca1.pem

@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB3zCCAYWgAwIBAgIJAPObjMBXKhGyMAoGCCqGSM49BAMCMFMxDDAKBgNVBAoM
+A09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJbmZyYXN0cnVjdHVyZTEfMB0GA1UE
+AwwWS3lyaW8gVEVTVCBST09UIENBMDAwMjAeFw0xODExMzAxNzMxMDVaFw0yODEx
+MjcxNzMxMDVaMFMxDDAKBgNVBAoMA09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJ
+bmZyYXN0cnVjdHVyZTEfMB0GA1UEAwwWS3lyaW8gVEVTVCBST09UIENBMDAwMjBZ
+MBMGByqGSM49AgEGCCqGSM49AwEHA0IABGt1sU2QhQcK/kflKSF9TCrvKaDckLWd
+ZoyvP6z0OrqNdtBscZgVYsSHMQZ1R19wWxsflvNr8bMVW1K3HWMkpsijQjBAMA8G
+A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBQoSOTlJ1jZ
+CO4JNOSxuz1ZZh/I9TAKBggqhkjOPQQDAgNIADBFAiAlMUwgVeL8d5W4jZdFJ5Zg
+clk7XT66LNMfGkExSjU1ngIhANOvTmd32A0kEtIpHbiKA8+RFDCPJWjN4loxrBC7
+v0JE
+-----END CERTIFICATE-----

+ 11 - 0
app/src/main/assets/pki_certs/rootca2.pem

@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBnTCCAUKgAwIBAgIUfKTxfZOGE/bSAF+l555yrmzbBZYwCgYIKoZIzj0EAwIw
+KzEMMAoGA1UEChMDT0NGMRswGQYDVQQDExJURVNUIE9DRiBSb290IENBIDIwIBcN
+MTgxMTI5MTY0MTIyWhgPMjA2ODExMjkxNjQxMjJaMCsxDDAKBgNVBAoTA09DRjEb
+MBkGA1UEAxMSVEVTVCBPQ0YgUm9vdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0D
+AQcDQgAED4xusXQP8CojjLCIy3Kc/6oDZUM2CxKiq4RfKi4A2hZ9uOKD1TrirCGh
+yVLso63+OQv1Zi6Og9E4SYMDHqvwZKNCMEAwDgYDVR0PAQH/BAQDAgEGMB0GA1Ud
+DgQWBBSYuivCP5E741G+c2v1466PlBfNizAPBgNVHRMBAf8EBTADAQH/MAoGCCqG
+SM49BAMCA0kAMEYCIQCyF9qhRMdtJhM922E7BrTENwrwrYU9X66zgRtBTuzrVgIh
+ANreyj+BcMMLqXLZUSw1Lbb+4fm+/2ETt92RbrZSwXYt
+-----END CERTIFICATE-----

+ 18 - 0
app/src/main/assets/pki_certs/subca1.pem

@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+jCCAqGgAwIBAgIJAPObjMBXKhG1MAoGCCqGSM49BAMCMFMxDDAKBgNVBAoM
+A09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJbmZyYXN0cnVjdHVyZTEfMB0GA1UE
+AwwWS3lyaW8gVEVTVCBST09UIENBMDAwMjAeFw0xODExMzAxODEyMTVaFw0yODEx
+MjYxODEyMTVaMFsxDDAKBgNVBAoMA09DRjEiMCAGA1UECwwZS3lyaW8gVGVzdCBJ
+bmZyYXN0cnVjdHVyZTEnMCUGA1UEAwweS3lyaW8gVEVTVCBJbnRlcm1lZGlhdGUg
+Q0EwMDAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvA+Gn3ofRpH40XuVppBR
+f78mDtfclOkBd7/32yQcmK2LQ0wm/uyl2cyeABPuN6NFcR9+LYkXZ5P4Ovy9R43Q
+vqOCAVQwggFQMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMB0G
+A1UdDgQWBBQZc2oEGgsHcE9TeVM2h/wMunyuCzAfBgNVHSMEGDAWgBQoSOTlJ1jZ
+CO4JNOSxuz1ZZh/I9TCBjQYIKwYBBQUHAQEEgYAwfjBVBggrBgEFBQcwAoZJaHR0
+cDovL3Rlc3Rwa2kua3lyaW8uY29tL29jZi80RTY4RTNGQ0YwRjJFNEY4MEE4RDE0
+MzhGNkExQkE1Njk1NzEzRDYzLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL3Rlc3Rv
+Y3NwLmt5cmlvLmNvbTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vdGVzdHBraS5r
+eXJpby5jb20vb2NmLzRFNjhFM0ZDRjBGMkU0RjgwQThEMTQzOEY2QTFCQTU2OTU3
+MTNENjMuY3JsMAoGCCqGSM49BAMCA0cAMEQCHwXkRYd+u5pOPH544wBmBRJz/b0j
+ppvUIHx8IUH0CioCIQDC8CnMVTOC5aIoo5Yg4k7BDDNxbRQoPujYes0OTVGgPA==
+-----END CERTIFICATE-----

+ 21 - 0
app/src/main/java/org/iotivity/bridge/homeserver/AlarmReceiver.java

@@ -0,0 +1,21 @@
+package org.iotivity.bridge.homeserver;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Build;
+
+public class AlarmReceiver  extends BroadcastReceiver {
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            Intent in = new Intent(context, BridgeService.class);
+            context.startForegroundService(in);
+        } else {
+            Intent in = new Intent(context, BridgeService.class);
+            context.startService(in);
+        }
+    }
+}

+ 362 - 0
app/src/main/java/org/iotivity/bridge/homeserver/BridgeServer.java

@@ -0,0 +1,362 @@
+package org.iotivity.bridge.homeserver;
+
+import android.util.Log;
+
+import org.iotivity.OCAddDeviceHandler;
+import org.iotivity.OCBridge;
+import org.iotivity.OCCoreRes;
+import org.iotivity.OCDeviceInfo;
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCIntrospection;
+import org.iotivity.OCMain;
+import org.iotivity.OCMethod;
+import org.iotivity.bridge.homeserver.handler.BridgeInitHandler;
+import org.iotivity.bridge.homeserver.handler.FactoryPresetsHandler;
+import org.iotivity.bridge.homeserver.handler.server.GetLightRequestHandler;
+import org.iotivity.bridge.homeserver.handler.server.PostLightRequestHandler;
+import org.iotivity.bridge.homeserver.handler.server.PutLightRequestHandler;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.model.VirtualOCFDevice;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcBridge;
+import org.iotivity.oc.OcPlatform;
+import org.iotivity.OCResource;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcUtils;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.OCUuid;
+import org.iotivity.OCVirtualDevice;
+
+import java.util.ArrayList;
+
+public class BridgeServer {
+
+    private static final String TAG = BridgeServer.class.getSimpleName();
+
+    // Virtual OCF Device's unique identifier such as uuid, MEID, serial number, mac address
+    private static final String LIGHT_UUID = "2b32e152-3756-4fb6-b3f2-d8db7aafe39f";
+    private static final String LIGHT2_UUID = "645b5166-3efb-4021-6ba0-4db90d434838";
+    private static final String CLIENT_UUID = "f2f0109f-ef7d-496a-9676-d3d87b38e52f";
+
+    private OcPlatform ocPlatform;
+    private OcBridge ocBridge ;
+    private BridgeInitHandler initHandler ;
+
+    private BridgeService service = null ;
+
+    private Bridge bridge = null ;
+    private Light light = null ;
+
+    private ArrayList<OcRemoteDevice> pairwised_devices = new ArrayList<OcRemoteDevice>();
+
+    public BridgeServer(BridgeService service) {
+        this.service = service;
+        this.bridge = new Bridge("Energy Home Hub");
+
+        // Note: If using a factory presets handler,
+        // the factory presets handler must be set prior to calling systemInit().
+        // The systemInit() function will cause the factory presets handler to
+        // be called if it is set.
+        OcUtils.setFactoryPresetsHandler(new FactoryPresetsHandler(this.service));
+
+        ocPlatform = OcPlatform.getInstance();
+        initHandler = new BridgeInitHandler(this.service, ocPlatform, bridge);
+        ocPlatform.systemInit(initHandler);
+
+        this.initBridgeServer();
+    }
+
+    public void initBridgeServer() {
+
+        this.addLightVirtualOCFServer(LIGHT_UUID, "Light Switch", "rs-485");
+        //this.addVirtualOCFClient(CLIENT_UUID, "Virtual OCF Client", "ocf");
+    }
+
+    public OCUuid getBridgeDeviceId() {
+        return OCCoreRes.getDeviceId(Bridge.BRIDGE_INDEX);
+    }
+    public void shutdown() {
+
+        ocPlatform.systemShutdown();
+    }
+
+    public void resetBridgeServer() {
+
+        OCMain.resetDevice(Bridge.BRIDGE_INDEX);
+
+        // this below logic has some issue for now so don't use
+        //ocPlatform.reset();
+        //ocPlatform.systemShutdown();
+        //ocPlatform.systemInit(initHandler);
+    }
+
+    public void resetVirtualOCFDevices() {
+        for(VirtualOCFDevice vod : bridge.getVODList()) {
+            OCBridge.removeVirtualDevice(vod.getVODIndex());
+            OCBridge.deleteVirtualDevice(vod.getVODIndex()); //  Note :This includes OCMain.resetDevice(index);
+        }
+        bridge.clearAllVODList();
+    }
+
+    public void resetVirtualOCFDevice(int vod_index) {
+        OCBridge.removeVirtualDevice(vod_index);
+        OCBridge.deleteVirtualDevice(vod_index); // Note : This includes OCMain.resetDevice(index);
+        bridge.removeVODList(vod_index);
+    }
+
+    public void resetDevice(int device_index) {
+
+        if(device_index < 0) return ;
+
+        OCDeviceInfo info = OCCoreRes.getDeviceInfo(device_index);
+        if(info == null) return ;
+        if(device_index == Bridge.BRIDGE_INDEX) {
+            if (info != null) {
+                Log.d(TAG, "Bridge Server[" + Bridge.BRIDGE_INDEX + "] DeviceId = " + OCUuidUtil.uuidToString(info.getDi())
+                        + " will reset");
+            }
+            this.resetBridgeServer();
+
+        } else if(device_index > 0) {
+            OCVirtualDevice vod = OCBridge.getVirtualDeviceInfo(device_index);
+            if (info != null) {
+                Log.d(TAG, "Virtual OCF Server/Client[" + vod.getIndex() + "] DeviceId = " + OCUuidUtil.uuidToString(info.getDi())
+                        + ", echoname = " + vod.getEconame() + " will reset");
+            }
+            this.resetVirtualOCFDevice(device_index);
+        }
+    }
+
+    /*public void loadVirtualOCFDevices() {
+        int vod_count = OCBridge.getVirtualDeviceCount();
+        Log.d(TAG, "Virtual OCF Device Count = [" + vod_count + "], Core Device Nums = ["+OCCoreRes.getNumDevices()+"] ");
+
+        for(int index = 1; index <= vod_count; index++) {
+            OCVirtualDevice vod = OCBridge.getVirtualDeviceInfo(index);
+            if(vod != null) {
+                String uuid = OCUuidUtil.bytesToString(vod.getId());
+
+                Log.d(TAG,"OCVirtualDevice["+index+"] econame = " + vod.getEconame() +", DI = " + uuid);
+
+                // Add VOD Data & State on memory of BridgeServer
+                VirtualOCFDevice vod_data = new VirtualOCFDevice(index, vod.getName(), vod.getEconame(), uuid);
+                if(OCMain.isOwnedDevice(index)) vod_data.setOwned(true);
+                bridge.addOrReplaceVODList(vod_data);
+            }
+        }
+    }*/
+
+    public String existVirtualOCFDevice(String virtual_di, String econame) {
+
+        for(VirtualOCFDevice vod : bridge.getVODList()){
+            if(vod.getVirtualDeviceId().equals(virtual_di) && vod.getEcoName().equals(econame)) {
+                return vod.getVirtualDeviceId();
+            }
+        }
+        return null ;
+    }
+
+    public void addLightVirtualOCFServer(String virtual_di, String devicename, String econame) {
+
+        // Add Virtual Device for Light
+        OCUuid uuid = OCUuidUtil.stringToUuid(virtual_di) ;
+        int vod_index = OCBridge.addVirtualDevice(uuid.getId(),
+                econame, "/oic/d", "oic.d.light",  // "oic.d.virtual" automatically added by internal api implements
+                devicename, "ocf.2.0.0", "ocf.res.1.3.0,ocf.sh.1.3.0",
+                new OCAddDeviceHandler() {
+                    @Override
+                    public void handler() {
+                        Log.d(TAG, "inside VirtualDevice.OCAddDeviceHandler.handler()");
+                    }
+                });
+
+        if (vod_index != 0) {
+            Log.d(TAG, "VOD Index = "+ vod_index + ", VOD Count = " + OCBridge.getVirtualDeviceCount());
+
+            light = new Light(devicename);
+            OCDeviceInfo dev_info = OCCoreRes.getDeviceInfo(vod_index);
+            OCVirtualDevice vod_info = OCBridge.getVirtualDeviceInfo(vod_index);
+            Log.d(TAG, "VOD Info = "+ vod_info);
+            if(vod_info != null) {
+                Log.d(TAG, "Virtual Server[" + vod_info.getIndex() + "] "
+                        + " DeviceId = " + OCUuidUtil.bytesToString(vod_info.getId())
+                        + ", Econame = " + vod_info.getEconame() + ", Name = " + dev_info.getName()
+                        + " was added");
+
+
+                // Add VOD Data
+                VirtualOCFDevice vod = new VirtualOCFDevice(vod_index, devicename, econame,
+                        OCUuidUtil.bytesToString(vod_info.getId()));
+                vod.setDiscovered(true);
+                vod.setAddedToBridge(true);
+                bridge.addOrReplaceVODList(vod);
+
+                // Add Light Device Resources and Handler
+                OCResource res_light = OCMain.newResource(devicename, "/light", (short) 1, (long) vod_index);
+                OCMain.resourceBindResourceType(res_light, "oic.r.switch.binary");  // BinarySwitch Resource Type
+                OCMain.resourceBindResourceInterface(res_light, OCInterfaceMask.RW);
+                OCMain.resourceSetDefaultInterface(res_light, OCInterfaceMask.RW);
+                OCMain.resourceSetDiscoverable(res_light, true);
+                OCMain.resourceSetObservable(res_light, true);
+                //TODO : check if it is needed for notifying to client :
+                OCMain.resourceSetPeriodicObservable(res_light, 60); // seconds
+                OCMain.resourceSetRequestHandler(res_light, OCMethod.OC_GET, new GetLightRequestHandler(service, light));
+                OCMain.resourceSetRequestHandler(res_light, OCMethod.OC_POST, new PostLightRequestHandler(service, light));
+                OCMain.resourceSetRequestHandler(res_light, OCMethod.OC_PUT, new PutLightRequestHandler(service, light));
+                OCMain.addResource(res_light);
+
+                // Add Dimming Resource
+                OCResource res_dimming = OCMain.newResource(devicename, "/dimming", (short) 1, (long) vod_index);
+                OCMain.resourceBindResourceType(res_dimming, "oic.r.light.dimming");
+                OCMain.resourceBindResourceInterface(res_dimming, OCInterfaceMask.RW);
+                OCMain.resourceSetDefaultInterface(res_dimming, OCInterfaceMask.RW);
+                OCMain.resourceSetDiscoverable(res_dimming, true);
+                OCMain.resourceSetObservable(res_dimming, true);
+                //TODO : check if it is needed for notifying to client :
+                OCMain.resourceSetPeriodicObservable(res_dimming, 60); // seconds
+                OCMain.resourceSetRequestHandler(res_dimming, OCMethod.OC_GET, new GetLightRequestHandler(service, light));
+                OCMain.resourceSetRequestHandler(res_dimming, OCMethod.OC_POST, new PostLightRequestHandler(service, light));
+                OCMain.resourceSetRequestHandler(res_dimming, OCMethod.OC_PUT, new PutLightRequestHandler(service, light));
+                OCMain.addResource(res_dimming);
+
+
+                // set immutable device id for Platform Independent Identifier (piid)
+                OCMain.setImmutableDeviceIdentifier(vod_index, OCUuidUtil.stringToUuid(virtual_di));
+                Log.d(TAG, "Virtual Server [" + vod_info.getIndex() + "] "
+                        + ", Virtual Device Id = " + virtual_di
+                        + ", Device Id = " + OCUuidUtil.uuidToString(dev_info.getDi())
+                        + ", Device Piid = " + OCUuidUtil.uuidToString(dev_info.getPiid()));
+
+                // Add Light OCF Device IDD
+                //byte[] idd_bytes = Utils.getFileBytes("idds/virtual_ocf_device_light_IDD.cbor", activity); // example : "dummy_bridge_bridge_device_IDD.cbor"
+                //OCIntrospection.setIntrospectionData(vod_index, idd_bytes);
+            }
+        }
+
+    }
+
+    public void removeLightVirtualOCFDevice(int vod_index) {
+
+        OCVirtualDevice vod_light = OCBridge.getVirtualDeviceInfo(vod_index);
+        if(vod_light != null) {
+            Log.d(TAG, "Virtual Server[" + vod_light.getIndex() + "] "
+                    + ", DeviceId = " + OCUuidUtil.bytesToString(vod_light.getId())
+                    + ", Econame = " + vod_light.getEconame() + ", Name = " + vod_light.getEconame()
+                    + " will be removed");
+
+            int ret = OCBridge.removeVirtualDevice(vod_index);
+            if (ret >=0) {
+                bridge.removeVODList(vod_index);
+            }
+        }
+    }
+
+    public void addVirtualOCFClient(String device_uuid, String devicename, String econame) {
+
+        // Add Virtual Device for Legarcy Client like such as zibee coodinater
+        OCUuid uuid = OCUuidUtil.stringToUuid(device_uuid) ;
+        int vod_index = OCBridge.addVirtualDevice(uuid.getId(),
+                econame, "/oic/d", "oic.d.virtualclient",  // "oic.d.virtual" automatically added by internal api implements
+                devicename, "ocf.2.0.0", "ocf.res.1.3.0,ocf.sh.1.3.0");
+
+        if(vod_index != 0) {
+            OCDeviceInfo dev_info = OCCoreRes.getDeviceInfo(vod_index);
+            OCVirtualDevice vod_client = OCBridge.getVirtualDeviceInfo(vod_index);
+            if(vod_client != null){
+                Log.d(TAG, "Virtual Client[" + vod_client.getIndex() + "] "
+                        + " DeviceId = " + OCUuidUtil.bytesToString(vod_client.getId())
+                        + ", Econame = " + vod_client.getEconame() + ", Name = " + dev_info.getName()
+                        + " was added");
+
+                // Add VOD Data
+                VirtualOCFDevice vod = new VirtualOCFDevice(vod_index, dev_info.getName(), vod_client.getEconame(),
+                        OCUuidUtil.bytesToString(vod_client.getId()));
+                vod.setDiscovered(true);
+                vod.setAddedToBridge(true);
+                bridge.addOrReplaceVODList(vod);
+            }
+        }
+
+    }
+
+    /*
+    private boolean checkExistVOD(String device_unique_id) {
+        String device_uuid = existVirtualOCFDevice(devicename, econame);
+        if (device_uuid == null) { // In case of no exist device
+            // generate new UUID
+            OCUuid new_uuid = OCUuidUtil.generateUuid();
+            device_uuid = OCUuidUtil.uuidToString(new_uuid);
+            Log.d(TAG, "Virtual Device : Name = " + devicename + ", DeviceId = " + device_uuid
+                    + ", echoname = " + econame + " will be added since it doesn't exist.");
+
+            return false ;
+        } else {
+            Log.d(TAG, "Virtual Device : Name = " + devicename + ", DeviceId = " + device_uuid
+                    + ", echoname = " + econame + " exists already.");
+            return true ;
+        }
+    }*/
+
+    public void disconnectVirtualDevice(int vod_index) {
+
+        Log.d(TAG, "disconnectVirtualDevice vod_index = "+vod_index+") called.");
+
+        VirtualOCFDevice vod = bridge.getVirtualOCFDevice(vod_index);
+        if (vod != null) {
+            vod.setDiscovered(false);
+            vod.setAddedToBridge(false);
+
+            OCDeviceInfo info = OCCoreRes.getDeviceInfo(vod_index);
+            if(OCBridge.removeVirtualDevice(vod_index) == 0) {
+                Log.d(TAG, "Virtual OCF Server/Client[" + vod.getVODIndex() + "] DeviceId = " + OCUuidUtil.uuidToString(info.getDi())
+                        + ", echoname = " + vod.getEcoName() + " was removed from the bridge");
+            } else {
+                Log.d(TAG, "Failed to remove Virtual OCF Server/Client["+vod_index+"] "+info.getName()+" from the bridge");
+            }
+        }
+    }
+
+    public void discoveredOCFDevice(OcRemoteDevice remoteDevice) {
+        // TODO : check if discovered OCF Device has to add to the bridge as a Virtual OCF Device or not
+
+    }
+
+    //public Light getLightData() { return light; }
+    //public Bridge getBridgeData() { return bridge; }
+
+
+    public ArrayList<OcRemoteDevice> getPairwisedDevices() {
+        return pairwised_devices;
+    }
+
+    public void clearAllPairwisedDevices() {
+        pairwised_devices.clear();
+    }
+
+    public boolean addOrReplacePairwisedDevice(OcRemoteDevice new_dev) {
+        for(OcRemoteDevice dev : pairwised_devices) {
+            if(OCUuidUtil.isEqual(dev.getDeviceId(), new_dev.getDeviceId())) {
+                return true ;
+            }
+        }
+        return this.pairwised_devices.add(new_dev);
+    }
+
+    public boolean removePairwisedDevices(OcRemoteDevice dev) {
+
+        return this.pairwised_devices.remove(dev);
+    }
+
+    public boolean removePairwisedDevices(int index) {
+
+        return pairwised_devices.remove(pairwised_devices.get(index));
+    }
+
+    public OcRemoteDevice getPairwisedDevice(int index) {
+        return pairwised_devices.get(index);
+    }
+
+}
+
+

+ 742 - 0
app/src/main/java/org/iotivity/bridge/homeserver/BridgeServerActivity.java

@@ -0,0 +1,742 @@
+package org.iotivity.bridge.homeserver;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Process;
+import android.os.RemoteException;
+import android.support.v7.app.AppCompatActivity;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.ScrollView;
+import android.widget.SimpleAdapter;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import org.iotivity.OCCoreRes;
+import org.iotivity.OCEndpoint;
+import org.iotivity.OCQos;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.bridge.homeserver.handler.client.DeviceDiscoveryHandler;
+import org.iotivity.bridge.homeserver.handler.client.GetCommonResponseHandler;
+import org.iotivity.bridge.homeserver.handler.client.GetLightResponseHandler;
+import org.iotivity.bridge.homeserver.handler.client.Post2LightResponseHandler;
+import org.iotivity.bridge.homeserver.handler.client.ResourceDetailsHelper;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class BridgeServerActivity extends AppCompatActivity {
+
+    private static final String TAG = BridgeServerActivity.class.getSimpleName();
+
+    private Button discoverDevicesButton;
+    private ListView listView;
+
+    private AdapterView.OnItemClickListener resourceItemClickListener;
+    private AdapterView.OnItemLongClickListener resourceItemLongClickListener ;
+    private ArrayAdapter<OcRemoteResource> resourceArrayAdapter;
+
+    private AdapterView.OnItemClickListener deviceItemClickListener;
+    private ArrayAdapter<OcRemoteDevice> deviceArrayAdapter;
+
+    ArrayList<OcRemoteDevice> deviceList = new ArrayList<OcRemoteDevice>();
+    private final Object arrayAdapterSync = new Object();
+
+    private TextView mConsoleTextView;
+    private ScrollView mScrollView;
+
+    private RemoteServiceConnection remoteConn ;
+    private LocalServiceConnection localConn ;
+    private IRemoteService mService = null ;
+    private BridgeService.LocalServiceBinder sBinder = null ;
+    private BridgeService bridgeService = null ;
+    private BridgeServer bridgeServer = null ;
+
+    //private Light res_light = new Light();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        createContent();
+
+        if (savedInstanceState == null) {
+            // start first time only
+            //bridgeServer = new BridgeServer(this);
+
+            // start Service
+            Intent intent = new Intent( BridgeServerActivity.this, BridgeService.class );
+            startService(intent);
+
+            // Local Bind Service
+            localConn = new LocalServiceConnection();
+            bindService(intent, localConn, Context.BIND_AUTO_CREATE);
+
+            // Remote Bind Service
+            Intent mBindIntent = new Intent(BridgeServerActivity.this, BridgeService.class);
+            mBindIntent.setAction(IRemoteService.class.getName());
+            remoteConn = new RemoteServiceConnection();
+            bindService(mBindIntent, remoteConn, Context.BIND_AUTO_CREATE);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+
+        this.unbindBridgeService();
+
+        super.onDestroy();
+
+        //Log.d(TAG, "Service Process will be killed : service pid = " + service_pid + ", application pid = " + Process.myPid());
+        // Bridge Service and Application Process Kill
+        //android.os.Process.killProcess(service_pid);
+
+        //or
+
+        /*Log.d(TAG, "System.exit() will be called");
+        System.runFinalizersOnExit(true);
+        System.exit(0);*/
+
+
+    }
+
+    private void unbindBridgeService() {
+
+        // Unregister Remote Client Callback
+        if (mService != null) {
+            try {
+                mService.unregisterCallback(mCallback);
+                Log.d(TAG, "unregister Remote Client Callback()");
+            } catch (RemoteException e) {
+                // There is nothing special we need to do if the service
+                // has crashed.
+            }
+        }
+
+        // Unbind Service
+        unbindService(localConn);
+        unbindService(remoteConn);
+        Log.d(TAG, "unbindServices()");
+
+    }
+
+    private void stopBridgeService() {
+
+        // unbind Service
+        unbindBridgeService();
+
+        // stop Service
+        Intent intent = new Intent( BridgeServerActivity.this, BridgeService.class );
+        stopService(intent);
+        Log.d(TAG, "stopService()");
+    }
+
+    class RemoteServiceConnection implements ServiceConnection {
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+
+            Log.d(TAG, "onServiceConnected ComponentName=" + name + ", IBinder=" + service.toString());
+            if (service instanceof IRemoteService.Stub) {
+
+                mService = IRemoteService.Stub.asInterface(service);
+
+                try {
+                    mService.registerCallback(mCallback);
+                } catch (RemoteException e) {
+                    // In this case the service has crashed before we could even
+                    // do anything with it; we can count on soon being
+                    // disconnected (and then reconnected if it can be restarted)
+                    // so there is no need to do anything here.
+                }
+
+                // As part of the sample, tell the user what happened.
+                Toast.makeText(BridgeServerActivity.this, "Bridge Remote Service Connected",
+                        Toast.LENGTH_SHORT).show();
+
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+
+            mService = null;
+
+            Toast.makeText(BridgeServerActivity.this, "Bridge Remote Service Disconnected",
+                    Toast.LENGTH_SHORT).show();
+
+        }
+
+    }
+
+    class LocalServiceConnection implements ServiceConnection {
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+
+            Log.d(TAG, "onServiceConnected ComponentName=" + name + ", IBinder=" + service.toString());
+            if (service instanceof BridgeService.LocalServiceBinder) {
+
+                sBinder = (BridgeService.LocalServiceBinder) service;
+                bridgeService = sBinder.getService();
+                bridgeServer = bridgeService.getBridgeServer();
+                Toast.makeText(BridgeServerActivity.this, "Bridge Local Service Connected",
+                        Toast.LENGTH_SHORT).show();
+
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+
+            sBinder = null;
+            bridgeService = null ;
+            bridgeServer = null ;
+
+            Toast.makeText(BridgeServerActivity.this, "Bridge Local Service Disconnected",
+                    Toast.LENGTH_SHORT).show();
+
+        }
+    }
+
+    private IRemoteServiceCallback mCallback = new IRemoteServiceCallback.Stub() {
+        /**
+         * This is called by the remote service regularly to tell us about
+         * new values.  Note that IPC calls are dispatched through a thread
+         * pool running in each process, so the code executing here will
+         * NOT be running in our main thread like most other things -- so,
+         * to update the UI, we need to use a Handler to hop over there.
+         */
+        @Override
+        public void lineMessageNotified() throws RemoteException {
+            printLine();
+        }
+
+        @Override
+        public void messageNotified(String msg) throws RemoteException {
+            msg(msg);
+        }
+
+        @Override
+        public void addDeviceNotified() throws RemoteException {
+
+            runOnUiThread(new Runnable() {
+                public void run() {
+                    synchronized (arrayAdapterSync) {
+                        deviceArrayAdapter.setNotifyOnChange(false);
+                        if(bridgeServer!=null) {
+                            deviceArrayAdapter.clear();
+                            deviceArrayAdapter.addAll(bridgeServer.getPairwisedDevices());
+                        }
+                        deviceArrayAdapter.setNotifyOnChange(true);
+                    }
+
+                    deviceArrayAdapter.notifyDataSetChanged();
+                }
+            });
+
+        }
+    };
+
+
+    /*private static final int BUMP_MSG = 1;
+
+    private Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case BUMP_MSG:
+                    msg("Received from service: " + msg.arg1);
+                    break;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+
+    };
+*/
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        getMenuInflater().inflate(R.menu.actionbar_actions, menu) ;
+        return true ;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.action_bridge_reset:
+                // TODO : do some action like start Activity or show Dialog
+            {
+                AlertDialog.Builder resetBridgeDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                resetBridgeDialogBuilder.setTitle(getString(R.string.resetBridge));
+                resetBridgeDialogBuilder.setMessage(getString(R.string.resetBridgeMessage));
+
+                resetBridgeDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        if(bridgeServer!=null) bridgeServer.resetBridgeServer();
+                    }
+                });
+
+                resetBridgeDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                    }
+                });
+
+                Dialog resebridgeDialog = resetBridgeDialogBuilder.create();
+                resebridgeDialog.show();
+                return true;
+            }
+
+            case R.id.action_vods_reset:
+                // TODO : do some action like start Activity or show Dialog
+                {
+                    AlertDialog.Builder resetVodsDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                    resetVodsDialogBuilder.setTitle(getString(R.string.resetVods));
+                    resetVodsDialogBuilder.setMessage(getString(R.string.resetVodsMessage));
+
+                    resetVodsDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                            if(bridgeServer!=null) bridgeServer.resetVirtualOCFDevices();
+                        }
+                    });
+
+                    resetVodsDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                        @Override
+                        public void onClick(DialogInterface dialog, int which) {
+                        }
+                    });
+
+                    Dialog resetVodsDialog = resetVodsDialogBuilder.create();
+                    resetVodsDialog.show();
+                    return true;
+            }
+            case R.id.action_bridgeservice_stop : {
+
+                AlertDialog.Builder stopServiceDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                stopServiceDialogBuilder.setTitle(getString(R.string.stopBridgeService));
+                stopServiceDialogBuilder.setMessage(getString(R.string.stopBridgeMessage));
+
+                stopServiceDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        // Stop Bridge Service
+                        stopBridgeService();
+                    }
+                });
+
+                stopServiceDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                    }
+                });
+
+                Dialog stopServiceDialog = stopServiceDialogBuilder.create();
+                stopServiceDialog.show();
+                return true;
+
+            }
+            default :
+                return super.onOptionsItemSelected(item) ;
+        }
+    }
+
+    private void createContent() {
+
+        mConsoleTextView = (TextView) findViewById(R.id.consoleTextView);
+        mConsoleTextView.setMovementMethod(new ScrollingMovementMethod());
+        mScrollView = (ScrollView) findViewById(R.id.scrollView);
+        mScrollView.fullScroll(View.FOCUS_DOWN);
+
+        resourceItemClickListener = new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                OcRemoteResource resource = resourceArrayAdapter.getItem((int) id);
+                if (resource != null) {
+                    AlertDialog.Builder resourceDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                    resourceDialogBuilder.setTitle(resource.getAnchor() + resource.getUri());
+
+                    ListView resourceDetailsListView = new ListView(BridgeServerActivity.this);
+                    final ArrayList<HashMap<String, String>> resourceDetailsList = new ArrayList<>();
+                    final SimpleAdapter resourceDetailsAdapter = new SimpleAdapter(BridgeServerActivity.this,
+                            resourceDetailsList, R.layout.resource_multi_line,
+                            new String[]{"line1", "line2", "line3", "line4"},
+                            new int[]{R.id.line_1, R.id.line_2, R.id.line_3, R.id.line_4});
+
+                    resourceDetailsListView.setAdapter(resourceDetailsAdapter);
+                    resourceDetailsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                        @Override
+                        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                            // TODO :
+                            Log.d(TAG, "resourceDetailsListView clicked!!");
+                        }
+                    });
+                    resourceDialogBuilder.setView(resourceDetailsListView);
+
+                    ResourceDetailsHelper.buildResourceDetails(resource, resourceDetailsList);
+
+
+                    Dialog resourceDialog = resourceDialogBuilder.create();
+                    resourceDialog.show();
+
+
+                } else {
+                    Log.w(TAG, "Resource not found in list");
+                }
+            }
+        };
+
+        resourceItemLongClickListener = new AdapterView.OnItemLongClickListener() {
+            @Override
+            public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
+                // TODO :
+
+                Log.d(TAG, "resourceItemLongClickListener clicked!!");
+                OcRemoteDevice device = null ;
+                if(view.getTag()!=null && view.getTag() instanceof OcRemoteDevice) {
+                    device = (OcRemoteDevice) view.getTag();
+                    Log.d(TAG, "getTag() OcRemoteDevice = " + device.getName());
+                }
+
+                OcRemoteResource resource = resourceArrayAdapter.getItem((int) id);
+                if (resource != null) {
+                    if (Utils.containsList(resource.getTypes(), Light.RT_BINARYSWITCH) ||   // Light Switch(Switch Binary) resource and
+                            Utils.containsList(resource.getTypes(), Light.RT_DIMMING)) {    // Dimming Control resource
+
+                        OCEndpoint ep = Utils.getCoapsEndpoint(resource.getEndpoints());
+                        Log.d(TAG, "Get Light Request by Client : Endpoint = " + OcUtils.endpointToString(ep) +", Uri = "+resource.getUri());
+
+                        Light res_light = new Light(device.getName());
+                        GetLightResponseHandler responseHandler = new GetLightResponseHandler(BridgeServerActivity.this, resource, new Light());
+                        OcUtils.doGet(resource.getUri(), ep, null, responseHandler, OCQos.LOW_QOS);
+                    }
+                    else { // Common Get Response
+                        GetCommonResponseHandler responseHandler = new GetCommonResponseHandler(BridgeServerActivity.this, resource);
+                        OcUtils.doGet(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()), null, responseHandler, OCQos.LOW_QOS);
+                    }
+                }
+                return true;
+            }
+        };
+
+        deviceItemClickListener = new AdapterView.OnItemClickListener() {
+            @Override
+            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                final OcRemoteDevice device = deviceArrayAdapter.getItem((int) id);
+                if (device != null) {
+                    AlertDialog.Builder discoverResourcesDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                    discoverResourcesDialogBuilder.setTitle(R.string.discoveredResources);
+
+                    ListView resourceListView = new ListView(BridgeServerActivity.this);
+                    resourceListView.setTag(device); // temporary device on view.setTag
+                    final ArrayList<OcRemoteResource> resourceArrayList = new ArrayList<OcRemoteResource>();
+                    resourceArrayAdapter = new ArrayAdapter(BridgeServerActivity.this, android.R.layout.simple_list_item_1, android.R.id.text1, resourceArrayList) {
+                        @Override
+                        public View getView(int position, View convertView, ViewGroup parent) {
+                            View view = super.getView(position, convertView, parent);
+                            TextView text1 = (TextView) view.findViewById(android.R.id.text1);
+
+                            view.setTag(device);
+                            OcRemoteResource resource = resourceArrayAdapter.getItem(position);
+                            if (resource != null) {
+                                text1.setText(resource.getAnchor() + resource.getUri());
+                            }
+                            return view;
+                        }
+                    };
+                    resourceListView.setAdapter(resourceArrayAdapter);
+                    resourceListView.setOnItemClickListener(resourceItemClickListener);
+                    resourceListView.setOnItemLongClickListener(resourceItemLongClickListener);
+                    discoverResourcesDialogBuilder.setView(resourceListView);
+
+                    resourceArrayAdapter.setNotifyOnChange(false);
+                    for (OcRemoteResource resource : device.getResources()) {
+                        if(Utils.isAccessableByPairwisedClient(resource.getTypes())) {
+                            resourceArrayAdapter.add(resource);
+                        }
+                    }
+                    resourceArrayAdapter.setNotifyOnChange(true);
+                    resourceArrayAdapter.notifyDataSetChanged();
+
+                    Dialog discoverResourcesDialog = discoverResourcesDialogBuilder.create();
+                    discoverResourcesDialog.show();
+
+                } else {
+                    Log.w(TAG, "Uuid not found in list");
+                }
+            }
+        };
+
+        discoverDevicesButton = (Button) findViewById(R.id.discover_devices_button);
+        discoverDevicesButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                deviceArrayAdapter.setNotifyOnChange(false);
+                deviceArrayAdapter.clear();
+                deviceArrayAdapter.setNotifyOnChange(true);
+
+                new Thread(new Runnable() {
+                    public void run() {
+
+                        OCUuid bridge_di = OCCoreRes.getDeviceId(Bridge.BRIDGE_INDEX);
+                        if (!OcUtils.discoverAllDevices(new DeviceDiscoveryHandler(bridgeService, bridge_di))) {
+                            final String msg = "Failed to discover devices";
+                            Log.d(TAG, msg);
+                            runOnUiThread(new Runnable() {
+                                public void run() {
+                                    Toast.makeText(BridgeServerActivity.this, msg, Toast.LENGTH_LONG).show();
+                                }
+                            });
+                        }
+                    }
+                }).start();
+            }
+        });
+
+        deviceArrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_2, android.R.id.text1, deviceList) {
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                View view = super.getView(position, convertView, parent);
+                TextView text1 = (TextView) view.findViewById(android.R.id.text1);
+                TextView text2 = (TextView) view.findViewById(android.R.id.text2);
+
+                OcRemoteDevice device = deviceArrayAdapter.getItem(position);
+                if (device != null) {
+                    text1.setText(OCUuidUtil.uuidToString(device.getDeviceId()));
+                    text2.setText("\t" + device.getName());
+                }
+                return view;
+            }
+        };
+
+        listView = (ListView) findViewById(R.id.list_view);
+        listView.setAdapter(deviceArrayAdapter);
+        listView.setOnItemClickListener(deviceItemClickListener);
+        listView.setFocusable(true);
+        listView.setFocusableInTouchMode(true);
+        listView.setItemsCanFocus(true);
+    }
+
+    public void addDevice(final OcRemoteDevice device) {
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+                synchronized (arrayAdapterSync) {
+                    deviceArrayAdapter.setNotifyOnChange(false);
+                    deviceArrayAdapter.add(device);
+                    deviceArrayAdapter.setNotifyOnChange(true);
+                }
+
+                deviceArrayAdapter.notifyDataSetChanged();
+            }
+        });
+    }
+
+    public void msg(final String text) {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                mConsoleTextView.append("\n");
+                mConsoleTextView.append(text);
+                mScrollView.fullScroll(View.FOCUS_DOWN);
+            }
+        });
+        Log.i(TAG, text);
+    }
+
+    public void printLine() {
+        msg("------------------------------------------------------------------------");
+    }
+
+    public void showErrorDialog(final String title, final String msg) {
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+
+                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                alertDialogBuilder.setTitle(title);
+                alertDialogBuilder.setMessage(msg);
+
+                alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+
+                    }
+                });
+
+                Dialog errorDialog = alertDialogBuilder.create();
+                errorDialog.show();
+            }
+        });
+    }
+
+    public void showResultDialog(final String title, final String msg) {
+
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+
+                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                alertDialogBuilder.setTitle(title);
+                alertDialogBuilder.setMessage(msg);
+
+                alertDialogBuilder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+
+                    }
+                });
+
+                Dialog errorDialog = alertDialogBuilder.create();
+                errorDialog.show();
+            }
+        });
+    }
+
+    public void showPropertiesDialog(final String title, final ArrayList<Pair<String, Object>> props, final OcRemoteResource resource) {
+
+        runOnUiThread(new Runnable() {
+            public void run() {
+
+                AlertDialog.Builder propertyDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                propertyDialogBuilder.setTitle(title);
+
+                ListView propertyDetailsListView = new ListView(BridgeServerActivity.this);
+                final ArrayAdapter propertyArrayAdapter = new ArrayAdapter(BridgeServerActivity.this,
+                        android.R.layout.simple_list_item_1, android.R.id.text1, props) {
+                    @Override
+                    public View getView(int position, View convertView, ViewGroup parent) {
+                        View view = super.getView(position, convertView, parent);
+                        TextView text1 = (TextView) view.findViewById(android.R.id.text1);
+
+
+                        Pair<String, Object> prop = (Pair<String, Object>) this.getItem(position);
+                        if (prop != null) {
+                            text1.setText(prop.first + " = "+ prop.second);
+                        }
+                        return view;
+                    }
+                };
+                propertyDetailsListView.setAdapter(propertyArrayAdapter);
+                propertyDetailsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+                    @Override
+                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+                        // TODO :
+                        Log.d(TAG, "propertyDetailsListView position["+position+"] clicked!!");
+                        final Pair<String, Object> property = (Pair<String, Object>)propertyArrayAdapter.getItem(position);
+                        AlertDialog.Builder postputDialogBuilder = new AlertDialog.Builder(BridgeServerActivity.this);
+                        postputDialogBuilder.setTitle("Post/Put value of " + property.first);
+                        postputDialogBuilder.setMessage("Do you want to change the value of this property \""+property.first+"\" ?");
+
+                        final EditText ed_value = new EditText(BridgeServerActivity.this) ;
+                        ed_value.setText(property.second.toString());
+                        postputDialogBuilder.setView(ed_value);
+                        postputDialogBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                String value = ed_value.getText().toString();
+                                Log.d(TAG, "Edit box value = " + value + ", type = " + property.second);
+
+                                // post/put
+                                OcRemoteDevice device = findRemoteDevice(resource);
+                                Light res_light = new Light(device.getName());
+                                Post2LightResponseHandler putLight = new Post2LightResponseHandler(BridgeServerActivity.this, resource, res_light);
+                                if (OcUtils.initPut(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()), null, putLight, OCQos.LOW_QOS)) {
+                                    OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
+                                    if(property.second instanceof Boolean) {
+                                        Log.d(TAG, "type = " + Boolean.class.toString());
+                                        root.setBoolean(property.first, Boolean.parseBoolean(value));
+                                    } else if(property.second instanceof Integer) {
+                                        Log.d(TAG, "type = " + Integer.class.toString());
+                                        root.setLong(property.first, Integer.parseInt(value));
+                                    } else if(property.second instanceof Long) {
+                                        Log.d(TAG, "type = " + Long.class.toString());
+                                        root.setLong(property.first, Long.parseLong(value));
+                                    } else if(property.second instanceof Double) {
+                                        Log.d(TAG, "type = " + Double.class.toString());
+                                        root.setDouble(property.first, Double.parseDouble(value));
+                                    } else if(property.second instanceof String) {
+                                        Log.d(TAG, "type = " + String.class.toString());
+                                        root.setTextString(property.first, value);
+                                    }
+                                    root.done();
+
+                                    if (OcUtils.doPut()) {
+                                        BridgeServerActivity.this.msg("\tSent Post request");
+                                    } else {
+                                        BridgeServerActivity.this.msg("\tCould not send Post request");
+                                    }
+                                } else {
+                                    BridgeServerActivity.this.msg("\tCould not init Post request");
+                                }
+                                BridgeServerActivity.this.printLine();
+                            }
+                        });
+                        postputDialogBuilder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
+                            @Override
+                            public void onClick(DialogInterface dialog, int which) {
+                                dialog.dismiss();
+                            }
+                        });
+
+                        Dialog postputDialog = postputDialogBuilder.create();
+                        postputDialog.show();
+                    }
+                });
+                propertyDialogBuilder.setView(propertyDetailsListView);
+                propertyDialogBuilder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        dialog.dismiss();
+                    }
+                });
+
+                Dialog propertyDialog = propertyDialogBuilder.create();
+                propertyDialog.show();
+            }
+        });
+
+    }
+
+    private OcRemoteDevice findRemoteDevice(OcRemoteResource current_resource) {
+        for (OcRemoteDevice device : deviceList) {
+            for(OcRemoteResource resource : device.getResources()) {
+                if(resource.equals(current_resource)) return device ;
+            }
+        }
+        return null ;
+    }
+
+}

+ 334 - 0
app/src/main/java/org/iotivity/bridge/homeserver/BridgeService.java

@@ -0,0 +1,334 @@
+package org.iotivity.bridge.homeserver;
+
+import android.app.AlarmManager;
+import android.app.IntentService;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.support.annotation.Nullable;
+import android.support.v4.app.NotificationCompat;
+import android.util.Log;
+import android.widget.Toast;
+
+
+import org.iotivity.OCCoreRes;
+import org.iotivity.OCUuid;
+import org.iotivity.bridge.homeserver.handler.client.DeviceDiscoveryHandler;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcUtils;
+
+import java.util.Calendar;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+public class BridgeService extends IntentService {
+
+    public static final String TAG = BridgeService.class.getName();
+
+    public static Intent serviceIntent = null ;
+    private final IBinder binder = new LocalServiceBinder();
+    private BridgeServer bridgeServer = null ;
+
+    private ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+
+    // IRemoteService MSG TYPEs
+    public static final int MSG_REPORT = 1 ;
+    public static final int MSG_STRING = 2;
+    public static final int MSG_LINE = 3;
+    public static final int MSG_DEVICE_DISCOVERED = 4 ;
+
+    final RemoteCallbackList<IRemoteServiceCallback> mCallbacks
+            = new RemoteCallbackList<IRemoteServiceCallback>();
+
+    public BridgeService() {
+        super(BridgeService.class.getName());
+    }
+
+    private BridgeService getService() {
+        return this ;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+
+        Log.d(TAG, "onCreate()");
+        // start first time only
+        bridgeServer = new BridgeServer(this);
+
+        scheduledTaskInit();
+    }
+
+    /*
+     * BridgeService can be binded with Local Activity and Remote Application
+     * through RemoteInterface and ServiceBinder
+     */
+    @Override
+    public IBinder onBind(Intent intent) {
+
+        Log.d(TAG, "onBind() action = " + intent.getAction());
+        if (IRemoteService.class.getName().equals(intent.getAction())) {
+            return mBinder;
+        }
+        return binder;
+    }
+
+    /*
+     * This is to bind Local Activity like Local Service
+     */
+    public class LocalServiceBinder extends Binder {
+        public BridgeService getService() {
+            return BridgeService.this ;
+        }
+
+        public int getPid() {
+            return Process.myPid();
+        }
+    }
+
+    /**
+     * The IRemoteInterface is defined through IDL
+     */
+    private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
+        public void registerCallback(IRemoteServiceCallback cb) {
+            if (cb != null) mCallbacks.register(cb);
+
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_STRING, "Remote Client Callback was registered."));
+            mHandler.sendEmptyMessage(MSG_LINE);
+
+        }
+        public void unregisterCallback(IRemoteServiceCallback cb) {
+            if (cb != null) mCallbacks.unregister(cb);
+        }
+
+        @Override
+        public int getPid() throws RemoteException {
+            return Process.myPid();
+        }
+
+    };
+
+    private final Handler mHandler = new Handler() {
+        @Override public void handleMessage(Message msg) {
+            switch (msg.what) {
+
+                case MSG_LINE: {
+
+                    // Broadcast to all clients the new value.
+                    final int N = mCallbacks.beginBroadcast();
+                    for (int i=0; i<N; i++) {
+                        try {
+                            mCallbacks.getBroadcastItem(i).lineMessageNotified();
+                        } catch (RemoteException e) {
+                            // The RemoteCallbackList will take care of removing
+                            // the dead object for us.
+                            Log.e(TAG, "RemoteException :", e);
+                        }
+                    }
+                    mCallbacks.finishBroadcast();
+
+                } break;
+                case MSG_STRING : {
+                    // Broadcast to all clients the new value.
+                    final int N = mCallbacks.beginBroadcast();
+                    for (int i=0; i<N; i++) {
+                        try {
+                            mCallbacks.getBroadcastItem(i).messageNotified((String)msg.obj);
+                        } catch (RemoteException e) {
+                            // The RemoteCallbackList will take care of removing
+                            // the dead object for us.
+                            Log.e(TAG, "RemoteException :", e);
+                        }
+                    }
+                    mCallbacks.finishBroadcast();
+                } break ;
+                case MSG_DEVICE_DISCOVERED: {
+                    // Broadcast to all clients the new value.
+                    final int N = mCallbacks.beginBroadcast();
+                    for (int i=0; i<N; i++) {
+                        try {
+                            mCallbacks.getBroadcastItem(i).addDeviceNotified();
+                        } catch (RemoteException e) {
+                            // The RemoteCallbackList will take care of removing
+                            // the dead object for us.
+                            Log.e(TAG, "RemoteException :", e);
+                        }
+                    }
+                    mCallbacks.finishBroadcast();
+                } break ;
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    };
+
+    public void msg(String msg) {
+        mHandler.sendMessage(mHandler.obtainMessage(MSG_STRING, msg));
+    }
+
+    public void printLine() {
+        mHandler.sendEmptyMessage(MSG_LINE);
+    }
+
+    @Override
+    protected void onHandleIntent(@Nullable Intent intent) {
+
+        Log.d(TAG, "onHandleIntent() intent=" + intent.getAction());
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+
+        Log.d(TAG, "onStartCommand() intent=" + intent.getAction());
+        serviceIntent = intent ;
+
+        initializeNotification();
+
+        return START_STICKY;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        Log.d(TAG, "onDestroy()");
+
+        Log.d(TAG, "Calling Bridge Shutdown.");
+        bridgeServer.shutdown();
+
+        // Unregister all callbacks.
+        mCallbacks.kill();
+
+        // Remove the next pending message to increment the counter, stopping
+        // the increment loop.
+        mHandler.removeMessages(MSG_REPORT);
+
+        // Bridge Service and Application Process Kill
+        // android.os.Process.killProcess(Process.myPid());
+        // or below action
+        Log.d(TAG, "System.exit() will be called");
+        System.runFinalizersOnExit(true);
+        System.exit(0);
+    }
+
+    @Override
+    public void onTaskRemoved(Intent rootIntent) {
+        super.onTaskRemoved(rootIntent);
+
+        Log.d(TAG, "onTaskRemoved()");
+
+        this.restartServiceByAlarmManager();
+    }
+
+    @Override
+    public void onStart(@Nullable Intent intent, int startId) {
+        super.onStart(intent, startId);
+        Log.d(TAG, "Bridge Service onStart()");
+    }
+
+    @Override
+    public boolean onUnbind(Intent intent) {
+        Log.d(TAG, "Bridge Service onUnbind()");
+
+        return super.onUnbind(intent);
+    }
+
+    private void initializeNotification() {
+
+        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "1");
+        builder.setSmallIcon(R.mipmap.ic_launcher);
+        NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
+        style.bigText("Press this to see settings.");
+        style.setBigContentTitle(null);
+        style.setSummaryText("Bridge Service is Running.");
+        builder.setContentText(null);
+        builder.setContentTitle(null);
+        builder.setOngoing(true);
+        builder.setStyle(style);
+        builder.setWhen(0);
+        builder.setShowWhen(false);
+
+        Intent notificationIntent = new Intent(this, BridgeServerActivity.class);
+        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+        builder.setContentIntent(pendingIntent);
+
+        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            manager.createNotificationChannel(new NotificationChannel("1", "bridge_service", NotificationManager.IMPORTANCE_NONE));
+        }
+        Notification notification = builder.build();
+        startForeground(1, notification);
+    }
+
+
+    /* Becuase stopSrvice() on Destroy() will kill all application process of service, activity clearly
+     * Do not use this function for undead foreground service. It's not meaningful */
+    private void restartServiceByAlarmManager() {
+
+        final Calendar calendar = Calendar.getInstance();
+        calendar.setTimeInMillis(System.currentTimeMillis());
+        calendar.add(Calendar.SECOND, 3);
+        Intent intent = new Intent(this, AlarmReceiver.class);
+        PendingIntent sender = PendingIntent.getBroadcast(this, 0,intent,0);
+        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
+        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
+    }
+
+    public BridgeServer getBridgeServer() {
+        return bridgeServer ;
+    }
+
+    public void scheduledTaskInit () {
+
+        // How to use ExecuterService like followings
+        // executorService.schedule(Classname::someTask, delayInSeconds, TimeUnit.SECONDS);                 // once after a delay
+        // executorService.scheduleAtFixedRate(Classname::someTask, 0, delayInSeconds, TimeUnit.SECONDS);   // at fixed time interval
+        executorService.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+                clearAllPairwisedDevices();
+                OCUuid bridge_di = OCCoreRes.getDeviceId(Bridge.BRIDGE_INDEX);
+                if (!OcUtils.discoverAllDevices(new DeviceDiscoveryHandler(getService(), bridge_di))) {
+                    final String msg = "Failed to discover devices";
+                    Log.d(TAG, msg);
+                }
+                Log.d(TAG, "DeviceDiscovery ScheduledTask per 60sec was called.");
+            }
+        }, 10, 60, TimeUnit.SECONDS); // 60sec interval after 10sec delay
+
+/*
+        executorService.scheduleAtFixedRate(new Runnable() {
+            @Override
+            public void run() {
+                // TODO
+            }
+        }, 30, 30, TimeUnit.SECONDS); // 30sec interval after 30sec delay
+*/
+    }
+
+    public void clearAllPairwisedDevices() {
+        if(bridgeServer!=null) {
+            bridgeServer.clearAllPairwisedDevices();
+        }
+    }
+
+    public void addPairwisedDevice(OcRemoteDevice device) {
+        if(bridgeServer!=null) {
+            bridgeServer.addOrReplacePairwisedDevice(device);
+            mHandler.sendEmptyMessage(MSG_DEVICE_DISCOVERED);
+        }
+    }
+}

+ 123 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/BridgeInitHandler.java

@@ -0,0 +1,123 @@
+package org.iotivity.bridge.homeserver.handler;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.iotivity.OCAddDeviceHandler;
+import org.iotivity.OCBridge;
+import org.iotivity.OCCoreRes;
+import org.iotivity.OCDeviceInfo;
+import org.iotivity.OCIntrospection;
+import org.iotivity.OCMain;
+import org.iotivity.OCMainInitHandler;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcPlatform;
+import org.iotivity.oc.OcUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class BridgeInitHandler implements OCMainInitHandler {
+
+    private static final String TAG = BridgeInitHandler.class.getSimpleName();
+
+    private BridgeService service;
+    private OcPlatform ocPlatform;
+    private Bridge bridge;
+
+    public BridgeInitHandler(BridgeService service, OcPlatform ocPlatform, Bridge modeldata) {
+        this.service = service;
+        this.ocPlatform = ocPlatform;
+        this.bridge = modeldata ;
+    }
+
+    @Override
+    public int initialize() {
+        Log.d(TAG, "inside BridgeInitHandler.initialize()");
+        int ret = ocPlatform.platformInit(Bridge.PLATFORM_MFG_NAME);
+        if (ret >= 0) {
+            // Create the devices and add them to the platform
+            ret = OCBridge.addBridgeDevice(bridge.getName(), "ocf.2.0.0", "ocf.res.1.3.0,ocf.sh.1.3.0");
+            /*, new OCAddDeviceHandler() {
+                        public void handler() {
+                            Log.d(TAG, "inside OcBridge.OCAddDeviceHandler.handler()");
+                        }
+                    });*/
+        } else {
+            Log.e(TAG, "Error in platformInit, return value = " + ret);
+        }
+
+        OcUtils.setRandomPinHandler(new RandomPinHandler(service));
+        return ret;
+    }
+
+    @Override
+    public void registerResources() {
+        Log.d(TAG, "inside BridgeInitHandler.registerResources()");
+
+        byte[] idd_bytes = getFileBytes("idds/bridge_device_IDD.cbor") ; // example : "dummy_bridge_bridge_device_IDD.cbor"
+        OCIntrospection.setIntrospectionData(Bridge.BRIDGE_INDEX, idd_bytes);
+
+
+    }
+
+    @Override
+    public void requestEntry() {
+        Log.d(TAG, "inside BridgeInitHandler.requestEntry()");
+
+        OCDeviceInfo info = OCCoreRes.getDeviceInfo(Bridge.BRIDGE_INDEX);
+        if(info != null) {
+            Log.d(TAG, "Bridge DeviceId = " + OCUuidUtil.uuidToString(info.getDi()) + ", Name = " + info.getName());
+            bridge.setDeviceId(OCUuidUtil.uuidToString(info.getDi())); ;
+
+            // set immutable device id for Platform Independent Identifier (piid)
+            // OCMain.setImmutableDeviceIdentifier(Bridge.BRIDGE_INDEX, info.getDi());
+        }
+    }
+
+    private byte[] getFileBytes(String filepath) {
+
+        ByteArrayOutputStream baos = null;
+        try {
+            InputStream is = service.getAssets().open(filepath);
+            Log.d(TAG, "reading file " + filepath);
+
+            try {
+                byte[] buffer = new byte[8192];
+                baos = new ByteArrayOutputStream();
+                int length = 0;
+                while ((length = is.read(buffer)) != -1) {
+                    Log.d(TAG, "bytes read = " + length);
+                    baos.write(buffer, 0, length);
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error reading file " + filepath);
+            } finally {
+                try {
+                    if (baos != null) {
+                        baos.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+                try {
+                    if (is != null) {
+                        is.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to read " + filepath);
+        }
+
+        return ((baos != null) ? baos.toByteArray() : null);
+    }
+}

+ 136 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/FactoryPresetsHandler.java

@@ -0,0 +1,136 @@
+package org.iotivity.bridge.homeserver.handler;
+
+import android.content.Context;
+import android.util.Log;
+
+import org.iotivity.OCFactoryPresetsHandler;
+import org.iotivity.OCPki;
+import org.iotivity.OCSpTypesMask;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.utils.Utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class FactoryPresetsHandler implements OCFactoryPresetsHandler {
+
+    private static final String TAG = FactoryPresetsHandler.class.getSimpleName();
+
+    private BridgeService service;
+
+    public FactoryPresetsHandler(BridgeService service) {
+        this.service = service;
+    }
+
+    @Override
+    public void handler(long deviceIndex) {
+        Log.d(TAG, "inside the FactoryPresetsHandler, deviceIndex  = " + deviceIndex);
+
+        // TODO : when attempting to add an identity certificate chain, could not parse identity cert's private key
+
+        boolean isMfgCertSupport = true;
+        if (isMfgCertSupport && deviceIndex != 0)
+            return; // TODO : Only Bridge will use pki certs in this case
+
+        //setPKISecurityMfgCert(deviceIndex);
+    }
+
+    private void setPKISecurityMfgCert(long deviceIndex) {
+        // load Root CA
+        byte[] rootCa = getFileBytes("pki_certs/rootca1.pem");
+        if (rootCa == null) {
+            Log.e(TAG, "Failed to read root ca cetificate");
+            return;
+        }
+        // add Root CA
+        int rootCaCredId = OCPki.addMfgTrustAnchor(deviceIndex, rootCa);
+        Log.d(TAG, "addMfgTrustAnchor() result = " + rootCaCredId);
+        if (rootCaCredId < 0) {
+            Log.e(TAG, "Error installing root ca certificate");
+            return;
+        }
+
+        // load End Endtity cert
+        byte[] cert = getFileBytes("pki_certs/ee.pem");
+        if (cert == null) {
+            Log.e(TAG, "Failed to read certificates");
+            return;
+        }
+
+        // load End Endtity private key
+        byte[] key = getFileBytes("pki_certs/key.pem");
+        if (key == null) {
+            Log.e(TAG, "Failed to read private key");
+            return;
+        }
+
+        // add End Entity Cert
+        int eeCredId = OCPki.addMfgCert(deviceIndex, cert, key);
+        Log.d(TAG, "addMfgCert() credId = " + eeCredId);
+        if (eeCredId < 0) {
+            Log.e(TAG, "Error installing manufacturer ee certificate");
+            return;
+        }
+
+        // load Sub CA
+        byte[] subCa = getFileBytes("pki_certs/subca1.pem");
+        if (subCa == null) {
+            Log.e(TAG, "Failed to read sub ca cetificate");
+            return;
+        }
+        // add Sub CA
+        int subCaCredId = OCPki.addMfgIntermediateCert(deviceIndex, eeCredId, subCa);
+        Log.d(TAG, "addMfgIntermediateCert() result = " + subCaCredId);
+        if (subCaCredId < 0) {
+            Log.e(TAG, "Error installing intermediate ca certificate");
+            return;
+        }
+
+        OCPki.setSecurityProfile(deviceIndex, OCSpTypesMask.BLACK, OCSpTypesMask.BLACK, eeCredId);
+        Log.d(TAG, "setSecurityProfile()");
+
+    }
+
+    private byte[] getFileBytes(String filepath) {
+
+        ByteArrayOutputStream baos = null;
+        try {
+            InputStream is = service.getAssets().open(filepath);
+            Log.d(TAG, "reading file " + filepath);
+
+            try {
+                byte[] buffer = new byte[8192];
+                baos = new ByteArrayOutputStream();
+                int length = 0;
+                while ((length = is.read(buffer)) != -1) {
+                    Log.d(TAG, "bytes read = " + length);
+                    baos.write(buffer, 0, length);
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Error reading file " + filepath);
+            } finally {
+                try {
+                    if (baos != null) {
+                        baos.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+                try {
+                    if (is != null) {
+                        is.close();
+                    }
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to read " + filepath);
+        }
+
+        return ((baos != null) ? baos.toByteArray() : null);
+    }
+}

+ 25 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/RandomPinHandler.java

@@ -0,0 +1,25 @@
+package org.iotivity.bridge.homeserver.handler;
+
+import android.util.Log;
+
+import org.iotivity.OCRandomPinHandler;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.BridgeService;
+
+public class RandomPinHandler implements OCRandomPinHandler {
+
+    private static final String TAG = RandomPinHandler.class.getSimpleName();
+
+    private BridgeService service;
+
+    public RandomPinHandler(BridgeService service) {
+        this.service = service;
+    }
+
+    @Override
+    public void handler(String pin) {
+        Log.d(TAG, "inside Random Pin Handler");
+        service.msg("\n!!!!!!!!!!!!!!!!!!!!\nRandom PIN: " + pin + "\n!!!!!!!!!!!!!!!!!!!!\n");
+        service.printLine();
+    }
+}

+ 49 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/DeviceDiscoveryHandler.java

@@ -0,0 +1,49 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+
+import org.iotivity.OCQos;
+import org.iotivity.OCUuid;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcDeviceDiscoveryHandler;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+public class DeviceDiscoveryHandler implements OcDeviceDiscoveryHandler {
+
+    private static final String TAG = DeviceDiscoveryHandler.class.getSimpleName();
+
+    private BridgeService service;
+    private OCUuid self_di  ;
+
+    public DeviceDiscoveryHandler(BridgeService service, OCUuid self_di) {
+        this.service = service;
+        this.self_di = self_di ;
+    }
+
+    @Override
+    public void discoveredDevice(OcRemoteDevice remoteDevice) {
+        Log.d(TAG, "Remote Device Discovery Handler: " + OCUuidUtil.uuidToString(remoteDevice.getDeviceId()) + ", " + remoteDevice.getName());
+
+        // Only paried devices except Bridge itself or OBT will be added in the pairwised device list
+        if(!OCUuidUtil.isEqual(remoteDevice.getDeviceId(), self_di) && !Utils.isObt(remoteDevice)) {
+
+
+            /* check if the device is accessible via coaps get /oic/d or not
+             * because no pairwised client can get STATUS_OK
+            */
+            OcRemoteResource[] resources = remoteDevice.getResources();
+            for(OcRemoteResource resource : resources) {
+                if(Utils.containsList(resource.getTypes(), "oic.wk.d")){//GetDoxmResponseHandler.RT_DOXM)) {
+                    GetDeviceAccessCheckResponseHandler responseHandler = new GetDeviceAccessCheckResponseHandler(service, remoteDevice, resource);
+                    OcUtils.doGet(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()), null, responseHandler, OCQos.LOW_QOS);
+                }
+            }
+        }
+
+    }
+}

+ 185 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetCommonResponseHandler.java

@@ -0,0 +1,185 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+import android.util.Pair;
+
+import org.iotivity.OCArray;
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCRep;
+import org.iotivity.OCRepresentation;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcRemoteResource;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class GetCommonResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = GetCommonResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private OcRemoteResource resource ;
+
+    public GetCommonResponseHandler(BridgeServerActivity activity, OcRemoteResource resource) {
+        this.activity = activity ;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("Get "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_OK) {
+            activity.showErrorDialog("Get "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        final ArrayList<Pair<String, Object>> props = new ArrayList<>();
+        OCRepresentation rep = response.getPayload();
+        while (rep != null) {
+            activity.msg("\t" + "Type" + " = " + rep.getType().name());
+            switch (rep.getType()) {
+                case OC_REP_BOOL:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
+                    props.add(new Pair(rep.getName(), rep.getValue().getBool()));
+                    break;
+                case OC_REP_INT:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getInteger());
+                    props.add(new Pair(rep.getName(), rep.getValue().getInteger()));
+                    break;
+                case OC_REP_STRING:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
+                    props.add(new Pair(rep.getName(), rep.getValue().getString()));
+                    break;
+                case OC_REP_DOUBLE:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getDouble());
+                    props.add(new Pair(rep.getName(), rep.getValue().getDouble()));
+                    break;
+                case OC_REP_STRING_ARRAY:
+                    String[] str_arr = OCRep.ocArrayToStringArray(rep.getValue().getArray());
+                    String str_strs = Utils.toString(str_arr);
+                    activity.msg("\t" + rep.getName() + " = " + str_strs);
+                    props.add(new Pair(rep.getName(), str_strs));
+                    break ;
+                case OC_REP_BOOL_ARRAY:
+                    boolean[] bool_arr = OCRep.ocArrayToBooleanArray(rep.getValue().getArray());
+                    String bool_strs = Utils.toString(bool_arr);
+                    activity.msg("\t" + rep.getName() + " = " + bool_strs);
+                    props.add(new Pair(rep.getName(), bool_strs));
+                    break;
+                case OC_REP_INT_ARRAY:
+                    long[] long_arr = OCRep.ocArrayToLongArray(rep.getValue().getArray());
+                    String long_strs = Utils.toString(long_arr);
+                    activity.msg("\t" + rep.getName() + " = " + long_strs);
+                    props.add(new Pair(rep.getName(), long_strs));
+                    break;
+                case OC_REP_DOUBLE_ARRAY:
+                    double[] double_arr = OCRep.ocArrayToDoubleArray(rep.getValue().getArray());
+                    String double_strs = Utils.toString(double_arr);
+                    activity.msg("\t" + rep.getName() + " = " + double_strs);
+                    props.add(new Pair(rep.getName(), double_strs));
+                    break;
+                case OC_REP_OBJECT:
+                    {
+                        OCRepresentation object = rep.getValue().getObject();
+                        StringBuffer sb = new StringBuffer();
+                        sb.append("{");
+                        while (object != null) {
+                            switch (object.getType()) {
+                                case OC_REP_STRING:
+                                    sb.append(object.getName() + " = " + object.getValue().getString());
+                                    break;
+                                default:
+                                    break;
+                            }
+                            object = object.getNext();
+                            if (object != null) sb.append(", ");
+                        }
+                        sb.append("}");
+                        activity.msg("\t" + rep.getName() + " = " + sb.toString());
+                        props.add(new Pair(rep.getName(), sb.toString()));
+                    }
+                    break;
+                case OC_REP_OBJECT_ARRAY:
+                    {
+                        OCRepresentation array = rep.getValue().getObject();
+                        StringBuffer sb = new StringBuffer();
+                        sb.append("[");
+                        while (array != null) {
+                            activity.msg("\t" + "OC_REP_OBJECT_ARRAY Type" + " = " + array.getType().name());
+                            switch (array.getType()) {
+                                case OC_REP_OBJECT: {
+                                    OCRepresentation object = array.getValue().getObject();
+                                    sb.append("{");
+                                    while (object != null) {
+                                        activity.msg("\t" + "OC_REP_OBJECT Type" + " = " + object.getType().name());
+                                        switch (object.getType()) {
+                                            case OC_REP_STRING:
+                                                sb.append(object.getName() + " = " + object.getValue().getString());
+                                                break;
+                                            case OC_REP_BOOL:
+                                                sb.append(object.getName() + " = " + object.getValue().getBool());
+                                                break;
+                                            case OC_REP_INT:
+                                                sb.append(object.getName() + " = " + object.getValue().getInteger());
+                                                break;
+                                            case OC_REP_DOUBLE:
+                                                sb.append(object.getName() + " = " + object.getValue().getDouble());
+                                                break;
+                                            case OC_REP_STRING_ARRAY:
+                                                activity.msg("\tarray size = " + OCRep.ocArrayToStringArray(rep.getValue().getArray()).length);
+
+                                                sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToStringArray(rep.getValue().getArray())));
+                                                break;
+                                            case OC_REP_INT_ARRAY:
+                                                sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToLongArray(rep.getValue().getArray())));
+                                                break;
+                                            case OC_REP_DOUBLE_ARRAY:
+                                                sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToDoubleArray(rep.getValue().getArray())));
+                                                break;
+                                            case OC_REP_BOOL_ARRAY:
+                                                sb.append(object.getName() + " = " + Arrays.toString(OCRep.ocArrayToBooleanArray(rep.getValue().getArray())));
+                                                break;
+                                            default:
+                                                break;
+                                        }
+                                        object = object.getNext();
+                                        if (object != null) sb.append(", ");
+                                    }
+                                    sb.append("}");
+                                }
+                                    break;
+                                default:
+                                    break;
+                            }
+                            array = array.getNext();
+                            if (array != null) sb.append(", ");
+                        }
+                        sb.append("]");
+                        activity.msg("\t" + rep.getName() + " = " + sb.toString());
+                        props.add(new Pair(rep.getName(), sb.toString()));
+                    }
+                    break;
+                default:
+                    break;
+            }
+            rep = rep.getNext();
+        }
+        activity.printLine();
+
+        if(resource.getInterfaceMask() == OCInterfaceMask.RW ||
+                resource.getInterfaceMask() == OCInterfaceMask.A) {
+            activity.showPropertiesDialog( "Properties of " + this.resource.getUri(), props, resource);
+            Log.d(TAG, "Properties : " + Utils.propertiesToString(props));
+        } else {
+            activity.showResultDialog("Get " + resource.getUri() + " Response Handler Result",
+                    "Result Code = " + response.getCode().toString() +"\n\n"+ Utils.propertiesToString(props));
+            Log.d(TAG, "Properties : " + Utils.propertiesToString(props));
+        }
+    }
+}

+ 77 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetDeviceAccessCheckResponseHandler.java

@@ -0,0 +1,77 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+import android.util.Pair;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCRepresentation;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.OCUuidUtil;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcRemoteResource;
+
+import java.util.ArrayList;
+
+public class GetDeviceAccessCheckResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = GetDeviceAccessCheckResponseHandler.class.getSimpleName();
+
+
+    private BridgeService service ;
+    private OcRemoteResource resource ;
+    private OcRemoteDevice device ;
+
+    public GetDeviceAccessCheckResponseHandler(BridgeService service, OcRemoteDevice device, OcRemoteResource resource) {
+        this.service = service ;
+        this.device = device ;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+
+        service.msg("Get "+resource.getUri()+" of "+device.getName()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_OK) {
+            service.msg("Get "+resource.getUri()+" Response Handler Error");
+            service.printLine();
+            return;
+        }
+
+        Log.d(TAG, "Remote Device Access Check Handler is STATUS_OK: " + OCUuidUtil.uuidToString(device.getDeviceId()) + ", " + device.getName());
+
+        final ArrayList<Pair<String, Object>> props = new ArrayList<>();
+        OCRepresentation rep = response.getPayload();
+        while (rep != null) {
+            switch (rep.getType()) {
+                case OC_REP_BOOL:
+                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
+                    props.add(new Pair(rep.getName(), rep.getValue().getBool()));
+                    break;
+                case OC_REP_INT:
+                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getInteger());
+                    props.add(new Pair(rep.getName(), rep.getValue().getInteger()));
+                    break;
+                case OC_REP_STRING:
+                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
+                    props.add(new Pair(rep.getName(), rep.getValue().getString()));
+                    break;
+                case OC_REP_DOUBLE:
+                    service.msg("\t" + rep.getName() + " = " + rep.getValue().getDouble());
+                    props.add(new Pair(rep.getName(), rep.getValue().getDouble()));
+                    break;
+                default:
+                    break;
+            }
+            rep = rep.getNext();
+        }
+        service.printLine();
+        Log.d(TAG, "Properties : " + Utils.propertiesToString(props));
+
+        service.addPairwisedDevice(device);
+
+    }
+}

+ 95 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetLight2ResponseHandler.java

@@ -0,0 +1,95 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+import android.util.Pair;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCQos;
+import org.iotivity.OCRepresentation;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+
+public class GetLight2ResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = GetLight2ResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public GetLight2ResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("Get "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_OK) {
+            activity.showErrorDialog("Get "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        final ArrayList<Pair<String, Object>> props = new ArrayList<>();
+
+        OCRepresentation rep = response.getPayload();
+        while (rep != null) {
+            switch (rep.getType()) {
+                case OC_REP_BOOL:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
+                    props.add(new Pair(rep.getName(), rep.getValue().getBool()));
+                    if(Light.SWITCH_KEY.equals(rep.getName())) {
+                        light.setSwitchOn(rep.getValue().getBool());
+                    }
+                    break;
+                case OC_REP_INT:
+                    activity.msg("\t" + rep.getName() + "= " + rep.getValue().getInteger());
+                    props.add(new Pair(rep.getName(), rep.getValue().getInteger()));
+                    if(Light.DIMMING_SETTING_KEY.equals(rep.getName())) {
+                        light.setDimmingLevel((int)rep.getValue().getInteger());
+                    } else if(Light.DIMMING_RANGE_KEY.equals(rep.getName())) {
+                        light.setDimmingRange((int) rep.getValue().getInteger());
+                    } else if(Light.DIMMING_STEP_KEY.equals(rep.getName())) {
+                        light.setDimmingStep((int) rep.getValue().getInteger());
+                    }
+                        break;
+                case OC_REP_STRING:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
+                    props.add(new Pair(rep.getName(), rep.getValue().getString()));
+                    if(Light.URI_LIGHT.equalsIgnoreCase(resource.getUri())) {
+                        light.setLightResourceName(rep.getValue().getString());
+                    } else if(Light.URI_DIMMING.equalsIgnoreCase(resource.getUri())) {
+                        light.setDimmingResourceName(rep.getValue().getString());
+                    }
+                    break;
+                default:
+                    break;
+            }
+            rep = rep.getNext();
+        }
+
+        activity.printLine();
+        activity.showPropertiesDialog( "Properties of " + this.resource.getUri(), props, resource);
+        Log.d(TAG, "Properties : " + Utils.propertiesToString(props));
+
+
+        // TODO : Check if Temporary Observe is suitable or not
+        ObserveLightResponseHandler observerLight = new ObserveLightResponseHandler(activity, resource, light);
+        OcUtils.doObserve(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()), null, observerLight, OCQos.LOW_QOS);
+        StopObserveTriggerHandler stopObserve = new StopObserveTriggerHandler(activity, resource, light);
+        OcUtils.setDelayedHandler(stopObserve, 30);
+        activity.msg("Sent OBSERVE request");
+        activity.printLine();
+
+    }
+}

+ 90 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/GetLightResponseHandler.java

@@ -0,0 +1,90 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+import android.util.Pair;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCQos;
+import org.iotivity.OCRepresentation;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcResource;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Random;
+
+public class GetLightResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = GetLightResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public GetLightResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("Get "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_OK) {
+            activity.showErrorDialog("Get "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        final ArrayList<Pair<String, Object>> props = new ArrayList<>();
+
+        OCRepresentation rep = response.getPayload();
+        while (rep != null) {
+            switch (rep.getType()) {
+                case OC_REP_BOOL:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
+                    props.add(new Pair(rep.getName(), rep.getValue().getBool()));
+                    if(Light.SWITCH_KEY.equals(rep.getName())) {
+                        light.setSwitchOn(rep.getValue().getBool());
+                    }
+                    break;
+                case OC_REP_INT:
+                    activity.msg("\t" + rep.getName() + "= " + rep.getValue().getInteger());
+                    props.add(new Pair(rep.getName(), rep.getValue().getInteger()));
+                    if(Light.DIMMING_SETTING_KEY.equals(rep.getName())) {
+                        light.setDimmingLevel((int)rep.getValue().getInteger());
+                    } else if(Light.DIMMING_RANGE_KEY.equals(rep.getName())) {
+                        light.setDimmingRange((int) rep.getValue().getInteger());
+                    } else if(Light.DIMMING_STEP_KEY.equals(rep.getName())) {
+                        light.setDimmingStep((int) rep.getValue().getInteger());
+                    }
+                        break;
+                case OC_REP_STRING:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
+                    props.add(new Pair(rep.getName(), rep.getValue().getString()));
+                    if(Light.URI_LIGHT.equalsIgnoreCase(resource.getUri())) {
+                        light.setLightResourceName(rep.getValue().getString());
+                    } else if(Light.URI_DIMMING.equalsIgnoreCase(resource.getUri())) {
+                        light.setDimmingResourceName(rep.getValue().getString());
+                    }
+                    break;
+                default:
+                    break;
+            }
+            rep = rep.getNext();
+        }
+
+        activity.printLine();
+        activity.showPropertiesDialog( "Properties of " + this.resource.getUri(), props, resource);
+        Log.d(TAG, "Properties : " + Utils.propertiesToString(props));
+
+    }
+}

+ 62 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/ObserveLightResponseHandler.java

@@ -0,0 +1,62 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCRepresentation;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.bridge.homeserver.BridgeServer;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.oc.OcRemoteResource;
+
+public class ObserveLightResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = ObserveLightResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public ObserveLightResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("OBSERVER Light:");
+        OCRepresentation rep = response.getPayload();
+        while (rep != null) {
+            switch (rep.getType()) {
+                case OC_REP_BOOL:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getBool());
+                    if(Light.SWITCH_KEY.equals(rep.getName())) {
+                        light.setSwitchOn(rep.getValue().getBool());
+                    }
+                    break;
+                case OC_REP_INT:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getInteger());
+                    if(Light.DIMMING_SETTING_KEY.equals(rep.getName())) {
+                        light.setDimmingLevel((int)rep.getValue().getInteger());
+                    } else if(Light.DIMMING_RANGE_KEY.equals(rep.getName())) {
+                        light.setDimmingRange((int) rep.getValue().getInteger());
+                    } else if(Light.DIMMING_STEP_KEY.equals(rep.getName())) {
+                        light.setDimmingStep((int) rep.getValue().getInteger());
+                    }
+                    break;
+                case OC_REP_STRING:
+                    activity.msg("\t" + rep.getName() + " = " + rep.getValue().getString());
+                    if(Light.URI_LIGHT.equals(resource.getUri())) {
+                        light.setLightResourceName(rep.getValue().getString());
+                    } else if(Light.URI_DIMMING.equals(resource.getUri())) {
+                        light.setDimmingResourceName(rep.getValue().getString());
+                    }
+                    break;
+                default:
+                    break;
+            }
+            rep = rep.getNext();
+        }
+        activity.printLine();
+    }
+}

+ 58 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/Post2LightResponseHandler.java

@@ -0,0 +1,58 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCQos;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+public class Post2LightResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = Post2LightResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public Post2LightResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+
+        activity.msg("POST2 "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_CHANGED && response.getCode() != OCStatus.OC_STATUS_CREATED) {
+            activity.showErrorDialog("POST2 "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        /*if (response.getCode() == OCStatus.OC_STATUS_CHANGED) {
+            activity.msg("\tPOST2 response: CHANGED");
+        } else if (response.getCode() == OCStatus.OC_STATUS_CREATED) {
+            activity.msg("\tPOST2 response: CREATED");
+        } else {
+            activity.msg("\tPOST2 response code " + response.getCode().toString() + " (" + response.getCode() + ")");
+        }*/
+        activity.printLine();
+        activity.showResultDialog("POST2 "+resource.getUri()+" Response Handler Result",
+                "Result Code = " + response.getCode().toString());
+
+
+        // Observe the response of Post Request
+        ObserveLightResponseHandler observerLight = new ObserveLightResponseHandler(activity, resource, light);
+        OcUtils.doObserve(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()), null, observerLight, OCQos.LOW_QOS);
+        StopObserveTriggerHandler stopObserve = new StopObserveTriggerHandler(activity, resource, light);
+        OcUtils.setDelayedHandler(stopObserve, 30);
+        activity.msg("Sent OBSERVE request");
+        activity.printLine();
+    }
+}

+ 68 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/PostLightResponseHandler.java

@@ -0,0 +1,68 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCQos;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+public class PostLightResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = PostLightResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public PostLightResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("POST "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_CHANGED && response.getCode() != OCStatus.OC_STATUS_CREATED) {
+            activity.showErrorDialog("POST "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        /*if (response.getCode() == OCStatus.OC_STATUS_CHANGED) {
+            activity.msg("\tPOST response: CHANGED");
+        } else if (response.getCode() == OCStatus.OC_STATUS_CREATED) {
+            activity.msg("\tPOST response: CREATED");
+        } else {
+            activity.msg("\tPOST response code " + response.getCode().toString() + " (" + response.getCode() + ")");
+        }*/
+        activity.printLine();
+        activity.showResultDialog("POST "+resource.getUri()+" Response Handler Result",
+                "Result Code = " + response.getCode().toString());
+
+        /*
+        Post2LightResponseHandler postLight = new Post2LightResponseHandler(activity, light);
+        if (OcUtils.initPut(light.getServerUri(), light.getServerEndpoint(), null, postLight, OCQos.LOW_QOS)) {
+            OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
+            root.setBoolean(Light.SWITCH_KEY, true);
+            root.setLong(Light.DIMMING_SETTING_KEY, 55);
+            root.done();
+
+            if (OcUtils.doPost()) {
+                activity.msg("\tSent POST2 request");
+            } else {
+                activity.msg("\tCould not send POST2 request");
+            }
+        } else {
+            activity.msg("\tCould not init POST2 request");
+        }
+        activity.printLine();
+
+         */
+    }
+}

+ 48 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/PutLightResponseHandler.java

@@ -0,0 +1,48 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import org.iotivity.OCClientResponse;
+import org.iotivity.OCQos;
+import org.iotivity.OCResponseHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+public class PutLightResponseHandler implements OCResponseHandler {
+
+    private static final String TAG = PutLightResponseHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public PutLightResponseHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public void handler(OCClientResponse response) {
+        activity.msg("PUT "+resource.getUri()+" Response Handler: Code = "+response.getCode().toString());
+        if(response.getCode() != OCStatus.OC_STATUS_CHANGED && response.getCode() != OCStatus.OC_STATUS_CREATED) {
+            activity.showErrorDialog("PUT "+resource.getUri()+" Response Handler Error",
+                    "Result Code = " + response.getCode().toString());
+            activity.printLine();
+            return;
+        }
+
+        /*if (response.getCode() == OCStatus.OC_STATUS_CHANGED) {
+            activity.msg("\tPUT response: CHANGED");
+        } else {
+            activity.msg("\tPUT response code " + response.getCode().toString() + " (" + response.getCode() + ")");
+        }*/
+        activity.printLine();
+        activity.showResultDialog("PUT "+resource.getUri()+" Response Handler Result",
+                "Result Code = " + response.getCode().toString());
+
+
+    }
+}

+ 117 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/ResourceDetailsHelper.java

@@ -0,0 +1,117 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import android.util.Log;
+
+import org.iotivity.OCEndpoint;
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCResourcePropertiesMask;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+
+public class ResourceDetailsHelper {
+
+    private static final String TAG = ResourceDetailsHelper.class.getSimpleName();
+
+    static public void buildResourceDetails(OcRemoteResource resource, ArrayList<HashMap<String, String>> resourceDetailsList) {
+        if (resource != null) {
+            HashMap<String, String> item = new HashMap<>();
+
+            String line = "Types: " + Arrays.toString(resource.getTypes());
+            item.put("line1", line);
+            Log.d(TAG, line);
+
+            StringBuilder interfaces = new StringBuilder();
+            if ((resource.getInterfaceMask() & OCInterfaceMask.BASELINE) > 0) {
+                interfaces.append("BASELINE");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.LL) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("LL");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.B) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("B");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.R) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("R");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.RW) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("RW");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.A) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("A");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.S) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("S");
+            }
+            if ((resource.getInterfaceMask() & OCInterfaceMask.CREATE) > 0) {
+                if (interfaces.length() > 0) {
+                    interfaces.append(" | ");
+                }
+                interfaces.append("CREATE");
+            }
+            line = "Interfaces: " + interfaces.toString();
+            item.put("line2", line);
+            Log.d(TAG, line);
+
+            StringBuilder resourceProperties = new StringBuilder();
+            if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_DISCOVERABLE) > 0) {
+                resourceProperties.append("DISCOVERABLE");
+            }
+            if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_OBSERVABLE) > 0) {
+                if (resourceProperties.length() > 0) {
+                    resourceProperties.append(" | ");
+                }
+                resourceProperties.append("OBSERVABLE");
+            }
+            if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_SECURE) > 0) {
+                if (resourceProperties.length() > 0) {
+                    resourceProperties.append(" | ");
+                }
+                resourceProperties.append("SECURE");
+            }
+            if ((resource.getResourcePropertiesMask() & OCResourcePropertiesMask.OC_PERIODIC) > 0) {
+                if (resourceProperties.length() > 0) {
+                    resourceProperties.append(" | ");
+                }
+                resourceProperties.append("PERIODIC");
+            }
+            line = "Resource Properties: " + resourceProperties.toString();
+            item.put("line3", line);
+            Log.d(TAG, line);
+
+            StringBuilder endPoints = new StringBuilder();
+            for (OCEndpoint endpoint : resource.getEndpoints()) {
+                if (endPoints.length() > 0) {
+                    endPoints.append("\n");
+                }
+                endPoints.append("\t" + OcUtils.endpointToString(endpoint));
+            }
+            line = "Endpoints:\n" + endPoints.toString();
+            item.put("line4", line);
+            Log.d(TAG, line);
+
+            resourceDetailsList.add(item);
+        }
+    }
+}

+ 32 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/client/StopObserveTriggerHandler.java

@@ -0,0 +1,32 @@
+package org.iotivity.bridge.homeserver.handler.client;
+
+import org.iotivity.OCEventCallbackResult;
+import org.iotivity.OCTriggerHandler;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.utils.Utils;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcUtils;
+
+public class StopObserveTriggerHandler implements OCTriggerHandler {
+
+    private static final String TAG = StopObserveTriggerHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Light light;
+    private OcRemoteResource resource ;
+
+    public StopObserveTriggerHandler(BridgeServerActivity activity, OcRemoteResource resource, Light light) {
+        this.activity = activity;
+        this.light = light;
+        this.resource = resource ;
+    }
+
+    @Override
+    public OCEventCallbackResult handler() {
+        activity.msg("Stopping OBSERVE");
+        activity.printLine();
+        OcUtils.stopObserve(resource.getUri(), Utils.getCoapsEndpoint(resource.getEndpoints()));
+        return OCEventCallbackResult.OC_EVENT_DONE;
+    }
+}

+ 84 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/server/GetBridgeRequestHandler.java

@@ -0,0 +1,84 @@
+package org.iotivity.bridge.homeserver.handler.server;
+
+import android.util.Log;
+
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCRequest;
+import org.iotivity.OCRequestHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.bridge.homeserver.model.VirtualOCFDevice;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcUtils;
+
+public class GetBridgeRequestHandler implements OCRequestHandler {
+
+    private static final String TAG = GetBridgeRequestHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Bridge bridge;
+
+    public GetBridgeRequestHandler(BridgeServerActivity activity, Bridge bridge) {
+        this.activity = activity;
+        this.bridge = bridge;
+    }
+
+    @Override
+    public void handler(OCRequest request, int interfaces) {
+        Log.d(TAG, "inside Get Bridge Request Handler");
+
+        activity.msg("Get Bridge :" + request.getResource().getUri());
+        activity.msg("\t" + bridge.getName() + ", " + bridge.getEcoName() + ", " + bridge.isSecureMode());
+        activity.printLine();
+
+        if(request.getResource().getUri().equals(Bridge.SECUREMODE_URI)) {
+
+            OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
+            switch (interfaces) {
+                case OCInterfaceMask.BASELINE: {
+                    root.processBaselineInterface(request.getResource());
+                    break;
+                }
+                case OCInterfaceMask.RW: {
+                    root.setBoolean(Bridge.SECUREMODE_RESOURCE_NAME, bridge.isSecureMode());
+                    break;
+                }
+                default:
+                    break;
+            }
+            root.done();
+            OcUtils.sendResponse(request, OCStatus.OC_STATUS_OK);
+        }
+        else if(request.getResource().getUri().equals(Bridge.VODLIST_URI)) {
+
+            OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
+            switch (interfaces) {
+                case OCInterfaceMask.BASELINE: {
+                    root.processBaselineInterface(request.getResource());
+                    break;
+                }
+                case OCInterfaceMask.R: {
+                    root.setStringArray("rt", new String[]{ Bridge.VODLIST_RT });
+                    OcCborEncoder vodList = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ARRAY, root, Bridge.VODS);
+                    for (VirtualOCFDevice vod : bridge.getVODList()) {
+                        OcCborEncoder mediaObject = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ARRAY_ITEM, vodList);
+                        mediaObject.setTextString(VirtualOCFDevice.NAME_KEY, vod.getName());
+                        mediaObject.setTextString(VirtualOCFDevice.ECONAME_KEY, vod.getEcoName());
+                        mediaObject.setTextString(VirtualOCFDevice.DI_KEY, vod.getVirtualDeviceId());
+                        mediaObject.done();
+
+                        activity.msg("\t\t" + vod.getName() + ", " + vod.getEcoName() + "," + vod.getVirtualDeviceId());
+                    }
+                    vodList.done();
+                    break;
+                }
+                default:
+                    break;
+            }
+            root.done();
+            OcUtils.sendResponse(request, OCStatus.OC_STATUS_OK);
+        }
+
+    }
+}

+ 64 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/server/GetLightRequestHandler.java

@@ -0,0 +1,64 @@
+package org.iotivity.bridge.homeserver.handler.server;
+
+import android.util.Log;
+
+import org.iotivity.OCInterfaceMask;
+import org.iotivity.OCRequest;
+import org.iotivity.OCRequestHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.oc.OcCborEncoder;
+import org.iotivity.oc.OcUtils;
+
+public class GetLightRequestHandler implements OCRequestHandler {
+
+    private static final String TAG = GetLightRequestHandler.class.getSimpleName();
+
+    private BridgeService service;
+    private Light light;
+
+    public GetLightRequestHandler(BridgeService service, Light light) {
+        this.service = service;
+        this.light = light;
+    }
+
+    @Override
+    public void handler(OCRequest request, int interfaces) {
+        Log.d(TAG, "inside Get Light Request Handler");
+
+        service.msg("Get "+request.getResource().getUri()+" Request :");
+        service.msg("\t" + request.getResource().getUri() + ", " + light.isSwitchOn() + ", " + light.getDimmingLevel());
+        service.printLine();
+
+        OcCborEncoder root = OcCborEncoder.createOcCborEncoder(OcCborEncoder.EncoderType.ROOT);
+        switch (interfaces) {
+            case OCInterfaceMask.BASELINE: {
+                root.processBaselineInterface(request.getResource());
+                break;
+            }
+            case OCInterfaceMask.RW:
+            case OCInterfaceMask.A:
+                if(Light.URI_LIGHT.equalsIgnoreCase(request.getResource().getUri())) {
+                    // Light Switch Optional Resource (read only)
+                    root.setTextString(Light.RESOURCE_NAME_KEY, light.getLightResourceName());
+                    // Light Switch (Switch Binary) Required Resource (read write)
+                    root.setBoolean(Light.SWITCH_KEY, light.isSwitchOn());
+                } else if (Light.URI_DIMMING.equalsIgnoreCase(request.getResource().getUri())) {
+                    // Dimming Optional Resource (read only)
+                    root.setTextString(Light.RESOURCE_NAME_KEY, light.getDimmingResourceName());
+                    // Dimming Required Resource (read write)
+                    root.setLong(Light.DIMMING_SETTING_KEY, (long)light.getDimmingLevel());
+                    // Dimming Optional Resources (read only)
+                    root.setLong(Light.DIMMING_RANGE_KEY, (long)light.getDimmingRange());
+                    root.setLong(Light.DIMMING_STEP_KEY, (long)light.getDimmingStep());
+                }
+                break;
+            default:
+                break;
+        }
+        root.done();
+        OcUtils.sendResponse(request, OCStatus.OC_STATUS_OK);
+    }
+}

+ 50 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PostBridgeRequestHandler.java

@@ -0,0 +1,50 @@
+package org.iotivity.bridge.homeserver.handler.server;
+
+import android.util.Log;
+
+import org.iotivity.OCRequest;
+import org.iotivity.OCRequestHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.model.Bridge;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.oc.OcCborException;
+import org.iotivity.oc.OcRepresentation;
+import org.iotivity.oc.OcUtils;
+
+public class PostBridgeRequestHandler implements OCRequestHandler {
+
+    private static final String TAG = PostBridgeRequestHandler.class.getSimpleName();
+
+    private BridgeServerActivity activity;
+    private Bridge bridge;
+
+    public PostBridgeRequestHandler(BridgeServerActivity activity, Bridge bridge) {
+        this.activity = activity;
+        this.bridge = bridge;
+    }
+
+    @Override
+    public void handler(OCRequest request, int interfaces) {
+        Log.d(TAG, "inside Post Bridge Request Handler");
+
+        activity.msg("Post Bridge:" + request.getResource().getUri());
+
+        if(request.getResource().getUri().equals(Bridge.SECUREMODE_URI)) {
+
+            OcRepresentation rep = new OcRepresentation(request.getRequestPayload());
+            while (rep != null) {
+                try {
+                    if (Bridge.SECUREMODE_RESOURCE_NAME.equalsIgnoreCase(rep.getKey())) {
+                        bridge.setSecureMode(rep.getBoolean(Bridge.SECUREMODE_RESOURCE_NAME));
+                        activity.msg("\t\t" + Bridge.SECUREMODE_RESOURCE_NAME + ": " + bridge.isSecureMode());
+                    }
+                } catch (OcCborException e) {
+                    // ignore -- no switch value
+                }
+                rep = rep.getNext();
+            }
+        }
+        activity.printLine();
+        OcUtils.sendResponse(request, OCStatus.OC_STATUS_CHANGED);
+    }
+}

+ 59 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PostLightRequestHandler.java

@@ -0,0 +1,59 @@
+package org.iotivity.bridge.homeserver.handler.server;
+
+import android.util.Log;
+
+import org.iotivity.OCRequest;
+import org.iotivity.OCRequestHandler;
+import org.iotivity.OCStatus;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+import org.iotivity.oc.OcCborException;
+import org.iotivity.oc.OcRepresentation;
+import org.iotivity.oc.OcUtils;
+
+public class PostLightRequestHandler implements OCRequestHandler {
+
+    private static final String TAG = PostLightRequestHandler.class.getSimpleName();
+
+    private BridgeService service;
+    private Light light;
+
+    public PostLightRequestHandler(BridgeService service, Light light) {
+        this.service = service;
+        this.light = light;
+    }
+
+    @Override
+    public void handler(OCRequest request, int interfaces) {
+        Log.d(TAG, "inside Post Light Request Handler");
+
+        service.msg("Post Light:");
+
+        OcRepresentation rep = new OcRepresentation(request.getRequestPayload());
+        while (rep != null) {
+            try {
+                if (Light.SWITCH_KEY.equalsIgnoreCase(rep.getKey())) {
+                    light.setSwitchOn(rep.getBoolean(Light.SWITCH_KEY));
+                    service.msg("\t\t" + Light.SWITCH_KEY + ": " + light.isSwitchOn());
+                }
+            } catch (OcCborException e) {
+                // ignore -- no switch value
+            }
+
+            try {
+                if (Light.DIMMING_SETTING_KEY.equalsIgnoreCase(rep.getKey())) {
+                    light.setDimmingLevel((int) rep.getLong(Light.DIMMING_SETTING_KEY));
+                    service.msg("\t\t" + Light.DIMMING_SETTING_KEY + ": " + light.getDimmingLevel());
+                }
+            } catch (OcCborException e) {
+                // ignore -- no dimming value
+            }
+
+            rep = rep.getNext();
+        }
+
+        service.printLine();
+        OcUtils.sendResponse(request, OCStatus.OC_STATUS_CHANGED);
+    }
+}

+ 28 - 0
app/src/main/java/org/iotivity/bridge/homeserver/handler/server/PutLightRequestHandler.java

@@ -0,0 +1,28 @@
+package org.iotivity.bridge.homeserver.handler.server;
+
+import android.util.Log;
+
+import org.iotivity.OCRequest;
+import org.iotivity.OCRequestHandler;
+import org.iotivity.bridge.homeserver.BridgeService;
+import org.iotivity.bridge.homeserver.model.Light;
+import org.iotivity.bridge.homeserver.BridgeServerActivity;
+
+public class PutLightRequestHandler implements OCRequestHandler {
+
+    private static final String TAG = PutLightRequestHandler.class.getSimpleName();
+
+    private BridgeService service;
+    private Light light;
+
+    public PutLightRequestHandler(BridgeService service, Light light) {
+        this.service = service;
+        this.light = light;
+    }
+
+    @Override
+    public void handler(OCRequest request, int interfaces) {
+        Log.d(TAG, "inside Put Light Request Handler");
+        new PostLightRequestHandler(service, light).handler(request, interfaces);
+    }
+}

+ 115 - 0
app/src/main/java/org/iotivity/bridge/homeserver/model/Bridge.java

@@ -0,0 +1,115 @@
+package org.iotivity.bridge.homeserver.model;
+
+import java.util.ArrayList;
+
+public class Bridge {
+
+    public static final int BRIDGE_INDEX = 0;
+    public static final String PLATFORM_MFG_NAME = "SignalInfoComm";
+
+    // Virtual OCF Device List Resource definition
+    public static final String VODLIST_RESOURCE_NAME = "vodlist";
+    public static final String VODLIST_RT = "oic.r.vodlist";
+    public static final String VODLIST_URI = "/OVDListResURI";
+
+    // Virtual OCF Device List Resource properties
+    public static final String VODLIST = "vodlist"; // required "vods"
+    public static final String VODS = "vods"; // array of vodentry
+    public static final String VOD_ENTRY = "vodentry"; // required "n", "di", "echoname"
+
+    // VOD Entry resource properties
+    public static final String VOD_NAME = "n";
+    public static final String VOD_DI = "di";
+    public static final String VOD_ECONAME = "econame";
+
+    // Bridge SecureMode Resource definition
+    public static final String SECUREMODE_RESOURCE_NAME = "secureMode";
+    public static final String SECUREMODE_RT = "oic.r.securemode";
+    public static final String SECUREMODE_URI = "/SecureModeResURI";
+
+    //public static final String SECUREMODE = "secureMode";
+
+    // Bridge Info variables
+    private String name ;
+    private String econame ; // TODO : check if di must need ??
+    private String di ;  // TODO : check if di must need ??
+
+    // SecureMode
+    private boolean secureMode;
+    // Virtual OCF Device List
+    private ArrayList<VirtualOCFDevice> vod_lists = new ArrayList<VirtualOCFDevice>();
+
+
+    public Bridge(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public boolean isSecureMode() {
+        return secureMode;
+    }
+    public void setSecureMode(boolean secureMode) {
+        this.secureMode = secureMode;
+    }
+
+    public String getEcoName() {
+        return econame;
+    }
+    public void setEcoName(String econame) {
+        this.econame = econame;
+    }
+
+    public String getDeviceId() {
+        return di;
+    }
+    public void setDeviceId(String di) {
+        this.di = di;
+    }
+
+    public ArrayList<VirtualOCFDevice> getVODList() {
+        return vod_lists;
+    }
+
+    public void clearAllVODList() {
+        vod_lists.clear();
+    }
+
+    public boolean addOrReplaceVODList(VirtualOCFDevice new_vod) {
+        for(VirtualOCFDevice vod : vod_lists) {
+            if(vod.getVODIndex() == new_vod.getVODIndex()) {
+                vod.setVirtualDeviceId(new_vod.getVirtualDeviceId());
+                vod.setDiscovered(new_vod.isDiscovered());
+                vod.setAddedToBridge(new_vod.isAddedToBridge());
+                return true ;
+            }
+        }
+        return this.vod_lists.add(new_vod);
+    }
+
+    public boolean removeVODList(VirtualOCFDevice vod) {
+
+        return this.vod_lists.remove(vod);
+    }
+
+    public boolean removeVODList(int vod_index) {
+        VirtualOCFDevice vod = getVirtualOCFDevice(vod_index);
+        if(vod != null) {
+            return removeVODList(vod);
+        }
+        return false;
+    }
+
+    public VirtualOCFDevice getVirtualOCFDevice(int vod_index) {
+        for (VirtualOCFDevice vod : vod_lists) {
+            if(vod.getVODIndex() == vod_index) return vod ;
+        }
+        return null ;
+    }
+
+}

+ 90 - 0
app/src/main/java/org/iotivity/bridge/homeserver/model/Light.java

@@ -0,0 +1,90 @@
+package org.iotivity.bridge.homeserver.model;
+
+import org.iotivity.OCEndpoint;
+
+public class Light {
+
+    // Device : oic.d.light
+    static public final String DT_LIGHT = "oic.d.light";
+    // Resources : oic.r.switch.binary, oic.r.light.dimming
+    static public final String RT_BINARYSWITCH = "oic.r.switch.binary";    // required
+    static public final String RT_DIMMING = "oic.r.light.dimming";    // optional
+    // Properties of BinarySwitch Resource(oic.r.switch.binary)
+    static public final String SWITCH_KEY = "value";    // required
+    // Properties of Dimming Resource(oic.r.light.dimming)
+    static public final String DIMMING_SETTING_KEY = "dimmingSetting"; // required
+    static public final String DIMMING_STEP_KEY = "step" ;  // optional, default 5
+    static public final String DIMMING_RANGE_KEY = "range" ; // optional, default [0, 100]
+    // Properties of light resource name
+    static public final String RESOURCE_NAME_KEY = "n" ;  // optional
+
+    public static final String URI_LIGHT = "/light" ;
+    public static final String URI_DIMMING = "/dimming" ;
+
+    private String device_name;
+
+    private String resource_name_light = "Light Switch";  // Dimming resource Name
+    private String resource_name_dimming = "Dimming Control";  // Dimming resource Name
+
+    private boolean switch_value = false;   // default switch value : false
+    private int dimming_level = 30 ;        // default dimming level : 30
+    private int dimming_range = 100;        // dimming range : 0 ~ 99
+    private int dimming_step = 10;          // dimming step : 10
+
+    //private OCEndpoint serverEndpoint;
+    //private String serverUri;
+
+    public Light() {
+
+        this.device_name = "Light";
+    }
+
+    public Light(String device_name) {
+        this.device_name = device_name;
+    }
+    public String getDeviceName() {
+        return device_name;
+    }
+    public void setDeviceName(String name) {
+        device_name = name ;
+    }
+
+    public String getLightResourceName() { return resource_name_light; }
+    public void setLightResourceName(String resource_name) {
+        this.resource_name_light = resource_name ;
+    }
+
+    public String getDimmingResourceName() { return resource_name_dimming; }
+    public void setDimmingResourceName(String resource_name) {
+        this.resource_name_dimming = resource_name ;
+    }
+
+    public boolean isSwitchOn() {
+        return switch_value;
+    }
+    public void setSwitchOn(boolean on) {
+        this.switch_value = on;
+    }
+
+    public int getDimmingLevel() {
+        return dimming_level;
+    }
+    public void setDimmingLevel(int dimming) {
+        this.dimming_level = dimming;
+    }
+
+    public int getDimmingStep() {
+        return dimming_step;
+    }
+    public void setDimmingStep(int step) {
+        this.dimming_step = step;
+    }
+
+    public int getDimmingRange() {
+        return dimming_range;
+    }
+    public void setDimmingRange(int range) {
+        this.dimming_range = range;
+    }
+
+}

+ 94 - 0
app/src/main/java/org/iotivity/bridge/homeserver/model/VirtualOCFDevice.java

@@ -0,0 +1,94 @@
+package org.iotivity.bridge.homeserver.model;
+
+import org.iotivity.oc.OcCborException;
+import org.iotivity.oc.OcRepresentation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class VirtualOCFDevice {
+
+    // Virtual OCF Device (VOD) resource names
+    static public final String NAME_KEY = "n";
+    static public final String ECONAME_KEY = "econame";
+    static public final String DI_KEY = "di";
+
+    // Virtual OCF Device variables
+    private String name;
+    private String econame;
+    private String di ;
+    private boolean discovered ;
+    private boolean added_to_bridge ;
+    private boolean isOwned ;
+    private int index ;
+
+    public VirtualOCFDevice(int vod_index, String name, String econame, String virtual_di) {
+        this.index = vod_index;
+        this.name = name;
+        this.econame = econame ;
+        this.di = virtual_di ;
+    }
+
+    public int getVODIndex() {
+        return index;
+    }
+    public void setVODIndex(int vod_index) {
+        this.index = vod_index;
+    }
+
+    public String getName() {
+        return name;
+    }
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getEcoName() {
+        return econame;
+    }
+    public void setEcoName(String econame) {
+        this.econame = econame;
+    }
+
+    public String getVirtualDeviceId() {
+        return di;
+    }
+    public void setVirtualDeviceId(String di) {
+        this.di = di;
+    }
+
+    public boolean isDiscovered() {
+        return discovered;
+    }
+    public void setDiscovered(boolean discovered) {
+        this.discovered = discovered;
+    }
+
+    public boolean isAddedToBridge() {
+        return added_to_bridge;
+    }
+    public void setAddedToBridge(boolean added) {
+        this.added_to_bridge = added;
+    }
+
+    public boolean isOwned() {
+        return isOwned;
+    }
+    public void setOwned(boolean owned) {
+        this.isOwned = owned;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("VOD ["+index+"]");
+        sb.append(", name="+name);
+        sb.append(", econame="+econame);
+        sb.append(", vod_di="+di);
+        sb.append(", isDiscoverd="+discovered);
+        sb.append(", addedToBridge="+added_to_bridge);
+        sb.append(", isOwned="+isOwned);
+
+        return sb.toString();
+    }
+}

+ 233 - 0
app/src/main/java/org/iotivity/bridge/homeserver/utils/Utils.java

@@ -0,0 +1,233 @@
+package org.iotivity.bridge.homeserver.utils;
+
+import android.content.Context;
+import android.util.Log;
+import android.util.Pair;
+import android.webkit.DownloadListener;
+import android.widget.Switch;
+
+import org.iotivity.OCEndpoint;
+import org.iotivity.bridge.homeserver.handler.FactoryPresetsHandler;
+import org.iotivity.oc.OcRemoteDevice;
+import org.iotivity.oc.OcRemoteResource;
+import org.iotivity.oc.OcResource;
+import org.iotivity.oc.OcUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Utils {
+
+    private static final String TAG = Utils.class.getSimpleName();
+
+    public static boolean containsList(String[] arr, String targetValue) {
+        return Arrays.asList(arr).contains(targetValue);
+    }
+
+    public static boolean containsSet(String[] arr, String targetValue) {
+        Set<String> set = new HashSet<String>(Arrays.asList(arr));
+        return set.contains(targetValue);
+    }
+
+    public static boolean containsLoop(String[] arr, String targetValue) {
+        for(String s: arr){
+            if(s.equals(targetValue))
+                return true;
+        }
+        return false;
+    }
+
+    public static boolean containsArraysBinarySearch(String[] arr, String targetValue) {
+        Arrays.sort(arr);
+        int a =  Arrays.binarySearch(arr, targetValue);
+        if(a > 0)
+            return true;
+        else
+            return false;
+    }
+
+    public static OCEndpoint containsEndPointList(OCEndpoint[] arr, String startValue) {
+        for(OCEndpoint ep: arr){
+            if(OcUtils.endpointToString(ep).contains(startValue))
+                return ep;
+        }
+        return null;
+    }
+
+    public static OCEndpoint getCoapsEndpoint (OCEndpoint[] arr) {
+        OCEndpoint endpoint = Utils.containsEndPointList(arr, "coaps");
+        if (endpoint != null) {
+            return endpoint ;
+        } else {
+            return arr[0];
+        }
+    }
+
+    public static OCEndpoint getCoapEndpoint (OCEndpoint[] arr) {
+        OCEndpoint endpoint = Utils.containsEndPointList(arr, "coap");
+        if (endpoint != null) {
+            return endpoint ;
+        } else {
+            return arr[0];
+        }
+    }
+
+    public static boolean isRemoteDCRs(OcRemoteResource resource) {
+        return isDCRs(resource.getTypes());
+    }
+
+    public static boolean isOwnDCRs(OcResource resource) {
+        return isDCRs(resource.getResourceTypes());
+    }
+
+    public static boolean isDCRs(String[] resource_types) {   // Device Configuration Resource
+
+        // Discovery Core Resources
+        if(containsList(resource_types, "oic.wk.res")          // Implicit Invisible Discovery Resource in client discovery
+                || containsList(resource_types, "oic.wk.d")    // Device Resource
+                || containsList(resource_types, "oic.wk.p")) { // Platform Resource
+            return true ;
+        }
+        // Optional Core Resource
+        else if(containsList(resource_types, "oic.wk.con")     // Configuration Resource
+                || containsList(resource_types, "oic.wk.introspection") // Device Introspection
+                || containsList(resource_types, "x.org.openconnectivity.oic.introspection.data")) {   // Device Introspection Data
+            return false ;
+        }
+        // Security Virtual Resources
+        else if (containsList(resource_types, "oic.r.doxm")            // Device Ownership Transfer Method Resource
+                || containsList(resource_types, "oic.r.pstat")         // Provision State Resource
+                || containsList(resource_types, "oic.r.acl2")          // Access Control List Resource
+                || containsList(resource_types, "oic.r.cred")          // Credentials Resource
+                || containsList(resource_types, "oic.r.sp")            // Security Profile Resource
+                || containsList(resource_types, "oic.r.csr")           // Certificate Signing Request Resource
+                || containsList(resource_types, "oic.r.roles")) {      // Role Maintain Resource with Role certificate
+            return true ;
+        }
+        else if (containsList(resource_types, "oic.wk.mnt")                // Management Resource
+                || containsList(resource_types, "oic.wk.nmon")             // Network Monitoring Resource
+                || containsList(resource_types, "oic.r.softwareupdate")    // Software Update Resource
+                || containsList(resource_types, "oic.r.coapcloudconf")) {  // Cloud Resource for CoapCloudConf
+            return true ;
+        }
+        return false ;
+    }
+
+    /* Non-Configuration Resource with auth-crypt wildcard(*) permission
+    * and Core Resource with anon-clear /oic/res(oic.wk.res), /oic/d(oic.wk.d), /oic/p(oic.wk.p) permission
+    * in ACL2 (/oic/sec/acl2)
+    */
+    public static boolean isAccessableByPairwisedClient(String[] resource_types) {
+        // Discovery Core Resources
+        if(containsList(resource_types, "oic.wk.res")          // Implicit Invisible Discovery Resource in client discovery
+                || containsList(resource_types, "oic.wk.d")    // Device Resource
+                || containsList(resource_types, "oic.wk.p")) { // Platform Resource
+            return true ;
+        }
+        // Optional Core Resource
+        else if(containsList(resource_types, "oic.wk.con")     // Configuration Resource
+                || containsList(resource_types, "oic.wk.introspection") // Device Introspection
+                || containsList(resource_types, "x.org.openconnectivity.oic.introspection.data")) {   // Device Introspection Data
+            return true ;
+        }
+        // Security Virtual Resources
+        else if (containsList(resource_types, "oic.r.doxm")            // Device Ownership Transfer Method Resource
+                || containsList(resource_types, "oic.r.pstat")         // Provision State Resource
+                || containsList(resource_types, "oic.r.acl2")          // Access Control List Resource
+                || containsList(resource_types, "oic.r.cred")          // Credentials Resource
+                || containsList(resource_types, "oic.r.sp")            // Security Profile Resource
+                || containsList(resource_types, "oic.r.csr")           // Certificate Signing Request Resource
+                || containsList(resource_types, "oic.r.roles")) {      // Role Maintain Resource with Role certificate
+            return false ;
+        }
+        else if (containsList(resource_types, "oic.wk.mnt")                // Management Resource
+                || containsList(resource_types, "oic.wk.nmon")             // Network Monitoring Resource
+                || containsList(resource_types, "oic.r.softwareupdate")    // Software Update Resource
+                || containsList(resource_types, "oic.r.coapcloudconf")) {  // Cloud Resource for CoapCloudConf
+            return false ;
+        }
+        return true ;
+    }
+
+    public static boolean isObt(OcRemoteDevice device) {
+
+        return containsDeviceType(device, "oic.d.dots") ;
+    }
+    public static boolean isBridge(OcRemoteDevice device) {
+
+        return containsDeviceType(device, "oic.d.bridge") ;
+    }
+
+    public static boolean isVod(OcRemoteDevice device) {
+
+        return containsDeviceType(device, "oic.d.virtual") ;
+    }
+
+    public static boolean containsDeviceType(OcRemoteDevice device, String device_type) {
+
+        for(OcRemoteResource resource : device.getResources()) {
+            if(containsList(resource.getTypes(), device_type)) {
+                return true ;
+            }
+        }
+        return false ;
+    }
+
+    public static String propertiesToString(ArrayList<Pair<String, Object>> props) {
+
+        StringBuffer sb = new StringBuffer();
+        for(Pair prop : props) {
+            sb.append(prop.first + " = " + prop.second.toString() + "\n");
+        }
+        return sb.toString();
+    }
+
+    public static String toString(String[] arr) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[");
+        for(int index = 0; index < arr.length; index++) {
+            String obj = arr[index];
+            sb.append(obj + ( index < arr.length -1 ? ", " : ""));
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public static String toString(long[] arr) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[");
+        for(int index = 0; index < arr.length; index++) {
+            Long obj = arr[index];
+            sb.append(obj + ( index < arr.length -1 ? ", " : ""));
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public static String toString(double[] arr) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[");
+        for(int index = 0; index < arr.length; index++) {
+            Double obj = arr[index];
+            sb.append(obj + ( index < arr.length -1 ? ", " : ""));
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+
+    public static String toString(boolean[] arr) {
+        StringBuffer sb = new StringBuffer();
+        sb.append("[");
+        for(int index = 0; index < arr.length; index++) {
+            boolean obj = arr[index];
+            sb.append(obj + ( index < arr.length -1 ? ", " : ""));
+        }
+        sb.append("]");
+        return sb.toString();
+    }
+}

BIN
app/src/main/jniLibs/arm64-v8a/libiotivity-lite-jni.so


+ 2 - 0
app/src/main/jniLibs/armeabi/.gitignore

@@ -0,0 +1,2 @@
+*.so
+

BIN
app/src/main/jniLibs/armeabi/libiotivity-lite-jni.so


BIN
app/src/main/jniLibs/x86/libiotivity-lite-jni.so


+ 2 - 0
app/src/main/jniLibs/x86_64/.gitignore

@@ -0,0 +1,2 @@
+*.so
+

BIN
app/src/main/jniLibs/x86_64/libiotivity-lite-jni.so


+ 40 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/activity_main"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context=".BridgeServerActivity">
+
+    <Button
+        android:id="@+id/discover_devices_button"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:enabled="true"
+        android:text="@string/discoverDevices" />
+
+    <ListView
+            android:id="@+id/list_view"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"/>
+
+    <ScrollView
+        android:id="@+id/scrollView"
+        android:layout_width="match_parent"
+        android:layout_height="100dp"
+        android:fillViewport="true">
+
+        <TextView
+            android:id="@+id/consoleTextView"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:textSize="10sp"
+            android:text="Console" />
+    </ScrollView>
+</LinearLayout>

+ 44 - 0
app/src/main/res/layout/resource_multi_line.xml

@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <TextView
+        android:id="@+id/line_1"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_2"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_3"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+    <TextView
+        android:id="@+id/line_4"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
+        android:textColor="#0000FF" />
+
+
+</LinearLayout>

+ 32 - 0
app/src/main/res/menu/actionbar_actions.xml

@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+
+    <item
+        android:id="@+id/action_bridge_reset"
+        android:title="Reset Bridge"
+        app:showAsAction="never"/>
+
+    <item
+        android:id="@+id/action_vods_reset"
+        android:title="Reset VODs"
+        app:showAsAction="never"/>
+
+    <item
+        android:id="@+id/action_bridgeservice_stop"
+        android:title="Stop Bridge Service"
+        app:showAsAction="never"/>
+
+    <!--
+    <item
+        android:id="@+id/action_settings"
+        android:title="Settings"
+        app:showAsAction="never"/>
+
+
+    <item
+        android:id="@+id/action_search"
+        android:icon="@drawable/ic_search_white_48dp"
+        android:title="Search"
+        app:showAsAction="ifRoom"/>-->
+</menu>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 6 - 0
app/src/main/res/values-w820dp/dimens.xml

@@ -0,0 +1,6 @@
+<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>

+ 6 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="colorPrimary">#3F51B5</color>
+    <color name="colorPrimaryDark">#303F9F</color>
+    <color name="colorAccent">#FF4081</color>
+</resources>

+ 5 - 0
app/src/main/res/values/dimens.xml

@@ -0,0 +1,5 @@
+<resources>
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+</resources>

+ 14 - 0
app/src/main/res/values/strings.xml

@@ -0,0 +1,14 @@
+<resources>
+    <string name="app_name">Energy Hub Bridge</string>
+
+    <!-- Client Strings -->
+    <string name="discoverDevices">Discover Devices</string>
+    <string name="discoveredResources">Discovered Resources</string>
+    <string name="resetBridge">Reset Bridge</string>
+    <string name="resetBridgeMessage">Note: All Bridge Resources including SVRs will be reset.</string>
+    <string name="resetVods">Reset Vods</string>
+    <string name="resetVodsMessage">Note: All virtual devices will no longer be viable.</string>
+    <string name="stopBridgeService">Stop Bridge Service</string>
+    <string name="stopBridgeMessage">Note: Foregrounding Bridge Service and BridgeServer Activity will be killed.</string>
+
+</resources>

+ 11 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,11 @@
+<resources>
+
+    <!-- Base application theme. -->
+    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+        <!-- Customize your theme here. -->
+        <item name="colorPrimary">@color/colorPrimary</item>
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+        <item name="colorAccent">@color/colorAccent</item>
+    </style>
+
+</resources>

+ 25 - 0
build.gradle

@@ -0,0 +1,25 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+    repositories {
+        google()
+        jcenter()
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:3.6.1'
+
+        // NOTE: Do not place your application dependencies here; they belong
+        // in the individual module build.gradle files
+    }
+}
+
+allprojects {
+    repositories {
+        google()
+        jcenter()
+    }
+}
+
+task clean(type: Delete) {
+    delete rootProject.buildDir
+}

+ 17 - 0
gradle.properties

@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
+#Thu Jun 04 14:54:56 KST 2020
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

+ 160 - 0
gradlew

@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

+ 90 - 0
gradlew.bat

@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega

+ 1 - 0
settings.gradle

@@ -0,0 +1 @@
+include ':app'