Merge branch 'master' into easysetup and fixed OCStack issue 92/1392/2
authorMadan Lanka <lanka.madan@samsung.com>
Mon, 22 Jun 2015 06:53:40 +0000 (02:53 -0400)
committerMadan Lanka <lanka.madan@samsung.com>
Tue, 23 Jun 2015 05:13:10 +0000 (05:13 +0000)
1) Merged latest master branch code to EasySetup branch
   - Needed as latest Security Layer apis have to integrated to EasySetup branch
2) OCConnectivityType Enum is modified in latest master branch code
   - Changed EasySetup implementation which is using the enum
3) Created json tags for EasySetup json attributes and used it EasySetup implementation
4) Optimized some of the EasySetup implementation
5) Reverted back caipnwmonitor.c modifications performed for resolving the network notification issue in Android
6) Added Broadcast listener code for listening to Android Soft AP enable and disable notification in Android
7) Fixed OCStack memset issue

Conflicts:
resource/csdk/connectivity/SConscript

Change-Id: I9ccd911c560b30aae1e9d5cb6b1356cca947c884
Signed-off-by: Madan Lanka <lanka.madan@samsung.com>
13 files changed:
1  2 
android/android_api/base/src/main/java/org/iotivity/ca/CaIpInterface.java
resource/csdk/connectivity/SConscript
resource/csdk/connectivity/src/ip_adapter/android/caipnwmonitor.c
resource/csdk/stack/src/ocstack.c
service/SConscript
service/easy-setup/SConscript
service/easy-setup/sampleapp/linux/richclient/easysetupsample.cpp
service/easy-setup/sdk/common/common.h
service/easy-setup/sdk/mediator/android/EasySetupCore/AndroidManifest.xml
service/easy-setup/sdk/mediator/android/jni/jni_easy_setup.cpp
service/easy-setup/sdk/mediator/inc/provisioninghandler.h
service/easy-setup/sdk/mediator/src/camutex_pthreads.c
service/easy-setup/sdk/mediator/src/provisioninghandler.cpp

@@@ -27,10 -27,10 +27,31 @@@ import android.content.IntentFilter
  import android.net.ConnectivityManager;\r
  import android.net.NetworkInfo;\r
  import android.net.wifi.WifiManager;\r
++import android.util.Log;\r
  \r
  public class CaIpInterface {\r
      private static Context mContext;\r
  \r
++    public enum WifiAPState{\r
++        WIFI_AP_STATE_DISABLING (10),\r
++        WIFI_AP_STATE_DISABLED (11),\r
++        WIFI_AP_STATE_ENABLING (12),\r
++        WIFI_AP_STATE_ENABLED (13),\r
++        WIFI_AP_STATE_FAILED (14)\r
++        ; // semicolon needed when fields / methods follow\r
++\r
++\r
++        private final int apstate;\r
++\r
++        WifiAPState(int apstate)\r
++        {\r
++            this.apstate = apstate;\r
++        }\r
++        public int getIntValue() {\r
++           return this.apstate;\r
++        }\r
++    }\r
++\r
      private CaIpInterface(Context context) {\r
          mContext = context;\r
          registerIpStateReceiver();\r
@@@ -40,6 -40,6 +61,7 @@@
          IntentFilter intentFilter = new IntentFilter();\r
          intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);\r
          intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);\r
++        intentFilter.addAction("android.net.wifi.WIFI_AP_STATE_CHANGED");\r
  \r
          mContext.registerReceiver(mReceiver, intentFilter);\r
      }\r
                      caIpStateEnabled();\r
                  }\r
              }\r
++\r
++            if (intent.getAction().equals("android.net.wifi.WIFI_AP_STATE_CHANGED")) {\r
++                if (intent.getIntExtra("wifi_state",\r
++                    WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
++                    == WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
++                {\r
++                    caIpStateDisabled();\r
++                }else if(intent.getIntExtra("wifi_state",\r
++                    WifiAPState.WIFI_AP_STATE_DISABLED.getIntValue())\r
++                    == WifiAPState.WIFI_AP_STATE_ENABLED.getIntValue())\r
++                {\r
++                    try {\r
++                        Thread.sleep(1000);\r
++                    } catch (InterruptedException e) {\r
++                        // TODO Auto-generated catch block\r
++                        e.printStackTrace();\r
++                    }\r
++                    caIpStateEnabled();\r
++                }\r
++           }\r
          }\r
      };\r
  \r
