Add an initial prototype of Multi-Phy Easy Setup service for Arduino device
authorJihun Ha <jihun.ha@samsung.com>
Thu, 4 Jun 2015 05:30:05 +0000 (14:30 +0900)
committerMadan Lanka <lanka.madan@samsung.com>
Thu, 4 Jun 2015 05:58:24 +0000 (05:58 +0000)
It provides the service library and an sample application using the library.
Arduino Mega board and WiFi shield are used for functionlity test.

Change-Id: Iadb19361db8a777b84437ad978887dedeb2e6e63
Signed-off-by: Jihun Ha <jihun.ha@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/1189
Reviewed-by: Madan Lanka <lanka.madan@samsung.com>
Tested-by: Madan Lanka <lanka.madan@samsung.com>
13 files changed:
resource/csdk/connectivity/SConscript
service/SConscript
service/easy-setup/SConscript [new file with mode: 0644]
service/easy-setup/sampleapp/SConscript [new file with mode: 0644]
service/easy-setup/sampleapp/arduino/thinserver/SConscript [new file with mode: 0644]
service/easy-setup/sampleapp/arduino/thinserver/thinserver.cpp [new file with mode: 0755]
service/easy-setup/sdk/arduino/wifi/inc/networkHandler.h [new file with mode: 0755]
service/easy-setup/sdk/arduino/wifi/src/networkHandler.cpp [new file with mode: 0755]
service/easy-setup/sdk/inc/common.h [new file with mode: 0755]
service/easy-setup/sdk/inc/easysetup.h [new file with mode: 0755]
service/easy-setup/sdk/inc/resourceHandler.h [new file with mode: 0755]
service/easy-setup/sdk/src/easysetup.cpp [new file with mode: 0755]
service/easy-setup/sdk/src/resourceHandler.cpp [new file with mode: 0755]

index bec1000..3d50078 100644 (file)
@@ -59,7 +59,7 @@ else:
 
 env.SConscript('./src/SConscript')
 
-if build_sample == 'ON':
-       if target_os in ['linux', 'arduino', 'android']:
-               env.SConscript('./samples/' + target_os + '/SConscript')
+#if build_sample == 'ON':
+#      if target_os in ['linux', 'arduino', 'android']:
+#              env.SConscript('./samples/' + target_os + '/SConscript')
        
index a3bd70e..92d7f0e 100644 (file)
@@ -26,7 +26,7 @@ Import('env')
 
 target_os = env.get('TARGET_OS')
 
-if target_os not in ['arduino','darwin','ios']:
+if target_os not in ['arduino','darwin']:
        # Build things manager project
        SConscript('things-manager/SConscript')
 
@@ -35,7 +35,7 @@ if target_os not in ['arduino','darwin','ios']:
 
        # Build protocol plugin project
        # protocol-plugin use 'inotify', this feature isn't support by MAC OSX
-       if target_os not in ['darwin', 'ios']:
+       if target_os not in ['darwin', 'ios', 'android']:
                SConscript('protocol-plugin/SConscript')
 
        # Build notification manager project
@@ -43,3 +43,5 @@ if target_os not in ['arduino','darwin','ios']:
 #else:
 #      SConscript('notification-manager/SampleApp/arduino/SConscript')
 
