Added initial prototype implementation of Android Multi-PHY Easy Setup
authorMadan Lanka <lanka.madan@samsung.com>
Wed, 10 Jun 2015 06:55:28 +0000 (02:55 -0400)
committerUze Choi <uzchoi@samsung.com>
Wed, 10 Jun 2015 08:07:46 +0000 (08:07 +0000)
The source code provides reference prototype implementation of Easy Setup Mediator for Android platform.
The implementation can be used to provision any Enrollee over Wi-Fi network.
The implementation follows the design mentioned in the following wiki page
https://wiki.iotivity.org/multi-phy_easy_setup

More information about Multi-PHY easy setup can be found at the following page
https://workspace.openinterconnect.org/apps/org/workgroup/oswg/document.php?document_id=2201

Change-Id: I809b5703800e7d95ead5ac08f6c4b2a04b570e91
Signed-off-by: Madan Lanka <lanka.madan@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1211
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
63 files changed:
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
service/SConscript
service/easy-setup/SConscript
service/easy-setup/sampleapp/SConscript
service/easy-setup/sampleapp/android/.gitignore [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/.classpath [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/.project [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/AndroidManifest.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/project.properties [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/background.png [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/cancel.png [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/icon.png [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/layout/activity_main.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/layout/capture.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/layout/decoder.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/layout/encoder.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/menu/main.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/values/colors.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/values/dimens.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/values/ids.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/values/strings.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/res/values/styles.xml [new file with mode: 0644]
service/easy-setup/sampleapp/android/EasySetup/src/org/iotivity/service/easysetup/MainActivity.java [new file with mode: 0644]
service/easy-setup/sampleapp/linux/richclient/SConscript [new file with mode: 0644]
service/easy-setup/sampleapp/linux/richclient/easysetupsample.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/.gitignore [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/.classpath [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/.project [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/AndroidManifest.xml [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/project.properties [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/res/drawable-hdpi/ic_launcher.png [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/res/values/strings.xml [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/res/values/styles.xml [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupCallbackHandler.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupManager.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeInfo.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeOnBoardingInfo.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IOnBoardingStatus.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IProvisioningListener.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/OnBoardEnrollee.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/ProvisionEnrollee.java [new file with mode: 0644]
service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/WiFiSoftAPManager.java [new file with mode: 0644]
service/easy-setup/sdk/android/jni/Android.mk [new file with mode: 0644]
service/easy-setup/sdk/android/jni/Application.mk [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jni_easy_setup.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jni_easy_setup.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/inc/jni_easy_setup_jvm.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/inc/jni_getter.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/inc/jni_object.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/inc/jni_setter.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/inc/jni_string.h [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/src/jni_easy_setup_jvm.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/src/jni_getter.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/src/jni_object.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/src/jni_setter.cpp [new file with mode: 0644]
service/easy-setup/sdk/android/jni/jniutil/src/jni_string.cpp [new file with mode: 0644]
service/easy-setup/sdk/inc/easysetupcommon.h [new file with mode: 0644]
service/easy-setup/sdk/inc/easysetupmgr.h [new file with mode: 0644]
service/easy-setup/sdk/inc/provisioninghandler.h [new file with mode: 0644]
service/easy-setup/sdk/src/camutex_pthreads.c [new file with mode: 0644]
service/easy-setup/sdk/src/easysetupmgr.cpp [new file with mode: 0644]
service/easy-setup/sdk/src/provisioninghandler.cpp [new file with mode: 0644]

index a4103eb..bd03d34 100644 (file)
@@ -479,7 +479,12 @@ CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
 
     VERIFY_NON_NULL(threadPool, IP_MONITOR_TAG, "threadPool is null");
 
-    CAResult_t ret = CAIPJniInit();
+    CAResult_t ret = CA_STATUS_FAILED;
+
+    //TODO: Have to fix the JNI load issue for CA using direct csdk APIs instead OCPlatform Java API
+    // and remove the EASY_SETUP_CA_INIT
+#ifndef EASY_SETUP_CA_INIT
+    ret = CAIPJniInit();
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG(ERROR, IP_MONITOR_TAG, "Initialization failed");
@@ -499,6 +504,7 @@ CAResult_t CAIPInitializeNetworkMonitor(const ca_thread_pool_t threadPool)
         OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create CaIpInterface instance");
         return ret;
     }
+#endif
 
     ret = CAInitializeNetworkMonitorMutexes();
 
index 92d7f0e..71d8d2e 100644 (file)
@@ -26,22 +26,20 @@ Import('env')
 
 target_os = env.get('TARGET_OS')
 
-if target_os not in ['arduino','darwin']:
+#if target_os not in ['arduino','darwin']:
        # Build things manager project
-       SConscript('things-manager/SConscript')
+       #SConscript('things-manager/SConscript')
 
        # Build soft sensor manager project
-       SConscript('soft-sensor-manager/SConscript')
+       #SConscript('soft-sensor-manager/SConscript')
 
        # Build protocol plugin project
        # protocol-plugin use 'inotify', this feature isn't support by MAC OSX
-       if target_os not in ['darwin', 'ios', 'android']:
-               SConscript('protocol-plugin/SConscript')
+       #if target_os not in ['darwin', 'ios', 'android']:
+       #       SConscript('protocol-plugin/SConscript')
 
        # Build notification manager project
-       SConscript('notification-manager/SConscript')
-#else:
-#      SConscript('notification-manager/SampleApp/arduino/SConscript')
-
-if target_os == 'arduino':
-   SConscript('easy-setup/SConscript')
\ No newline at end of file
+       #SConscript('notification-manager/SConscript')
+       
+if target_os in ['arduino','android', 'linux']:
+       SConscript('easy-setup/SConscript')
\ No newline at end of file
index 945b93c..b434f0a 100644 (file)
 ##
 # easy-setup project build script
 ##
+
 import os
+
 Import('env')
 
-# Add third party libraries
-lib_env = env.Clone()
-#SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+env.AppendUnique(CPPDEFINES = ['EASY_SETUP_CA_INIT'])
 
-easy_setup_env = lib_env.Clone()
+easy_setup_env = env.Clone()
 target_os = env.get('TARGET_OS')
+
+lib_env = env.Clone()
+if target_os == 'android':
+       SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', exports = 'lib_env')
+
 ######################################################################
 # Build flags
 ######################################################################
@@ -40,12 +45,21 @@ if target_os not in ['windows', 'winrt']:
     if target_os not in ['android', 'arduino']:
         easy_setup_env.AppendUnique(CXXFLAGS = ['-pthread'])
 
-if target_os == 'android':
-    easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
-    easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'gnustl_shared'])
+if target_os in ['android', 'linux']:
+       easy_setup_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+       easy_setup_env.AppendUnique(RPATH = [env.get('BUILD_DIR')])
+       easy_setup_env.AppendUnique(CXXFLAGS = ['-frtti', '-fexceptions'])
+       if target_os not in ['linux', 'arduino']:
+               easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'connectivity_abstraction', 'gnustl_shared'])      
+       else:
+               easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction'])
+       
+       if not env.get('RELEASE'):
+               easy_setup_env.AppendUnique(LIBS = ['log'])
+       
 
 if target_os == 'arduino':
-   easy_setup_env.AppendUnique(CPPPATH = [
+       easy_setup_env.AppendUnique(CPPPATH = [
                                       '../../resource/oc_logger/include',
                                       '../../resource/csdk/logger/include',
                                       '../../resource/csdk/stack/include',
@@ -53,26 +67,42 @@ if target_os == 'arduino':
                                       'sdk/arduino/wifi/inc', 
                                       'sdk/arduino/wifi/src' ])
 
+if target_os in ['android','linux']:                                      
+       easy_setup_env.PrependUnique(CPPPATH = [
+               env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',         
+               env.get('SRC_DIR') + '/resource/csdk/connectivity/common/inc',
+               env.get('SRC_DIR') + '/resource/csdk/connectivity/api',
+        env.get('SRC_DIR') + '/resource/csdk/stack/include',
+        env.get('SRC_DIR') + '/resource/csdk/logger/include',
+               env.get('SRC_DIR') + '/resource/csdk/security/include',
+               env.get('SRC_DIR') + '/extlibs/cjson'           
+               ])
+
 ######################################################################
 # Source files and Targets
 ######################################################################
 
-#if target_os == 'arduino':
-   es_src = env.Glob('sdk/src/*.cpp')
-   es_src += env.Glob('sdk/arduino/wifi/src/*.cpp')
-   es_sdk_static = easy_setup_env.StaticLibrary('ESSDKLibrary', es_src)
-   easy_setup_env.InstallTarget(es_sdk_static, 'libESSDK')
+if target_os == 'arduino':
+       es_sdk_static = easy_setup_env.StaticLibrary('ESSDKLibrary',
+                                       ['sdk/src/easysetup.cpp',
+                                       'sdk/src/resourceHandler.cpp',
+                                       'sdk/arduino/wifi/src/networkHandler.cpp'])
+       easy_setup_env.InstallTarget(es_sdk_static, 'libESSDK')
+
 
 if target_os == 'android':
-   es_src = env.Glob('sdk/src/*.cpp')
-   es_src += env.Glob('sdk/android/wifi/src/*.cpp')    
-   es_sdk_static = easy_setup_env.StaticLibrary('ESLib', es_src)
-   es_sdk_shared = easy_setup_env.SharedLibrary('ESLib', es_src)
-   easy_setup_env.InstallTarget([es_sdk_static, es_sdk_shared], 'libESSDK')
-
-# Build JNI layer
-#if target_os == 'android':
-#    SConscript(os.path.join('sdk', 'java', 'jni', 'SConscript'))
+       es_sdk_shared = easy_setup_env.SharedLibrary('libESSDK',
+                                       ['sdk/src/easysetupmgr.cpp',
+                                       'sdk/src/camutex_pthreads.c',
+                                       'sdk/src/provisioninghandler.cpp'])
+       easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
+
+if target_os == 'linux':
+       es_sdk_shared = easy_setup_env.SharedLibrary('ESSDKLibrary',
+                                       ['sdk/src/easysetupmgr.cpp',
+                                       'sdk/src/camutex_pthreads.c',
+                                       'sdk/src/provisioninghandler.cpp'])
+       easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
 
 #Go to build sample apps
 SConscript('sampleapp/SConscript')
index a00282c..13c1c3a 100644 (file)
@@ -26,7 +26,7 @@ Import('env')
 
 # Add third party libraries
 lib_env = env.Clone()
-#SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
 sample_env = lib_env.Clone()
 target_os = env.get('TARGET_OS')
 
@@ -41,3 +41,6 @@ if target_os == 'arduino' :
        # Build linux sample app
        SConscript('arduino/thinserver/SConscript')
 
+if target_os == 'linux' :
+       # Build linux sample app
+       SConscript('linux/richclient/SConscript')
diff --git a/service/easy-setup/sampleapp/android/.gitignore b/service/easy-setup/sampleapp/android/.gitignore
new file mode 100644 (file)
index 0000000..6451fc5
--- /dev/null
@@ -0,0 +1,50 @@
+#built application files\r
+*.apk\r
+*.ap_\r
+\r
+# files for the dex VM\r
+*.dex\r
+\r
+# Java class files\r
+*.class\r
+\r
+# generated files\r
+bin/\r
+gen/\r
+\r
+# Local configuration file (sdk path, etc)\r
+local.properties\r
+\r
+# Proguard folder generated by Eclipse \r
+proguard/ \r
+\r
+# Windows thumbnail db\r
+Thumbs.db\r
+\r
+# OSX files\r
+.DS_Store\r
+\r
+# Eclipse project files\r
+.classpath\r
+.project\r
+\r
+#Android Studio & Gradle\r
+.gradle\r
+/local.properties\r
+/.idea/workspace.xml\r
+/.idea/libraries\r
+.DS_Store\r
+/build/*\r
+/base/build/*\r
+/base/obj/*\r
+/base/libs/*\r
+/sample/*\r
+\r
+#Some older projects\r
+/*/out\r
+/*/*/build\r
+/*/*/production\r
+*.iws\r
+*.ipr\r
+*~\r
+*.swp
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/android/EasySetup/.classpath b/service/easy-setup/sampleapp/android/EasySetup/.classpath
new file mode 100644 (file)
index 0000000..c30d6df
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="gen"/>\r
+       <classpathentry combineaccessrules="false" kind="src" path="/EasySetupCore"/>\r
+       <classpathentry kind="output" path="bin/classes"/>\r
+</classpath>\r
diff --git a/service/easy-setup/sampleapp/android/EasySetup/.project b/service/easy-setup/sampleapp/android/EasySetup/.project
new file mode 100644 (file)
index 0000000..5e22258
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>EasySetup</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ApkBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>com.android.ide.eclipse.adt.AndroidNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/service/easy-setup/sampleapp/android/EasySetup/AndroidManifest.xml b/service/easy-setup/sampleapp/android/EasySetup/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..bce0044
--- /dev/null
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="org.iotivity.service.easysetup"\r
+    android:versionCode="1"\r
+    android:versionName="1.0" >
+    
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />    
+    <uses-feature android:name="android.hardware.camera" android:required="true" />
+       <uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
+       <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
+
+    <uses-permission android:name="android.permission.CAMERA"/>\r
+\r
+    <uses-sdk\r
+        android:minSdkVersion="8"\r
+        android:targetSdkVersion="21" />
+    
+     <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name=".MainActivity"
+            android:label="@string/app_name" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                               <action android:name="android.intent.action.SEND"/>
+                               <category android:name="android.intent.category.DEFAULT"/>
+                               <data android:mimeType="text/plain"/>
+                       </intent-filter>
+        </activity>
+        
+         <activity android:name="com.jwetherell.quick_response_code.CaptureActivity"
+            android:label="@string/capture_name"
+            android:icon="@drawable/icon"
+            android:screenOrientation="landscape"
+            android:clearTaskOnLaunch="true"
+            android:stateNotNeeded="true"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden">
+        </activity>
+
+        <activity android:name="com.jwetherell.quick_response_code.DecoderActivity"
+            android:label="@string/decoder_name"
+            android:icon="@drawable/icon"
+            android:screenOrientation="landscape"
+            android:clearTaskOnLaunch="true"
+            android:stateNotNeeded="true"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden">
+        </activity>
+
+        <activity android:name="com.jwetherell.quick_response_code.EncoderActivity"
+            android:label="@string/encoder_name"
+            android:icon="@drawable/icon"
+            android:screenOrientation="landscape"
+            android:clearTaskOnLaunch="true"
+            android:stateNotNeeded="true"
+            android:configChanges="orientation|keyboardHidden"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
+            android:windowSoftInputMode="stateAlwaysHidden">
+        </activity>
+
+    </application>\r
+\r
+</manifest>\r
diff --git a/service/easy-setup/sampleapp/android/EasySetup/project.properties b/service/easy-setup/sampleapp/android/EasySetup/project.properties
new file mode 100644 (file)
index 0000000..4630921
--- /dev/null
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-21
+android.library.reference.1=../../../sdk/android/EasySetupCore
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/background.png b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/background.png
new file mode 100644 (file)
index 0000000..561cce8
Binary files /dev/null and b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/background.png differ
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/cancel.png b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/cancel.png
new file mode 100644 (file)
index 0000000..da342e5
Binary files /dev/null and b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/cancel.png differ
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/ic_launcher.png b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/ic_launcher.png differ
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/icon.png b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/icon.png
new file mode 100644 (file)
index 0000000..24a8af2
Binary files /dev/null and b/service/easy-setup/sampleapp/android/EasySetup/res/drawable-hdpi/icon.png differ
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/layout/activity_main.xml b/service/easy-setup/sampleapp/android/EasySetup/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..2f7737e
--- /dev/null
@@ -0,0 +1,71 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:tools="http://schemas.android.com/tools"\r
+    android:layout_width="match_parent"\r
+    android:layout_height="match_parent"\r
+    android:background="@drawable/background"\r
+    android:paddingBottom="@dimen/activity_vertical_margin"\r
+    android:paddingLeft="@dimen/activity_horizontal_margin"\r
+    android:paddingRight="@dimen/activity_horizontal_margin"\r
+    android:paddingTop="@dimen/activity_vertical_margin"\r
+    tools:context="org.iotivity.service.easysetup.mediator.MainActivity" >\r
+\r
+    <Button\r
+        android:id="@+id/button1"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_alignParentTop="true"\r
+        android:layout_centerHorizontal="true"\r
+        android:layout_margin="10dp"\r
+        android:layout_marginTop="20dp"\r
+        android:elegantTextHeight="true"\r
+        android:text="@string/start_soft_ap"\r
+        android:textAllCaps="false"\r
+        android:textSize="18sp" />\r
+\r
+    <Button\r
+        android:id="@+id/button2"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_alignParentBottom="true"\r
+        android:layout_centerHorizontal="true"\r
+        android:layout_marginBottom="72dp"\r
+        android:elegantTextHeight="true"\r
+        android:text="@string/provision_device"\r
+        android:textAllCaps="false"\r
+        android:textSize="18sp" />\r
+\r
+    <Button\r
+        android:id="@+id/stopapbutton"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_below="@+id/button1"\r
+        android:layout_centerHorizontal="true"\r
+        android:layout_margin="10dp"\r
+        android:elegantTextHeight="true"\r
+        android:text="@string/stop_soft_ap"\r
+        android:textAllCaps="false"\r
+        android:textSize="18sp" />\r
+\r
+    <TextView\r
+        android:id="@+id/textView1"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_alignLeft="@+id/TextView01"\r
+        android:layout_below="@+id/stopapbutton"\r
+        android:layout_marginTop="43dp"\r
+        android:text="@string/textview1"\r
+        android:textColor="#ffffff"\r
+        android:textSize="15sp" />\r
+\r
+    <TextView\r
+        android:id="@+id/TextView01"\r
+        android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content"\r
+        android:layout_alignLeft="@+id/button2"\r
+        android:layout_below="@+id/stopapbutton"\r
+        android:layout_marginTop="16dp"\r
+        android:text="@string/textview2"\r
+        android:textColor="#ffffff"\r
+        android:textSize="20sp" />\r
+\r
+</RelativeLayout>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/layout/capture.xml b/service/easy-setup/sampleapp/android/EasySetup/res/layout/capture.xml
new file mode 100644 (file)
index 0000000..544094d
--- /dev/null
@@ -0,0 +1,184 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="fill_parent"
+             android:layout_height="fill_parent">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent">
+  </SurfaceView>
+
+  <com.jwetherell.quick_response_code.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"
+      android:background="@color/transparent">
+  </com.jwetherell.quick_response_code.ViewfinderView>
+
+  <LinearLayout android:id="@+id/result_view"
+                android:orientation="horizontal"
+                android:layout_width="fill_parent"
+                android:layout_height="fill_parent"
+                android:background="@color/result_view"
+                android:gravity="center"
+                android:padding="4dip">
+        <Button
+        android:id="@+id/cancelButton"
+        android:layout_width="50dip"
+        android:layout_height="50dip"
+        android:layout_alignParentTop="true"
+        android:layout_margin="10dp"
+        android:layout_marginTop="28dp"
+        android:elegantTextHeight="true"
+        android:background="@drawable/cancel"
+        android:textSize="18sp" />
+        
+    <LinearLayout
+      android:orientation="vertical"
+      android:layout_width="wrap_content"
+      android:layout_height="fill_parent"
+      android:gravity="right|center_vertical">
+
+      <ImageView android:id="@+id/barcode_image_view"
+                 android:layout_width="160dip"
+                 android:layout_height="wrap_content"
+                 android:maxWidth="160dip"
+                 android:maxHeight="160dip"
+                 android:layout_marginBottom="4dip"
+                 android:adjustViewBounds="true"
+                 android:scaleType="centerInside"
+                 android:contentDescription="@string/barcode_image">
+      </ImageView>
+
+      <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView android:id="@+id/format_text_view_label"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:text="@string/msg_default_format"
+                  android:textColor="@color/result_minor_text"
+                  android:textStyle="bold"
+                  android:textSize="14sp"
+                  android:paddingRight="4dip">
+        </TextView>
+        <TextView android:id="@+id/format_text_view"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textColor="@color/result_minor_text"
+                  android:textSize="14sp">
+        </TextView>
+      </LinearLayout>
+
+      <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView android:id="@+id/type_text_view_label"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:text="@string/msg_default_type"
+                  android:textColor="@color/result_minor_text"
+                  android:textStyle="bold"
+                  android:textSize="14sp"
+                  android:paddingRight="4dip">
+        </TextView>
+        <TextView android:id="@+id/type_text_view"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textColor="@color/result_minor_text"
+                  android:textSize="14sp">
+        </TextView>
+      </LinearLayout>
+       
+      <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView android:id="@+id/time_text_view_label"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:text="@string/msg_default_time"
+                  android:textColor="@color/result_minor_text"
+                  android:textStyle="bold"
+                  android:textSize="14sp"
+                  android:paddingRight="4dip">
+        </TextView>
+        <TextView android:id="@+id/time_text_view"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textColor="@color/result_minor_text"
+                  android:textSize="14sp">
+        </TextView>
+      </LinearLayout>
+        
+      <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+        <TextView android:id="@+id/meta_text_view_label"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:text="@string/msg_default_meta"
+                  android:textColor="@color/result_minor_text"
+                  android:textStyle="bold"
+                  android:textSize="14sp"
+                  android:paddingRight="4dip">
+        </TextView>
+        <TextView android:id="@+id/meta_text_view"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textColor="@color/result_minor_text"
+                  android:textSize="14sp">
+        </TextView>
+      </LinearLayout>
+    
+    </LinearLayout>
+
+    <ScrollView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content">
+      <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical">
+        <TextView android:id="@+id/contents_text_view"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:textColor="@color/result_text"
+                  android:textColorLink="@color/result_text"
+                  android:textSize="22sp"
+                  android:paddingLeft="12dip">
+        </TextView>
+      </LinearLayout>
+    </ScrollView>
+
+  </LinearLayout>
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"
+            android:textSize="14sp">
+  </TextView>
+
+</FrameLayout>
\ No newline at end of file
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/layout/decoder.xml b/service/easy-setup/sampleapp/android/EasySetup/res/layout/decoder.xml
new file mode 100644 (file)
index 0000000..3099f59
--- /dev/null
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="fill_parent"
+             android:layout_height="fill_parent">
+
+  <SurfaceView android:id="@+id/preview_view"
+               android:layout_width="fill_parent"
+               android:layout_height="fill_parent">
+  </SurfaceView>
+
+  <com.jwetherell.quick_response_code.ViewfinderView
+      android:id="@+id/viewfinder_view"
+      android:layout_width="fill_parent"
+      android:layout_height="fill_parent"
+      android:background="@color/transparent">
+  </com.jwetherell.quick_response_code.ViewfinderView>
+
+  <TextView android:id="@+id/status_view"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="bottom|center_horizontal"
+            android:background="@color/transparent"
+            android:text="@string/msg_default_status"
+            android:textColor="@color/status_text"
+            android:textSize="14sp"/>
+
+</FrameLayout>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/layout/encoder.xml b/service/easy-setup/sampleapp/android/EasySetup/res/layout/encoder.xml
new file mode 100644 (file)
index 0000000..d3fdec7
--- /dev/null
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:id="@+id/encode_view"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:fillViewport="true"
+              android:background="@color/encode_view"
+              android:orientation="vertical"
+              android:gravity="center">
+
+  <ImageView android:id="@+id/image_view"
+             android:layout_width="fill_parent"
+             android:layout_height="wrap_content"
+             android:layout_gravity="center_horizontal"
+             android:scaleType="center"
+             android:contentDescription="@string/barcode_image"/>
+
+  <ScrollView android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_horizontal"
+              android:gravity="center">
+
+    <TextView android:id="@+id/contents_text_view"
+              android:layout_width="fill_parent"
+              android:layout_height="wrap_content"
+              android:layout_gravity="center_horizontal"
+              android:gravity="center"
+              android:textColor="@color/contents_text"
+              android:textSize="18sp"
+              android:paddingBottom="8dip"
+              android:paddingLeft="8dip"
+              android:paddingRight="8dip"/>
+
+  </ScrollView>
+
+</LinearLayout>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/menu/main.xml b/service/easy-setup/sampleapp/android/EasySetup/res/menu/main.xml
new file mode 100644 (file)
index 0000000..921b3c4
--- /dev/null
@@ -0,0 +1,11 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:app="http://schemas.android.com/apk/res-auto"\r
+    xmlns:tools="http://schemas.android.com/tools"\r
+    tools:context="org.iotivity.service.easysetup.MainActivity" >\r
+\r
+    <item\r
+        android:id="@+id/action_settings"\r
+        android:orderInCategory="100"\r
+        android:title="@string/action_settings"/>\r
+\r
+</menu>\r
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/values/colors.xml b/service/easy-setup/sampleapp/android/EasySetup/res/values/colors.xml
new file mode 100644 (file)
index 0000000..3dea3d5
--- /dev/null
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>  
+  <color name="transparent">#00000000</color>
+  
+  <color name="contents_text">#ff000000</color>
+  
+  <color name="encode_view">#ffffffff</color>
+
+  <color name="possible_result_points">#c07FFF00</color>
+  
+  <color name="result_image_border">#ff526F35</color>
+  <color name="result_minor_text">#ffc0c0c0</color>
+  <color name="result_points">#c07FFF00</color>
+  <color name="result_text">#ffffffff</color>
+  <color name="result_view">#b0000000</color>
+
+  <color name="status_view">#50000000</color>
+  <color name="status_text">#ffffffff</color>
+
+  <color name="viewfinder_frame">#ff526F35</color>
+  <color name="viewfinder_laser">#ff7FFF00</color>
+  <color name="viewfinder_mask">#607CFC00</color>
+</resources>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/values/dimens.xml b/service/easy-setup/sampleapp/android/EasySetup/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..55c1e59
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/values/ids.xml b/service/easy-setup/sampleapp/android/EasySetup/res/values/ids.xml
new file mode 100644 (file)
index 0000000..fc4a1e5
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2008 ZXing authors
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+<resources>
+  <!-- Messages IDs -->
+  <item type="id" name="auto_focus"/>
+  <item type="id" name="decode"/>
+  <item type="id" name="decode_failed"/>
+  <item type="id" name="decode_succeeded"/>
+  <item type="id" name="quit"/>
+  <item type="id" name="restart_preview"/>
+  <item type="id" name="return_scan_result"/>
+</resources>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/values/strings.xml b/service/easy-setup/sampleapp/android/EasySetup/res/values/strings.xml
new file mode 100644 (file)
index 0000000..6a9aa12
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+    <string name="app_name">Easy Setup</string>
+    <string name="action_settings">Settings</string>
+    <string name="textview2">Device Information</string>
+    <string name="textview1"> -- empty -- </string>
+    <string name="scan_qr_code">Scan QR Code</string> 
+       <string name="start_easy_setup">Start Easy Setup</string> 
+       <string name="start_soft_ap">Start Wi-Fi Soft AP</string>
+       <string name="stop_soft_ap">Stop Soft AP</string>  
+    <string name="provision_device">Provision Connected Device</string>    
+    
+       <string name="capture_name">QR Code Capture</string>
+       <string name="encoder_name">QR Code Encoder</string>
+       <string name="decoder_name">QR Code Decoder</string>
+       
+       <string name="contents_contact">Contact info</string>
+       <string name="contents_email">Email address</string>
+       <string name="contents_location">Geographic coordinates</string>
+       <string name="contents_phone">Phone number</string>
+       <string name="contents_sms">SMS address</string>
+       <string name="contents_text">Plain text</string>
+       
+       <string name="msg_default_contents">Contents</string>
+       <string name="msg_default_format">Format</string>
+       <string name="msg_default_meta">Metadata</string>
+       <string name="msg_default_mms_subject">Hi</string>
+       <string name="msg_default_status">Place a QR code inside the viewfinder rectangle to scan it.</string>
+       <string name="msg_default_time">Time</string>
+       <string name="msg_default_type">Type</string>
+       
+       <string name="result_address_book">Found contact info</string>
+       <string name="result_calendar">Found calendar event</string>
+       <string name="result_email_address">Found email address</string>
+       <string name="result_geo">Found geographic coordinates</string>
+       <string name="result_isbn">Found book</string>
+       <string name="result_product">Found product</string>
+       <string name="result_sms">Found SMS address</string>
+       <string name="result_tel">Found phone number</string>
+       <string name="result_text">Found plain text</string>
+       <string name="result_uri">Found URL</string>
+       <string name="result_wifi">Found WLAN Configuration</string>
+       
+       <string name="wifi_changing_network">Changing Network</string>
+       <string name="wifi_ssid_label">Network Name</string>
+       <string name="wifi_type_label">Type</string>
+       
+       <string name="barcode_image">Barcode Image</string>
+
+</resources>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/res/values/styles.xml b/service/easy-setup/sampleapp/android/EasySetup/res/values/styles.xml
new file mode 100644 (file)
index 0000000..6ce89c7
--- /dev/null
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
diff --git a/service/easy-setup/sampleapp/android/EasySetup/src/org/iotivity/service/easysetup/MainActivity.java b/service/easy-setup/sampleapp/android/EasySetup/src/org/iotivity/service/easysetup/MainActivity.java
new file mode 100644 (file)
index 0000000..fb9fb47
--- /dev/null
@@ -0,0 +1,310 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+package org.iotivity.service.easysetup;\r
+\r
+import java.util.Timer;\r
+import java.util.TimerTask;\r
+\r
+import org.iotivity.service.easysetup.mediator.EnrolleeInfo;\r
+import org.iotivity.service.easysetup.mediator.EasySetupManager;\r
+import org.iotivity.service.easysetup.mediator.IOnBoardingStatus;\r
+import org.iotivity.service.easysetup.mediator.IProvisioningListener;\r
+import org.iotivity.service.easysetup.mediator.OnBoardEnrollee;\r
+import org.iotivity.service.easysetup.mediator.ProvisionEnrollee;\r
+\r
+import android.app.Activity;\r
+import android.content.Intent;\r
+import android.graphics.Bitmap;\r
+import android.net.wifi.WifiConfiguration;\r
+import android.os.Bundle;\r
+import android.util.Log;\r
+import android.view.Menu;\r
+import android.view.View;\r
+import android.view.View.OnClickListener;\r
+import android.widget.Button;\r
+import android.widget.ImageView;\r
+import android.widget.TextView;\r
+import android.widget.Toast;\r
+\r
+public class MainActivity extends Activity implements IProvisioningListener,\r
+        IOnBoardingStatus {\r
+    String            devicesConnected;\r
+    TextView          textView1;\r
+\r
+    private Timer     myTimer;\r
+    private Timer     myTimer2;\r
+    static int        scanCount             = 0;\r
+    static int        easySetupCount        = 0;\r
+    static final int  REQUEST_IMAGE_CAPTURE = 1;\r
+    ImageView         imageView;\r
+    EnrolleeInfo      connectedDevice;\r
+\r
+    OnBoardEnrollee   onBoardingHandlerInstance;\r
+    ProvisionEnrollee provisionEnrolleInstance;\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        setContentView(R.layout.activity_main);\r
+\r
+        textView1 = (TextView) findViewById(R.id.textView1);\r
+\r
+        // OnBoarding Process\r
+        onBoardingHandlerInstance = new OnBoardEnrollee(this);\r
+        onBoardingHandlerInstance.registerOnBoardingStatusHandler(this);\r
+\r
+        // Provisioning Process\r
+        provisionEnrolleInstance = new ProvisionEnrollee(this);\r
+        provisionEnrolleInstance.registerProvisioningHandler(this);\r
+\r
+        // Get intent, action and MIME type\r
+        Intent intent = getIntent();\r
+        String action = intent.getAction();\r
+        String type = intent.getType();\r
+\r
+        if (Intent.ACTION_SEND.equals(action) && type != null) {\r
+            if ("text/plain".equals(type)) {\r
+                handleSendText(intent); // Handle text being sent\r
+            }\r
+        } else {\r
+            // Handle other intents, such as being started from the home screen\r
+        }\r
+\r
+        addListenerForStartAP();\r
+        addListenerForStopAP();\r
+        addListenerOnProvisioning();\r
+\r
+        myTimer2 = new Timer();\r
+        myTimer2.schedule(new TimerTask() {\r
+            @Override\r
+            public void run() {\r
+                onBoardingHandlerInstance.startDeviceScan();\r
+            }\r
+\r
+        }, 0, 2000);\r
+    }\r
+\r
+    public void onDestroy() {\r
+        super.onDestroy();\r
+        provisionEnrolleInstance.stopEnrolleeProvisioning(0);\r
+        onBoardingHandlerInstance.disableWiFiAP();\r
+        finish();\r
+    }\r
+\r
+    @Override\r
+    public boolean onCreateOptionsMenu(Menu menu) {\r
+        menu.add(0, 0, 0, "Get Clients");\r
+        menu.add(0, 1, 0, "Start AP");\r
+        menu.add(0, 2, 0, "Stop AP");\r
+        menu.add(0, 3, 0, "Provision");\r
+        // Inflate the menu; this adds items to the action bar if it is present.\r
+        getMenuInflater().inflate(R.menu.main, menu);\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public void onFinishProvisioning(final int statuscode) {\r
+        // TODO Auto-generated method stub\r
+        try {\r
+            // code runs in a thread\r
+            runOnUiThread(new Runnable() {\r
+                @Override\r
+                public void run() {\r
+                    // TODO Auto-generated method stub\r
+                    Toast toast = null;\r
+                    if (statuscode == 0) {\r
+                        toast = Toast.makeText(getApplicationContext(),\r
+                                connectedDevice.getIpAddr()\r
+                                        + " - is Provisioned",\r
+                                Toast.LENGTH_LONG);\r
+                        Log.i("EasyConnect", "Provisioned statuscode-"\r
+                                + statuscode);\r
+                    } else {\r
+                        toast = Toast.makeText(getApplicationContext(),\r
+                                connectedDevice.getIpAddr()\r
+                                        + " - is NOT Provisioned",\r
+                                Toast.LENGTH_LONG);\r
+                        Log.i("EasyConnect", "Not Provisioned statuscode-"\r
+                                + statuscode);\r
+                    }\r
+\r
+                    toast.show();\r
+                }\r
+            });\r
+        } catch (final Exception ex) {\r
+            Log.i("---", "Exception in thread");\r
+        }\r
+    }\r
+\r
+    void handleSendText(Intent intent) {\r
+        String sharedText = intent.getStringExtra(Intent.EXTRA_TEXT);\r
+        if (sharedText != null) {\r
+            // Update UI to reflect text being shared\r
+            WifiConfiguration netConfig = new WifiConfiguration();\r
+            netConfig.SSID = "EasyConnect";\r
+            netConfig.allowedAuthAlgorithms\r
+                    .set(WifiConfiguration.AuthAlgorithm.OPEN);\r
+            // netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);\r
+            // netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);\r
+            netConfig.allowedKeyManagement\r
+                    .set(WifiConfiguration.KeyMgmt.WPA_PSK);\r
+            netConfig.preSharedKey = "EasyConnect";\r
+            // netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);\r
+            // netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);\r
+            // netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);\r
+            // netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);\r
+            onBoardingHandlerInstance.enableWiFiAP(netConfig, true);\r
+\r
+            Toast.makeText(getApplicationContext(),\r
+                    "QR Code Captured. Starting Wi-Fi Access Point!",\r
+                    Toast.LENGTH_LONG).show();\r
+\r
+            myTimer = new Timer();\r
+            myTimer.schedule(new TimerTask() {\r
+                @Override\r
+                public void run() {\r
+                    scan();\r
+                    scanCount++;\r
+                    Log.i("EasyConnect", "Scan Count -" + scanCount);\r
+                }\r
+\r
+            }, 0, 5000);\r
+        }\r
+    }\r
+\r
+    private void scan() {\r
+        onBoardingHandlerInstance.registerOnBoardingStatusHandler(this);\r
+        onBoardingHandlerInstance.startDeviceScan();\r
+    }\r
+\r
+    public void addListenerForStartAP() {\r
+        Button button = (Button) findViewById(R.id.button1);\r
+\r
+        button.setOnClickListener(new OnClickListener() {\r
+            @Override\r
+            public void onClick(View arg0) {\r
+                WifiConfiguration netConfig = new WifiConfiguration();\r
+                netConfig.SSID = "EasyConnect";\r
+                netConfig.allowedAuthAlgorithms\r
+                        .set(WifiConfiguration.AuthAlgorithm.OPEN);\r
+                // netConfig.allowedProtocols.set(WifiConfiguration.Protocol.RSN);\r
+                // netConfig.allowedProtocols.set(WifiConfiguration.Protocol.WPA);\r
+                netConfig.allowedKeyManagement\r
+                        .set(WifiConfiguration.KeyMgmt.WPA_PSK);\r
+                netConfig.preSharedKey = "EasyConnect";\r
+                // netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);\r
+                // netConfig.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);\r
+                // netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);\r
+                // netConfig.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);\r
+                onBoardingHandlerInstance.enableWiFiAP(netConfig, true);\r
+            }\r
+        });\r
+    }\r
+\r
+    public void addListenerForStopAP() {\r
+        Button button = (Button) findViewById(R.id.stopapbutton);\r
+\r
+        button.setOnClickListener(new OnClickListener() {\r
+            @Override\r
+            public void onClick(View arg0) {\r
+                onBoardingHandlerInstance.disableWiFiAP();\r
+            }\r
+        });\r
+    }\r
+\r
+    public void addListenerOnProvisioning() {\r
+        Button button = (Button) findViewById(R.id.button2);\r
+\r
+        button.setOnClickListener(new OnClickListener() {\r
+            @Override\r
+            public void onClick(View arg0) {\r
+                provisionEnrolleInstance.provisionEnrollee(\r
+                        connectedDevice.getIpAddr(), "NewAccessPoint",\r
+                        "NewAccessPoint", 0);\r
+                easySetupCount++;\r
+                Log.i("EasyConnect", "easy Setup Count-" + easySetupCount);\r
+                Log.i("EasyConnect",\r
+                        "IP Address-" + connectedDevice.getIpAddr());\r
+            }\r
+        });\r
+\r
+    }\r
+\r
+    @Override\r
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {\r
+        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {\r
+            Bundle extras = data.getExtras();\r
+            Bitmap imageBitmap = (Bitmap) extras.get("data");\r
+            imageView.setImageBitmap(imageBitmap);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void deviceOnBoardingStatus(EnrolleeInfo enrolleStatus) {\r
+        // TODO Auto-generated method stub\r
+        // TODO Auto-generated method stub\r
+        if (enrolleStatus != null && enrolleStatus.getIpAddr() != null) {\r
+            String finalResult = "Easy Connect : ";\r
+\r
+            if (enrolleStatus.isReachable()) {\r
+                finalResult = "Device OnBoarded" + "["\r
+                        + enrolleStatus.getIpAddr() + "]";\r
+\r
+                /*\r
+                 * easySetupInstance.StartEasySetup(enrolleStatus.getIpAddr()) ;\r
+                 * easySetupCount++; Log.i("EasyConnect",\r
+                 * "easy Setup Count-"+easySetupCount); Log.i("EasyConnect",\r
+                 * "IP Address-"+enrolleStatus.getIpAddr());\r
+                 */\r
+                connectedDevice = enrolleStatus;\r
+            } else {\r
+                finalResult = "Device Removed" + "["\r
+                        + enrolleStatus.getIpAddr() + "]";\r
+            }\r
+\r
+            textView1.setText("");\r
+            textView1.append("Clients: \n");\r
+            textView1.append("####################\n");\r
+            textView1.append("IP Address       : " + enrolleStatus.getIpAddr()\r
+                    + "\n");\r
+            textView1.append("Device           : " + enrolleStatus.getDevice() + "\n");\r
+            textView1.append("HW Address       : " + enrolleStatus.getHWAddr()\r
+                    + "\n");\r
+            textView1.append("Is OnBoarded     : " + enrolleStatus.isReachable()\r
+                    + "\n");\r
+\r
+            Toast.makeText(getApplicationContext(), finalResult,\r
+                    Toast.LENGTH_LONG).show();\r
+\r
+            /*\r
+             * myTimer2 = new Timer(); myTimer2.schedule(new TimerTask() {\r
+             *\r
+             * @Override public void run() {\r
+             * easySetupInstance.StartEasySetup(enrolleStatus.getIpAddr());\r
+             * easySetupCount++; Log.i("EasyConnect",\r
+             * "easy Setup Count-"+easySetupCount); Log.i("EasyConnect",\r
+             * "IP Address-"+enrolleStatus.getIpAddr()); }\r
+             *\r
+             * }, 0, 10000);\r
+             */\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/service/easy-setup/sampleapp/linux/richclient/SConscript b/service/easy-setup/sampleapp/linux/richclient/SConscript
new file mode 100644 (file)
index 0000000..f0f606a
--- /dev/null
@@ -0,0 +1,51 @@
+#******************************************************************
+#
+# Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+Import('env')
+
+richclient_env = env.Clone()
+
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+richclient_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+richclient_env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+richclient_env.PrependUnique(CPPPATH = [
+                       env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',         
+                       env.get('SRC_DIR') + '/resource/csdk/connectivity/common/inc',
+                       env.get('SRC_DIR') + '/resource/csdk/connectivity/api',
+                       env.get('SRC_DIR') + '/resource/csdk/stack/include',
+                       env.get('SRC_DIR') + '/resource/csdk/logger/include',
+                       env.get('SRC_DIR') + '/resource/csdk/security/include',
+                       env.get('SRC_DIR') + '/extlibs/cjson',
+                       env.get('SRC_DIR') + '/service/easy-setup/sdk/inc'
+                       ])
+
+richclient_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction', 'coap', 'ESSDKLibrary'])
+
+richclient = richclient_env.Program('richclient', 'easysetupsample.cpp')
+
+i_richclient = richclient_env.Install(env.get('BUILD_DIR'), richclient)
+
+Alias('richclient', i_richclient)
+env.AppendTarget('richclient')
diff --git a/service/easy-setup/sampleapp/linux/richclient/easysetupsample.cpp b/service/easy-setup/sampleapp/linux/richclient/easysetupsample.cpp
new file mode 100644 (file)
index 0000000..3f65b64
--- /dev/null
@@ -0,0 +1,117 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sstream>
+
+#include "easysetupmgr.h"
+#include "logger.h"
+
+#define TAG "easysetupsample"
+
+int quitFlag = 0;
+
+/* SIGINT handler: set quitFlag to 1 for graceful termination */
+void handleSigInt(int signum) {
+    if (signum == SIGINT) {
+        quitFlag = 1;
+    }
+}
+
+/**
+ * This callback function is used to receive the notifications about the provisioning status
+ * In success or failure, ProvisioningInfo structure holds the current state of provisioning
+ * and also holds the Enrollee information for which provisioning is requested
+ * This function can be used to update the application about the current provisioning status of the Enrollee
+ */
+void ProvisioningStatusCallback(ProvisioningInfo provInfo) {
+    OIC_LOG_V(INFO, TAG, "Enrollee connectivity: %d", provInfo.provDeviceInfo.connType);
+    if(provInfo.provStatus == DEVICE_PROVISIONED)
+    {
+        OIC_LOG_V(INFO, TAG, "Successfully provisioned the Enrollee with IP : %d.%d.%d.%d ",
+            provInfo.provDeviceInfo.addr->addr[0],
+            provInfo.provDeviceInfo.addr->addr[1],
+            provInfo.provDeviceInfo.addr->addr[2],
+            provInfo.provDeviceInfo.addr->addr[3]);
+    }
+    else{
+        OIC_LOG_V(INFO, TAG, "Provisioing Failed for the Enrollee with IP : %d.%d.%d.%d ",
+            provInfo.provDeviceInfo.addr->addr[0],
+            provInfo.provDeviceInfo.addr->addr[1],
+            provInfo.provDeviceInfo.addr->addr[2],
+            provInfo.provDeviceInfo.addr->addr[3]);
+    }
+}
+
+static void PrintUsage()
+{
+    OIC_LOG(INFO, TAG, "Usage : occlient -d \"192.168.0.20\"");
+}
+
+
+int main (int argc, char**argv) {
+    int opt;
+    EnrolleeNWProvInfo_t netInfo;
+    PrintUsage();
+    InitEasySetupManager();
+
+    RegisterProvisioningStausCallback(ProvisioningStatusCallback);
+
+    while ((opt = getopt(argc, argv, "d:s:p:")) != -1)
+    {
+        switch(opt)
+        {
+            case 'd':
+                strncpy(netInfo.netAddressInfo.WIFI.ipAddress, optarg, IPV4_ADDR_SIZE);
+                break;
+            case 's':
+                strncpy(netInfo.netAddressInfo.WIFI.ssid, optarg, NET_WIFI_SSID_SIZE);
+                break;
+            case 'p':
+                strncpy(netInfo.netAddressInfo.WIFI.pwd, optarg, NET_WIFI_PWD_SIZE);
+                break;
+            default:
+                PrintUsage();
+                return -1;
+        }
+    }
+
+    netInfo.connType = OC_IPV4;
+    OIC_LOG_V(INFO, TAG, "IP Address of the Provisioning device is =%s\n",
+                        netInfo.netAddressInfo.WIFI.ipAddress);
+    OIC_LOG_V(INFO, TAG, "SSID of the Enroller is =%s\n",netInfo.netAddressInfo.WIFI.ssid);
+    OIC_LOG_V(INFO, TAG, "Password of the Enroller is =%s\n",netInfo.netAddressInfo.WIFI.pwd);
+
+    ProvisionEnrollee(&netInfo);
+
+    signal(SIGINT, handleSigInt);
+    while (!quitFlag) {
+        sleep(1);
+    }
+    OIC_LOG(INFO, TAG, "Exiting occlient main loop...");
+
+    return 0;
+}
+
diff --git a/service/easy-setup/sdk/android/.gitignore b/service/easy-setup/sdk/android/.gitignore
new file mode 100644 (file)
index 0000000..6451fc5
--- /dev/null
@@ -0,0 +1,50 @@
+#built application files\r
+*.apk\r
+*.ap_\r
+\r
+# files for the dex VM\r
+*.dex\r
+\r
+# Java class files\r
+*.class\r
+\r
+# generated files\r
+bin/\r
+gen/\r
+\r
+# Local configuration file (sdk path, etc)\r
+local.properties\r
+\r
+# Proguard folder generated by Eclipse \r
+proguard/ \r
+\r
+# Windows thumbnail db\r
+Thumbs.db\r
+\r
+# OSX files\r
+.DS_Store\r
+\r
+# Eclipse project files\r
+.classpath\r
+.project\r
+\r
+#Android Studio & Gradle\r
+.gradle\r
+/local.properties\r
+/.idea/workspace.xml\r
+/.idea/libraries\r
+.DS_Store\r
+/build/*\r
+/base/build/*\r
+/base/obj/*\r
+/base/libs/*\r
+/sample/*\r
+\r
+#Some older projects\r
+/*/out\r
+/*/*/build\r
+/*/*/production\r
+*.iws\r
+*.ipr\r
+*~\r
+*.swp
\ No newline at end of file
diff --git a/service/easy-setup/sdk/android/EasySetupCore/.classpath b/service/easy-setup/sdk/android/EasySetupCore/.classpath
new file mode 100644 (file)
index 0000000..b76ec6c
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+       <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>\r
+       <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>\r
+       <classpathentry kind="src" path="src"/>\r
+       <classpathentry kind="src" path="gen"/>\r
+       <classpathentry kind="output" path="bin/classes"/>\r
+</classpath>\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/.project b/service/easy-setup/sdk/android/EasySetupCore/.project
new file mode 100644 (file)
index 0000000..ad4699b
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<projectDescription>\r
+       <name>EasySetupCore</name>\r
+       <comment></comment>\r
+       <projects>\r
+       </projects>\r
+       <buildSpec>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>org.eclipse.jdt.core.javabuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+               <buildCommand>\r
+                       <name>com.android.ide.eclipse.adt.ApkBuilder</name>\r
+                       <arguments>\r
+                       </arguments>\r
+               </buildCommand>\r
+       </buildSpec>\r
+       <natures>\r
+               <nature>com.android.ide.eclipse.adt.AndroidNature</nature>\r
+               <nature>org.eclipse.jdt.core.javanature</nature>\r
+       </natures>\r
+</projectDescription>\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/AndroidManifest.xml b/service/easy-setup/sdk/android/EasySetupCore/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..c1cf70e
--- /dev/null
@@ -0,0 +1,17 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="org.iotivity.service.easysetup"\r
+    android:versionCode="1"\r
+    android:versionName="1.0" >\r
+\r
+    <uses-sdk\r
+        android:minSdkVersion="8"\r
+        android:targetSdkVersion="21" />\r
+\r
+    <application\r
+        android:allowBackup="true"\r
+        android:icon="@drawable/ic_launcher"\r
+        android:label="@string/app_name"\r
+        android:theme="@style/AppTheme" >\r
+    </application>\r
+\r
+</manifest>\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/project.properties b/service/easy-setup/sdk/android/EasySetupCore/project.properties
new file mode 100644 (file)
index 0000000..93c8c3c
--- /dev/null
@@ -0,0 +1,15 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=android-21
+android.library=true
diff --git a/service/easy-setup/sdk/android/EasySetupCore/res/drawable-hdpi/ic_launcher.png b/service/easy-setup/sdk/android/EasySetupCore/res/drawable-hdpi/ic_launcher.png
new file mode 100644 (file)
index 0000000..288b665
Binary files /dev/null and b/service/easy-setup/sdk/android/EasySetupCore/res/drawable-hdpi/ic_launcher.png differ
diff --git a/service/easy-setup/sdk/android/EasySetupCore/res/values/strings.xml b/service/easy-setup/sdk/android/EasySetupCore/res/values/strings.xml
new file mode 100644 (file)
index 0000000..6ce9178
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>\r
+\r
+    <string name="app_name">EasySetupCore</string>\r
+\r
+</resources>\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/res/values/styles.xml b/service/easy-setup/sdk/android/EasySetupCore/res/values/styles.xml
new file mode 100644 (file)
index 0000000..4ea9326
--- /dev/null
@@ -0,0 +1,20 @@
+<resources>\r
+\r
+    <!--\r
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.\r
+    -->\r
+    <style name="AppBaseTheme" parent="android:Theme.Light">\r
+        <!--\r
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.\r
+        -->\r
+    </style>\r
+\r
+    <!-- Application theme. -->\r
+    <style name="AppTheme" parent="AppBaseTheme">\r
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->\r
+    </style>\r
+\r
+</resources>\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupCallbackHandler.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupCallbackHandler.java
new file mode 100644 (file)
index 0000000..5c59c97
--- /dev/null
@@ -0,0 +1,53 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+package org.iotivity.service.easysetup.mediator;\r
+\r
+import android.util.Log;\r
+\r
+public class EasySetupCallbackHandler {\r
+    private static final String             TAG = "EasySetupCallbackHandler";\r
+    ProvisionEnrollee                       provisioningListener;\r
+\r
+    private static EasySetupCallbackHandler easySetupCallbackHandlerObj;\r
+\r
+    public static synchronized EasySetupCallbackHandler getInstance() {\r
+        if (null == easySetupCallbackHandlerObj) {\r
+            easySetupCallbackHandlerObj = new EasySetupCallbackHandler();\r
+        }\r
+        return easySetupCallbackHandlerObj;\r
+    }\r
+\r
+    public void ProvisioningStatusCallBack(int statuscode) {\r
+        // TODO Auto-generated method stub\r
+        Log.d(TAG,\r
+                "onFinishProvisioning() inside Android Java application. statuscode - "\r
+                        + statuscode);\r
+        if (this.provisioningListener != null) {\r
+            this.provisioningListener.ProvisioningStatusCallBack(statuscode);\r
+        } else {\r
+            Log.e(TAG, "provisioningListener is not registered");\r
+        }\r
+    }\r
+\r
+    public void registerProvisioningHandler(\r
+            ProvisionEnrollee provisioningListener) {\r
+        this.provisioningListener = provisioningListener;\r
+    }\r
+}\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupManager.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EasySetupManager.java
new file mode 100644 (file)
index 0000000..f5cea15
--- /dev/null
@@ -0,0 +1,95 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+package org.iotivity.service.easysetup.mediator;\r
+\r
+import android.content.Context;\r
+\r
+//import org.iotivity.ca.CaInterface;\r
+\r
+public class EasySetupManager {\r
+    private native void InitEasySetup();\r
+\r
+    private native void TerminateEasySetup();\r
+\r
+    // TODO : "OcConnectivityType connectivityType" has to be passed as the\r
+    // second parameter for PerformEasySetup\r
+    // instead of integer\r
+    private native void ProvisionEnrollee(String ipAddress, String netSSID,\r
+            String netPWD, int connectivityType);\r
+\r
+    private native void StopEnrolleeProvisioning(int connectivityType);\r
+\r
+    public static native void initialize(Context context);\r
+\r
+    private static EasySetupManager easySetupManagerInterfaceObj = null;\r
+    private Context                 appContext                   = null;\r
+\r
+    static {\r
+        // Load Easy Setup JNI interface\r
+        System.loadLibrary("gnustl_shared");\r
+        System.loadLibrary("octbstack");\r
+        System.loadLibrary("oc");\r
+        System.loadLibrary("connectivity_abstraction");\r
+        System.loadLibrary("ca-interface");\r
+        System.loadLibrary("ESSDK");\r
+        System.loadLibrary("easysetup-jni");\r
+    }\r
+\r
+    private EasySetupManager() {\r
+\r
+    }\r
+\r
+    /**\r
+     * Function for Getting instance of EasySetupManager object.\r
+     *\r
+     * @return EasySetupManager instance.\r
+     *\r
+     */\r
+    public static synchronized EasySetupManager getInstance() {\r
+        if (null == easySetupManagerInterfaceObj) {\r
+            easySetupManagerInterfaceObj = new EasySetupManager();\r
+        }\r
+        return easySetupManagerInterfaceObj;\r
+    }\r
+\r
+    public void setApplicationContext(Context context) {\r
+        appContext = context;\r
+    }\r
+\r
+    public void initEasySetup() {\r
+        // CaInterface.initialize(appContext);\r
+        InitEasySetup();\r
+    }\r
+\r
+    public void terminateEasySetup() {\r
+        TerminateEasySetup();\r
+    }\r
+\r
+    public void provisionEnrollee(String ipAddress, String netSSID,\r
+            String netPWD, int connectivityType) {\r
+\r
+        ProvisionEnrollee(ipAddress, netSSID, netPWD, connectivityType);\r
+    }\r
+\r
+    public void stopEnrolleeProvisioning(int connectivityType) {\r
+        StopEnrolleeProvisioning(connectivityType);\r
+    }\r
+\r
+}\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeInfo.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeInfo.java
new file mode 100644 (file)
index 0000000..a00758e
--- /dev/null
@@ -0,0 +1,62 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+package org.iotivity.service.easysetup.mediator;
+
+public class EnrolleeInfo {
+
+    private String  IpAddr;
+    private String  HWAddr;
+    private String  Device;
+    private boolean isReachable;
+
+    public String getIpAddr() {
+        return IpAddr;
+    }
+
+    public void setIpAddr(String ipAddr) {
+        IpAddr = ipAddr;
+    }
+
+    public String getHWAddr() {
+        return HWAddr;
+    }
+
+    public void setHWAddr(String hWAddr) {
+        HWAddr = hWAddr;
+    }
+
+    public String getDevice() {
+        return Device;
+    }
+
+    public void setDevice(String device) {
+        Device = device;
+    }
+
+    public boolean isReachable() {
+        return isReachable;
+    }
+
+    public void setReachable(boolean isReachable) {
+        this.isReachable = isReachable;
+    }
+
+}
\ No newline at end of file
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeOnBoardingInfo.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/EnrolleeOnBoardingInfo.java
new file mode 100644 (file)
index 0000000..161b7fb
--- /dev/null
@@ -0,0 +1,90 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.service.easysetup.mediator;
+
+public class EnrolleeOnBoardingInfo {
+
+    private String  IpAddr;
+    private String  HWAddr;
+    private String  Device;
+    private boolean isReachable;
+    private boolean isAdditionNotified;
+    private boolean isRemovalNotified;
+
+    public EnrolleeOnBoardingInfo(String ipAddr, String hWAddr, String device,
+            boolean isReachable, boolean isRemovalNotified,
+            boolean isAdditionNotified) {
+        this.IpAddr = ipAddr;
+        this.HWAddr = hWAddr;
+        this.Device = device;
+        this.isReachable = isReachable;
+        this.isRemovalNotified = isRemovalNotified;
+        this.isAdditionNotified = isAdditionNotified;
+    }
+
+    public String getIpAddr() {
+        return IpAddr;
+    }
+
+    public void setIpAddr(String ipAddr) {
+        IpAddr = ipAddr;
+    }
+
+    public String getHWAddr() {
+        return HWAddr;
+    }
+
+    public void setHWAddr(String hWAddr) {
+        HWAddr = hWAddr;
+    }
+
+    public String getDevice() {
+        return Device;
+    }
+
+    public void setDevice(String device) {
+        Device = device;
+    }
+
+    public boolean isReachable() {
+        return isReachable;
+    }
+
+    public void setReachable(boolean isReachable) {
+        this.isReachable = isReachable;
+    }
+
+    public boolean isRemovalNotified() {
+        return isRemovalNotified;
+    }
+
+    public void setRemovalNotified(boolean isRemovalNotified) {
+        this.isRemovalNotified = isRemovalNotified;
+    }
+
+    public boolean isAdditionNotified() {
+        return isAdditionNotified;
+    }
+
+    public void setAdditionNotified(boolean isAdditionNotified) {
+        this.isAdditionNotified = isAdditionNotified;
+    }
+
+}
\ No newline at end of file
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IOnBoardingStatus.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IOnBoardingStatus.java
new file mode 100644 (file)
index 0000000..fff0634
--- /dev/null
@@ -0,0 +1,38 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.service.easysetup.mediator;
+
+import java.util.ArrayList;
+
+import org.iotivity.service.easysetup.mediator.EnrolleeInfo;
+
+public interface IOnBoardingStatus {
+
+    /**
+     * Interface called when the scan method finishes. Network operations should
+     * not execute on UI thread
+     * 
+     * @param ArrayList
+     *            of {@link EnrolleeInfo}
+     */
+
+    public void deviceOnBoardingStatus(EnrolleeInfo clients);
+
+}
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IProvisioningListener.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/IProvisioningListener.java
new file mode 100644 (file)
index 0000000..a178401
--- /dev/null
@@ -0,0 +1,28 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+package org.iotivity.service.easysetup.mediator;\r
+\r
+public interface IProvisioningListener {\r
+    /**\r
+     * Interface called when the provisioning finishes\r
+     */\r
+\r
+    public void onFinishProvisioning(int statuscode);\r
+}\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/OnBoardEnrollee.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/OnBoardEnrollee.java
new file mode 100644 (file)
index 0000000..2f07442
--- /dev/null
@@ -0,0 +1,53 @@
+/******************************************************************\r
+ *\r
+ * Copyright 2015 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+package org.iotivity.service.easysetup.mediator;\r
+\r
+import android.content.Context;\r
+import android.net.wifi.WifiConfiguration;\r
+import android.widget.Toast;\r
+\r
+public class OnBoardEnrollee {\r
+    WiFiSoftAPManager wifiSoftAPManager;\r
+    IOnBoardingStatus deviceScanListener;\r
+\r
+    /**\r
+     * Constructor for OnBoardEnrollee. Constructs a new OnBoardEnrollee.\r
+     */\r
+    public OnBoardEnrollee(Context context) {\r
+        wifiSoftAPManager = new WiFiSoftAPManager(context);\r
+    }\r
+\r
+    public void registerOnBoardingStatusHandler(\r
+            IOnBoardingStatus deviceScanListener) {\r
+        this.deviceScanListener = deviceScanListener;\r
+    }\r
+\r
+    public void startDeviceScan() {\r
+        wifiSoftAPManager.getClientList(false, this.deviceScanListener);\r
+    }\r
+\r
+    public void enableWiFiAP(WifiConfiguration netConfig, boolean enabled) {\r
+        wifiSoftAPManager.setWifiApEnabled(netConfig, true);\r
+    }\r
+\r
+    public void disableWiFiAP() {\r
+        wifiSoftAPManager.setWifiApEnabled(null, false);\r
+    }\r
+}\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/ProvisionEnrollee.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/ProvisionEnrollee.java
new file mode 100644 (file)
index 0000000..a315aa2
--- /dev/null
@@ -0,0 +1,52 @@
+package org.iotivity.service.easysetup.mediator;\r
+\r
+import android.content.Context;\r
+import android.util.Log;\r
+\r
+public class ProvisionEnrollee {\r
+    private static final String   TAG                            = "ProvisionEnrollee";\r
+    private Context               appContext                     = null;\r
+    private EasySetupManager      easySetupManagerNativeInstance = null;\r
+    private IProvisioningListener provisioningListener;\r
+\r
+    /**\r
+     * Constructor for ProvisionEnrollee. Constructs a new ProvisionEnrollee.\r
+     */\r
+    public ProvisionEnrollee(Context context) {\r
+        appContext = context;\r
+        easySetupManagerNativeInstance = EasySetupManager.getInstance();\r
+        easySetupManagerNativeInstance.initEasySetup();\r
+    }\r
+    \r
+    @Override\r
+    protected void finalize() throws Throwable {\r
+        super.finalize();\r
+        easySetupManagerNativeInstance.terminateEasySetup();\r
+    }\r
+\r
+    public void provisionEnrollee(String ipAddress, String netSSID,\r
+            String netPWD, int connectivityType) {\r
+        easySetupManagerNativeInstance.provisionEnrollee(ipAddress, netSSID,\r
+                netPWD, connectivityType);\r
+    }\r
+\r
+    public void stopEnrolleeProvisioning(int connectivityType) {\r
+        easySetupManagerNativeInstance\r
+                .stopEnrolleeProvisioning(connectivityType);\r
+    }\r
+\r
+    public void ProvisioningStatusCallBack(int statuscode) {\r
+        // TODO Auto-generated method stub\r
+        Log.d(TAG,\r
+                "onFinishProvisioning() inside Android Java application. statuscode - "\r
+                        + statuscode);\r
+        this.provisioningListener.onFinishProvisioning(statuscode);\r
+    }\r
+\r
+    public void registerProvisioningHandler(\r
+            IProvisioningListener provisioningListener) {\r
+        this.provisioningListener = provisioningListener;\r
+        EasySetupCallbackHandler.getInstance()\r
+                .registerProvisioningHandler(this);\r
+    }\r
+}\r
diff --git a/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/WiFiSoftAPManager.java b/service/easy-setup/sdk/android/EasySetupCore/src/org/iotivity/service/easysetup/mediator/WiFiSoftAPManager.java
new file mode 100644 (file)
index 0000000..0c51b22
--- /dev/null
@@ -0,0 +1,342 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.service.easysetup.mediator;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Handler;
+import android.util.Log;
+
+public class WiFiSoftAPManager {
+    private final WifiManager                mWifiManager;
+    private Context                          context;
+    static ArrayList<EnrolleeOnBoardingInfo> appNotification = new ArrayList<EnrolleeOnBoardingInfo>();
+    IOnBoardingStatus                        finishListener  = null;
+
+    public enum WIFI_AP_STATE {
+        WIFI_AP_STATE_DISABLING, WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_ENABLING, WIFI_AP_STATE_ENABLED, WIFI_AP_STATE_FAILED
+    }
+
+    public WiFiSoftAPManager(Context context) {
+        this.context = context;
+        mWifiManager = (WifiManager) this.context
+                .getSystemService(Context.WIFI_SERVICE);
+    }
+
+    /**
+     * Start AccessPoint mode with the specified configuration. If the radio is
+     * already running in AP mode, update the new configuration Note that
+     * starting in access point mode disables station mode operation
+     *
+     * @param wifiConfig
+     *            SSID, security and channel details as part of
+     *            WifiConfiguration
+     * @return {@code true} if the operation succeeds, {@code false} otherwise
+     */
+    public boolean setWifiApEnabled(WifiConfiguration wifiConfig,
+            boolean enabled) {
+        try {
+            if (enabled) { // disable WiFi in any case
+                mWifiManager.setWifiEnabled(false);
+            }
+
+            Method method = mWifiManager.getClass().getMethod(
+                    "setWifiApEnabled", WifiConfiguration.class, boolean.class);
+            return (Boolean) method.invoke(mWifiManager, wifiConfig, enabled);
+        } catch (Exception e) {
+            Log.e(this.getClass().toString(), "", e);
+            return false;
+        }
+    }
+
+    /**
+     * Gets the Wi-Fi enabled state.
+     *
+     * @return {@link WIFI_AP_STATE}
+     * @see #isWifiApEnabled()
+     */
+    public WIFI_AP_STATE getWifiApState() {
+        try {
+            Method method = mWifiManager.getClass().getMethod("getWifiApState");
+
+            int tmp = ((Integer) method.invoke(mWifiManager));
+
+            // Fix for Android 4
+            if (tmp >= 10) {
+                tmp = tmp - 10;
+            }
+
+            return WIFI_AP_STATE.class.getEnumConstants()[tmp];
+        } catch (Exception e) {
+            Log.e(this.getClass().toString(), "", e);
+            return WIFI_AP_STATE.WIFI_AP_STATE_FAILED;
+        }
+    }
+
+    /**
+     * Return whether Wi-Fi AP is enabled or disabled.
+     *
+     * @return {@code true} if Wi-Fi AP is enabled
+     * @see #getWifiApState()
+     *
+     * @hide Dont open yet
+     */
+    public boolean isWifiApEnabled() {
+        return getWifiApState() == WIFI_AP_STATE.WIFI_AP_STATE_ENABLED;
+    }
+
+    /**
+     * Gets the Wi-Fi AP Configuration.
+     *
+     * @return AP details in {@link WifiConfiguration}
+     */
+    public WifiConfiguration getWifiApConfiguration() {
+        try {
+            Method method = mWifiManager.getClass().getMethod(
+                    "getWifiApConfiguration");
+            return (WifiConfiguration) method.invoke(mWifiManager);
+        } catch (Exception e) {
+            Log.e(this.getClass().toString(), "", e);
+            return null;
+        }
+    }
+
+    /**
+     * Sets the Wi-Fi AP Configuration.
+     *
+     * @return {@code true} if the operation succeeded, {@code false} otherwise
+     */
+    public boolean setWifiApConfiguration(WifiConfiguration wifiConfig) {
+        try {
+            Method method = mWifiManager.getClass().getMethod(
+                    "setWifiApConfiguration", WifiConfiguration.class);
+            return (Boolean) method.invoke(mWifiManager, wifiConfig);
+        } catch (Exception e) {
+            Log.e(this.getClass().toString(), "", e);
+            return false;
+        }
+    }
+
+    /**
+     * Gets a list of the clients connected to the Hotspot, reachable timeout is
+     * 300
+     *
+     * @param onlyReachables
+     *            {@code false} if the list should contain unreachable (probably
+     *            disconnected) clients, {@code true} otherwise
+     * @param finishListener
+     *            , Interface called when the scan method finishes
+     */
+    public void getClientList(boolean onlyReachables,
+            IOnBoardingStatus finishListener) {
+        this.finishListener = finishListener;
+        getClientList(onlyReachables, 300);
+    }
+
+    /**
+     * Gets a list of the clients connected to the Hotspot
+     *
+     * @param onlyReachables
+     *            {@code false} if the list should contain unreachable (probably
+     *            disconnected) clients, {@code true} otherwise
+     * @param reachableTimeout
+     *            Reachable Timeout in miliseconds
+     * @param finishListener
+     *            , Interface called when the scan method finishes
+     */
+    public void getClientList(final boolean onlyReachables,
+            final int reachableTimeout) {
+
+        Runnable runnable = new Runnable() {
+            public void run() {
+
+                BufferedReader br = null;
+                final EnrolleeInfo result = new EnrolleeInfo();
+
+                try {
+                    br = new BufferedReader(new FileReader("/proc/net/arp"));
+                    String line;
+                    while ((line = br.readLine()) != null) {
+                        boolean deviceAddedToList = false;
+
+                        String[] splitted = line.split(" +");
+
+                        if ((splitted != null) && (splitted.length >= 4)) {
+                            // Basic sanity check
+                            String mac = splitted[3];
+
+                            if (mac.matches("..:..:..:..:..:..")) {
+                                boolean isReachable = InetAddress.getByName(
+                                        splitted[0]).isReachable(
+                                        reachableTimeout);
+
+                                // String execStatement =
+                                // "ping -c 1 "+splitted[0];
+                                //
+                                // Process p1 =
+                                // java.lang.Runtime.getRuntime().exec(execStatement);
+                                //
+                                // int returnVal = p1.waitFor();
+                                // boolean isReachable = (returnVal==0);
+
+                                Log.i("exec statement", splitted[0]);
+                                Log.i("Return Value", " " + isReachable);
+
+                                if (appNotification.size() > 0) {
+                                    for (EnrolleeOnBoardingInfo ipDeviceOnBoardingNotification : appNotification) {
+                                        boolean macAddressComparison = ipDeviceOnBoardingNotification
+                                                .getHWAddr().equalsIgnoreCase(
+                                                        mac) ? true : false;
+
+                                        if (macAddressComparison) {
+                                            deviceAddedToList = true;
+
+                                            if (ipDeviceOnBoardingNotification
+                                                    .isAdditionNotified()
+                                                    && isReachable) {
+                                                continue;
+                                            } else if (ipDeviceOnBoardingNotification
+                                                    .isRemovalNotified()
+                                                    && !isReachable) {
+                                                continue;
+                                            } else {
+                                                result.setIpAddr(splitted[0]);
+                                                result.setHWAddr(splitted[3]);
+                                                result.setDevice(splitted[5]);
+                                                result.setReachable(isReachable);
+
+                                                appNotification
+                                                        .remove(ipDeviceOnBoardingNotification);
+                                                if (isReachable) {
+                                                    appNotification
+                                                            .add(new EnrolleeOnBoardingInfo(
+                                                                    splitted[0],
+                                                                    splitted[3],
+                                                                    splitted[5],
+                                                                    isReachable,
+                                                                    false, true));
+                                                } else {
+                                                    appNotification
+                                                            .add(new EnrolleeOnBoardingInfo(
+                                                                    splitted[0],
+                                                                    splitted[3],
+                                                                    splitted[5],
+                                                                    isReachable,
+                                                                    true, false));
+                                                }
+
+                                                NotifyApplication(result);
+                                            }
+                                        }
+                                    }
+                                    if (!deviceAddedToList) {
+                                        if (isReachable) {
+                                            appNotification
+                                                    .add(new EnrolleeOnBoardingInfo(
+                                                            splitted[0],
+                                                            splitted[3],
+                                                            splitted[5],
+                                                            isReachable, false,
+                                                            true));
+                                        } else {
+                                            appNotification
+                                                    .add(new EnrolleeOnBoardingInfo(
+                                                            splitted[0],
+                                                            splitted[3],
+                                                            splitted[5],
+                                                            isReachable, true,
+                                                            false));
+                                        }
+
+                                        result.setIpAddr(splitted[0]);
+                                        result.setHWAddr(splitted[3]);
+                                        result.setDevice(splitted[5]);
+                                        result.setReachable(isReachable);
+
+                                        NotifyApplication(result);
+
+                                        break;
+                                    }
+                                } else {
+                                    if (isReachable) {
+                                        appNotification
+                                                .add(new EnrolleeOnBoardingInfo(
+                                                        splitted[0],
+                                                        splitted[3],
+                                                        splitted[5],
+                                                        isReachable, false,
+                                                        true));
+                                    } else {
+                                        appNotification
+                                                .add(new EnrolleeOnBoardingInfo(
+                                                        splitted[0],
+                                                        splitted[3],
+                                                        splitted[5],
+                                                        isReachable, true,
+                                                        false));
+                                    }
+
+                                    result.setIpAddr(splitted[0]);
+                                    result.setHWAddr(splitted[3]);
+                                    result.setDevice(splitted[5]);
+                                    result.setReachable(isReachable);
+
+                                    NotifyApplication(result);
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    Log.e(this.getClass().toString(), e.toString());
+                } finally {
+                    try {
+                        br.close();
+                    } catch (IOException e) {
+                        Log.e(this.getClass().toString(), e.getMessage());
+                    }
+                }
+            }
+        };
+
+        Thread mythread = new Thread(runnable);
+        mythread.start();
+    }
+
+    void NotifyApplication(final EnrolleeInfo result) {
+        // Get a handler that can be used to post to the main thread
+        Handler mainHandler = new Handler(context.getMainLooper());
+        Runnable myRunnable = new Runnable() {
+            @Override
+            public void run() {
+                finishListener.deviceOnBoardingStatus(result);
+            }
+        };
+        mainHandler.post(myRunnable);
+    }
+}
diff --git a/service/easy-setup/sdk/android/jni/Android.mk b/service/easy-setup/sdk/android/jni/Android.mk
new file mode 100644 (file)
index 0000000..8a0df30
--- /dev/null
@@ -0,0 +1,112 @@
+LOCAL_PATH := $(call my-dir)
+
+ifeq ($(strip $(ANDROID_NDK)),)
+$(error ANDROID_NDK is not set!)
+endif
+
+$(warning "Current path" $(LOCAL_PATH))
+$(info TC_PREFIX=$(TOOLCHAIN_PREFIX))
+$(info CFLAGS=$(TARGET_CFLAGS))
+$(info CXXFLAGS=$(TARGET_CXXFLAGS) $(TARGET_NO_EXECUTE_CFLAGS))
+$(info CPPFLAGS=$(TARGET_CPPFLAGS))
+$(info CPPPATH=$(TARGET_C_INCLUDES) $(__ndk_modules.$(APP_STL).EXPORT_C_INCLUDES))
+$(info SYSROOT=$(SYSROOT_LINK))
+$(info LDFLAGS=$(TARGET_LDFLAGS) $(TARGET_NO_EXECUTE_LDFLAGS) $(TARGET_NO_UNDEFINED_LDFLAGS) $(TARGET_RELRO_LDFLAGS))
+$(info TC_VER=$(TOOLCHAIN_VERSION))
+$(info PLATFORM=$(APP_PLATFORM))
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../dep/android/$(TARGET_ARCH_ABI)/usr/lib
+LOCAL_MODULE := libandroid-boost_system
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libboost_system.a
+include $(PREBUILT_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/debug
+LOCAL_MODULE := android-oc_logger
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc_logger.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/debug
+LOCAL_MODULE := android-octbstack
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboctbstack.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/debug
+LOCAL_MODULE := android-oc
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboc.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/debug
+LOCAL_MODULE := android-connectivity_abstraction
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../android/android_api/base/libs/$(TARGET_ARCH_ABI)
+LOCAL_MODULE := android-ocstack-jni
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libocstack-jni.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../android/android_api/base/libs/$(TARGET_ARCH_ABI)
+LOCAL_MODULE := android-ca-interface
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libca-interface.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+OIC_LIB_PATH := ../../../../../out/android/$(TARGET_ARCH_ABI)/debug
+LOCAL_MODULE := android-easysetup
+LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libESSDK.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE    := easysetup-jni
+
+#Add Pre processor definitions
+DEFINE_FLAG =  -DWITH_POSIX -D__ANDROID__
+
+#Add Debug flags here
+DEBUG_FLAG      = -DTB_LOG
+
+BUILD_FLAG = $(DEFINE_FLAG) $(DEBUG_FLAG)
+
+LOCAL_CPPFLAGS = $(BUILD_FLAG)
+LOCAL_CPPFLAGS += -std=c++0x -frtti -fexceptions
+
+$(info CPPFLAGSUPDATED=$(LOCAL_CPPFLAGS))
+
+NDK_ROOT         := /home/madan/android-ndk-r10d
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH) \
+                                       $(LOCAL_PATH)/jniutil/inc \
+                                       $(LOCAL_PATH)/../../../../../service/easy-setup/sdk/inc \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/logger/include \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/connectivity/common/inc \
+                                       $(LOCAL_PATH)/../../../../../resource/include \
+                                       $(LOCAL_PATH)/../../../../../resource/oc_logger/include \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/ocmalloc/include \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/connectivity/api \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/stack/include \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/logger/include \
+                                       $(LOCAL_PATH)/../../../../../resource/csdk/security/include \
+                                       $(LOCAL_PATH)/../../../../../extlibs/cjson \
+                                       $(LOCAL_PATH)/../../../../../extlibs/boost/boost_1_58_0 \
+                    $(LOCAL_PATH)/../../../../../extlibs/timer \
+                                       $(LOCAL_PATH)/../../../../../android/android_api/base/jni \
+                                       $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/include \
+                    $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI)/include \
+                                       
+LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/jni_easy_setup.cpp))
+LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/jniutil/src/*.cpp))
+
+LOCAL_LDLIBS := -llog
+LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI)
+LOCAL_SHARED_LIBRARIES := android-easysetup
+LOCAL_STATIC_LIBRARIES := android-boost_system
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/service/easy-setup/sdk/android/jni/Application.mk b/service/easy-setup/sdk/android/jni/Application.mk
new file mode 100644 (file)
index 0000000..fff0785
--- /dev/null
@@ -0,0 +1,3 @@
+APP_STL               := gnustl_shared
+NDK_TOOLCHAIN_VERSION := 4.8
+
diff --git a/service/easy-setup/sdk/android/jni/jni_easy_setup.cpp b/service/easy-setup/sdk/android/jni/jni_easy_setup.cpp
new file mode 100644 (file)
index 0000000..8ea6049
--- /dev/null
@@ -0,0 +1,171 @@
+//******************************************************************\r
+//\r
+// Copyright 2015 Samsung Electronics All Rights Reserved.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+//\r
+// Licensed under the Apache License, Version 2.0 (the "License");\r
+// you may not use this file except in compliance with the License.\r
+// You may obtain a copy of the License at\r
+//\r
+//      http://www.apache.org/licenses/LICENSE-2.0\r
+//\r
+// Unless required by applicable law or agreed to in writing, software\r
+// distributed under the License is distributed on an "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+// See the License for the specific language governing permissions and\r
+// limitations under the License.\r
+//\r
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\r
+\r
+#include "jni_easy_setup.h"\r
+\r
+#include "jni_easy_setup_jvm.h"\r
+#include "easysetupmgr.h"\r
+\r
+void JNIProvisioningStatusCallback(ProvisioningInfo provInfo) {\r
+    JNIEnv *env = EasySetupJVM::getEnv();\r
+    if (env == NULL) {\r
+        LOGE("JNIProvisioningStatusCallback : Getting JNIEnv failed");\r
+        return;\r
+    }\r
+\r
+    // Get EasySetupHandler class reference\r
+    jclass easysetupCallbacks = GetJClass(\r
+            EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH);\r
+    if (NULL == easysetupCallbacks) {\r
+        LOGE(\r
+                "JNIProvisioningStatusCallback : GetJClass easysetupCallbacks failed");\r
+        EasySetupJVM::releaseEnv();\r
+        return;\r
+    }\r
+\r
+    // Get the easysetupCallback class instance\r
+    jobject jobjectCallback = GetJObjectInstance(\r
+            EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH);\r
+    if (NULL == jobjectCallback) {\r
+        LOGE("getInstance( %s) failed!",\r
+                EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH);\r
+        EasySetupJVM::releaseEnv();\r
+        return;\r
+    }\r
+\r
+    // Get onResourceCallback method reference\r
+    jmethodID method_id = env->GetMethodID(easysetupCallbacks,\r
+            "ProvisioningStatusCallBack",\r
+            METHOD_PROVISIONING_STATUS_INTEGER_CALLBACK);\r
+    if (NULL == method_id) {\r
+        LOGE(\r
+                "JNIProvisioningStatusCallback: onResourceCallback : GetMethodID failed");\r
+        EasySetupJVM::releaseEnv();\r
+        return;\r
+    }\r
+\r
+    if ((env)->ExceptionCheck()) {\r
+        LOGE("JNIProvisioningStatusCallback : ExceptionCheck failed");\r
+        EasySetupJVM::releaseEnv();\r
+        return;\r
+    }\r
+\r
+    if (NULL == method_id) {\r
+        LOGI("JNI method_id is NULL");\r
+    } else {\r
+        LOGI("JNI method_id is VALID");\r
+\r
+        jint result;\r
+        if (provInfo.provStatus == DEVICE_PROVISIONED) {\r
+            result = 0;\r
+        } else {\r
+            result = -1;\r
+        }\r
+\r
+        env->CallVoidMethod(jobjectCallback, method_id, (jint) result);\r
+    }\r
+\r
+    EasySetupJVM::releaseEnv();\r
+}\r
+\r
+JNIEXPORT void JNICALL JNIInitEasySetup(JNIEnv *env, jobject thisObj)\r
+{\r
+    LOGI("JNI JNIInitEasySetup: Enter");\r
+    InitEasySetupManager();\r
+    RegisterProvisioningStausCallback(JNIProvisioningStatusCallback);\r
+}\r
+\r
+JNIEXPORT void JNICALL JNITerminateEasySetup(JNIEnv *env, jobject thisObj)\r
+{\r
+    LOGI("JNI JNITerminateEasySetup: Enter");\r
+    TerminateEasySetupManager();\r
+}\r
+\r
+\r
+JNIEXPORT void JNICALL JNIProvisionEnrollee(JNIEnv *env, jobject thisObj,\r
+                                                    jstring jIPAddress,\r
+                                                    jstring jNetSSID,\r
+                                                    jstring jNetPWD,\r
+                                                    jint jConnectivityType)\r
+{\r
+    LOGI("JNI JNIProvisionEnrollee: Enter");\r
+\r
+    if (!jIPAddress)\r
+    {\r
+        LOGE("JNI JNIProvisionEnrollee : jIPAddress is NULL!");\r
+        return;\r
+    }\r
+\r
+    const char *ipAddress = env->GetStringUTFChars(jIPAddress, NULL);\r
+    if (NULL == ipAddress)\r
+    {\r
+        LOGE("JNI JNIProvisionEnrollee : Failed to convert jstring to char string!");\r
+    }\r
+\r
+    LOGI("JNI JNIProvisionEnrollee : ipAddress is : %s",ipAddress);\r
+\r
+    const char *netSSID = env->GetStringUTFChars(jNetSSID, NULL);\r
+    if (NULL == netSSID)\r
+    {\r
+        LOGE("JNI JNIProvisionEnrollee : Failed to convert jstring to char string!");\r
+    }\r
+\r
+    LOGI("JNI JNIProvisionEnrollee : netSSID is : %s",netSSID);\r
+\r
+    const char *netPWD = env->GetStringUTFChars(jNetPWD, NULL);\r
+    if (NULL == netPWD)\r
+    {\r
+        LOGE("JNI JNIProvisionEnrollee : Failed to convert jstring to char string!");\r
+    }\r
+\r
+    LOGI("JNI JNIProvisionEnrollee : netPWD is : %s",netPWD);\r
+\r
+    OCConnectivityType connecitivityType;\r
+    EnrolleeNWProvInfo_t netInfo = {0};\r
+\r
+    strncpy(netInfo.netAddressInfo.WIFI.ipAddress, ipAddress, IPV4_ADDR_SIZE);\r
+    strncpy(netInfo.netAddressInfo.WIFI.ssid, netSSID, NET_WIFI_SSID_SIZE);\r
+    strncpy(netInfo.netAddressInfo.WIFI.pwd, netPWD, NET_WIFI_PWD_SIZE);\r
+    netInfo.connType = OCConnectivityType::OC_IPV4;\r
+    netInfo.isSecured = true;\r
+\r
+    ProvisionEnrollee(&netInfo);\r
+\r
+    return;\r
+}\r
+\r
+JNIEXPORT void JNICALL JNIStopEnrolleeProvisioning(JNIEnv *env, jobject thisObj,\r
+                                                    jint jConnectivityType)\r
+{\r
+    LOGI("JNI Stop Easy Setup: Entering");\r
+\r
+    OCConnectivityType connecitivityType;\r
+\r
+    if(jConnectivityType == 0)\r
+    {\r
+        connecitivityType = OCConnectivityType::OC_IPV4;\r
+    }\r
+\r
+    StopEnrolleeProvisioning(connecitivityType);\r
+\r
+    return;\r
+}\r
+\r
+\r
diff --git a/service/easy-setup/sdk/android/jni/jni_easy_setup.h b/service/easy-setup/sdk/android/jni/jni_easy_setup.h
new file mode 100644 (file)
index 0000000..a69d657
--- /dev/null
@@ -0,0 +1,42 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include <jni.h>\r
+#include <jni_string.h>\r
+\r
+#include "JniOcStack.h"\r
+\r
+#define METHOD_PROVISIONING_STATUS_VOID_CALLBACK    "("")V"\r
+#define METHOD_PROVISIONING_STATUS_INTEGER_CALLBACK    "("EASY_SETUP_JAVA_INTEGER_TYPE")V"\r
+\r
+/* Header for class org_iotivity_service_easyconnect_java_EasySetupHandler */\r
+\r
+#ifndef _Included_org_iotivity_service_easysetup_java_EasySetupHandler\r
+#define _Included_org_iotivity_service_easysetup_java_EasySetupHandler\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+JNIEXPORT void JNICALL JNIInitEasySetup(JNIEnv *env, jobject thisObj);\r
+JNIEXPORT void JNICALL JNITerminateEasySetup(JNIEnv *env, jobject thisObj);\r
+\r
+/*\r
+ * Class:     org_iotivity_service_easyconnect_java_EasySetupHandler\r
+ * Method:    JNIProvisionEnrollee\r
+ * Signature: ()V\r
+ */\r
+JNIEXPORT void JNICALL JNIProvisionEnrollee(JNIEnv *env, jobject ,\r
+                                                jstring ,\r
+                                                jstring ,\r
+                                                jstring ,\r
+                                                jint jConnectivityType);\r
+\r
+JNIEXPORT void JNICALL JNIStopEnrolleeProvisioning(JNIEnv *, jobject, jint);\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif\r
diff --git a/service/easy-setup/sdk/android/jni/jniutil/inc/jni_easy_setup_jvm.h b/service/easy-setup/sdk/android/jni/jniutil/inc/jni_easy_setup_jvm.h
new file mode 100644 (file)
index 0000000..0e9e383
--- /dev/null
@@ -0,0 +1,94 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file   jni_easy_setup_jvm.h
+ *
+ * @brief  This file contains the essential declarations and functions required
+ *            for JNI implementation
+ */
+
+#ifndef __JNI_EASY_SETUP_JVM_H_
+#define __JNI_EASY_SETUP_JVM_H_
+
+#include <jni.h>
+#include <thread>
+#include <mutex>
+
+#define EASY_SETUP_SERVICE_NATIVE_API_CLASS_PATH    "org/iotivity/service/easysetup/mediator/EasySetupManager"
+#define EASY_SETUP_SERVICE_NATIVE_API_CLASS_TYPE    "Lorg/iotivity/service/easysetup/mediator/EasySetupManager;"
+#define EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH    "org/iotivity/service/easysetup/mediator/EasySetupCallbackHandler"
+#define EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_TYPE    "Lorg/iotivity/service/easysetup/mediator/EasySetupCallbackHandler;"
+
+#define EASY_SETUP_JAVA_STRING_TYPE "Ljava/lang/String;"
+#define EASY_SETUP_JAVA_INTEGER_TYPE "I"
+
+/**
+ * @class   EasySetupJVM
+ * @brief   This class provides functions related to JNI Environment.
+ *
+ */
+class EasySetupJVM {
+public:
+    /**
+     * @brief destructor
+     */
+    ~EasySetupJVM() {
+    }
+    ;
+
+    /**
+     * @brief  Get JVM instance
+     */
+    static JNIEnv *getEnv();
+
+    /**
+     * @brief  Release aquired JVM instance
+     */
+    static void releaseEnv();
+
+public:
+    /**
+     *  Java VM pointer
+     */
+    static JavaVM *m_jvm;
+
+private:
+    /**
+     * @brief constructor
+     */
+    EasySetupJVM();
+
+    /**
+     *  Mutex for thread synchronization
+     */
+    static std::mutex m_currentThreadMutex;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+jclass GetJClass(const char *szClassPath);
+jobject GetJObjectInstance(const char *szClassPath);
+#ifdef __cplusplus
+}
+#endif
+#endif //__JNI_EASY_SETUP_JVM_H_
+
diff --git a/service/easy-setup/sdk/android/jni/jniutil/inc/jni_getter.h b/service/easy-setup/sdk/android/jni/jniutil/inc/jni_getter.h
new file mode 100644 (file)
index 0000000..fe92a82
--- /dev/null
@@ -0,0 +1,111 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file   jni_getter.h
+ *
+ * @brief  This file contains the JGetter class  declarations and its functions required
+ *            for getting and setting basic data types in C++ and Java
+ */
+
+#ifndef __JNI_GETTER_H_
+#define __JNI_GETTER_H_
+
+#include <string>
+#include <jni.h>
+
+/**
+ * @class   JGetter
+ * @brief  This class provide utility for get/set basic data types in C++ and Java
+ *
+ */
+class JGetter {
+public:
+       /**
+        * This function is called to get String field from the C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject from which string field is expected
+        * @param fieldName
+        *           Name of the field to be extracted from JObject
+        * @param value
+        *         reference to string value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool getJStringField(JNIEnv *env, jobject &object,
+                       const char *fieldName, std::string &value);
+
+       /**
+        * This function is called to get Boolean field from the C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject from which boolean field is expected
+        * @param fieldName
+        *           Name of the field to be extracted from JObject
+        * @param value
+        *         reference to boolean value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool getJBoolField(JNIEnv *env, jobject &object,
+                       const char *fieldName, bool &value);
+
+       /**
+        * This function is called to get Integer field from the C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject from which integer field is expected
+        * @param fieldName
+        *           Name of the field to be extracted from JObject
+        * @param value
+        *         reference to integer value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool getJIntField(JNIEnv *env, jobject &object,
+                       const char *fieldName, int &value);
+
+       /**
+        * This function is called to get Object reference from the C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject from which Object reference is expected
+        * @param fieldName
+        *           Name of the field to be extracted from JObject
+        * @param fieldType
+        *           Type of the field to be extracted from JObject
+        * @param value
+        *         reference to Object reference mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool getJObjectField(JNIEnv *env, jobject &object,
+                       const char *fieldName, const char *fieldType, jobject &value);
+};
+#endif //__JNI_GETTER_H_
diff --git a/service/easy-setup/sdk/android/jni/jniutil/inc/jni_object.h b/service/easy-setup/sdk/android/jni/jniutil/inc/jni_object.h
new file mode 100644 (file)
index 0000000..5f27a47
--- /dev/null
@@ -0,0 +1,96 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file   jni_object.h
+ *
+ * @brief  This file contains the JObject class  declarations and its functions required
+ *            for getting and setting basic data types in C++ and Java
+ */
+
+#ifndef __JNI_OBJECT_H_
+#define __JNI_OBJECT_H_
+
+#include <jni.h>
+#include "JniOcResource.h"
+
+/**
+ * @class   JObject
+ * @brief   This class provides a set of functions for JNI object.
+ *
+ */
+class JObject {
+public:
+       /**
+        * @brief constructor
+        */
+       JObject(JNIEnv *env);
+
+       /**
+        * @brief constructor
+        */
+       JObject(JNIEnv *env, jobject obj);
+
+       /**
+        * @brief constructor
+        */
+       JObject(JNIEnv *env, const char *classPath);
+
+       /**
+        * @brief destructor
+        *
+        */
+       virtual ~JObject();
+
+       /**
+        * Function to get the jobject.
+        *
+        * @return jobject, returns a new JNI object or NULL otherwise.
+        *
+        */
+       virtual jobject getObject() const;
+
+       /**
+        * Function to detach the jobject.
+        *
+        * @return void
+        *
+        */
+       void detachObject();
+
+protected:
+       /**
+        *  JNI Environment Pointer
+        */
+       JNIEnv *m_pEnv;
+       /**
+        *  Java Object
+        */
+       jobject m_pObject;
+       /**
+        *  Java Class
+        */
+       jclass m_pClazz;
+       /**
+        *  Boolean variable to check if an object is new
+        */
+       bool m_fIsNewObject;
+};
+#endif //__JNI_OBJECT_H_
diff --git a/service/easy-setup/sdk/android/jni/jniutil/inc/jni_setter.h b/service/easy-setup/sdk/android/jni/jniutil/inc/jni_setter.h
new file mode 100644 (file)
index 0000000..c4593cc
--- /dev/null
@@ -0,0 +1,128 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file   jni_setter.h
+ *
+ * @brief  This file contains the JSetter class declarations and and its functions required
+ *            to set data types in C++ object from Java object
+ */
+
+#ifndef __JNI_SETTER_H_
+#define __JNI_SETTER_H_
+
+#include <jni.h>
+
+/**
+ * @class   JSetter
+ * @brief  This class provide utility to set data types in C++ object from Java object
+ *
+ */
+class JSetter {
+public:
+
+       /**
+        * This function is called to set Integer field in to C++ object.
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject to which integer field will be set.
+        * @param fieldName
+        *           Name of the field to be set in JObject
+        * @param value
+        *         integer value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool setJIntField(JNIEnv *env, jobject &object,
+                       const char *fieldName, int value);
+
+       /**
+        * This function is called to set Long field in to C++ object.
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject to which Long field will be set.
+        * @param fieldName
+        *           Name of the field to be set in JObject
+        * @param value
+        *         Long value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool setJLongField(JNIEnv *env, jobject &object,
+                       const char *fieldName, jlong value);
+
+       /**
+        * This function is called to Set Boolean field to C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject to which boolean field has to be set
+        * @param fieldName
+        *           Name of the field to be set in JObject
+        * @param value
+        *         boolean value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool setJBoolField(JNIEnv *env, jobject &object,
+                       const char *fieldName, bool value);
+       /**
+        * This function is called to Set String field from the C++ object
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject in which string value has to be set
+        * @param fieldName
+        *           Name of the field to be set in JObject
+        * @param value
+        *         string value mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool setJStringField(JNIEnv *env, jobject &object,
+                       const char *fieldName, const char *value);
+
+       /**
+        * This function is called to set Object reference in C++ object.
+        *
+        * @param env
+        *           JNI Environment reference
+        * @param object
+        *           JObject to which Object reference is to be set.
+        * @param fieldName
+        *           Name of the field to be set in JObject
+        * @param fieldType
+        *           Type of the field to be set in JObject
+        * @param value
+        *         value of Object mentioned in fieldName
+        *
+        * @return returns true on success and false on failer.
+        */
+       static bool setJObjectField(JNIEnv *env, jobject &object,
+                       const char *fieldName, const char *fieldType, const jobject value);
+};
+
+#endif //__JNI_SETTER_H_
diff --git a/service/easy-setup/sdk/android/jni/jniutil/inc/jni_string.h b/service/easy-setup/sdk/android/jni/jniutil/inc/jni_string.h
new file mode 100644 (file)
index 0000000..358e869
--- /dev/null
@@ -0,0 +1,80 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @file   jni_string.h
+ *
+ * @brief  This file contains the declaration of JString class and its members related to JString.
+ *
+ */
+
+#ifndef __JNI_STRING_H_
+#define __JNI_STRING_H_
+
+#include <string>
+
+#include "jni_object.h"
+
+/**
+ * @class   JString
+ * @brief   This class inherits JObject class and provides a set of functions for JNI String.
+ *
+ */
+class JString: public JObject {
+public:
+       /**
+        * @brief constructor
+        */
+       JString(JNIEnv *env, jstring value);
+       /**
+        * @brief constructor
+        */
+       JString(JNIEnv *env, const char *value);
+       /**
+        * @brief constructor
+        */
+       JString(JNIEnv *env, const std::string &value);
+       /**
+        * @brief destructor
+        */
+       ~JString();
+
+       /**
+        * Function to get the string value and set it.
+        *
+        * @param value - String value to set to a private member variable.
+        *
+        * @return bool - true on success
+        *
+        */
+       bool getValue(std::string &value);
+
+       /**
+        * Function to get the private string value.
+        *
+        * @return  C String value.
+        *
+        */
+       const char *c_str();
+
+private:
+       std::string m_cstr;
+};
+#endif //__JNI_STRING_H_
diff --git a/service/easy-setup/sdk/android/jni/jniutil/src/jni_easy_setup_jvm.cpp b/service/easy-setup/sdk/android/jni/jniutil/src/jni_easy_setup_jvm.cpp
new file mode 100644 (file)
index 0000000..acfe662
--- /dev/null
@@ -0,0 +1,318 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_easy_setup_jvm.h"
+#include <string>
+#include "jni_easy_setup.h"
+
+/**
+ * @class   JClassMap
+ * @brief   This class provides functions for initializing the Java class path and Java class.
+ *
+ */
+class JClassMap {
+public:
+    /**
+     *  Java Class
+     */
+    jclass classRef;
+    /**
+     *  Java Class Path
+     */
+    const char *szClassPath;
+
+    /**
+     * @brief constructor
+     */
+    JClassMap(const char *path) :
+            classRef(NULL) {
+        szClassPath = path;
+    }
+};
+
+/**
+ * @class   JObjectMap
+ * @brief   This class provides functins for initializing the Java Class path and Java Class
+ * Object.
+ *
+ */
+class JObjectMap {
+public:
+    /**
+     *  Java Object
+     */
+    jobject object;
+    /**
+     *  Java Class Path
+     */
+    const char *szClassPath;
+
+    /**
+     * @brief constructor
+     */
+    JObjectMap(const char *path) :
+            object(NULL) {
+        szClassPath = path;
+    }
+};
+
+static JClassMap gJClassMapArray[] = { JClassMap(
+        EASY_SETUP_SERVICE_NATIVE_API_CLASS_PATH), JClassMap(
+        EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH) };
+
+static JObjectMap gJObjectMapArray[] = { JObjectMap(
+        EASY_SETUP_SERVICE_CALLBACK_NATIVE_API_CLASS_PATH) };
+
+static JNINativeMethod gEasySetupMethodTable[] = {
+    { "InitEasySetup", "()V", (void *) JNIInitEasySetup },
+    { "TerminateEasySetup", "()V", (void *) JNITerminateEasySetup },
+    { "ProvisionEnrollee", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V",
+                                (void *) JNIProvisionEnrollee },
+    { "StopEnrolleeProvisioning", "(I)V", (void *) JNIStopEnrolleeProvisioning }, };
+
+static int gEasySetupMethodTableSize = sizeof(gEasySetupMethodTable)
+        / sizeof(gEasySetupMethodTable[0]);
+
+int InitializeJClassMapArray(JNIEnv *env) {
+    LOGI("InitializeJClassMapArray: Enter");
+
+    unsigned int nLen = sizeof(gJClassMapArray) / sizeof(JClassMap);
+
+    for (unsigned int i = 0; i < nLen; i++) {
+        jclass classRef = env->FindClass(gJClassMapArray[i].szClassPath);
+        if (NULL == classRef) {
+            LOGE("FindClass failed for [%s]", gJClassMapArray[i].szClassPath);
+            return -1;
+        }
+        gJClassMapArray[i].classRef = (jclass) env->NewGlobalRef(classRef);
+        env->DeleteLocalRef(classRef);
+    }
+
+    LOGI("InitializeJClassMapArray: Exit");
+    return 0;
+}
+
+jclass GetJClass(const char *szClassPath) {
+    unsigned int nLen = sizeof(gJClassMapArray) / sizeof(JClassMap);
+
+    jclass classRef = NULL;
+
+    for (unsigned int i = 0; i < nLen; i++) {
+        if (0 == strcmp(gJClassMapArray[i].szClassPath, szClassPath)) {
+            classRef = gJClassMapArray[i].classRef;
+            break;
+        }
+    }
+
+    return classRef;
+}
+
+void DeleteClassMapArray(JNIEnv *env) {
+    LOGI("DeleteClassMapArray: Enter");
+
+    unsigned int nLen = sizeof(gJClassMapArray) / sizeof(JClassMap);
+    for (unsigned int i = 0; i < nLen; i++) {
+        if (NULL != gJClassMapArray[i].classRef) {
+            env->DeleteGlobalRef(gJClassMapArray[i].classRef);
+            gJClassMapArray[i].classRef = NULL;
+        }
+    }
+
+    LOGI("DeleteClassMapArray: Exit");
+}
+
+int InitializeJObjectMapArray(JNIEnv *env) {
+    LOGI("InitializeJObjectMapArray: Enter");
+
+    unsigned int nLen = sizeof(gJObjectMapArray) / sizeof(JObjectMap);
+
+    for (unsigned int i = 0; i < nLen; i++) {
+        jclass classRef = env->FindClass(gJObjectMapArray[i].szClassPath);
+        if (NULL == classRef) {
+            LOGE("InitializeJObjectMapArray: FindClass failed for [%s]",
+                    gJObjectMapArray[i].szClassPath);
+            return -1;
+        }
+
+        std::string methodSignature = "()L";
+        methodSignature.append(gJObjectMapArray[i].szClassPath);
+        methodSignature.append(";");
+
+        // Get the object form "getInstance"
+        jmethodID methodid = env->GetStaticMethodID(classRef, "getInstance",
+                methodSignature.c_str());
+        if (NULL == methodid) {
+            LOGE("InitializeJObjectMapArray: GetStaticMethodID failed for [%s]",
+                    gJObjectMapArray[i].szClassPath);
+            return -1;
+        }
+
+        // Get the singleton object
+        jobject objectRef = (jobject) env->CallStaticObjectMethod(classRef,
+                methodid);
+        if (NULL == objectRef) {
+            LOGE(
+                    "InitializeJObjectMapArray: CallStaticObjectMethod failed for [%s]",
+                    gJObjectMapArray[i].szClassPath);
+            return -1;
+        }
+
+        gJObjectMapArray[i].object = (jobject) env->NewGlobalRef(objectRef);
+        env->DeleteLocalRef(classRef);
+    }
+
+    LOGI("InitializeJObjectMapArray: Exit");
+    return 0;
+}
+
+jobject GetJObjectInstance(const char *szClassPath) {
+    unsigned int nLen = sizeof(gJObjectMapArray) / sizeof(JObjectMap);
+
+    jobject object = NULL;
+
+    for (unsigned int i = 0; i < nLen; i++) {
+        if (0 == strcmp(gJObjectMapArray[i].szClassPath, szClassPath)) {
+            object = gJObjectMapArray[i].object;
+            break;
+        }
+    }
+
+    return object;
+}
+
+void DeleteObjectMapArray(JNIEnv *env) {
+    LOGI("DeleteObjectMapArray: Enter");
+
+    unsigned int nLen = sizeof(gJObjectMapArray) / sizeof(JObjectMap);
+    for (unsigned int i = 0; i < nLen; i++) {
+        if (NULL != gJObjectMapArray[i].object) {
+            env->DeleteGlobalRef(gJObjectMapArray[i].object);
+            gJObjectMapArray[i].object = NULL;
+        }
+    }
+
+    LOGI("DeleteObjectMapArray: Exit");
+}
+
+JavaVM *EasySetupJVM::m_jvm = NULL;
+std::mutex EasySetupJVM::m_currentThreadMutex;
+JNIEnv *EasySetupJVM::getEnv() {
+    std::unique_lock < std::mutex > scoped_lock(m_currentThreadMutex);
+
+    if (NULL == m_jvm) {
+        LOGE("Failed to get JVM");
+        return NULL;
+    }
+
+    JNIEnv *env = NULL;
+    jint ret = m_jvm->GetEnv((void **) &env, JNI_CURRENT_VERSION);
+    switch (ret) {
+    case JNI_OK:
+        return env;
+    case JNI_EDETACHED:
+        if (0 > m_jvm->AttachCurrentThread(&env, NULL)) {
+            LOGE("Failed to attach current thread to env");
+            return NULL;
+        }
+        return env;
+    case JNI_EVERSION:
+        LOGE("JNI version not supported");
+    default:
+        LOGE("Failed to get the environment");
+        return NULL;
+    }
+}
+
+void EasySetupJVM::releaseEnv() {
+    std::unique_lock < std::mutex > scoped_lock(m_currentThreadMutex);
+
+    if (0 == m_jvm) {
+        LOGE("Failed to release JVM");
+        return;
+    }
+
+    m_jvm->DetachCurrentThread();
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+    LOGD("JNI_OnLoad: Enter");
+
+    if (!vm) {
+        LOGE("JNI_OnLoad: vm is invalid");
+        return JNI_ERR;
+    }
+
+    JNIEnv *env = NULL;
+    if (JNI_OK != vm->GetEnv((void **) &env, JNI_CURRENT_VERSION)) {
+        LOGE("JNI_OnLoad: Version check is failed!");
+        return JNI_ERR;
+    }
+
+    if (0 != InitializeJClassMapArray(env)) {
+        LOGE("JNI_OnLoad: Initialize JClass Array failed!");
+        return JNI_ERR;
+    }
+
+    if (0 != InitializeJObjectMapArray(env)) {
+        LOGE("JNI_OnLoad: Initialize JObject Array failed!");
+        return JNI_ERR;
+    }
+
+    jclass easySetupClassRef = GetJClass(
+            EASY_SETUP_SERVICE_NATIVE_API_CLASS_PATH);
+    if (NULL == easySetupClassRef) {
+        LOGE("JNI_OnLoad: GetJClass gEasySetupClass failed !");
+        return JNI_ERR;
+    }
+    env->RegisterNatives(easySetupClassRef, gEasySetupMethodTable,
+            gEasySetupMethodTableSize);
+
+    EasySetupJVM::m_jvm = vm;
+
+    LOGI("JNI_OnLoad: Exit");
+    return JNI_CURRENT_VERSION;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved)
+{
+    LOGD("JNI_OnUnload: Enter");
+
+    JNIEnv *env = NULL;
+    if (JNI_OK != vm->GetEnv((void **)&env, JNI_CURRENT_VERSION))
+    {
+        LOGE("JNI_OnLoad: Version check is failed!");
+        return;
+    }
+
+    // delete all class references
+    DeleteClassMapArray(env);
+
+    // delete all jobject
+    DeleteObjectMapArray(env);
+
+    LOGD("JNI_OnUnload: Exit");
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/service/easy-setup/sdk/android/jni/jniutil/src/jni_getter.cpp b/service/easy-setup/sdk/android/jni/jniutil/src/jni_getter.cpp
new file mode 100644 (file)
index 0000000..135f6a2
--- /dev/null
@@ -0,0 +1,148 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_getter.h"
+
+#include <string>
+
+#include "JniOcResource.h"
+
+#define LOG_TAG "TM_JGetter"
+
+bool JGetter::getJStringField(JNIEnv *env, jobject &object,
+        const char *fieldName, std::string &value) {
+    if (NULL == env || NULL == object || NULL == fieldName) {
+        LOGE("getJStringField invalid parameters");
+        return false;
+    }
+
+    jclass clazz = env->GetObjectClass(object);
+    if (NULL == clazz) {
+        LOGE("GetObjectClass failed [%s]", fieldName);
+        return false;
+    }
+
+    jfieldID fieldID = env->GetFieldID(clazz, fieldName, "Ljava/lang/String;");
+    if (0 == fieldID) {
+        LOGE("GetFieldID failed [%s]", fieldName);
+        env->DeleteLocalRef(clazz);
+        return false;
+    }
+
+    jstring jValue = (jstring) env->GetObjectField(object, fieldID);
+    if (NULL == jValue) {
+        LOGE("GetObjectField failed [%s]", fieldName);
+        env->DeleteLocalRef(clazz);
+        return false;
+    }
+
+    const char *cstr = env->GetStringUTFChars(jValue, 0);
+    if (cstr == NULL) {
+        LOGE("GetStringUTFChars failed");
+    } else {
+        value = cstr;
+        env->ReleaseStringUTFChars(jValue, cstr);
+    }
+
+    env->DeleteLocalRef(clazz);
+    env->DeleteLocalRef(jValue);
+
+    return true;
+}
+
+bool JGetter::getJBoolField(JNIEnv *env, jobject &object, const char *fieldName,
+        bool &value) {
+    if (NULL == env || NULL == object || NULL == fieldName) {
+        LOGE("getJBoolField invalid parameters");
+        return false;
+    }
+
+    jclass clazz = env->GetObjectClass(object);
+    if (NULL == clazz) {
+        LOGE("GetObjectClass failed");
+        return false;
+    }
+
+    jfieldID fieldID = env->GetFieldID(clazz, fieldName, "Z");
+    if (0 == fieldID) {
+        LOGE("GetFieldID failed [%s]", fieldName);
+        env->DeleteLocalRef(clazz);
+        return false;
+    }
+
+    value = env->GetBooleanField(object, fieldID);
+
+    env->DeleteLocalRef(clazz);
+
+    return true;
+}
+
+bool JGetter::getJIntField(JNIEnv *env, jobject &object, const char *fieldName,
+        int &value) {
+    if (NULL == env || NULL == object || NULL == fieldName) {
+        LOGE("getJIntField invalid parameters");
+        return false;
+    }
+
+    jclass clazz = env->GetObjectClass(object);
+    if (NULL == clazz) {
+        LOGE("GetObjectClass failed");
+        return false;
+    }
+
+    jfieldID fieldID = env->GetFieldID(clazz, fieldName, "I");
+    if (0 == fieldID) {
+        LOGE("GetFieldID failed [%s]", fieldName);
+        env->DeleteLocalRef(clazz);
+        return false;
+    }
+
+    value = env->GetIntField(object, fieldID);
+
+    env->DeleteLocalRef(clazz);
+
+    return true;
+}
+
+bool JGetter::getJObjectField(JNIEnv *env, jobject &object,
+        const char *fieldName, const char *fieldType, jobject &value) {
+    if (NULL == env || NULL == object || NULL == fieldName) {
+        return false;
+    }
+
+    jclass clazz = env->GetObjectClass(object);
+    if (NULL == clazz) {
+        return false;
+    }
+
+    jfieldID fieldID = env->GetFieldID(clazz, fieldName, fieldType);
+    if (0 == fieldID) {
+        LOGE("GetFieldID failed [%s][%s]", fieldName, fieldType);
+        return false;
+    }
+
+    value = env->GetObjectField(object, fieldID);
+    if (NULL == value) {
+        return false;
+    }
+
+    env->DeleteLocalRef(clazz);
+
+    return true;
+}
diff --git a/service/easy-setup/sdk/android/jni/jniutil/src/jni_object.cpp b/service/easy-setup/sdk/android/jni/jniutil/src/jni_object.cpp
new file mode 100644 (file)
index 0000000..51c6bf6
--- /dev/null
@@ -0,0 +1,67 @@
+#include "jni_object.h"
+
+//#define NULL 0
+#define LOG_TAG "TM_JObject"
+
+JObject::JObject(JNIEnv *env) :
+               m_pEnv(env), m_pObject(NULL), m_pClazz(NULL), m_fIsNewObject(true) {
+}
+
+JObject::JObject(JNIEnv *env, jobject obj) :
+               m_pEnv(NULL), m_pObject(NULL), m_pClazz(NULL), m_fIsNewObject(false) {
+       if (NULL == env || NULL == obj) {
+               return;
+       }
+
+       m_pEnv = env;
+       m_pObject = obj;
+       m_pClazz = m_pEnv->GetObjectClass(obj);
+}
+
+JObject::JObject(JNIEnv *env, const char *classPath) :
+               m_pEnv(NULL), m_pObject(NULL), m_pClazz(NULL), m_fIsNewObject(true) {
+       if (NULL == env || NULL == classPath) {
+               LOGI("JObject Invalid parameters");
+               return;
+       }
+
+       m_pEnv = env;
+       //m_pClazz = GetJClass( classPath );
+
+       if (NULL == m_pClazz) {
+               LOGE("GetJClass failed [%s]", classPath);
+               return;
+       }
+
+       jmethodID mid = env->GetMethodID(m_pClazz, "<init>", "()V");
+       if (NULL == mid) {
+               LOGE("GetMethodID failed [%s]", classPath);
+               return;
+       }
+
+       m_pObject = env->NewObject(m_pClazz, mid);
+}
+
+JObject::~JObject() {
+       if (m_pEnv) {
+               if (m_pObject && m_fIsNewObject) {
+                       m_pEnv->DeleteLocalRef(m_pObject);
+               }
+
+               if (m_pClazz && !m_fIsNewObject) {
+                       m_pEnv->DeleteLocalRef(m_pClazz);
+               }
+       }
+}
+
+jobject JObject::getObject() const {
+       return m_pObject;
+}
+
+void JObject::detachObject() {
+       if (m_fIsNewObject) {
+               m_fIsNewObject = false;
+               m_pClazz = NULL;
+       }
+}
+
diff --git a/service/easy-setup/sdk/android/jni/jniutil/src/jni_setter.cpp b/service/easy-setup/sdk/android/jni/jniutil/src/jni_setter.cpp
new file mode 100644 (file)
index 0000000..6c38004
--- /dev/null
@@ -0,0 +1,175 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_setter.h"
+
+#include <string>
+
+#include "JniOcResource.h"
+
+#define LOG_TAG "TM_JSetter"
+
+bool JSetter::setJStringField(JNIEnv *env, jobject &object,
+               const char *fieldName, const char *value) {
+       if (NULL == env || NULL == fieldName) {
+               LOGE("setJStringField invalid parameters");
+               return false;
+       }
+
+       jclass clazz = env->GetObjectClass(object);
+       if (NULL == clazz) {
+               LOGE("GetObjectClass failed");
+               return false;
+       }
+
+       jfieldID fieldID = env->GetFieldID(clazz, fieldName, "Ljava/lang/String;");
+       if (0 == fieldID) {
+               LOGE("GetFieldID failed [%s]", fieldName);
+               env->DeleteLocalRef(clazz);
+               return false;
+       }
+
+       jstring jvalue;
+       if (value != NULL && strlen(value) > 0) {
+               jclass strClass = env->FindClass("java/lang/String");
+               jmethodID ctorID = env->GetMethodID(strClass, "<init>",
+                               "([BLjava/lang/String;)V");
+               jbyteArray bytes = env->NewByteArray(strlen(value));
+               env->SetByteArrayRegion(bytes, 0, strlen(value), (jbyte *) value);
+               jstring encoding = env->NewStringUTF("utf-8");
+               jvalue = (jstring) env->NewObject(strClass, ctorID, bytes, encoding);
+               env->DeleteLocalRef(strClass);
+               env->DeleteLocalRef(bytes);
+               env->DeleteLocalRef(encoding);
+       } else {
+               jvalue = env->NewStringUTF("");
+       }
+
+       env->SetObjectField(object, fieldID, jvalue);
+
+       env->DeleteLocalRef(jvalue);
+       env->DeleteLocalRef(clazz);
+
+       return true;
+}
+
+bool JSetter::setJIntField(JNIEnv *env, jobject &object, const char *fieldName,
+               int value) {
+       if (NULL == env || NULL == fieldName) {
+               LOGE("setJIntField invalid paramter");
+               return false;
+       }
+
+       jclass clazz = env->GetObjectClass(object);
+       if (NULL == clazz) {
+               LOGE("GetObjectClass failed");
+               return false;
+       }
+
+       jfieldID fieldID = env->GetFieldID(clazz, fieldName, "I");
+       if (0 == fieldID) {
+               LOGE("GetFieldID failed [%s]", fieldName);
+               env->DeleteLocalRef(clazz);
+               return false;
+       }
+       env->SetIntField(object, fieldID, value);
+
+       env->DeleteLocalRef(clazz);
+
+       return true;
+}
+
+bool JSetter::setJLongField(JNIEnv *env, jobject &object, const char *fieldName,
+               jlong value) {
+       if (NULL == env || NULL == fieldName) {
+               LOGE("setJLongField invalid parameters");
+               return false;
+       }
+
+       jclass clazz = env->GetObjectClass(object);
+       if (NULL == clazz) {
+               LOGE("GetObjectClass failed");
+               return false;
+       }
+
+       jfieldID fieldID = env->GetFieldID(clazz, fieldName, "J");
+       if (0 == fieldID) {
+               LOGE("GetFieldID failed [%s]", fieldName);
+               env->DeleteLocalRef(clazz);
+               return false;
+       }
+       env->SetLongField(object, fieldID, value);
+
+       env->DeleteLocalRef(clazz);
+
+       return true;
+}
+
+bool JSetter::setJBoolField(JNIEnv *env, jobject &object, const char *fieldName,
+               bool value) {
+       if (NULL == env || NULL == fieldName) {
+               LOGE("setJBoolField invalid parameters");
+               return false;
+       }
+
+       jclass clazz = env->GetObjectClass(object);
+       if (NULL == clazz) {
+               LOGE("GetObjectClass failed");
+               return false;
+       }
+
+       jfieldID fieldID = env->GetFieldID(clazz, fieldName, "Z");
+       if (0 == fieldID) {
+               LOGE("GetFieldID failed [%s]", fieldName);
+               env->DeleteLocalRef(clazz);
+               return false;
+       }
+       env->SetBooleanField(object, fieldID, value);
+
+       env->DeleteLocalRef(clazz);
+
+       return true;
+}
+
+bool JSetter::setJObjectField(JNIEnv *env, jobject &object,
+               const char *fieldName, const char *fieldType, const jobject value) {
+       if (NULL == env || NULL == fieldName) {
+               LOGE("setJBoolField invalid parameters");
+               return false;
+       }
+
+       jclass clazz = env->GetObjectClass(object);
+       if (NULL == clazz) {
+               LOGE("GetObjectClass failed");
+               return false;
+       }
+
+       jfieldID fieldID = env->GetFieldID(clazz, fieldName, fieldType);
+       if (0 == fieldID) {
+               LOGE("GetFieldID failed [%s] [%s]", fieldName, fieldType);
+               env->DeleteLocalRef(clazz);
+               return false;
+       }
+       env->SetObjectField(object, fieldID, value);
+
+       env->DeleteLocalRef(clazz);
+
+       return true;
+}
+
diff --git a/service/easy-setup/sdk/android/jni/jniutil/src/jni_string.cpp b/service/easy-setup/sdk/android/jni/jniutil/src/jni_string.cpp
new file mode 100644 (file)
index 0000000..93bcdf4
--- /dev/null
@@ -0,0 +1,62 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_string.h"
+
+#define LOG_TAG "TM_JString"
+
+JString::JString(JNIEnv *env, jstring value) :
+               JObject(env, value) {
+       const char *buff = env->GetStringUTFChars(value, 0);
+
+       m_cstr = buff;
+
+       env->ReleaseStringUTFChars(value, buff);
+}
+
+JString::JString(JNIEnv *env, const char *value) :
+               JObject(env) {
+       m_cstr = value;
+
+       if (env) {
+               m_pObject = env->NewStringUTF(value);
+       }
+}
+
+JString::JString(JNIEnv *env, const std::string &value) :
+               JObject(env) {
+       m_cstr = value;
+
+       if (env) {
+               m_pObject = env->NewStringUTF(value.c_str());
+       }
+}
+
+JString::~JString() {
+}
+
+bool JString::getValue(std::string &value) {
+       value = m_cstr;
+       return true;
+}
+
+const char *JString::c_str() {
+       return m_cstr.c_str();
+}
+
diff --git a/service/easy-setup/sdk/inc/easysetupcommon.h b/service/easy-setup/sdk/inc/easysetupcommon.h
new file mode 100644 (file)
index 0000000..8650dd5
--- /dev/null
@@ -0,0 +1,122 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __EASY_CONNECT_COMMON_H_
+#define __EASY_CONNECT_COMMON_H_
+
+#include "ocstack.h"
+#include "octypes.h"
+
+// Defines
+#define OIC_STRING_MAX_VALUE 100
+#define IPV4_ADDR_SIZE 16
+#define IP_PORT 6298
+#define NET_WIFI_SSID_SIZE 16
+#define NET_WIFI_PWD_SIZE 16
+
+/**
+ * @brief Mac address length for BT port
+ */
+#define NET_MACADDR_SIZE 18
+
+//The following variable determines the interface (wifi, ethernet etc.)
+//to be used for sending unicast messages. Default set to Ethernet.
+static OCConnectivityType OC_CONNTYPE = OC_IPV4;
+
+static const char * UNICAST_PROVISIONING_QUERY = "coap://%s:%d/oic/res?rt=oic.prov";
+static const char * OIC_PROVISIONING_URI = "/oic/prov";
+
+/**
+ * Provisioning Device Status
+ */
+typedef struct {
+    /// Address of remote server
+    OCDevAddr * addr;
+    /// Indicates adaptor type on which the response was received
+    OCConnectivityType connType;
+} ProvDeviceInfo;
+
+/**
+ * Provosioning Status
+ */
+typedef enum {
+    DEVICE_PROVISIONED = 0, DEVICE_NOT_PROVISIONED
+} ProvStatus;
+
+/**
+ * Response from queries to remote servers. Queries are made by calling the @ref OCDoResource API.
+ */
+typedef struct {
+    // Provisioning Status
+    ProvStatus provStatus;
+    // Provisioning Device Info
+    ProvDeviceInfo provDeviceInfo;
+} ProvisioningInfo;
+
+/**
+ * @brief  Network information of the Enroller
+ */
+typedef union
+{
+    /**
+     * @brief BT Mac Information
+     */
+    struct
+    {
+        char btMacAddress[NET_MACADDR_SIZE];   /**< BT mac address **/
+    } BT;
+
+    /**
+     * @brief LE MAC Information
+     */
+    struct
+    {
+        char leMacAddress[NET_MACADDR_SIZE];   /**< BLE mac address **/
+    } LE;
+
+    /**
+     * @brief IP Information
+     */
+    struct
+    {
+        char ipAddress[IPV4_ADDR_SIZE]; /**< IP Address of the Enroller**/
+        char ssid[NET_WIFI_SSID_SIZE]; /**< ssid of the Enroller**/
+        char pwd[NET_WIFI_PWD_SIZE]; /**< pwd of the Enroller**/
+    } WIFI;
+} EnrolleeInfo_t;
+
+
+/**
+ * @brief Network Information
+ */
+typedef struct
+{
+    EnrolleeInfo_t netAddressInfo;          /**< Enroller Network Info**/
+    OCConnectivityType connType;            /**< Connectivity Type**/
+    bool isSecured;                         /**< Secure connection**/
+} EnrolleeNWProvInfo_t;
+
+/**
+ * Client applications implement this callback to consume responses received from Servers.
+ */
+typedef void (*OCProvisioningStatusCB)(ProvisioningInfo provInfo);
+
+#endif
+
diff --git a/service/easy-setup/sdk/inc/easysetupmgr.h b/service/easy-setup/sdk/inc/easysetupmgr.h
new file mode 100644 (file)
index 0000000..683ef2d
--- /dev/null
@@ -0,0 +1,54 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#ifndef __EASYSETUP_MGR_H_
+#define __EASYSETUP_MGR_H_
+
+#include <string.h>
+
+#include "logger.h"
+#include "ocstack.h"
+#include "octypes.h"
+#include "easysetupcommon.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+OCStackResult InitEasySetupManager();
+
+OCStackResult TerminateEasySetupManager();
+
+OCStackResult RegisterProvisioningStausCallback(
+        OCProvisioningStatusCB provisioningStatusCallback);
+
+void UnRegisterProvisioningStausCallback();
+
+OCStackResult ProvisionEnrollee(const EnrolleeNWProvInfo_t *netInfo);
+
+OCStackResult StopEnrolleeProvisioning(OCConnectivityType connectivityType);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/service/easy-setup/sdk/inc/provisioninghandler.h b/service/easy-setup/sdk/inc/provisioninghandler.h
new file mode 100644 (file)
index 0000000..30c658c
--- /dev/null
@@ -0,0 +1,86 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef __PROVISIONING_HANDLER_H_
+#define __PROVISIONING_HANDLER_H_
+
+#include "logger.h"
+#include "ocstack.h"
+#include "easysetupcommon.h"
+
+//-----------------------------------------------------------------------------
+// Defines
+//-----------------------------------------------------------------------------
+#define TAG "provisioninghandler"
+#define DEFAULT_CONTEXT_VALUE 0x99
+#ifndef MAX_LENGTH_IPv4_ADDR
+#define MAX_LENGTH_IPv4_ADDR 16
+#endif
+
+//-----------------------------------------------------------------------------
+// Typedefs
+//-----------------------------------------------------------------------------
+
+/**
+ * List of methods that can be inititated from the client
+ */
+OCStackResult InitProvisioningHandler();
+
+OCStackResult TerminateProvisioningHandler();
+
+void listeningFunc(void*);
+
+OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse);
+
+OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query);
+
+OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
+        OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
+        OCHeaderOption * options, uint8_t numOptions);
+
+OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query);
+
+OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
+        OCProvisioningStatusCB provisioningStatusCallback);
+
+
+void StopProvisioningProcess();
+
+OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
+        OCClientResponse* clientResponse);
+
+OCStackResult SubscribeProvPresence(OCQualityOfService qos, const char* requestURI);
+
+OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse);
+
+OCStackResult FindProvisioningResource(OCQualityOfService qos,
+        const char* requestURI);
+
+//Invoke Provisioning Status Callback
+void PrepareProvisioingStatusCB(ProvisioningInfo *provInfo,
+        OCClientResponse * clientResponse, ProvStatus provStatus);
+
+#endif
+
diff --git a/service/easy-setup/sdk/src/camutex_pthreads.c b/service/easy-setup/sdk/src/camutex_pthreads.c
new file mode 100644 (file)
index 0000000..4db91e0
--- /dev/null
@@ -0,0 +1,320 @@
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+//*********************************************************************
+
+/**
+ * @file
+ * This file provides APIs related to mutex and semaphores.
+ */
+
+// Defining _POSIX_C_SOURCE macro with 199309L (or greater) as value
+// causes header files to expose definitions
+// corresponding to the POSIX.1b, Real-time extensions
+// (IEEE Std 1003.1b-1993) specification
+//
+// For this specific file, see use of clock_gettime and PTHREAD_MUTEX_DEFAULT
+#ifndef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200809L
+#endif
+
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/time.h>
+#include <assert.h>
+#include <ocmalloc.h>
+
+#include "camutex.h"
+#include "logger.h"
+
+/**
+ * TAG
+ * Logging tag for module name
+ */
+#define TAG PCF("UMUTEX")
+
+static const uint64_t USECS_PER_SEC = 1000000;
+static const uint64_t NANOSECS_PER_USECS = 1000;
+static const uint64_t NANOSECS_PER_SEC = 1000000000L;
+
+typedef struct _tagMutexInfo_t {
+       pthread_mutex_t mutex;
+} ca_mutex_internal;
+
+typedef struct _tagEventInfo_t {
+       pthread_cond_t cond;
+       pthread_condattr_t condattr;
+} ca_cond_internal;
+
+ca_mutex ca_mutex_new(void) {
+       ca_mutex retVal = NULL;
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) OICMalloc(
+                       sizeof(ca_mutex_internal));
+       if (NULL != mutexInfo) {
+               // create the mutex with the attributes set
+               int ret = pthread_mutex_init(&(mutexInfo->mutex),
+                               PTHREAD_MUTEX_DEFAULT);
+               if (0 == ret) {
+                       retVal = (ca_mutex) mutexInfo;
+               } else {
+                       OIC_LOG_V(ERROR, TAG, "%s Failed to initialize mutex !", __func__);
+                       OICFree(mutexInfo);
+               }
+       }
+
+       return retVal;
+}
+
+bool ca_mutex_free(ca_mutex mutex) {
+       bool bRet = false;
+
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+       if (mutexInfo) {
+               int ret = pthread_mutex_destroy(&mutexInfo->mutex);
+               if (0 == ret) {
+                       OICFree(mutexInfo);
+                       bRet = true;
+               } else {
+                       OIC_LOG_V(ERROR, TAG, "%s Failed to free mutex !", __func__);
+               }
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
+       }
+
+       return bRet;
+}
+
+void ca_mutex_lock(ca_mutex mutex) {
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+       if (mutexInfo) {
+               int ret = pthread_mutex_lock(&mutexInfo->mutex);
+               assert(0 == ret);
+               (void) ret;
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
+               return;
+       }
+}
+
+bool ca_mutex_trylock(ca_mutex mutex) {
+       if (NULL == mutex) {
+               OIC_LOG_V(ERROR, TAG, "%s Invalid mutex !", __func__);
+               return false;
+       }
+
+       bool bRet = false;
+
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+
+       int result = pthread_mutex_trylock(&mutexInfo->mutex);
+
+       switch (result) {
+       case 0:
+               // Success
+               bRet = true;
+               break;
+       case EINVAL:
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__);
+               break;
+       case EBUSY:
+       default:
+               break;
+       }
+
+       return bRet;
+}
+
+void ca_mutex_unlock(ca_mutex mutex) {
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+       if (mutexInfo) {
+               int ret = pthread_mutex_unlock(&mutexInfo->mutex);
+               assert(0 == ret);
+               (void) ret;
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex !", __func__);
+               return;
+       }
+}
+
+ca_cond ca_cond_new(void) {
+       ca_cond retVal = NULL;
+       ca_cond_internal *eventInfo = (ca_cond_internal*) OICMalloc(
+                       sizeof(ca_cond_internal));
+       if (NULL != eventInfo) {
+               int ret = pthread_condattr_init(&(eventInfo->condattr));
+               if (0 != ret) {
+                       OIC_LOG_V(ERROR, TAG,
+                                       "%s: Failed to initialize condition variable attribute %d!",
+                                       __func__, ret);
+                       return retVal;
+               }
+
+#if defined(__ANDROID__) || _POSIX_TIMERS > 0
+               ret = pthread_condattr_setclock(&(eventInfo->condattr), CLOCK_MONOTONIC);
+
+               if(0 != ret)
+               {
+                       OIC_LOG_V(ERROR, TAG, "%s: Failed to set condition variable clock %d!",
+                                       __func__, ret);
+                       return retVal;
+               }
+#endif
+               ret = pthread_cond_init(&(eventInfo->cond), &(eventInfo->condattr));
+               if (0 == ret) {
+                       retVal = (ca_cond) eventInfo;
+               } else {
+                       OIC_LOG_V(ERROR, TAG,
+                                       "%s: Failed to initialize condition variable %d!", __func__,
+                                       ret);
+                       OICFree(eventInfo);
+               }
+       }
+
+       return retVal;
+}
+
+void ca_cond_free(ca_cond cond) {
+       ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
+       if (eventInfo != NULL) {
+               int ret = pthread_cond_destroy(&(eventInfo->cond));
+               int ret2 = pthread_condattr_destroy(&(eventInfo->condattr));
+               if (0 == ret && 0 == ret2) {
+                       OICFree(cond);
+               } else {
+                       OIC_LOG_V(ERROR, TAG,
+                                       "%s: Failed to destroy condition variable %d, %d", __func__,
+                                       ret, ret2);
+               }
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+       }
+}
+
+void ca_cond_signal(ca_cond cond) {
+       ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
+       if (eventInfo != NULL) {
+               int ret = pthread_cond_signal(&(eventInfo->cond));
+               if (0 != ret) {
+                       OIC_LOG_V(ERROR, TAG, "%s: Failed to signal condition variable",
+                                       __func__);
+               }
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+       }
+}
+
+void ca_cond_broadcast(ca_cond cond) {
+       ca_cond_internal* eventInfo = (ca_cond_internal*) cond;
+       if (eventInfo != NULL) {
+               int ret = pthread_cond_broadcast(&(eventInfo->cond));
+               if (0 != ret) {
+                       OIC_LOG_V(ERROR, TAG, "%s: failed to signal condition variable",
+                                       __func__);
+               }
+       } else {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid parameter", __func__);
+       }
+}
+
+void ca_cond_wait(ca_cond cond, ca_mutex mutex) {
+       ca_cond_wait_for(cond, mutex, 0L);
+}
+
+struct timespec ca_get_current_time() {
+#if defined(__ANDROID__) || _POSIX_TIMERS > 0
+       struct timespec ts;
+       clock_gettime(CLOCK_MONOTONIC, &ts);
+       return ts;
+#else
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       struct timespec ts;
+       TIMEVAL_TO_TIMESPEC(&tv, &ts);
+       return ts;
+#endif
+}
+
+void ca_add_microseconds_to_timespec(struct timespec* ts,
+               uint64_t microseconds) {
+       time_t secPart = microseconds / USECS_PER_SEC;
+       uint64_t nsecPart = (microseconds % USECS_PER_SEC) * NANOSECS_PER_USECS;
+       uint64_t totalNs = ts->tv_nsec + nsecPart;
+       time_t secOfNs = totalNs / NANOSECS_PER_SEC;
+
+       ts->tv_nsec = (totalNs) % NANOSECS_PER_SEC;
+       ts->tv_sec += secPart + secOfNs;
+}
+
+CAWaitResult_t ca_cond_wait_for(ca_cond cond, ca_mutex mutex,
+               uint64_t microseconds) {
+       CAWaitResult_t retVal = CA_WAIT_INVAL;
+
+       ca_cond_internal *eventInfo = (ca_cond_internal*) cond;
+       ca_mutex_internal *mutexInfo = (ca_mutex_internal*) mutex;
+
+       if (NULL == mutexInfo) {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid mutex", __func__);
+               return CA_WAIT_INVAL;
+       }
+
+       if (NULL == eventInfo) {
+               OIC_LOG_V(ERROR, TAG, "%s: Invalid condition", __func__);
+               return CA_WAIT_INVAL;
+       }
+
+       if (microseconds > 0) {
+               struct timespec abstime = ca_get_current_time();
+               ca_add_microseconds_to_timespec(&abstime, microseconds);
+
+               //Wait for the given time
+               int ret = pthread_cond_timedwait(&(eventInfo->cond),
+                               &(mutexInfo->mutex), &abstime);
+               switch (ret) {
+               case 0:
+                       // Success
+                       retVal = CA_WAIT_SUCCESS;
+                       break;
+               case ETIMEDOUT:
+                       retVal = CA_WAIT_TIMEDOUT;
+                       break;
+               case EINVAL:
+                       OIC_LOG_V(ERROR, TAG, "%s: condition, mutex, or abstime is Invalid",
+                                       __func__);
+                       retVal = CA_WAIT_INVAL;
+                       break;
+               default:
+                       OIC_LOG_V(ERROR, TAG, "%s: pthread_cond_timedwait returned %d",
+                                       __func__, retVal);
+                       retVal = CA_WAIT_INVAL;
+                       break;
+               }
+       } else {
+               // Wait forever
+               int ret = pthread_cond_wait(&eventInfo->cond, &mutexInfo->mutex);
+               retVal = ret == 0 ? CA_WAIT_SUCCESS : CA_WAIT_INVAL;
+       }
+
+       return retVal;
+}
+
diff --git a/service/easy-setup/sdk/src/easysetupmgr.cpp b/service/easy-setup/sdk/src/easysetupmgr.cpp
new file mode 100644 (file)
index 0000000..3dda241
--- /dev/null
@@ -0,0 +1,91 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sstream>
+
+#include "easysetupmgr.h"
+#include "provisioninghandler.h"
+
+//Use ipv4addr for both InitDiscovery and InitDeviceDiscovery
+char ipv4addr[IPV4_ADDR_SIZE] = { 0 };
+
+static OCProvisioningStatusCB cbData = NULL;
+
+OCStackResult InitEasySetupManager() {
+    OCStackResult result = OC_STACK_ERROR;
+
+    if (InitProvisioningHandler() == OC_STACK_OK) {
+        result = OC_STACK_OK;
+        OIC_LOG(DEBUG, TAG, "InitProvisioningHandler returned Success");
+    } else {
+        result = OC_STACK_ERROR;
+        OIC_LOG_V(ERROR, TAG, "InitProvisioningHandler returned error = %s",
+                result);
+    }
+
+    return result;
+}
+
+OCStackResult TerminateEasySetupManager() {
+    return TerminateProvisioningHandler();
+}
+
+OCStackResult RegisterProvisioningStausCallback(
+        OCProvisioningStatusCB provisioningStatusCallback) {
+    OCStackResult result = OC_STACK_OK;
+
+    if(provisioningStatusCallback != NULL)
+    {
+        cbData = provisioningStatusCallback;
+    }
+    else
+    {
+        result = OC_STACK_ERROR;
+        OIC_LOG(ERROR, TAG, "provisioningStatusCallback is NULL");
+    }
+
+    return result;
+}
+
+void UnRegisterProvisioningStausCallback() {
+    if (cbData) {
+        cbData = NULL;
+    }
+}
+
+OCStackResult ProvisionEnrollee(const EnrolleeNWProvInfo_t *netInfo)
+{
+    return StartProvisioningProcess(netInfo, cbData);
+}
+
+OCStackResult StopEnrolleeProvisioning(OCConnectivityType connectivityType) {
+    OCStackResult result = OC_STACK_OK;
+
+    //TODO: Have to handle the transport specific easy setup termination
+    StopProvisioningProcess();
+
+    return result;
+}
+
diff --git a/service/easy-setup/sdk/src/provisioninghandler.cpp b/service/easy-setup/sdk/src/provisioninghandler.cpp
new file mode 100644 (file)
index 0000000..c2731eb
--- /dev/null
@@ -0,0 +1,694 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "provisioninghandler.h"
+
+// External includes
+#include "cJSON.h"
+#include "camutex.h"
+#include "cathreadpool.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+
+/**
+ * @var g_provisioningMutex
+ * @brief Mutex to synchronize access to g_caDtlsContext.
+ */
+static ca_mutex g_provisioningMutex = NULL;
+static ca_cond g_provisioningCond = NULL;
+bool g_provisioningCondFlag = false;
+
+static EnrolleeNWProvInfo_t* netProvInfo;
+
+/**
+ * @var cbData
+ * @brief Callback for providing provisioning status callback to application
+ */
+static OCProvisioningStatusCB cbData = NULL;
+static ca_thread_pool_t g_threadPoolHandle = NULL;
+
+OCStackResult InitProvisioningHandler() {
+    OCStackResult ret = OC_STACK_ERROR;
+    /* Initialize OCStack*/
+    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack init error");
+        return ret;
+    }
+
+    g_provisioningMutex = ca_mutex_new();
+
+    OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
+
+    if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
+        OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
+        return OC_STACK_ERROR;
+    }
+
+    g_provisioningCond = ca_cond_new();
+    if (NULL == g_provisioningCond) {
+        OIC_LOG(DEBUG, TAG, "Failed to create condition");
+        ca_mutex_free(g_provisioningMutex);
+        ca_thread_pool_free(g_threadPoolHandle);
+        return OC_STACK_ERROR;
+    }
+
+    char *string = "listeningFunc invoked in a thread";
+    if (CA_STATUS_OK
+            != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
+                    (void *) string)) {
+        OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
+        ca_thread_pool_free(g_threadPoolHandle);
+        ca_mutex_unlock(g_provisioningMutex);
+        ca_mutex_free(g_provisioningMutex);
+        ca_cond_free(g_provisioningCond);
+        return OC_STACK_ERROR;
+    }
+    return OC_STACK_OK;
+}
+
+OCStackResult TerminateProvisioningHandler() {
+    OCStackResult ret = OC_STACK_ERROR;
+    if (OCStop() != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack stop error");
+    }
+
+    ca_mutex_lock(g_provisioningMutex);
+    g_provisioningCondFlag = true;
+    //ca_cond_signal(g_provisioningCond);
+    ca_mutex_unlock(g_provisioningMutex);
+
+    ca_mutex_free(g_provisioningMutex);
+    g_provisioningMutex = NULL;
+
+    ca_thread_pool_free(g_threadPoolHandle);
+    g_threadPoolHandle = NULL;
+
+    ret = OC_STACK_OK;
+    return ret;
+}
+
+void listeningFunc(void *data) {
+    while (!g_provisioningCondFlag) {
+        OCStackResult result;
+
+        ca_mutex_lock(g_provisioningMutex);
+        result = OCProcess();
+        ca_mutex_unlock(g_provisioningMutex);
+
+        if (result != OC_STACK_OK) {
+            OIC_LOG(ERROR, TAG, "OCStack stop error");
+        }
+
+        // To minimize CPU utilization we may wish to do this with sleep
+        sleep(1);
+    }
+}
+
+OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse) {
+    ProvisioningInfo provInfo;
+
+    if (clientResponse) {
+        OIC_LOG_V(INFO, TAG, "Put Response JSON = %s",
+                clientResponse->resJSONPayload);
+    } else {
+        OIC_LOG_V(INFO, TAG,
+                "ProvisionEnrolleeResponse received Null clientResponse");
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+        cbData(provInfo);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    uint16_t remotePortNum;
+
+    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
+
+    char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
+    snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
+            clientResponse->addr->addr[0], clientResponse->addr->addr[1],
+            clientResponse->addr->addr[2], clientResponse->addr->addr[3],
+            remotePortNum, OIC_PROVISIONING_URI);
+
+    OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s @ %s",
+            clientResponse->resJSONPayload, sourceaddr);
+
+    if (clientResponse->resJSONPayload) {
+        cJSON *observeJson = cJSON_CreateObject();
+        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
+
+        cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
+        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
+
+        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
+        char *ocArray_str = cJSON_PrintUnformatted(representationArray);
+
+        if (strstr(ocArray_str, "[{}") == ocArray_str) {
+            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
+            cJSON_Delete(observeJson);
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+
+        int countofrep = cJSON_GetArraySize(representationArray);
+
+        for (int i = 0; i < countofrep; ++i) {
+            cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
+            OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
+
+            switch (arrayJSON->type) {
+            case cJSON_False:
+            case cJSON_True:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
+                        arrayJSON->valueint);
+                break;
+            case cJSON_Number:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
+                        arrayJSON->valuedouble);
+                break;
+            case cJSON_String:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
+                        arrayJSON->valuestring);
+                break;
+            case cJSON_NULL:
+            default:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
+                break;
+            }
+        }
+
+        cJSON_Delete(observeJson);
+
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_PROVISIONED);
+        cbData(provInfo);
+
+        return OC_STACK_KEEP_TRANSACTION;
+    } else {
+        OIC_LOG(INFO, TAG,
+                "ProvisionEnrolleeResponse received NULL clientResponse. \
+                                Invoking Provisioing Status Callback");
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+        cbData(provInfo);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+}
+
+OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query) {
+    OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
+
+    cJSON *jsonFinal = cJSON_CreateObject();
+    cJSON *json = cJSON_CreateObject();
+    cJSON *jsonArray;
+    cJSON *format;
+    char* payload = NULL;
+
+    char nodeData[OIC_STRING_MAX_VALUE] = { '\0' };
+    snprintf(nodeData, sizeof(nodeData), "%s", OIC_PROVISIONING_URI);
+
+    cJSON_AddStringToObject(json, "href", nodeData);
+    cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+    cJSON_AddStringToObject(format, "tnn", netProvInfo->netAddressInfo.WIFI.ssid);
+    cJSON_AddStringToObject(format, "cd", netProvInfo->netAddressInfo.WIFI.pwd);
+    cJSON_AddItemToObject(jsonFinal, "oic", jsonArray = cJSON_CreateArray());
+    cJSON_AddItemToArray(jsonArray, json);
+
+    OIC_LOG_V(DEBUG, TAG, "ProvisionEnrollee : %s",
+            cJSON_PrintUnformatted(jsonFinal));
+    payload = cJSON_Print(jsonFinal);
+    OIC_LOG_V(DEBUG, TAG, "Payload : %s", payload);
+
+    OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, OC_HIGH_QOS,
+            ProvisionEnrolleeResponse, payload, NULL, 0);
+
+    cJSON_Delete(json);
+    return ret;
+}
+
+OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse) {
+    ProvisioningInfo provInfo;
+
+    if (clientResponse == NULL) {
+        OIC_LOG(INFO, TAG,
+                "getReqCB received NULL clientResponse. \
+            Invoking Provisioing Status Callback");
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+        cbData(provInfo);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+
+    if (clientResponse->rcvdVendorSpecificHeaderOptions
+            && clientResponse->numRcvdVendorSpecificHeaderOptions) {
+        OIC_LOG(INFO, TAG, "Received vendor specific options");
+        uint8_t i = 0;
+        OCHeaderOption * rcvdOptions =
+                clientResponse->rcvdVendorSpecificHeaderOptions;
+        for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
+                i++) {
+            if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {
+                OIC_LOG_V(INFO, TAG,
+                        "Received option with OC_COAP_ID and ID %u with",
+                        ((OCHeaderOption) rcvdOptions[i]).optionID);
+
+                OIC_LOG_BUFFER(INFO, TAG,
+                        ((OCHeaderOption) rcvdOptions[i]).optionData,
+                        MAX_HEADER_OPTION_DATA_LENGTH);
+            }
+        }
+    }
+
+    char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
+    snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
+            clientResponse->addr->addr[0], clientResponse->addr->addr[1],
+            clientResponse->addr->addr[2], clientResponse->addr->addr[3],
+            6298, OIC_PROVISIONING_URI);
+
+    if (clientResponse->resJSONPayload) {
+        cJSON *observeJson = cJSON_CreateObject();
+        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
+
+        cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
+        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
+
+        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
+        char *ocArray_str = cJSON_PrintUnformatted(representationArray);
+
+        if (strstr(ocArray_str, "[{}") == ocArray_str) {
+            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
+            cJSON_Delete(observeJson);
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+
+        int countofrep = cJSON_GetArraySize(representationArray);
+
+        for (int i = 0; i < countofrep; ++i) {
+            cJSON *arrayJSON = cJSON_GetArrayItem(representationArray, i);
+            OIC_LOG_V(DEBUG, TAG, "rep#%d's name : %s", i, arrayJSON->string);
+
+            switch (arrayJSON->type) {
+            case cJSON_False:
+            case cJSON_True:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
+                        arrayJSON->valueint);
+                break;
+            case cJSON_Number:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
+                        arrayJSON->valuedouble);
+                break;
+            case cJSON_String:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %s", i,
+                        arrayJSON->valuestring);
+                break;
+            case cJSON_NULL:
+            default:
+                OIC_LOG_V(DEBUG, TAG, "rep#%d's value : NULL", i);
+                break;
+            }
+        }
+        cJSON_Delete(observeJson);
+
+        if (ProvisionEnrollee(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
+            OIC_LOG(INFO, TAG,
+                    "GetProvisioningStatusResponse received NULL clientResponse. \
+                Invoking Provisioing Status Callback");
+            PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                    DEVICE_NOT_PROVISIONED);
+            cbData(provInfo);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    } else {
+        OIC_LOG(INFO, TAG,
+                "GetProvisioningStatusResponse received NULL clientResponse. \
+            Invoking Provisioing Status Callback");
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+        cbData(provInfo);
+        return OC_STACK_DELETE_TRANSACTION;
+    }
+    return OC_STACK_DELETE_TRANSACTION;
+}
+
+OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
+        OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
+        OCHeaderOption * options, uint8_t numOptions) {
+    OCStackResult ret;
+    OCCallbackData cbData;
+
+    cbData.cb = cb;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    ret = OCDoResource(NULL, method, query, 0, request, OC_CONNTYPE, qos,
+            &cbData, options, numOptions);
+
+    if (ret != OC_STACK_OK) {
+        OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",
+                ret, method);
+    }
+
+    return ret;
+}
+
+OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
+    OCStackResult ret = OC_STACK_ERROR;
+    OCHeaderOption options[MAX_HEADER_OPTIONS];
+
+    OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);
+
+    uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
+    uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
+    memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);
+    options[0].protocolID = OC_COAP_ID;
+    options[0].optionID = 2048;
+    memcpy(options[0].optionData, option0, sizeof(option0));
+    options[0].optionLength = 10;
+    options[1].protocolID = OC_COAP_ID;
+    options[1].optionID = 3000;
+    memcpy(options[1].optionData, option1, sizeof(option1));
+    options[1].optionLength = 10;
+
+    ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
+            GetProvisioningStatusResponse, NULL, options, 2);
+    return ret;
+}
+
+OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
+        OCProvisioningStatusCB provisioningStatusCallback) {
+    OCStackResult result = OC_STACK_ERROR;
+    ProvisioningInfo provInfo;
+
+    if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
+        OIC_LOG(ERROR, TAG, "Request URI is NULL");
+        return result;
+    }
+
+    if (provisioningStatusCallback == NULL) {
+        OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
+        return result;
+    }
+
+    cbData = provisioningStatusCallback;
+
+    //Copy Network Provisioning  Information
+    netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
+
+    if (NULL == netProvInfo)
+    {
+        OIC_LOG(ERROR, TAG, "Invalid input..");
+        return OC_STACK_ERROR;
+    }
+    memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));
+
+    OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",
+        netProvInfo->netAddressInfo.WIFI.ssid);
+
+    OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",
+        netProvInfo->netAddressInfo.WIFI.pwd);
+
+    /* Start a discovery query*/
+    char szQueryUri[64] = { 0 };
+
+    snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
+            netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
+
+    OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
+
+    if (FindProvisioningResource(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG,
+                "FindProvisioningResource failed. \
+            Invoking Provisioing Status Callback");
+
+        ProvDeviceInfo provDeviceIndo;
+        OCDevAddr dst = { };
+
+        dst.addr[0] = netProvInfo->netAddressInfo.WIFI.ipAddress[0];
+        dst.addr[1] = netProvInfo->netAddressInfo.WIFI.ipAddress[1];
+        dst.addr[2] = netProvInfo->netAddressInfo.WIFI.ipAddress[2];
+        dst.addr[3] = netProvInfo->netAddressInfo.WIFI.ipAddress[3];
+        dst.addr[4] = (uint8_t) IP_PORT;
+        dst.addr[5] = (uint8_t)(IP_PORT >> 8);
+
+        provInfo.provStatus = DEVICE_NOT_PROVISIONED;
+        provDeviceIndo.addr = &dst;
+        provDeviceIndo.connType = OC_IPV4;
+        provInfo.provDeviceInfo = provDeviceIndo;
+
+        cbData(provInfo);
+        return result;
+    }
+    result = OC_STACK_OK;
+
+    return result;
+}
+
+void StopProvisioningProcess() {
+    cbData = NULL;
+}
+
+// This is a function called back when a device is discovered
+OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
+        OCDoHandle handle, OCClientResponse * clientResponse) {
+    OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));
+
+    OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
+
+    ProvisioningInfo provInfo;
+
+    if (clientResponse->result != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG,
+                "OCStack stop error. Calling Provisioing Status Callback");
+
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+
+        cbData(provInfo);
+        return response;
+    }
+
+    if (clientResponse) {
+        // Parse header options from server
+        uint16_t optionID;
+        uint8_t* optionData;
+        const char* payload;
+
+        for (int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
+                i++) {
+            optionID =
+                    clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
+            optionData =
+                    clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData;
+            payload = clientResponse->resJSONPayload;
+        }
+
+        cJSON *discoveryJson = cJSON_CreateObject();
+        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
+
+        cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
+        char *ocArray_str = cJSON_PrintUnformatted(ocArray);
+
+        if (strstr(ocArray_str, "[{}") == ocArray_str) {
+            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
+            cJSON_Delete(discoveryJson);
+
+            PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                    DEVICE_NOT_PROVISIONED);
+            cbData(provInfo);
+            return response;
+        }
+
+        char sourceaddr[OIC_STRING_MAX_VALUE] = { '\0' };
+        snprintf(sourceaddr, sizeof(sourceaddr), "%d.%d.%d.%d:%d%s",
+                clientResponse->addr->addr[0], clientResponse->addr->addr[1],
+                clientResponse->addr->addr[2], clientResponse->addr->addr[3],
+                IP_PORT, OIC_PROVISIONING_URI);
+
+        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
+                clientResponse->resJSONPayload, sourceaddr);
+
+        if (GetProvisioningStatus(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
+            OIC_LOG(INFO, TAG,
+                    "GetProvisioningStatus returned error. \
+                                Invoking Provisioing Status Callback");
+            PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                    DEVICE_NOT_PROVISIONED);
+            cbData(provInfo);
+
+            return OC_STACK_DELETE_TRANSACTION;
+        }
+    } else {
+        // clientResponse is invalid
+        OIC_LOG(ERROR, TAG,
+                "Invalid response for Provisioning Discovery request. \
+        Invoking Provisioing Status Callback");
+        PrepareProvisioingStatusCB(&provInfo, clientResponse,
+                DEVICE_NOT_PROVISIONED);
+        cbData(provInfo);
+        return response;
+    }
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackResult FindProvisioningResource(OCQualityOfService qos,
+        const char* requestURI) {
+    OCStackResult ret = OC_STACK_ERROR;
+
+    OCCallbackData cbData;
+
+    cbData.cb = FindProvisioningResourceResponse;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    ret = OCDoResource(NULL, OC_REST_GET, requestURI, 0, 0, OC_CONNTYPE,
+            OC_LOW_QOS, &cbData, NULL, 0);
+
+    if (ret != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+    }
+
+    return ret;
+}
+
+OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
+        OCClientResponse* clientResponse) {
+    OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
+
+    OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
+
+    if (clientResponse->result != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack stop error");
+        return response;
+    }
+
+    if (clientResponse) {
+        OIC_LOG(INFO, TAG, PCF("Client Response exists"));
+        // Parse header options from server
+        uint16_t optionID;
+        uint8_t* optionData;
+        const char* payload;
+
+        for (int i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;
+                i++) {
+            optionID =
+                    clientResponse->rcvdVendorSpecificHeaderOptions[i].optionID;
+            optionData =
+                    clientResponse->rcvdVendorSpecificHeaderOptions[i].optionData;
+            payload = clientResponse->resJSONPayload;
+        }
+
+        cJSON *discoveryJson = cJSON_CreateObject();
+        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
+
+        cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
+        char *ocArray_str = cJSON_PrintUnformatted(ocArray);
+
+        if (strstr(ocArray_str, "[{}") == ocArray_str) {
+            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
+            cJSON_Delete(discoveryJson);
+            return response;
+        }
+
+        char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
+        snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%d.%d.%d.%d",
+                clientResponse->addr->addr[0], clientResponse->addr->addr[1],
+                clientResponse->addr->addr[2], clientResponse->addr->addr[3]);
+
+        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
+                clientResponse->resJSONPayload, sourceIPAddr);
+
+        /* Start a discovery query*/
+        char szQueryUri[64] = { 0 };
+        OCQualityOfService qos = OC_NA_QOS;
+
+        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
+                sourceIPAddr, IP_PORT);
+
+        if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
+            OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
+            return OC_STACK_KEEP_TRANSACTION;
+        }
+    } else {
+        // clientResponse is invalid
+        OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
+    }
+    return OC_STACK_KEEP_TRANSACTION;
+}
+
+OCStackResult SubscribeProvPresence(OCQualityOfService qos,
+        const char* requestURI) {
+    OCStackResult ret = OC_STACK_ERROR;
+
+    OCCallbackData cbData;
+
+    cbData.cb = &SubscribeProvPresenceCallback;
+    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
+    cbData.cd = NULL;
+
+    ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,
+            OC_LOW_QOS, &cbData, NULL, 0);
+
+    if (ret != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack resource error");
+    }
+
+    return ret;
+}
+
+OCStackResult FindNetworkResource() {
+    OCStackResult ret = OC_STACK_ERROR;
+    if (OCStop() != OC_STACK_OK) {
+        OIC_LOG(ERROR, TAG, "OCStack stop error");
+    }
+
+    return ret;
+}
+
+void PrepareProvisioingStatusCB(ProvisioningInfo *provInfo,
+        OCClientResponse * clientResponse, ProvStatus provStatus) {
+    ProvDeviceInfo provDeviceIndo;
+    OCDevAddr dst = { };
+
+    uint16_t remotePortNum;
+    OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
+
+    dst.addr[0] = clientResponse->addr->addr[0];
+    dst.addr[1] = clientResponse->addr->addr[1];
+    dst.addr[2] = clientResponse->addr->addr[2];
+    dst.addr[3] = clientResponse->addr->addr[3];
+    dst.addr[4] = (uint8_t) remotePortNum;
+    dst.addr[5] = (uint8_t)(remotePortNum >> 8);
+
+    provInfo->provStatus = provStatus;
+
+    provDeviceIndo.addr = &dst;
+    provDeviceIndo.connType = OC_IPV4;
+
+    provInfo->provDeviceInfo = provDeviceIndo;
+}
+