@@@ -59,7 -59,7 +59,6 @@@ 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')
-       
@@@ -479,12 -479,7 +479,9 @@@ CAResult_t CAIPInitializeNetworkMonitor
  
      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");
@@@ -1971,75 -1779,238 +1779,238 @@@ OCStackResult verifyUriQueryLength(cons
      return OC_STACK_OK;
  }
  
- OCStackResult OCDoResource(OCDoHandle *handle, OCMethod method, const char *requiredUri,
-             const char *referenceUri, const char *request, OCConnectivityType conType,
-             OCQualityOfService qos, OCCallbackData *cbData,
-             OCHeaderOption * options, uint8_t numOptions)
+ /**
+  *  A request uri consists of the following components in order:
+  *                              example
+  *  optional prefix             "coap://"
+  *  optionally one of
+  *      IPv6 address            "[1234::5678]"
+  *      IPv4 address            "192.168.1.1"
+  *  optional port               ":5683"
+  *  resource uri                "/oc/core..."
+  *
+  *  for PRESENCE requests, extract resource type.
+  */
+ static OCStackResult ParseRequestUri(const char *fullUri,
+                                         OCTransportAdapter adapter,
+                                         OCTransportFlags flags,
+                                         OCDevAddr **devAddr,
+                                         char **resourceUri,
+                                         char **resourceType)
  {
-     OCStackResult result = OC_STACK_ERROR;
-     ClientCB *clientCB = NULL;
-     char * requestUri = NULL;
-     char * resourceType = NULL;
-     char * query = NULL;
-     char * newUri = (char *)requiredUri;
-     (void) referenceUri;
-     CARemoteEndpoint_t* endpoint = NULL;
-     CAResult_t caResult;
-     CAToken_t token = NULL;
-     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
-     OCDoHandle resHandle = NULL;
-     CAInfo_t requestData ={};
-     CARequestInfo_t requestInfo ={};
-     CAGroupEndpoint_t grpEnd = {};
+     VERIFY_NON_NULL(fullUri, FATAL, OC_STACK_INVALID_CALLBACK);
  
-     OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
+     OCStackResult result = OC_STACK_OK;
+     OCDevAddr *da = NULL;
+     char *colon = NULL;
+     char *end;
  
-     // Validate input parameters
-     VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
-     VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+     // provide defaults for all returned values
+     if (devAddr)
+     {
+         *devAddr = NULL;
+     }
+     if (resourceUri)
+     {
+         *resourceUri = NULL;
+     }
+     if (resourceType)
+     {
+         *resourceType = NULL;
+     }
  
-     //TODO ("Need to form the final query by concatenating require and reference URI's");
-     VERIFY_NON_NULL(requiredUri, FATAL, OC_STACK_INVALID_URI);
+     // delimit url prefix, if any
+     const char *start = fullUri;
+     char *slash2 = strstr(start, "//");
+     if (slash2)
+     {
+         start = slash2 + 2;
+     }
+     char *slash = strchr(start, '/');
+     if (!slash)
+     {
+         return OC_STACK_INVALID_URI;
+     }
  
-     uint16_t uriLen = strlen(requiredUri);
+     // processs url prefix, if any
+     size_t urlLen = slash - start;
+     if (urlLen && devAddr)
+     {   // construct OCDevAddr
+         if (start[0] == '[')
+         {   // ipv6 address
+             char *close = strchr(++start, ']');
+             if (!close || close > slash)
+             {
+                 return OC_STACK_INVALID_URI;
+             }
+             end = close;
+             if (close[1] == ':')
+             {
+                 colon = close + 1;
+             }
+         }
+         else
+         {   // ipv4 address
+             end = slash;
+             colon = strchr(start, ':');
+             end = (colon && colon < slash) ? colon : slash;
+         }
+         size_t len = end - start;
+         if (len > MAX_ADDR_STR_SIZE)
+         {
+             return OC_STACK_INVALID_URI;
+         }
  
-     // ToDo: We should also check if the requiredUri has a mutlicast address,
-     // then qos has to be OC_Low_QOS
-     switch (method)
-     {
-         case OC_REST_GET:
-         case OC_REST_OBSERVE:
-         case OC_REST_OBSERVE_ALL:
-         case OC_REST_CANCEL_OBSERVE:
-             requestInfo.method = CA_GET;
-             break;
+         // port
+         uint16_t port = 0;      // use standard multicast port
+         if (colon && colon < slash)
+         {
+             for (colon++; colon < slash; colon++)
+             {
+                 char c = colon[0];
+                 if (c < '0' || c > '9')
+                 {
+                     return OC_STACK_INVALID_URI;
+                 }
+                 port = 10 * port + c - '0';
+             }
+         }
  
-         case OC_REST_PUT:
-             requestInfo.method = CA_PUT;
-             break;
 -        da = (OCDevAddr *)OICMalloc(sizeof (OCDevAddr));
++        da = (OCDevAddr *)OICCalloc(1, sizeof (OCDevAddr));
+         if (!da)
+         {
+             return OC_STACK_NO_MEMORY;
+         }
+         strncpy(da->addr, start, len);
+         da->port = port;
+         da->adapter = adapter;
+         da->flags = flags;
+         if (!strncmp(fullUri, "coaps:", 6))
+         {
+             da->flags = (OCTransportFlags)(da->flags|CA_SECURE);
+         }
+         *devAddr = da;
+     }
  
-         case OC_REST_POST:
-             requestInfo.method = CA_POST;
-             break;
+     // process resource uri, if any
+     if (slash)
+     {   // request uri and query
+         size_t ulen = strlen(slash); // resource uri length
+         size_t tlen = 0;      // resource type length
+         char *type = NULL;
  
-         case OC_REST_DELETE:
-             requestInfo.method = CA_DELETE;
-             break;
+         static const char *strPresence = "/oc/presence?rt=";
+         static const size_t lenPresence = 15; // = strlen(presence);
+         if (!strncmp(slash, strPresence, lenPresence))
+         {
+             type = slash + lenPresence;
+             tlen = ulen - lenPresence;
+         }
+         // resource uri
+         if (resourceUri)
+         {
+             *resourceUri = (char *)OICMalloc(ulen + 1);
+             if (!*resourceUri)
+             {
+                 result = OC_STACK_NO_MEMORY;
+                 goto error;
+             }
+             strcpy(*resourceUri, slash);
+         }
+         // resource type
+         if (type && resourceType)
+         {
+             *resourceType = (char *)OICMalloc(tlen + 1);
+             if (!*resourceType)
+             {
+                 result = OC_STACK_NO_MEMORY;
+                 goto error;
+             }
+             strncpy(*resourceType, type, tlen);
+         }
+     }
  
-         #ifdef WITH_PRESENCE
-         case OC_REST_PRESENCE:
-             // Replacing method type with GET because "presence"
-             // is a stack layer only implementation.
-             requestInfo.method = CA_GET;
-             break;
-         #endif
+     return OC_STACK_OK;
  
-         default:
-             result = OC_STACK_INVALID_METHOD;
-             goto exit;
+ error:
+     // free all returned values
+     if (devAddr)
+     {
+         OICFree(*devAddr);
+     }
+     if (resourceUri)
+     {
+         OICFree(*resourceUri);
      }
+     if (resourceType)
+     {
+         OICFree(*resourceType);
+     }
+     return result;
+ }
+ static OCStackResult OCPreparePresence(CAEndpoint_t *endpoint,
+                                         char *resourceUri, char **requestUri)
+ {
+     char uri[CA_MAX_URI_LENGTH];
+     FormCanonicalPresenceUri(endpoint, resourceUri, uri);
+     *requestUri = (char *)OICMalloc(strlen(uri) + 1);
+     if (!*requestUri)
+     {
+         return OC_STACK_NO_MEMORY;
+     }
+     strcpy(*requestUri, uri);
+     return OC_STACK_OK;
+ }
+ /**
+  * Discover or Perform requests on a specified resource
+  */
+ OCStackResult OCDoResource(OCDoHandle *handle,
+                             OCMethod method,
+                             const char *requestUri,
+                             const OCDevAddr *destination,
+                             const char *request,
+                             OCConnectivityType connectivityType,
+                             OCQualityOfService qos,
+                             OCCallbackData *cbData,
+                             OCHeaderOption *options,
+                             uint8_t numOptions)
+ {
+     OC_LOG(INFO, TAG, PCF("Entering OCDoResource"));
+     // Validate input parameters
+     VERIFY_NON_NULL(cbData, FATAL, OC_STACK_INVALID_CALLBACK);
+     VERIFY_NON_NULL(cbData->cb, FATAL, OC_STACK_INVALID_CALLBACK);
+     VERIFY_NON_NULL(requestUri , FATAL, OC_STACK_INVALID_URI);
  
-     if((result = verifyUriQueryLength(requiredUri, uriLen)) != OC_STACK_OK)
+     OCStackResult result = OC_STACK_ERROR;
+     CAResult_t caResult;
+     CAToken_t token = NULL;
+     uint8_t tokenLength = CA_MAX_TOKEN_LEN;
+     ClientCB *clientCB = NULL;
+     OCDoHandle resHandle = NULL;
+     CAEndpoint_t *endpoint = NULL;
+     OCDevAddr tmpDevAddr = { OC_DEFAULT_ADAPTER };
+     uint32_t ttl = 0;
+     OCTransportAdapter adapter;
+     OCTransportFlags flags;
+     // the request contents are put here
+     CARequestInfo_t requestInfo = { CA_GET };
+     // requestUri  will be parsed into the following three variables
+     OCDevAddr *devAddr = NULL;
+     char *resourceUri = NULL;
+     char *resourceType = NULL;
+     // To track if memory is allocated for additional header options
+     uint8_t hdrOptionMemAlloc = 0;
+     // This validation is broken, but doesn't cause harm
+     size_t uriLen = strlen(requestUri );
+     if ((result = verifyUriQueryLength(requestUri , uriLen)) != OC_STACK_OK)
      {
          goto exit;
      }
@@@ -35,11 -35,11 +35,11 @@@ target_os = env.get('TARGET_OS'
  
        # Build protocol plugin project
        # protocol-plugin use 'inotify', this feature isn't support by MAC OSX
 -      if target_os not in ['darwin', 'ios']:
 -              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')
 -
 +      #SConscript('notification-manager/SConscript')
 +      
 +if target_os in ['arduino','android', 'linux']:
-       SConscript('easy-setup/SConscript')
++      SConscript('easy-setup/SConscript')
index ef4285c,0000000..36096c2
mode 100755,000000..100755
--- /dev/null
@@@ -1,110 -1,0 +1,110 @@@
-               env.get('SRC_DIR') + '/resource/csdk/ocmalloc/include',         
 +#******************************************************************
 +#
 +# 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')
 +
 +env.AppendUnique(CPPDEFINES = ['EASY_SETUP_CA_INIT'])
 +
 +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
 +######################################################################
 +easy_setup_env.AppendUnique(CPPPATH = ['sdk/inc', 'sdk/src', 'sdk/common'])
 +
 +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 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'])      
 +              if not env.get('RELEASE'):
 +                      easy_setup_env.AppendUnique(LIBS = ['log'])
 +      else:
 +              easy_setup_env.PrependUnique(LIBS = ['oc', 'octbstack', 'oc_logger', 'pthread', 'connectivity_abstraction'])
 +
 +if target_os == 'arduino':
 +      easy_setup_env.AppendUnique(CPPPATH = [
 +                                     '../../resource/oc_logger/include',
 +                                     '../../resource/csdk/logger/include',
 +                                     '../../resource/csdk/stack/include',
 +                                     '../../extlibs/cjson',
 +                                     'sdk/enrollee/arduino/wifi',
 +                                     'sdk/enrollee/common/src',
 +                                     'sdk/enrollee/common/inc'])
 +
 +if target_os in ['android','linux']:                                     
 +      easy_setup_env.PrependUnique(CPPPATH = [
++              env.get('SRC_DIR') + '/resource/c_common/oic_malloc/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',
 +              'sdk/common',
 +              'sdk/mediator/inc'])
 +
 +######################################################################
 +# Source files and Targets
 +######################################################################
 +
 +if target_os == 'arduino':
 +      es_sdk_static = easy_setup_env.StaticLibrary('ESSDKLibrary',
 +                                      ['sdk/enrollee/common/src/easysetup.cpp',
 +                                      'sdk/enrollee/common/src/resourceHandler.cpp',
 +                                      'sdk/enrollee/arduino/wifi/networkHandler.cpp'])
 +      easy_setup_env.InstallTarget(es_sdk_static, 'libESSDK')
 +
 +
 +if target_os == 'android':
 +      es_sdk_shared = easy_setup_env.StaticLibrary('libESSDK',
 +                                      ['sdk/mediator/src/easysetupmgr.cpp',
 +                                      'sdk/mediator/src/camutex_pthreads.c',
 +                                      'sdk/mediator/src/provisioninghandler.cpp'])
 +      easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
 +
 +if target_os == 'linux':
 +      es_sdk_shared = easy_setup_env.SharedLibrary('ESSDKLibrary',
 +                                      ['sdk/mediator/src/easysetupmgr.cpp',
 +                                      'sdk/mediator/src/camutex_pthreads.c',
 +                                      'sdk/mediator/src/provisioninghandler.cpp'])
 +      easy_setup_env.InstallTarget(es_sdk_shared, 'libESSDK')
 +
 +#Go to build sample apps
 +SConscript('sampleapp/SConscript')
 +
 +
index 3f65b64,0000000..54735b9
mode 100644,000000..100644
--- /dev/null
@@@ -1,117 -1,0 +1,113 @@@
- void ProvisioningStatusCallback(ProvisioningInfo provInfo) {
-     OIC_LOG_V(INFO, TAG, "Enrollee connectivity: %d", provInfo.provDeviceInfo.connType);
-     if(provInfo.provStatus == DEVICE_PROVISIONED)
 +//******************************************************************
 +//
 +// 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
 + */
-         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]);
++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, "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]);
++        OIC_LOG_V(INFO, TAG, "Successfully provisioned the Enrollee with IP : %s ",
++            provInfo->provDeviceInfo.addr->addr);
 +    }
 +    else{
-     netInfo.connType = OC_IPV4;
++        OIC_LOG_V(INFO, TAG, "Provisioing Failed for the Enrollee with IP : %s",
++            provInfo->provDeviceInfo.addr->addr);
 +    }
 +}
 +
 +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 = CT_ADAPTER_IP;
 +    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);
 +    }