+if target_os == 'arduino':
+   SConscript('easy-setup/SConscript')
\ No newline at end of file
diff --git a/service/easy-setup/SConscript b/service/easy-setup/SConscript
new file mode 100644 (file)
index 0000000..945b93c
--- /dev/null
@@ -0,0 +1,80 @@
+#******************************************************************
+#
+# Copyright 2014 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# 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')
+
+easy_setup_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+######################################################################
+# Build flags
+######################################################################
+easy_setup_env.AppendUnique(CPPPATH = ['sdk/inc', 'sdk/src'])
+
+if target_os not in ['windows', 'winrt']:
+    easy_setup_env.AppendUnique(CXXFLAGS = ['-std=c++0x', '-Wall'])
+    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 == 'arduino':
+   easy_setup_env.AppendUnique(CPPPATH = [
+                                      '../../resource/oc_logger/include',
+                                      '../../resource/csdk/logger/include',
+                                      '../../resource/csdk/stack/include',
+                                      '../../extlibs/cjson',
+                                      'sdk/arduino/wifi/inc', 
+                                      'sdk/arduino/wifi/src' ])
+
+######################################################################
+# 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 == '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'))
+
+#Go to build sample apps
+SConscript('sampleapp/SConscript')
+
+
diff --git a/service/easy-setup/sampleapp/SConscript b/service/easy-setup/sampleapp/SConscript
new file mode 100644 (file)
index 0000000..a00282c
--- /dev/null
@@ -0,0 +1,43 @@
+#******************************************************************
+#
+# Copyright 2014 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# sampleapp build script
+##
+
+Import('env')
+
+# Add third party libraries
+lib_env = env.Clone()
+#SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+sample_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+
+######################################################################
+# Source files and Targets
+######################################################################
+if target_os == 'arduino' :
+       # Build linux sample app
+       SConscript('arduino/thinserver/SConscript')
+
diff --git a/service/easy-setup/sampleapp/arduino/thinserver/SConscript b/service/easy-setup/sampleapp/arduino/thinserver/SConscript
new file mode 100644 (file)
index 0000000..d03e18e
--- /dev/null
@@ -0,0 +1,54 @@
+#******************************************************************
+#
+# 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')
+
+thinserver_env = env.Clone()
+######################################################################
+# Build flags
+######################################################################
+thinserver_env.PrependUnique(CPPPATH = [
+                '../../../../../resource/oc_logger/include',
+               '../../../../../resource/csdk/logger/include',
+                '../../../../../resource/csdk/stack/include',
+               '../../../../../extlibs/cjson',
+               '../../../sdk/inc',
+               '../../../sdk/arduino/wifi/inc'
+               ])
+
+thinserver_env.AppendUnique(LIBPATH = [env.get('BUILD_DIR')])
+thinserver_env.AppendUnique(CPPDEFINES = ['TB_LOG', 'ARDUINOWIFI'])
+
+thinserver_env.PrependUnique(LIBS = ['octbstack', 'connectivity_abstraction','coap', 'ESSDKLibrary'])
+
+thinserver = thinserver_env.Program('thinserver', 'thinserver.cpp')
+env.CreateBin('thinserver')
+
+i_thinserver = thinserver_env.Install(env.get('BUILD_DIR'), thinserver)
+
+Alias('thinserver', i_thinserver)
+env.AppendTarget('thinserver')
+
+if(thinserver_env['UPLOAD'] == True):
+       from sys import platform as _platform
+       if _platform == "linux" or _platform == "linux2":
+               thinserver_env.Upload(env.get('BUILD_DIR') + '/service/easy-setup/sampleapp/arduino/thinserver/thinserver.hex')
+       else:
+               print 'Please use appropriate install method for your developing machine. Linux is the only supported platform right now.'
diff --git a/service/easy-setup/sampleapp/arduino/thinserver/thinserver.cpp b/service/easy-setup/sampleapp/arduino/thinserver/thinserver.cpp
new file mode 100755 (executable)
index 0000000..d352e1e
--- /dev/null
@@ -0,0 +1,116 @@
+//******************************************************************
+//
+// Copyright 2014 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+#include "easysetup.h"
+
+const char *getResult(OCStackResult result);
+
+PROGMEM const char TAG[] = "ArduinoServer";
+
+void EventCallbackInApp(ES_RESULT eventFlag)
+{
+    Serial.println("callback!!! in app");
+}
+
+// On Arduino Atmel boards with Harvard memory architecture, the stack grows
+// downwards from the top and the heap grows upwards. This method will print
+// the distance(in terms of bytes) between those two.
+// See here for more details :
+// http://www.atmel.com/webdoc/AVRLibcReferenceManual/malloc_1malloc_intro.html
+void PrintArduinoMemoryStats()
+{
+#ifdef ARDUINO_AVR_MEGA2560
+    //This var is declared in avr-libc/stdlib/malloc.c
+    //It keeps the largest address not allocated for heap
+    extern char *__brkval;
+    //address of tmp gives us the current stack boundry
+    int tmp;
+    OC_LOG_V(INFO, TAG, "Stack: %u         Heap: %u", (unsigned int)&tmp, (unsigned int)__brkval);
+    OC_LOG_V(INFO, TAG, "Unallocated Memory between heap and stack: %u",
+            ((unsigned int)&tmp - (unsigned int)__brkval));
+#endif
+}
+//The setup function is called once at startup of the sketch
+void setup()
+{
+    // Add your initialization code here
+    // Note : This will initialize Serial port on Arduino at 115200 bauds
+    OC_LOG_INIT();
+    OC_LOG(DEBUG, TAG, PCF("OCServer is starting..."));
+
+    WaitingForOnboarding(ES_WIFI, EventCallbackInApp);
+
+    // Initialize the OC Stack in Server mode
+    if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("OCStack init error"));
+        return;
+    }
+
+    PrepareToProvisioning(EventCallbackInApp);
+
+    if (OCStartPresence(0) != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("Start Presence init error"));
+        return;
+    }
+}
+
+// The loop function is called in an endless loop
+void loop()
+{
+    // This artificial delay is kept here to avoid endless spinning
+    // of Arduino microcontroller. Modify it as per specific application needs.
+    delay(2000);
+
+    // This call displays the amount of free SRAM available on Arduino
+    PrintArduinoMemoryStats();
+
+    // Give CPU cycles to OCStack to perform send/recv and other OCStack stuff
+    if (OCProcess() != OC_STACK_OK)
+    {
+        OC_LOG(ERROR, TAG, PCF("OCStack process error"));
+        return;
+    }
+    //ChangeLightRepresentation(NULL);
+}
diff --git a/service/easy-setup/sdk/arduino/wifi/inc/networkHandler.h b/service/easy-setup/sdk/arduino/wifi/inc/networkHandler.h
new file mode 100755 (executable)
index 0000000..89ee67c
--- /dev/null
@@ -0,0 +1,76 @@
+//******************************************************************
+//
+// Copyright 2014 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+#include "common.h"
+
+#ifndef ES_NETWORK_HANDLER_H_
+#define ES_NETWORK_HANDLER_H_
+
+#define MAXSSIDLEN 33
+#define MAXNETCREDLEN 20
+#define MAXNUMTYPE 5
+#define MAXADDRLEN 15
+
+typedef void (*NetworkEventCallback)(ES_RESULT);
+
+enum NetworkType
+{
+    ES_WIFI = 1, ES_BT = 2, ES_BLE = 3, ES_ZIGBEE = 4, ES_ETH = 5
+};
+
+typedef struct NETWORKINFO
+{
+    NetworkType type;
+
+    // for WiFI
+    IPAddress ipaddr;
+    char ssid[MAXSSIDLEN];
+
+    // for BT, BLE
+    byte mac[6];
+} NetworkInfo;
+
+ES_RESULT ConnectToWiFiNetworkForOnboarding(char *ssid, char *pass, NetworkEventCallback);
+int getCurrentNetworkInfo(NetworkType targetType, NetworkInfo *info);
+
+#endif
diff --git a/service/easy-setup/sdk/arduino/wifi/src/networkHandler.cpp b/service/easy-setup/sdk/arduino/wifi/src/networkHandler.cpp
new file mode 100755 (executable)
index 0000000..9fef111
--- /dev/null
@@ -0,0 +1,185 @@
+//******************************************************************
+//
+// Copyright 2014 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 "networkHandler.h"
+
+PROGMEM const char TAG[] = "ArduinoServer";
+
+int findNetwork(char *ssid);
+int ConnectToNetwork(char *ssid, char *pass);
+void printEncryptionType(int thisType);
+
+// Arduino WiFi Shield
+// Note : Arduino WiFi Shield currently does NOT support multicast and therefore
+// this server will NOT be listening on 224.0.1.187 multicast address.
+
+static const char ARDUINO_WIFI_SHIELD_UDP_FW_VER[] = "1.1.0";
+
+IPAddress myIP;
+
+ES_RESULT ConnectToWiFiNetworkForOnboarding(char *ssid, char *pass, NetworkEventCallback cb)
+{
+    char *fwVersion;
+    int status = WL_IDLE_STATUS;
+    int res;
+
+    // check for the presence of the shield:
+    if (WiFi.status() == WL_NO_SHIELD)
+    {
+        OC_LOG(ERROR, TAG, PCF("WiFi shield not present"));
+        return ES_ERROR;
+    }
+
+    // Verify that WiFi Shield is running the firmware with all UDP fixes
+    fwVersion = WiFi.firmwareVersion();
+    OC_LOG_V(INFO, TAG, "WiFi Shield Firmware version %s", fwVersion);
+    if (strncmp(fwVersion, ARDUINO_WIFI_SHIELD_UDP_FW_VER, sizeof(ARDUINO_WIFI_SHIELD_UDP_FW_VER))
+            != 0)
+    {
+        OC_LOG(DEBUG, TAG, PCF("!!!!! Upgrade WiFi Shield Firmware version !!!!!!"));
+        return ES_ERROR;
+    }
+
+    while (findNetwork(ssid) == 0) // found
+    {
+        delay(2000);
+    }
+
+    if (cb != NULL)
+    {
+        cb(ES_NETWORKFOUND);
+    }
+
+    if (WiFi.status() == WL_CONNECTED)
+        WiFi.disconnect();
+
+    res = ConnectToNetwork(ssid, pass);
+
+    if (res == 0)
+    {
+        return ES_NETWORKCONNECTED;
+    }
+    else
+    {
+        return ES_NETWORKNOTCONNECTED;
+    }
+}
+
+int findNetwork(char *ssid)
+{
+    int res = 0;
+    // scan for nearby networks:
+    Serial.println("** Scan Networks **");
+    int numSsid = WiFi.scanNetworks();
+    if (numSsid == -1)
+    {
+        Serial.println("Couldn't get a wifi connection");
+
+        return res;
+    }
+
+    // print the list of networks seen:
+    Serial.print("number of available networks:");
+    Serial.println(numSsid);
+
+    // print the network number and name for each network found:
+    for (int thisNet = 0; thisNet < numSsid; thisNet++)
+    {
+        Serial.print(thisNet);
+        Serial.print(") ");
+        Serial.print(WiFi.SSID(thisNet));
+        Serial.print("\tEncryption: ");
+        printEncryptionType(WiFi.encryptionType(thisNet));
+
+        if (strcmp(WiFi.SSID(thisNet), ssid) == 0)
+        {
+            res = 1;
+        }
+    }
+
+    return res;
+}
+
+int ConnectToNetwork(char *ssid, char *pass)
+{
+    int status = WL_IDLE_STATUS;
+    //IPAddress desiredIP(192, 168, 43, 2);
+    //IPAddress desiredIP(192, 168, 0, 115);
+
+    //WiFi.config(desiredIP);
+
+    // attempt to connect to Wifi network:
+    while (status != WL_CONNECTED)
+    {
+        OC_LOG_V(INFO, TAG, "Attempting to connect to SSID: %s", ssid);
+
+        status = WiFi.begin(ssid, pass);
+
+        // wait 10 seconds for connection:
+        delay(10000);
+    }
+    OC_LOG(DEBUG, TAG, PCF("Connected to wifi"));
+
+    myIP = WiFi.localIP();
+    OC_LOG_V(INFO, TAG, "IP Address:  %d.%d.%d.%d", myIP[0], myIP[1], myIP[2], myIP[3]);
+
+    char buf[50];
+    sprintf(buf, "IP Address:  %d.%d.%d.%d", myIP[0], myIP[1], myIP[2], myIP[3]);
+    Serial.println(buf);
+
+    return 0;
+}
+
+int getCurrentNetworkInfo(NetworkType targetType, NetworkInfo *info)
+{
+    if (targetType == ES_WIFI && WiFi.status() == WL_CONNECTED)
+    {
+        info->type = ES_WIFI;
+        info->ipaddr = WiFi.localIP();
+        strcpy(info->ssid, WiFi.SSID());
+
+        return 0;
+    }
+
+    return -1;
+}
+
+void printEncryptionType(int thisType)
+{
+    // read the encryption type and print out the name:
+    switch (thisType)
+    {
+        case ENC_TYPE_WEP:
+            Serial.println("WEP");
+            break;
+        case ENC_TYPE_TKIP:
+            Serial.println("WPA");
+            break;
+        case ENC_TYPE_CCMP:
+            Serial.println("WPA2");
+            break;
+        case ENC_TYPE_NONE:
+            Serial.println("None");
+            break;
+        case ENC_TYPE_AUTO:
+            Serial.println("Auto");
+            break;
+    }
+}
diff --git a/service/easy-setup/sdk/inc/common.h b/service/easy-setup/sdk/inc/common.h
new file mode 100755 (executable)
index 0000000..3a6fd16
--- /dev/null
@@ -0,0 +1,38 @@
+//******************************************************************
+//
+// Copyright 2014 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 ES_COMMON_H_
+#define ES_COMMON_H_
+
+typedef enum
+{
+    ES_ERROR = -1,
+    ES_OK = 0,
+    ES_NETWORKFOUND = 1,
+    ES_NETWORKCONNECTED,
+    ES_NETWORKNOTCONNECTED,
+    ES_RESOURCECREATED = 11,
+    ES_RECVREQOFPROVRES = 21,
+    ES_RECVREQOFNETRES,
+    ES_RECVUPDATEOFPROVRES,
+    ES_RECVTRIGGEROFPROVRES,
+} ES_RESULT;
+
+#endif
diff --git a/service/easy-setup/sdk/inc/easysetup.h b/service/easy-setup/sdk/inc/easysetup.h
new file mode 100755 (executable)
index 0000000..665d8e3
--- /dev/null
@@ -0,0 +1,56 @@
+//******************************************************************
+//
+// Copyright 2014 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+#include "common.h"
+#include "networkHandler.h"
+#include "resourceHandler.h"
+
+typedef void (*EventCallback)(ES_RESULT);
+
+OCStackResult Init();
+
+ES_RESULT WaitingForOnboarding(NetworkType networkType, EventCallback);
+//OCStackResult WaitingForOnboarding(NetworkType networkType, char *name);
+//OCStackResult WaitingForOnboarding(NetworkType networkType, char *name, char *pass);
+
+ES_RESULT PrepareToProvisioning(EventCallback);
diff --git a/service/easy-setup/sdk/inc/resourceHandler.h b/service/easy-setup/sdk/inc/resourceHandler.h
new file mode 100755 (executable)
index 0000000..cae38ce
--- /dev/null
@@ -0,0 +1,78 @@
+//******************************************************************
+//
+// Copyright 2014 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+// Do not remove the include below
+#include "Arduino.h"
+
+#include "logger.h"
+#include "ocstack.h"
+#include <string.h>
+
+#ifdef ARDUINOWIFI
+// Arduino WiFi Shield
+#include <SPI.h>
+#include <WiFi.h>
+#include <WiFiUdp.h>
+#else
+// Arduino Ethernet Shield
+#include <EthernetServer.h>
+#include <Ethernet.h>
+#include <Dns.h>
+#include <EthernetClient.h>
+#include <util.h>
+#include <EthernetUdp.h>
+#include <Dhcp.h>
+#endif
+
+#include "common.h"
+#include "networkHandler.h"
+#include "octypes.h"
+
+#ifndef ES_RESOURCE_HANDLER_H_
+#define ES_RESOURCE_HANDLER_H_
+
+typedef void (*ResourceEventCallback)(ES_RESULT);
+
+/* Structure to represent a Light resource */
+typedef struct PROVRESOURCE
+{
+    OCResourceHandle handle;
+    int ps; // provisiong status, 1 : need to provisioning, 2 : Connected to Internet
+    int tnt; // target network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+    char tnn[MAXSSIDLEN]; // target network name, i.e. SSID for WLAN, MAC address for BT
+    char cd[MAXNETCREDLEN]; // credential information
+} ProvResource;
+
+/* Structure to represent a Light resource */
+typedef struct NETRESOURCE
+{
+    OCResourceHandle handle;
+    int cnt; // current network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+    int ant[MAXNUMTYPE]; // available network type, 1: WLAN, 2: BT, 3: BLE, 4: Zigbee, ...
+    char ipaddr[MAXADDRLEN]; // ip address
+    char cnn[MAXSSIDLEN]; // current network name
+} NetResource;
+
+OCStackResult createProvisioningResource();
+OCStackResult createNetworkResource();
+void getTargetNetworkInfoFromProvResource(char *, char *);
+void RegisterResourceEventCallBack(ResourceEventCallback);
+
+#endif
diff --git a/service/easy-setup/sdk/src/easysetup.cpp b/service/easy-setup/sdk/src/easysetup.cpp
new file mode 100755 (executable)
index 0000000..0706b52
--- /dev/null
@@ -0,0 +1,129 @@
+//******************************************************************
+//
+// Copyright 2014 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 "easysetup.h"
+
+PROGMEM const char TAG[] = "ArduinoServer";
+
+/// WiFi network info and credentials
+char defaultSsid[] = "EasyConnect";
+char defaultPass[] = "EasyConnect";
+
+int g_eventflag = 0;
+int g_cnt = 0;
+char *targetSsid;
+char *targetPass;
+
+EventCallback g_cbForProvisioning = NULL;
+EventCallback g_cbForOnboarding = NULL;
+
+void EventCallbackInOnboarding(ES_RESULT event);
+void EventCallbackInProvisioning(ES_RESULT event);
+void EventCallbackAfterProvisioning(ES_RESULT event);
+
+void EventCallbackInOnboarding(ES_RESULT event)
+{
+    Serial.println("[Callback] in onboarding process");
+
+    if (event == ES_NETWORKFOUND || event == ES_NETWORKCONNECTED)
+    {
+        if (g_cbForOnboarding != NULL)
+        {
+            g_cbForOnboarding(event);
+        }
+    }
+}
+
+void EventCallbackInProvisioning(ES_RESULT event)
+{
+    ES_RESULT res = ES_OK;
+
+    Serial.println("[Callback] in provisioning process");
+
+    if (event == ES_RECVTRIGGEROFPROVRES)
+    {
+        targetSsid = (char *) malloc(MAXSSIDLEN);
+        targetPass = (char *) malloc(MAXNETCREDLEN);
+
+        getTargetNetworkInfoFromProvResource(targetSsid, targetPass);
+
+        res = ConnectToWiFiNetworkForOnboarding(targetSsid, targetPass,
+                EventCallbackAfterProvisioning);
+
+        if (g_cbForProvisioning != NULL)
+        {
+            g_cbForProvisioning(res);
+        }
+    }
+}
+
+void EventCallbackAfterProvisioning(ES_RESULT event)
+{
+    Serial.println("[Callback] after provisioning process");
+
+    if (event == ES_NETWORKFOUND || event == ES_NETWORKCONNECTED)
+    {
+        if (g_cbForProvisioning != NULL)
+        {
+            g_cbForProvisioning(event);
+        }
+    }
+}
+
+ES_RESULT WaitingForOnboarding(NetworkType networkType, EventCallback cb)
+{
+    if (networkType == ES_WIFI)
+    {
+        if (g_cbForOnboarding == NULL)
+        {
+            g_cbForOnboarding = cb;
+        }
+
+        return ConnectToWiFiNetworkForOnboarding(defaultSsid, defaultPass,
+                EventCallbackInOnboarding);
+    }
+}
+
+ES_RESULT PrepareToProvisioning(EventCallback cb)
+{
+    if (cb == NULL)
+    {
+        return ES_ERROR;
+    }
+    else
+    {
+        g_cbForProvisioning = cb;
+    }
+
+    if (createProvisioningResource() != OC_STACK_OK)
+    {
+        return ES_ERROR;
+    }
+
+    if (createNetworkResource() != OC_STACK_OK)
+    {
+        return ES_ERROR;
+    }
+
+    RegisterResourceEventCallBack(EventCallbackInProvisioning);
+
+    return ES_RESOURCECREATED;
+}
+
diff --git a/service/easy-setup/sdk/src/resourceHandler.cpp b/service/easy-setup/sdk/src/resourceHandler.cpp
new file mode 100755 (executable)
index 0000000..d220960
--- /dev/null
@@ -0,0 +1,404 @@
+//******************************************************************
+//
+// Copyright 2014 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 "resourceHandler.h"
+#include "cJSON.h"
+
+PROGMEM const char TAG[] = "ArduinoServer";
+
+ProvResource g_prov;
+NetResource g_net;
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *);
+const char *getResult(OCStackResult result);
+
+OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize);
+OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize);
+OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize);
+char* constructJsonResponse(OCEntityHandlerRequest *ehRequest);
+
+int g_flag = 0;
+
+ResourceEventCallback g_cbForResEvent = NULL;
+
+void RegisterResourceEventCallBack(ResourceEventCallback cb)
+{
+    g_cbForResEvent = cb;
+}
+
+void getTargetNetworkInfoFromProvResource(char *name, char *pass)
+{
+    if (name != NULL && pass != NULL)
+    {
+        sprintf(name, "%s", g_prov.tnn);
+        sprintf(pass, "%s", g_prov.cd);
+    }
+}
+
+OCStackResult createProvisioningResource()
+{
+    g_prov.ps = 1; // need to provisioning
+    g_prov.tnt = ES_WIFI;
+    sprintf(g_prov.tnn, "Unknown");
+    sprintf(g_prov.cd, "Unknown");
+
+    OCStackResult res = OCCreateResource(&g_prov.handle, "oic.prov", OC_RSRVD_INTERFACE_DEFAULT,
+            "/oic/prov", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
+
+    OC_LOG_V(INFO, TAG, "Created Prov resource with result: %s", getResult(res));
+
+    return res;
+}
+
+OCStackResult createNetworkResource()
+{
+    NetworkInfo netInfo;
+
+    if (getCurrentNetworkInfo(ES_WIFI, &netInfo) != 0)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    if (netInfo.type != ES_WIFI)
+    {
+        return OC_STACK_ERROR;
+    }
+
+    g_net.cnt = (int) netInfo.type;
+    g_net.ant[0] = (int) ES_WIFI;
+    sprintf(g_net.ipaddr, "%d.%d.%d.%d", netInfo.ipaddr[0], netInfo.ipaddr[1], netInfo.ipaddr[2],
+            netInfo.ipaddr[3]);
+    sprintf(g_net.cnn, "%s", netInfo.ssid);
+
+    OC_LOG_V(INFO, TAG, "SSID: %s", g_net.cnn);
+    OC_LOG_V(INFO, TAG, "IP Address: %s", g_net.ipaddr);
+
+    OCStackResult res = OCCreateResource(&g_net.handle, "oic.net", OC_RSRVD_INTERFACE_DEFAULT,
+            "/oic/net", OCEntityHandlerCb, OC_DISCOVERABLE | OC_OBSERVABLE);
+    OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
+
+    return res;
+}
+
+OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize)
+{
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    char *getResp = constructJsonResponse(ehRequest);
+
+    if (!getResp)
+    {
+        OC_LOG(ERROR, TAG, "constructJsonResponse failed");
+        return OC_EH_ERROR;
+    }
+
+    if (MAX_RESPONSE_LENGTH > strlen(getResp))
+    {
+        strncpy(payload, getResp, strlen(getResp));
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
+        ehResult = OC_EH_ERROR;
+    }
+
+    free(getResp);
+
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize)
+{
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+
+    OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
+
+    // Get cJSON pointer to query
+    cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
+    if (!putJson)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+
+    // Get root of JSON payload, then the 1st resource.
+    cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
+    if (!carrier)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+    carrier = cJSON_GetArrayItem(carrier, 0);
+    carrier = cJSON_GetObjectItem(carrier, "rep");
+    if (!carrier)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+
+    cJSON* prop = cJSON_GetObjectItem(carrier, "tnn");
+    if (prop)
+    {
+        sprintf(g_prov.tnn, "%s", prop->valuestring);
+    }
+
+    prop = cJSON_GetObjectItem(carrier, "cd");
+    if (prop)
+    {
+        sprintf(g_prov.cd, "%s", prop->valuestring);
+    }
+
+    cJSON_Delete(putJson);
+
+    // TODO: Now once receiving PUT request, the enrollee start to connect to enroller.
+    g_flag = 1;
+
+    char *getResp = constructJsonResponse(ehRequest);
+
+    if (!getResp)
+    {
+        OC_LOG(ERROR, TAG, "constructJsonResponse failed");
+        return OC_EH_ERROR;
+    }
+
+    if (MAX_RESPONSE_LENGTH > strlen(getResp))
+    {
+        strncpy(payload, getResp, strlen(getResp));
+        ehResult = OC_EH_OK;
+    }
+    else
+    {
+        OC_LOG_V(INFO, TAG, "Response buffer: %d bytes is too small", maxPayloadSize);
+        ehResult = OC_EH_ERROR;
+    }
+
+    free(getResp);
+    return ehResult;
+}
+
+OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, char *payload,
+        uint16_t maxPayloadSize)
+{
+    OCEntityHandlerResult ehResult = OC_EH_ERROR;
+    OC_LOG_V(INFO, TAG, "PUT Request Payload: %s", ehRequest->reqJSONPayload);
+
+    // Get cJSON pointer to query
+    cJSON *putJson = cJSON_Parse(ehRequest->reqJSONPayload);
+
+    if (!putJson)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+
+    // Get root of JSON payload, then the 1st resource.
+    cJSON* carrier = cJSON_GetObjectItem(putJson, "oic");
+    if (!carrier)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+    carrier = cJSON_GetArrayItem(carrier, 0);
+    carrier = cJSON_GetObjectItem(carrier, "rep");
+    if (!carrier)
+    {
+        OC_LOG_V(ERROR, TAG, "Failed to parse JSON: %s", ehRequest->reqJSONPayload);
+        return ehResult;
+    }
+
+    cJSON* prop = cJSON_GetObjectItem(carrier, "tr");
+    if (prop)
+    {
+        // Triggering
+        ehResult = OC_EH_OK;
+    }
+
+    cJSON_Delete(putJson);
+
+    g_flag = 1;
+
+    return ehResult;
+}
+
+char* constructJsonResponse(OCEntityHandlerRequest *ehRequest)
+{
+    cJSON *json = cJSON_CreateObject();
+    cJSON *format;
+    char *jsonResponse;
+    char *JsonResp;
+    char temp_resp[256];
+
+    if (g_prov.handle != NULL && ehRequest->resource == g_prov.handle)
+    {
+        char *uri = (char *) "/oic/prov";
+
+        cJSON_AddStringToObject(json, "href", uri);
+        cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+        cJSON_AddNumberToObject(format, "ps", g_prov.ps);
+        cJSON_AddNumberToObject(format, "tnt", g_prov.tnt);
+        cJSON_AddStringToObject(format, "tnn", g_prov.tnn);
+        cJSON_AddStringToObject(format, "cd", g_prov.cd);
+
+        jsonResponse = cJSON_Print(json);
+        cJSON_Delete(json);
+    }
+    else if (g_net.handle != NULL && ehRequest->requestHandle == g_net.handle)
+    {
+        char *uri = (char *) "/oic/net";
+
+        cJSON_AddStringToObject(json, "href", uri);
+        cJSON_AddItemToObject(json, "rep", format = cJSON_CreateObject());
+        cJSON_AddNumberToObject(format, "ant", g_net.ant[0]);
+
+        jsonResponse = cJSON_Print(json);
+        cJSON_Delete(json);
+    }
+    else
+    {
+        return jsonResponse;
+    }
+
+    OC_LOG_V(INFO, TAG, "Constructed Response: %s", jsonResponse);
+
+    Serial.print("Constructed Response: ");
+    Serial.println(jsonResponse);
+
+    return jsonResponse;
+}
+
+// This is the entity handler for the registered resource.
+// This is invoked by OCStack whenever it recevies a request for this resource.
+
+OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag flag,
+        OCEntityHandlerRequest* entityHandlerRequest)
+{
+    OCEntityHandlerResult ehRet = OC_EH_OK;
+    OCEntityHandlerResponse response =
+    { 0 };
+    char payload[MAX_RESPONSE_LENGTH] =
+    { 0 };
+
+    if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
+    {
+        if (OC_REST_GET == entityHandlerRequest->method)
+        {
+            OC_LOG_V(INFO, TAG, "Received GET request");
+            ehRet = ProcessGetRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
+        }
+        else if (OC_REST_PUT == entityHandlerRequest->method)
+        {
+            OC_LOG_V(INFO, TAG, "Received PUT request");
+
+            if (g_prov.handle != NULL && entityHandlerRequest->resource == g_prov.handle)
+            {
+                ehRet = ProcessPutRequest(entityHandlerRequest, payload, sizeof(payload) - 1);
+            }
+            else
+            {
+                ehRet = OC_EH_ERROR;
+            }
+        }
+        else if (OC_REST_POST == entityHandlerRequest->method)
+        {
+            // TODO: As of now, POST request will be not received.
+            OC_LOG(INFO, TAG, "Received OC_REST_POST from client");
+            //ehRet = ProcessPostRequest (entityHandlerRequest, payload, sizeof(payload) - 1);
+        }
+
+        if (ehRet == OC_EH_OK)
+        {
+            // Format the response.  Note this requires some info about the request
+            response.requestHandle = entityHandlerRequest->requestHandle;
+            response.resourceHandle = entityHandlerRequest->resource;
+            response.ehResult = ehRet;
+            response.payload = payload;
+            response.payloadSize = strlen(payload);
+            response.numSendVendorSpecificHeaderOptions = 0;
+            memset(response.sendVendorSpecificHeaderOptions, 0,
+                    sizeof response.sendVendorSpecificHeaderOptions);
+            memset(response.resourceUri, 0, sizeof response.resourceUri);
+            // Indicate that response is NOT in a persistent buffer
+            response.persistentBufferFlag = 0;
+
+            // Send the response
+            if (OCDoResponse(&response) != OC_STACK_OK)
+            {
+                OC_LOG(ERROR, TAG, "Error sending response");
+                ehRet = OC_EH_ERROR;
+            }
+        }
+    }
+
+    if (g_flag == 1)
+    {
+        g_cbForResEvent(ES_RECVTRIGGEROFPROVRES);
+        g_flag = 0;
+    }
+
+    return ehRet;
+}
+
+const char *getResult(OCStackResult result)
+{
+    switch (result)
+    {
+        case OC_STACK_OK:
+            return "OC_STACK_OK";
+        case OC_STACK_INVALID_URI:
+            return "OC_STACK_INVALID_URI";
+        case OC_STACK_INVALID_QUERY:
+            return "OC_STACK_INVALID_QUERY";
+        case OC_STACK_INVALID_IP:
+            return "OC_STACK_INVALID_IP";
+        case OC_STACK_INVALID_PORT:
+            return "OC_STACK_INVALID_PORT";
+        case OC_STACK_INVALID_CALLBACK:
+            return "OC_STACK_INVALID_CALLBACK";
+        case OC_STACK_INVALID_METHOD:
+            return "OC_STACK_INVALID_METHOD";
+        case OC_STACK_NO_MEMORY:
+            return "OC_STACK_NO_MEMORY";
+        case OC_STACK_COMM_ERROR:
+            return "OC_STACK_COMM_ERROR";
+        case OC_STACK_INVALID_PARAM:
+            return "OC_STACK_INVALID_PARAM";
+        case OC_STACK_NOTIMPL:
+            return "OC_STACK_NOTIMPL";
+        case OC_STACK_NO_RESOURCE:
+            return "OC_STACK_NO_RESOURCE";
+        case OC_STACK_RESOURCE_ERROR:
+            return "OC_STACK_RESOURCE_ERROR";
+        case OC_STACK_SLOW_RESOURCE:
+            return "OC_STACK_SLOW_RESOURCE";
+        case OC_STACK_NO_OBSERVERS:
+            return "OC_STACK_NO_OBSERVERS";
+        case OC_STACK_ERROR:
+            return "OC_STACK_ERROR";
+        default:
+            return "UNKNOWN";
+    }
+}
+