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>
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");
OIC_LOG(ERROR, IP_MONITOR_TAG, "unable to create CaIpInterface instance");
return ret;
}
+#endif
ret = CAInitializeNetworkMonitorMutexes();
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
##
# 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
######################################################################
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',
'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')
# 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')
# Build linux sample app
SConscript('arduino/thinserver/SConscript')
+if target_os == 'linux' :
+ # Build linux sample app
+ SConscript('linux/richclient/SConscript')
--- /dev/null
+#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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+# 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
--- /dev/null
+<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
--- /dev/null
+<?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
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<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
--- /dev/null
+<?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>
--- /dev/null
+<resources>
+
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
--- /dev/null
+<?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>
--- /dev/null
+<?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>
--- /dev/null
+<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>
--- /dev/null
+/******************************************************************\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
--- /dev/null
+#******************************************************************
+#
+# 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')
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <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;
+}
+
--- /dev/null
+#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
--- /dev/null
+<?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
--- /dev/null
+<?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
--- /dev/null
+<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
--- /dev/null
+# 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
--- /dev/null
+<resources>\r
+\r
+ <string name="app_name">EasySetupCore</string>\r
+\r
+</resources>\r
--- /dev/null
+<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
--- /dev/null
+/******************************************************************\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
--- /dev/null
+/******************************************************************\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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+package org.iotivity.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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.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);
+
+}
--- /dev/null
+/******************************************************************\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
--- /dev/null
+/******************************************************************\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
--- /dev/null
+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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+package org.iotivity.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);
+ }
+}
--- /dev/null
+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
--- /dev/null
+APP_STL := gnustl_shared
+NDK_TOOLCHAIN_VERSION := 4.8
+
--- /dev/null
+//******************************************************************\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
--- /dev/null
+/* 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
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @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_
+
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @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_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @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_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @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_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+/**
+ * @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_
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_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
+
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_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;
+}
--- /dev/null
+#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;
+ }
+}
+
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_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;
+}
+
--- /dev/null
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "jni_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();
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#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
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#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
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#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
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+//
+//*********************************************************************
+
+/**
+ * @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;
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+#include <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;
+}
+
--- /dev/null
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics All Rights Reserved.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#include <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;
+}
+