++
++    TerminateEasySetupManager();
 +    OIC_LOG(INFO, TAG, "Exiting occlient main loop...");
 +
 +    return 0;
 +}
 +
index 453499c,0000000..ffe04a0
mode 100755,000000..100755
--- /dev/null
@@@ -1,136 -1,0 +1,147 @@@
- static OCConnectivityType OC_CONNTYPE = OC_IPV4;
 +//******************************************************************
 +//
 +// 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_
 +
 +#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 const char * OIC_PROVISIONING_URI = "/oic/prov";
++static OCConnectivityType OC_CONNTYPE = CT_ADAPTER_IP;
 +
 +static const char * UNICAST_PROVISIONING_QUERY = "coap://%s:%d/oic/res?rt=oic.prov";
- typedef void (*OCProvisioningStatusCB)(ProvisioningInfo provInfo);
++static const char * UNICAST_PROV_STATUS_QUERY = "coap://%s:%d%s";
++
++
++/**
++ * Attributes used to form a proper easysetup conforming JSON message.
++ */
++#define OC_RSRVD_ES_PS                     "ps"
++#define OC_RSRVD_ES_TNN                    "tnn"
++#define OC_RSRVD_ES_CD                     "cd"
++
++
++
 +
 +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;
 +
 +
 +/**
 + * 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
index c1cf70e,0000000..a77611d
mode 100644,000000..100644
--- /dev/null
@@@ -1,17 -1,0 +1,17 @@@
-     package="org.iotivity.service.easysetup"\r
 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
++    package="org.iotivity.service.easysetup.mediator"\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
index 8ea6049,0000000..bab8c05
mode 100644,000000..100644
--- /dev/null
@@@ -1,171 -1,0 +1,171 @@@
- void JNIProvisioningStatusCallback(ProvisioningInfo provInfo) {\r
 +//******************************************************************\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
-         if (provInfo.provStatus == DEVICE_PROVISIONED) {\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
-     netInfo.connType = OCConnectivityType::OC_IPV4;\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
-         connecitivityType = OCConnectivityType::OC_IPV4;\r
++    netInfo.connType = OCConnectivityType::CT_ADAPTER_IP;\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::CT_ADAPTER_IP;\r
 +    }\r
 +\r
 +    StopEnrolleeProvisioning(connecitivityType);\r
 +\r
 +    return;\r
 +}\r
 +\r
 +\r
index 8bad6c5,0000000..6be7bc2
mode 100644,000000..100644
--- /dev/null
@@@ -1,86 -1,0 +1,85 @@@
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query);
 +//******************************************************************
 +//
 +// 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 "common.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 FindProvisioningResource(OCQualityOfService qos,
-         const char* requestURI);
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri);
 +
 +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);
 +
- void PrepareProvisioingStatusCB(ProvisioningInfo *provInfo,
-         OCClientResponse * clientResponse, ProvStatus provStatus);
++void FindProvisioningResource(void *data);
 +
 +//Invoke Provisioning Status Callback
++ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
++            ProvStatus provStatus);
 +
 +#endif
 +
index 4db91e0,0000000..58549bc
mode 100644,000000..100644
--- /dev/null
@@@ -1,320 -1,0 +1,320 @@@
- #include <ocmalloc.h>
 +//******************************************************************
 +//
 +// 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 <oic_malloc.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;
 +}
 +
index c2731eb,0000000..5d5f31a
mode 100644,000000..100644
--- /dev/null
@@@ -1,694 -1,0 +1,727 @@@
-     ProvisioningInfo provInfo;
 +//******************************************************************
 +//
 +// 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) {
-         PrepareProvisioingStatusCB(&provInfo, 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");
-     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);
++        provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                DEVICE_NOT_PROVISIONED);
 +        cbData(provInfo);
 +        return OC_STACK_DELETE_TRANSACTION;
 +    }
 +
-         cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
++    OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s ",
++            clientResponse->resJSONPayload);
 +
 +    if (clientResponse->resJSONPayload) {
 +        cJSON *observeJson = cJSON_CreateObject();
 +        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
 +
-         cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
++        cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
 +        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
 +
-                 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %d", i,
++        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
 +        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);
 +
++            if (!strcmp(arrayJSON->string, OC_RSRVD_ES_PS))
++            {
++                if(arrayJSON->valueint == 1)
++                {
++                    OIC_LOG_V(DEBUG, TAG, "PS is proper");
++                    continue;
++                }
++                else{
++                    OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
++                    provInfo = PrepareProvisioingStatusCB(clientResponse,
++                            DEVICE_NOT_PROVISIONED);
++                    cbData(provInfo);
++                }
++            }
++
++            if (!strcmp(arrayJSON->string, OC_RSRVD_ES_TNN))
++            {
++                if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.ssid))
++                {
++                    OIC_LOG_V(DEBUG, TAG, "SSID is proper");
++                    continue;
++                }
++                else{
++                    OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
++                    provInfo = PrepareProvisioingStatusCB(clientResponse,
++                            DEVICE_NOT_PROVISIONED);
++                    cbData(provInfo);
++                }
++            }
++
++            if (!strcmp(arrayJSON->string, OC_RSRVD_ES_CD))
++            {
++                if(!strcmp(arrayJSON->valuestring, netProvInfo->netAddressInfo.WIFI.pwd))
++                {
++                    OIC_LOG_V(DEBUG, TAG, "Password is proper");
++                    continue;
++                }
++                else{
++                    OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
++                    provInfo = PrepareProvisioingStatusCB(clientResponse,
++                            DEVICE_NOT_PROVISIONED);
++                    cbData(provInfo);
++                }
++            }
++
 +            switch (arrayJSON->type) {
 +            case cJSON_False:
 +            case cJSON_True:
-                 OIC_LOG_V(DEBUG, TAG, "rep#%d's value : %f", i,
++                OIC_LOG_V(DEBUG, TAG, "rep#%d's int value : %d", i,
 +                        arrayJSON->valueint);
 +                break;
 +            case cJSON_Number:
-         PrepareProvisioingStatusCB(&provInfo, clientResponse,
++                OIC_LOG_V(DEBUG, TAG, "rep#%d's double 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,
++        provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                DEVICE_PROVISIONED);
 +        cbData(provInfo);
 +
 +        return OC_STACK_KEEP_TRANSACTION;
 +    } else {
 +        OIC_LOG(INFO, TAG,
 +                "ProvisionEnrolleeResponse received NULL clientResponse. \
 +                                Invoking Provisioing Status Callback");
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query) {
++        provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                DEVICE_NOT_PROVISIONED);
 +        cbData(provInfo);
 +        return OC_STACK_DELETE_TRANSACTION;
 +    }
 +}
 +
-     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());
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {
 +    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;
 +
-     ProvisioningInfo provInfo;
++    cJSON_AddStringToObject(json, OC_RSRVD_HREF, resUri);
++    cJSON_AddItemToObject(json, OC_RSRVD_REPRESENTATION, format = cJSON_CreateObject());
++    cJSON_AddStringToObject(format, OC_RSRVD_ES_TNN, netProvInfo->netAddressInfo.WIFI.ssid);
++    cJSON_AddStringToObject(format, OC_RSRVD_ES_CD, netProvInfo->netAddressInfo.WIFI.pwd);
++    cJSON_AddItemToObject(jsonFinal, OC_RSRVD_OC, 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) {
-         PrepareProvisioingStatusCB(&provInfo, clientResponse,
++    ProvisioningInfo *provInfo;
 +
 +    if (clientResponse == NULL) {
 +        OIC_LOG(INFO, TAG,
 +                "getReqCB received NULL clientResponse. \
 +            Invoking Provisioing Status Callback");
-     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);
++        provInfo = PrepareProvisioingStatusCB(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);
 +            }
 +        }
 +    }
 +
-         cJSON *ocArray = cJSON_GetObjectItem(observeJson, "oic");
++    char query[OIC_STRING_MAX_VALUE] = { '\0' };
++
 +
 +    if (clientResponse->resJSONPayload) {
 +        cJSON *observeJson = cJSON_CreateObject();
 +        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
 +
-         cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, "rep");
++        cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
 +        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
 +
-         if (ProvisionEnrollee(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
++        cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
++
++        OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
++            resUriObj->string, resUriObj->valuestring);
++
++        char resURI[MAX_URI_LENGTH]={'\0'};
++
++        strncpy(resURI, resUriObj->valuestring, sizeof(resURI));
++
++        snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
++                clientResponse->addr->addr,
++                IP_PORT, resURI);
++
++        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
 +        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,
++        if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {
 +            OIC_LOG(INFO, TAG,
 +                    "GetProvisioningStatusResponse received NULL clientResponse. \
 +                Invoking Provisioing Status Callback");
-         PrepareProvisioingStatusCB(&provInfo, clientResponse,
++            provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                    DEVICE_NOT_PROVISIONED);
 +            cbData(provInfo);
 +
 +            return OC_STACK_DELETE_TRANSACTION;
 +        }
 +    } else {
 +        OIC_LOG(INFO, TAG,
 +                "GetProvisioningStatusResponse received NULL clientResponse. \
 +            Invoking Provisioing Status Callback");
-     ProvisioningInfo provInfo;
++        provInfo = PrepareProvisioingStatusCB(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;
-     /* 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 = { };
 +
 +    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);
 +
-         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;
++    if (CA_STATUS_OK
++            != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
++                    (void *) "")) {
++        OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource 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;
 +    }
-     ProvisioningInfo provInfo;
++    return OC_STACK_OK;
 +}
 +
 +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;
 +
-         PrepareProvisioingStatusCB(&provInfo, clientResponse,
++    ProvisioningInfo *provInfo;
 +
 +    if (clientResponse->result != OC_STACK_OK) {
 +        OIC_LOG(ERROR, TAG,
 +                "OCStack stop error. Calling Provisioing Status Callback");
 +
-         // 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;
-         }
++        provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                DEVICE_NOT_PROVISIONED);
 +
 +        cbData(provInfo);
 +        return response;
 +    }
 +
 +    if (clientResponse) {
-         cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
 +        cJSON *discoveryJson = cJSON_CreateObject();
 +        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
 +
-             PrepareProvisioingStatusCB(&provInfo, clientResponse,
++        cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
 +        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);
 +
-         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);
++            provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                    DEVICE_NOT_PROVISIONED);
 +            cbData(provInfo);
 +            return response;
 +        }
 +
-         OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
-                 clientResponse->resJSONPayload, sourceaddr);
++        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
++        cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
 +
-         if (GetProvisioningStatus(OC_HIGH_QOS, sourceaddr) != OC_STACK_OK) {
++        OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
++            resUriObj->string, resUriObj->valuestring);
 +
-             PrepareProvisioingStatusCB(&provInfo, clientResponse,
++
++        char szQueryUri[64] = { 0 };
++
++        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
++                clientResponse->devAddr.addr, IP_PORT, resUriObj->valuestring);
++        OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
++
++        if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri) != OC_STACK_OK) {
 +            OIC_LOG(INFO, TAG,
 +                    "GetProvisioningStatus returned error. \
 +                                Invoking Provisioing Status Callback");
-             cbData(provInfo);
++            provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                    DEVICE_NOT_PROVISIONED);
-         PrepareProvisioingStatusCB(&provInfo, clientResponse,
 +
++            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");
- OCStackResult FindProvisioningResource(OCQualityOfService qos,
-         const char* requestURI) {
++        provInfo = PrepareProvisioingStatusCB(clientResponse,
 +                DEVICE_NOT_PROVISIONED);
 +        cbData(provInfo);
 +        return response;
 +    }
 +    return OC_STACK_KEEP_TRANSACTION;
 +}
 +
-     OCCallbackData cbData;
++void FindProvisioningResource(void *data)
++{
 +    OCStackResult ret = OC_STACK_ERROR;
 +
-     cbData.cb = FindProvisioningResourceResponse;
-     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
-     cbData.cd = NULL;
++    /* Start a discovery query*/
++    char szQueryUri[64] = { 0 };
 +
-     ret = OCDoResource(NULL, OC_REST_GET, requestURI, 0, 0, OC_CONNTYPE,
-             OC_LOW_QOS, &cbData, NULL, 0);
++    snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
++            netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
 +
-     }
++    OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);
++
++    OCCallbackData ocCBData;
++
++    ocCBData.cb = FindProvisioningResourceResponse;
++    ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
++    ocCBData.cd = NULL;
++
++    ret = OCDoResource(NULL, OC_REST_GET, szQueryUri, 0, 0, OC_CONNTYPE,
++            OC_LOW_QOS, &ocCBData, NULL, 0);
 +
 +    if (ret != OC_STACK_OK) {
 +        OIC_LOG(ERROR, TAG, "OCStack resource error");
-     return ret;
 +
-         // 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;
-         }
++        OIC_LOG(ERROR, TAG,
++                "FindProvisioningResource failed. \
++            Invoking Provisioing Status Callback");
++
++        ProvisioningInfo *provInfo;
++        provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
++
++        if(provInfo == NULL)
++        {
++            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++            return;
++        }
++
++        OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
++
++        if(devAddr == NULL)
++        {
++            OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++            return;
++        }
++
++        strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));
++        devAddr->port= IP_PORT;
++        provInfo->provDeviceInfo.addr = devAddr;
++        provInfo->provStatus = DEVICE_NOT_PROVISIONED;
++
++
++        cbData(provInfo);
++    }
 +}
 +
 +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"));
-         cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, "oic");
 +
 +        cJSON *discoveryJson = cJSON_CreateObject();
 +        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
 +
-         snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%d.%d.%d.%d",
-                 clientResponse->addr->addr[0], clientResponse->addr->addr[1],
-                 clientResponse->addr->addr[2], clientResponse->addr->addr[3]);
++        cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
 +        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' };
-         OCQualityOfService qos = OC_NA_QOS;
++        snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
 +
 +        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
 +                clientResponse->resJSONPayload, sourceIPAddr);
 +
 +        /* Start a discovery query*/
 +        char szQueryUri[64] = { 0 };
-         if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
 +
 +        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;
- void PrepareProvisioingStatusCB(ProvisioningInfo *provInfo,
-         OCClientResponse * clientResponse, ProvStatus provStatus) {
-     ProvDeviceInfo provDeviceIndo;
-     OCDevAddr dst = { };
++        }*/
 +    } 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;
 +}
 +
-     uint16_t remotePortNum;
-     OCDevAddrToPort((OCDevAddr *) clientResponse->addr, &remotePortNum);
++ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
 +
-     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);
++    ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
 +
-     provInfo->provStatus = provStatus;
++    if(provInfo == NULL)
++    {
++        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++        return NULL;
++    }
 +
-     provDeviceIndo.addr = &dst;
-     provDeviceIndo.connType = OC_IPV4;
++    OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
 +
-     provInfo->provDeviceInfo = provDeviceIndo;
++    if(devAddr == NULL)
++    {
++        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++        return NULL;
++    }
++
++    strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));
++    devAddr->port= clientResponse->addr->port;
++
++    provInfo->provDeviceInfo.addr = devAddr;
++
++    provInfo->provStatus = provStatus;
 +
++    return provInfo;
 +}
 +