Merge remote-tracking branch 'origin/master' into easysetup, Provisioning Handler...
authorsandipan.p <sandipan.p@samsung.com>
Tue, 8 Sep 2015 10:14:32 +0000 (15:44 +0530)
committersandipan.p <sandipan.p@samsung.com>
Tue, 8 Sep 2015 10:16:17 +0000 (15:46 +0530)
-Vinil Jain

Change-Id: Ia5e04b1efba94f7c178b7034147ca0722b29bd4f
Signed-off-by: sandipan.p <sandipan.p@samsung.com>
1  2 
resource/csdk/stack/src/ocstack.c
service/easy-setup/sdk/enrollee/common/src/resourceHandler.cpp
service/easy-setup/sdk/mediator/android/jni/Android.mk
service/easy-setup/sdk/mediator/inc/provisioninghandler.h
service/easy-setup/sdk/mediator/src/provisioninghandler.cpp

Simple merge
index 768ecc2,0000000..3660137
mode 100644,000000..100644
--- /dev/null
@@@ -1,343 -1,0 +1,343 @@@
-     const char* tnn;
 +//******************************************************************
 +//
 +// 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 "ocpayload.h"
 +
 +PROGMEM const char TAG[] = "resourceHandler";
 +
 +ProvResource g_prov;
 +NetResource g_net;
 +
 +OCEntityHandlerResult OCEntityHandlerCb(OCEntityHandlerFlag, OCEntityHandlerRequest *, void *callback);
 +const char *getResult(OCStackResult result);
 +
 +OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
 +OCEntityHandlerResult ProcessPutRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
 +OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest,OCRepPayload** payload);
 +OCRepPayload* constructResponse(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,
 +            OC_RSRVD_ES_URI_PROV, OCEntityHandlerCb,NULL, 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,
 +            OC_RSRVD_ES_URI_NET, OCEntityHandlerCb,NULL, OC_DISCOVERABLE | OC_OBSERVABLE);
 +    OC_LOG_V(INFO, TAG, "Created Net resource with result: %s", getResult(res));
 +
 +    return res;
 +}
 +
 +OCEntityHandlerResult ProcessGetRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload **payload)
 +{
 +    OCEntityHandlerResult ehResult = OC_EH_ERROR;
 +    if(!ehRequest)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Request is Null"));
 +        return ehResult;
 +    }
 +    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
 +        return ehResult;
 +    }
 +
 +    OCRepPayload *getResp = constructResponse(ehRequest);
 +    if(!getResp)
 +    {
 +        OC_LOG(ERROR, TAG, "constructResponse failed");
 +        return OC_EH_ERROR;
 +    }
 +
 +    *payload = getResp;
 +    ehResult = OC_EH_OK;
 +
 +    return ehResult;
 +}
 +
 +OCEntityHandlerResult ProcessPutRequest (OCEntityHandlerRequest *ehRequest,
 +        OCRepPayload** payload)
 +{
 +
 +    OCEntityHandlerResult ehResult=OC_EH_ERROR;
 +    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
 +        return ehResult;
 +    }
 +
 +    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
 +    if(!input)
 +    {
 +        OC_LOG_V(ERROR, TAG, "Failed to parse");
 +        return ehResult;
 +    }
 +
-     const char* cd;
++    char* tnn;
 +    if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN, &tnn))
 +    {
 +        sprintf(g_prov.tnn, "%s", tnn);
 +    }
 +
-     const char* tr;
++    char* cd;
 +    if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
 +    {
 +        sprintf(g_prov.cd, "%s", cd);
 +    }
 +
 +    g_flag = 1;
 +
 +    OCRepPayload *getResp = constructResponse(ehRequest);
 +    if(!getResp)
 +    {
 +        OC_LOG(ERROR, TAG, "constructResponse failed");
 +        return OC_EH_ERROR;
 +    }
 +
 +    *payload = getResp;
 +    ehResult = OC_EH_OK;
 +
 +
 +
 +    return ehResult;
 +}
 +
 +
 +OCEntityHandlerResult ProcessPostRequest(OCEntityHandlerRequest *ehRequest, OCRepPayload** payload)
 +{
 +    OCEntityHandlerResult ehResult = OC_EH_ERROR;
 +    if(!ehRequest)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Request is Null"));
 +        return ehResult;
 +    }
 +    if(ehRequest->payload && ehRequest->payload->type != PAYLOAD_TYPE_REPRESENTATION)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Incoming payload not a representation"));
 +        return ehResult;
 +    }
 +
 +    OCRepPayload* input = (OCRepPayload*)(ehRequest->payload);
 +    if(!input)
 +    {
 +        OC_LOG_V(ERROR, TAG, "Failed to parse" );
 +        return ehResult;
 +    }
++    char* tr;
 +    if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_TR, &tr))
 +    {
 +
 +        // Triggering
 +        ehResult = OC_EH_OK;
 +    }
 +
 +    g_flag = 1;
 +
 +    return ehResult;
 +}
 +
 +OCRepPayload* constructResponse(OCEntityHandlerRequest *ehRequest)
 +{
 +    OCRepPayload* payload = OCRepPayloadCreate();
 +    if(!payload)
 +    {
 +        OC_LOG(ERROR, TAG, PCF("Failed to allocate Payload"));
 +        return NULL;
 +    }
 +
 +    if (ehRequest->resource == g_prov.handle)
 +    {
 +        OCRepPayloadSetUri(payload,OC_RSRVD_ES_URI_PROV);
 +        OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_PS,g_prov.ps);
 +        OCRepPayloadSetPropInt(payload, OC_RSRVD_ES_TNT, g_prov.tnt);
 +        OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN, g_prov.tnn);
 +        OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD, g_prov.cd);
 +    }
 +    else if (ehRequest->requestHandle == g_net.handle)
 +    {
 +
 +        OCRepPayloadSetUri(payload, OC_RSRVD_ES_URI_NET);
 +        OCRepPayloadSetPropInt(payload, "ant", g_net.ant[0]);
 +    }
 +    return payload;
 +}
 +
 +// 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,void *callback)
 +{
 +    (void)callback;
 +    OCEntityHandlerResult ehRet = OC_EH_OK;
 +    OCEntityHandlerResponse response =
 +    { 0 };
 +    OCRepPayload* payload = NULL;
 +    if (entityHandlerRequest && (flag & OC_REQUEST_FLAG))
 +    {
 +        if (OC_REST_GET == entityHandlerRequest->method)
 +        {
 +            OC_LOG_V(INFO, TAG, "Received GET request");
 +            ehRet = ProcessGetRequest(entityHandlerRequest, &payload);
 +        }
 +        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);
 +            }
 +            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 = (OCPayload*)(payload);  //response uses OCPaylod while all get,put methodes use OCRepPayload
 +            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";
 +    }
 +}
 +
index d85ab3f,0000000..0e87f2a
mode 100644,000000..100644
--- /dev/null
@@@ -1,84 -1,0 +1,85 @@@
 +LOCAL_PATH := $(call my-dir)
 +
 +ifeq ($(strip $(ANDROID_NDK)),)
 +$(error ANDROID_NDK is not set!)
 +endif
 +
 +$(warning "Current path" $(LOCAL_PATH))
 +$(info TC_PREFIX=$(TOOLCHAIN_PREFIX))
 +$(info CFLAGS=$(TARGET_CFLAGS))
 +$(info CXXFLAGS=$(TARGET_CXXFLAGS) $(TARGET_NO_EXECUTE_CFLAGS))
 +$(info CPPFLAGS=$(TARGET_CPPFLAGS))
 +$(info CPPPATH=$(TARGET_C_INCLUDES) $(__ndk_modules.$(APP_STL).EXPORT_C_INCLUDES))
 +$(info SYSROOT=$(SYSROOT_LINK))
 +$(info LDFLAGS=$(TARGET_LDFLAGS) $(TARGET_NO_EXECUTE_LDFLAGS) $(TARGET_NO_UNDEFINED_LDFLAGS) $(TARGET_RELRO_LDFLAGS))
 +$(info TC_VER=$(TOOLCHAIN_VERSION))
 +$(info PLATFORM=$(APP_PLATFORM))
 +
 +include $(CLEAR_VARS)
 +OIC_LIB_PATH := ../../../../../../out/android/$(TARGET_ARCH_ABI)/debug
 +LOCAL_MODULE := android-octbstack
 +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/liboctbstack.so
 +include $(PREBUILT_SHARED_LIBRARY)
 +
 +include $(CLEAR_VARS)
 +OIC_LIB_PATH := ../../../../../../out/android/$(TARGET_ARCH_ABI)/debug
 +LOCAL_MODULE := android-connectivity_abstraction
 +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libconnectivity_abstraction.so
 +include $(PREBUILT_SHARED_LIBRARY)
 +
 +include $(CLEAR_VARS)
 +OIC_LIB_PATH := ../../../../../../out/android/$(TARGET_ARCH_ABI)/debug
 +LOCAL_MODULE := android-easysetup
 +LOCAL_SRC_FILES := $(OIC_LIB_PATH)/libESSDK.a
 +include $(PREBUILT_STATIC_LIBRARY)
 +
 +include $(CLEAR_VARS)
 +
 +LOCAL_MODULE    := easysetup-jni
 +
 +#Add Pre processor definitions
 +DEFINE_FLAG =  -DWITH_POSIX -D__ANDROID__
 +
 +#Add Debug flags here
 +DEBUG_FLAG      = -DTB_LOG
 +
 +BUILD_FLAG = $(DEFINE_FLAG) $(DEBUG_FLAG)
 +
 +LOCAL_CPPFLAGS = $(BUILD_FLAG)
 +LOCAL_CPPFLAGS += -std=c++0x -frtti -fexceptions
 +
 +$(info CPPFLAGSUPDATED=$(LOCAL_CPPFLAGS))
 +
 +NDK_ROOT         := /home/madan/android-ndk-r10d
 +
 +LOCAL_C_INCLUDES := $(LOCAL_PATH) \
 +                                      $(LOCAL_PATH)/jniutil/inc \
 +                                      $(LOCAL_PATH)/../../../../../../service/easy-setup/sdk/mediator/inc \
 +                                      $(LOCAL_PATH)/../../../../../../service/easy-setup/sdk/common \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/logger/include \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/connectivity/common/inc \
 +                                      $(LOCAL_PATH)/../../../../../../resource/include \
++                                      $(LOCAL_PATH)/../../../../../../resource/c_common \
 +                                      $(LOCAL_PATH)/../../../../../../resource/oc_logger/include \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/ocmalloc/include \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/connectivity/api \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/stack/include \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/logger/include \
 +                                      $(LOCAL_PATH)/../../../../../../resource/csdk/security/include \
 +                                      $(LOCAL_PATH)/../../../../../../extlibs/cjson \
 +                                      $(LOCAL_PATH)/../../../../../../extlibs/boost/boost_1_58_0 \
 +                    $(LOCAL_PATH)/../../../../../../extlibs/timer \
 +                                      $(LOCAL_PATH)/../../../../../../android/android_api/base/jni \
 +                                      $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/include \
 +                    $(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI)/include \
 +                                      
 +LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/jni_easy_setup.cpp))
 +LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/jniutil/src/*.cpp))
 +
 +LOCAL_LDLIBS := -llog 
 +LOCAL_LDLIBS += -L$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/$(TOOLCHAIN_VERSION)/libs/$(TARGET_ARCH_ABI)
 +LOCAL_SHARED_LIBRARIES := android-easysetup
 +LOCAL_SHARED_LIBRARIES += android-connectivity_abstraction
 +LOCAL_SHARED_LIBRARIES += android-octbstack
 +
 +include $(BUILD_SHARED_LIBRARY)
index b9d801c,0000000..62a462c
mode 100644,000000..100644
--- /dev/null
@@@ -1,91 -1,0 +1,120 @@@
 +//******************************************************************
 +//
 +// 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_
 +
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,
-                                     OCDevAddr *destination);
 +#include "octypes.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);
 +
- OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
-         OCDoHandle handle, OCClientResponse * clientResponse);
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,OCDevAddr *destination);
 +
-         OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload * request,
++OCStackApplicationResult GetProvisioningStatusResponse(void* ctx, OCDoHandle handle,
++        OCClientResponse * clientResponse);
 +
 +OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,
-                                          const OCDevAddr *destination);
++        OCQualityOfService qos, OCClientResponseHandler cb, OCRepPayload* payload,
 +        OCHeaderOption * options, uint8_t numOptions);
 +
 +OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query,
++        const OCDevAddr*destination);
 +
 +OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
 +        OCProvisioningStatusCB provisioningStatusCallback);
 +
- OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,
-         OCDoHandle handle, OCClientResponse * clientResponse);
 +void StopProvisioningProcess();
 +
 +OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
 +        OCClientResponse* clientResponse);
 +
 +OCStackResult SubscribeProvPresence(OCQualityOfService qos, const char* requestURI);
 +
-             ProvStatus provStatus);
++OCStackApplicationResult FindProvisioningResourceResponse(void* ctx, OCDoHandle handle,
++        OCClientResponse * clientResponse);
 +
 +void FindProvisioningResource(void *data);
 +
 +//Invoke Provisioning Status Callback
 +ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
++        ProvStatus provStatus);
++
++
++void LogProvisioningResponse(OCRepPayloadValue* val);
++
++bool ConfigEnrolleeObject(const EnrolleeNWProvInfo_t *netInfo);
++
++bool ClearMemory();
++
++void SuccessCallback(OCClientResponse * clientResponse);
++
++void ErrorCallback(ProvStatus status);
++
++bool ValidateEnrolleResponse(OCClientResponse * clientResponse);
++
++bool ValidateFinddResourceResponse(OCClientResponse * clientResponse);
++
++ProvisioningInfo* GetCallbackObjectOnSuccess(OCClientResponse * clientResponse,
++        ProvStatus provStatus);
++
++ProvisioningInfo* GetCallbackObjectOnError(ProvStatus status);
++
++ProvisioningInfo* CreateCallBackObject();
++
++bool ResetProgress();
++
++bool SetProgress(OCProvisioningStatusCB provisioningStatusCallback);
++
++bool InProgress();
++
++bool ValidateEasySetupParams(const EnrolleeNWProvInfo_t *netInfo,
++        OCProvisioningStatusCB provisioningStatusCallback);
++
 +
 +#endif
 +
index f0a7780,0000000..1e3b235
mode 100644,000000..100644
--- /dev/null
@@@ -1,719 -1,0 +1,829 @@@
- //******************************************************************\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 <stdio.h>\r
- #include <stdlib.h>\r
- #include <string.h>\r
- #include <signal.h>\r
- #include <unistd.h>\r
- #include "ocpayload.h"\r
- #include "provisioninghandler.h"\r
\r
- // External includes\r
\r
- #include "camutex.h"\r
- #include "cathreadpool.h"\r
- #include "logger.h"\r
- #include "oic_malloc.h"\r
\r
\r
- /**\r
-  * @var g_provisioningMutex\r
-  * @brief Mutex to synchronize access to g_caDtlsContext.\r
-  */\r
- static ca_mutex g_provisioningMutex = NULL;\r
- static ca_cond g_provisioningCond = NULL;\r
- bool g_provisioningCondFlag = false;\r
\r
- static EnrolleeNWProvInfo_t* netProvInfo;\r
\r
- /**\r
-  * @var cbData\r
-  * @brief Callback for providing provisioning status callback to application\r
-  */\r
- static OCProvisioningStatusCB cbData = NULL;\r
- static ca_thread_pool_t g_threadPoolHandle = NULL;\r
\r
- OCStackResult InitProvisioningHandler() {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
-     /* Initialize OCStack*/\r
-     if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack init error");\r
-         return ret;\r
-     }\r
\r
-     g_provisioningMutex = ca_mutex_new();\r
\r
-     OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");\r
\r
-     if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {\r
-         OIC_LOG(DEBUG, TAG, "thread_pool_init failed");\r
-         return OC_STACK_ERROR;\r
-     }\r
\r
-     g_provisioningCond = ca_cond_new();\r
-     if (NULL == g_provisioningCond) {\r
-         OIC_LOG(DEBUG, TAG, "Failed to create condition");\r
-         ca_mutex_free(g_provisioningMutex);\r
-         ca_thread_pool_free(g_threadPoolHandle);\r
-         return OC_STACK_ERROR;\r
-     }\r
\r
-     char *string = "listeningFunc invoked in a thread";\r
-     if (CA_STATUS_OK\r
-             != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,\r
-                     (void *) string)) {\r
-         OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");\r
-         ca_thread_pool_free(g_threadPoolHandle);\r
-         ca_mutex_unlock(g_provisioningMutex);\r
-         ca_mutex_free(g_provisioningMutex);\r
-         ca_cond_free(g_provisioningCond);\r
-         return OC_STACK_ERROR;\r
-     }\r
-     return OC_STACK_OK;\r
- }\r
\r
- OCStackResult TerminateProvisioningHandler() {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
-     if (OCStop() != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack stop error");\r
-     }\r
\r
-     ca_mutex_lock(g_provisioningMutex);\r
-     g_provisioningCondFlag = true;\r
-     //ca_cond_signal(g_provisioningCond);\r
-     ca_mutex_unlock(g_provisioningMutex);\r
\r
-     ca_mutex_free(g_provisioningMutex);\r
-     g_provisioningMutex = NULL;\r
\r
-     ca_thread_pool_free(g_threadPoolHandle);\r
-     g_threadPoolHandle = NULL;\r
\r
-     ret = OC_STACK_OK;\r
-     return ret;\r
- }\r
\r
- void listeningFunc(void *data) {\r
-     while (!g_provisioningCondFlag) {\r
-         OCStackResult result;\r
\r
-         ca_mutex_lock(g_provisioningMutex);\r
-         result = OCProcess();\r
-         ca_mutex_unlock(g_provisioningMutex);\r
\r
-         if (result != OC_STACK_OK) {\r
-             OIC_LOG(ERROR, TAG, "OCStack stop error");\r
-         }\r
\r
-         // To minimize CPU utilization we may wish to do this with sleep\r
-         sleep(1);\r
-     }\r
- }\r
\r
- OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,\r
-         OCClientResponse * clientResponse) {\r
-     ProvisioningInfo *provInfo;\r
\r
-     if (clientResponse) {\r
-         OIC_LOG_V(INFO, TAG, "Put Response");\r
-     } else {\r
-         OIC_LOG_V(INFO, TAG,\r
-                 "ProvisionEnrolleeResponse received Null clientResponse");\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
-         cbData(provInfo);\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
\r
-     if (clientResponse->payload) {\r
\r
-         if(clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
-         {\r
-             OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
-             return OC_STACK_DELETE_TRANSACTION;\r
-         }\r
\r
-         OCRepPayload* input = (OCRepPayload*)(clientResponse->payload);\r
-         if(!input)\r
-         {\r
-             OIC_LOG_V(DEBUG, TAG, "Failed To parse");\r
-             return OC_STACK_DELETE_TRANSACTION;\r
-         }\r
\r
-         while(input){\r
\r
-             int64_t ps;\r
-             if(OCRepPayloadGetPropInt(input,OC_RSRVD_ES_PS,&ps))    {\r
-                 if(ps == 1)\r
-                 {\r
-                     OIC_LOG_V(DEBUG, TAG, "PS is proper");\r
-                     input = input->next;\r
-                     continue;\r
-                 }\r
-                 else{\r
-                     OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");\r
-                     provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                             DEVICE_NOT_PROVISIONED);\r
-                     cbData(provInfo);\r
-                     return OC_STACK_DELETE_TRANSACTION;\r
-                 }\r
-             }\r
\r
-             const char* tnn;\r
-             if(OCRepPayloadGetPropString(input,OC_RSRVD_ES_TNN,&tnn)){\r
-                 if(!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))\r
-                 {\r
-                     OIC_LOG_V(DEBUG, TAG, "SSID is proper");\r
-                     input = input->next;\r
-                     continue;\r
-                 }\r
-                 else{\r
-                     OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");\r
-                     provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                             DEVICE_NOT_PROVISIONED);\r
-                     cbData(provInfo);\r
-                     return OC_STACK_DELETE_TRANSACTION;\r
-                 }\r
-             }\r
-             const char* cd;\r
-             if(OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD,&cd)){\r
-                 if(!strcmp(cd,netProvInfo->netAddressInfo.WIFI.pwd))\r
-                 {\r
-                     OIC_LOG_V(DEBUG, TAG, "Password is proper");\r
-                     input = input->next;\r
-                     continue;\r
-                 }\r
-                 else{\r
-                     OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");\r
-                     provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                             DEVICE_NOT_PROVISIONED);\r
-                     cbData(provInfo);\r
-                     return OC_STACK_DELETE_TRANSACTION;\r
-                 }\r
-             }\r
\r
-             OCRepPayloadValue* val = input->values;\r
\r
-             switch(val->type)\r
-             {\r
-                 case OCREP_PROP_NULL:\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);\r
-                     break;\r
-                 case OCREP_PROP_INT:\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);\r
-                     break;\r
-                 case OCREP_PROP_DOUBLE:\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);\r
-                     break;\r
-                 case OCREP_PROP_BOOL:\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");\r
-                     break;\r
-                 case OCREP_PROP_STRING:\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);\r
-                     break;\r
-                 case OCREP_PROP_OBJECT:\r
-                     // Note: Only prints the URI (if available), to print further, you'll\r
-                     // need to dig into the object better!\r
-                     OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);\r
-                     break;\r
-                 case OCREP_PROP_ARRAY:\r
-                     switch(val->arr.type)\r
-                     {\r
-                         case OCREP_PROP_INT:\r
-                             OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld",\r
-                                     val->name,\r
-                                     val->arr.dimensions[0], val->arr.dimensions[1],\r
-                                     val->arr.dimensions[2]);\r
-                             break;\r
-                         case OCREP_PROP_DOUBLE:\r
-                             OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld",\r
-                                     val->name,\r
-                                     val->arr.dimensions[0], val->arr.dimensions[1],\r
-                                     val->arr.dimensions[2]);\r
-                             break;\r
-                         case OCREP_PROP_BOOL:\r
-                             OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld",\r
-                                     val->name,\r
-                                     val->arr.dimensions[0], val->arr.dimensions[1],\r
-                                     val->arr.dimensions[2]);\r
-                             break;\r
-                         case OCREP_PROP_STRING:\r
-                             OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld",\r
-                                     val->name,\r
-                                     val->arr.dimensions[0], val->arr.dimensions[1],\r
-                                     val->arr.dimensions[2]);\r
-                             break;\r
-                         case OCREP_PROP_OBJECT:\r
-                             OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld",\r
-                                     val->name,\r
-                                     val->arr.dimensions[0], val->arr.dimensions[1],\r
-                                     val->arr.dimensions[2]);\r
-                             break;\r
-                         default:\r
-                             //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",\r
-                             //  val->name);\r
-                             break;\r
-                     }\r
-                     break;\r
-                         default:\r
-                             /*OC_LOG_V(ERROR, TAG\r
-                                 , "\t\t%s <-- Unknown type!", val->name);*/\r
-                             break;\r
-             }\r
-             input=input->next;\r
-         }\r
\r
\r
\r
\r
\r
\r
\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_PROVISIONED);\r
-         cbData(provInfo);\r
\r
-         return OC_STACK_KEEP_TRANSACTION;\r
-     } else {\r
-         OIC_LOG(INFO, TAG,\r
-                 "ProvisionEnrolleeResponse received NULL clientResponse. \\r
-         Invoking Provisioing Status Callback");\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
-         cbData(provInfo);\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
- }\r
\r
\r
\r
- OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,\r
-                                     OCDevAddr *destination) {\r
-     OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);\r
\r
\r
-     OCRepPayload* payload = OCRepPayloadCreate();\r
\r
-     OCRepPayloadSetUri(payload,resUri);\r
-     OCRepPayloadSetPropString(payload,OC_RSRVD_ES_TNN,netProvInfo->netAddressInfo.WIFI.ssid);\r
-     OCRepPayloadSetPropString(payload,OC_RSRVD_ES_CD,netProvInfo->netAddressInfo.WIFI.pwd);\r
\r
-     OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");\r
\r
-     OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, destination, OC_HIGH_QOS,\r
-             ProvisionEnrolleeResponse, payload, NULL, 0);\r
\r
-     return ret;\r
- }\r
\r
\r
- OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,\r
-         OCDoHandle handle, OCClientResponse * clientResponse) {\r
-     ProvisioningInfo *provInfo;\r
\r
-     if (clientResponse == NULL) {\r
-         OIC_LOG(INFO, TAG,\r
-                 "getReqCB received NULL clientResponse. \\r
-         Invoking Provisioing Status Callback");\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
-         cbData(provInfo);\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
\r
-     if (clientResponse->rcvdVendorSpecificHeaderOptions\r
-             && clientResponse->numRcvdVendorSpecificHeaderOptions) {\r
-         OIC_LOG(INFO, TAG, "Received vendor specific options");\r
-         uint8_t i = 0;\r
-         OCHeaderOption * rcvdOptions =\r
-                 clientResponse->rcvdVendorSpecificHeaderOptions;\r
-         for (i = 0; i < clientResponse->numRcvdVendorSpecificHeaderOptions;\r
-                 i++) {\r
-             if (((OCHeaderOption) rcvdOptions[i]).protocolID == OC_COAP_ID) {\r
-                 OIC_LOG_V(INFO, TAG,\r
-                         "Received option with OC_COAP_ID and ID %u with",\r
-                         ((OCHeaderOption) rcvdOptions[i]).optionID);\r
\r
-                 OIC_LOG_BUFFER(INFO, TAG,\r
-                         ((OCHeaderOption) rcvdOptions[i]).optionData,\r
-                         MAX_HEADER_OPTION_DATA_LENGTH);\r
-             }\r
-         }\r
-     }\r
\r
-     char query[OIC_STRING_MAX_VALUE] = { '\0' };\r
\r
-     if(NULL == clientResponse->payload)\r
\r
-     {\r
-         OIC_LOG_V(DEBUG, TAG, "OCClientResponse is NULL");\r
\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
-         cbData(provInfo);\r
\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
\r
-     OCRepPayload* repPayload = (OCRepPayload*)clientResponse->payload;\r
\r
-     OIC_LOG_V(DEBUG, TAG, "repPayload URI = %s",repPayload->uri);\r
\r
-     snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,\r
-             clientResponse->addr->addr,\r
-             IP_PORT, repPayload->uri);\r
\r
-     //OCPayloadLogRep(DEBUG,TAG,input);\r
\r
-     if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV,\r
-                           clientResponse->addr) != OC_STACK_OK) {\r
-         OIC_LOG(INFO, TAG,\r
-                 "GetProvisioningStatusResponse received NULL clientResponse. \\r
-         Invoking Provisioing Status Callback");\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
-         cbData(provInfo);\r
\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
\r
-     return OC_STACK_DELETE_TRANSACTION;\r
- }\r
\r
- OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,\r
-         OCQualityOfService qos, OCClientResponseHandler cb,OCRepPayload* payload,\r
-         OCHeaderOption * options, uint8_t numOptions) {\r
-     OCStackResult ret;\r
-     OCCallbackData cbData;\r
\r
-     cbData.cb = cb;\r
-     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
-     cbData.cd = NULL;\r
\r
-     ret = OCDoResource(NULL, method, query, dest, (OCPayload*)payload, OC_CONNTYPE, qos,\r
-             &cbData, options, numOptions);\r
\r
-     if (ret != OC_STACK_OK) {\r
-         OIC_LOG_V(ERROR, TAG, "OCDoResource returns error %d with method %d",\r
-                 ret, method);\r
-     }\r
\r
-     return ret;\r
- }\r
\r
- OCStackResult GetProvisioningStatus(OCQualityOfService qos,\r
-                                          const char* query,\r
-                                          const OCDevAddr *destination) {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
-     OCHeaderOption options[MAX_HEADER_OPTIONS];\r
\r
-     OIC_LOG_V(INFO, TAG, "\n\nExecuting %s", __func__);\r
\r
-     uint8_t option0[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r
-     uint8_t option1[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };\r
-     memset(options, 0, sizeof(OCHeaderOption) * MAX_HEADER_OPTIONS);\r
-     options[0].protocolID = OC_COAP_ID;\r
-     options[0].optionID = 2048;\r
-     memcpy(options[0].optionData, option0, sizeof(option0));\r
-     options[0].optionLength = 10;\r
-     options[1].protocolID = OC_COAP_ID;\r
-     options[1].optionID = 3000;\r
-     memcpy(options[1].optionData, option1, sizeof(option1));\r
-     options[1].optionLength = 10;\r
\r
-     ret = InvokeOCDoResource(query, OC_REST_GET, destination, OC_HIGH_QOS,\r
-                              GetProvisioningStatusResponse, NULL, options, 2);\r
-     return ret;\r
- }\r
\r
- OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,\r
-         OCProvisioningStatusCB provisioningStatusCallback) {\r
-     OCStackResult result = OC_STACK_ERROR;\r
\r
-     if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {\r
-         OIC_LOG(ERROR, TAG, "Request URI is NULL");\r
-         return result;\r
-     }\r
\r
-     if (provisioningStatusCallback == NULL) {\r
-         OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");\r
-         return result;\r
-     }\r
\r
-     cbData = provisioningStatusCallback;\r
\r
-     //Copy Network Provisioning  Information\r
-     netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));\r
\r
-     if (NULL == netProvInfo)\r
-     {\r
-         OIC_LOG(ERROR, TAG, "Invalid input..");\r
-         return OC_STACK_ERROR;\r
-     }\r
-     memcpy(netProvInfo, netInfo, sizeof(EnrolleeNWProvInfo_t));\r
\r
-     OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. SSID = %s",\r
-             netProvInfo->netAddressInfo.WIFI.ssid);\r
\r
-     OIC_LOG_V(DEBUG, TAG, "Network Provisioning Info. PWD = %s",\r
-             netProvInfo->netAddressInfo.WIFI.pwd);\r
\r
\r
-     if (CA_STATUS_OK\r
-             != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,\r
-                     (void *) "")) {\r
-         OIC_LOG(DEBUG, TAG, "thread_pool_add_task of FindProvisioningResource failed");\r
-         ca_thread_pool_free(g_threadPoolHandle);\r
-         ca_mutex_unlock(g_provisioningMutex);\r
-         ca_mutex_free(g_provisioningMutex);\r
-         ca_cond_free(g_provisioningCond);\r
-         return OC_STACK_ERROR;\r
-     }\r
-     return OC_STACK_OK;\r
- }\r
\r
- void StopProvisioningProcess() {\r
-     cbData = NULL;\r
- }\r
\r
\r
- // This is a function called back when a device is discovered\r
- OCStackApplicationResult FindProvisioningResourceResponse(void* ctx,\r
-         OCDoHandle handle, OCClientResponse * clientResponse) {\r
-     OIC_LOG(INFO, TAG, PCF("Entering FindProvisioningResourceResponse"));\r
\r
-     ProvisioningInfo *provInfo = NULL;\r
-     OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
\r
-     if(clientResponse == NULL)\r
-     {\r
-         OIC_LOG(ERROR, TAG,\r
-                 "OCClientResponse is NULL");\r
\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
\r
-         cbData(provInfo);\r
-         return response;\r
-     }\r
\r
-     if (clientResponse->result != OC_STACK_OK || NULL == clientResponse->payload) {\r
-         OIC_LOG(ERROR, TAG,\r
-                 "OCStack stop error. Calling Provisioing Status Callback");\r
\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
\r
-         cbData(provInfo);\r
-         return response;\r
-     }\r
\r
-     OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*)clientResponse->payload;\r
\r
-     OIC_LOG_V(DEBUG, TAG, "discoveryPayload->resources->uri = %s",\r
-                                             discoveryPayload->resources->uri);\r
-     char szQueryUri[64] = { 0 };\r
\r
-     snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,\r
-             clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);\r
-     OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);\r
\r
-     if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != OC_STACK_OK) {\r
-         OIC_LOG(INFO, TAG,\r
-                 "GetProvisioningStatus returned error. \\r
-         Invoking Provisioing Status Callback");\r
-         provInfo = PrepareProvisioingStatusCB(clientResponse,\r
-                 DEVICE_NOT_PROVISIONED);\r
\r
-         cbData(provInfo);\r
-         return OC_STACK_DELETE_TRANSACTION;\r
-     }\r
\r
-     return OC_STACK_KEEP_TRANSACTION;\r
- }\r
\r
\r
- void FindProvisioningResource(void *data)\r
- {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
\r
-     /* Start a discovery query*/\r
-     char szQueryUri[64] = { 0 };\r
\r
-     snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
-             netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);\r
\r
-     OIC_LOG_V(DEBUG, TAG, "szQueryUri = %s", szQueryUri);\r
\r
-     OCCallbackData ocCBData;\r
\r
-     ocCBData.cb = FindProvisioningResourceResponse;\r
-     ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
-     ocCBData.cd = NULL;\r
\r
-     ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, NULL, OC_CONNTYPE,\r
-             OC_LOW_QOS, &ocCBData, NULL, 0);\r
\r
-     if (ret != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack resource error");\r
\r
-         OIC_LOG(ERROR, TAG,\r
-                 "FindProvisioningResource failed. \\r
-         Invoking Provisioing Status Callback");\r
\r
-         ProvisioningInfo *provInfo;\r
-         provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
\r
-         if(provInfo == NULL)\r
-         {\r
-             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
-             return;\r
-         }\r
\r
-         OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
\r
-         if(devAddr == NULL)\r
-         {\r
-             OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
-             return;\r
-         }\r
\r
-         strncpy(devAddr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress, sizeof(devAddr->addr));\r
-         devAddr->port= IP_PORT;\r
-         provInfo->provDeviceInfo.addr = devAddr;\r
-         provInfo->provStatus = DEVICE_NOT_PROVISIONED;\r
\r
\r
-         cbData(provInfo);\r
-     }\r
- }\r
\r
- OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,\r
-         OCClientResponse* clientResponse) {\r
-     OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));\r
\r
-     OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;\r
\r
-     if (clientResponse->result != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack stop error");\r
-         return response;\r
-     }\r
\r
-     if (clientResponse) {\r
-         OIC_LOG(INFO, TAG, PCF("Client Response exists"));\r
\r
-         if(clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)\r
-         {\r
-             OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");\r
-             return response;\r
-         }\r
\r
-         OCRepPayload* discoveryPayload= (OCRepPayload*)(clientResponse->payload);\r
-         if(!discoveryPayload)\r
-         {\r
-             OIC_LOG_V(DEBUG, TAG, "invalid payload");\r
-             return response;\r
-         }\r
\r
-         char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };\r
-         snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);\r
\r
-         OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",\r
-                 discoveryPayload->uri, sourceIPAddr);\r
\r
-         /* Start a discovery query*/\r
-         char szQueryUri[64] = { 0 };\r
\r
-         snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,\r
-                 sourceIPAddr, IP_PORT);\r
\r
-         /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {\r
-             OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");\r
-             return OC_STACK_KEEP_TRANSACTION;\r
-         }*/\r
-     } else {\r
-         // clientResponse is invalid\r
-         OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));\r
-     }\r
-     return OC_STACK_KEEP_TRANSACTION;\r
- }\r
\r
\r
- OCStackResult SubscribeProvPresence(OCQualityOfService qos,\r
-         const char* requestURI) {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
\r
-     OCCallbackData cbData;\r
\r
-     cbData.cb = &SubscribeProvPresenceCallback;\r
-     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;\r
-     cbData.cd = NULL;\r
\r
-     ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE,\r
-             OC_LOW_QOS, &cbData, NULL, 0);\r
\r
-     if (ret != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack resource error");\r
-     }\r
\r
-     return ret;\r
- }\r
\r
- OCStackResult FindNetworkResource() {\r
-     OCStackResult ret = OC_STACK_ERROR;\r
-     if (OCStop() != OC_STACK_OK) {\r
-         OIC_LOG(ERROR, TAG, "OCStack stop error");\r
-     }\r
\r
-     return ret;\r
- }\r
\r
- ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {\r
\r
-     ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));\r
\r
-     if(provInfo == NULL)\r
-     {\r
-         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
-         return NULL;\r
-     }\r
\r
-     OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));\r
\r
-     if(devAddr == NULL)\r
-     {\r
-         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");\r
-         return NULL;\r
-     }\r
\r
-     strncpy(devAddr->addr, clientResponse->addr->addr, sizeof(devAddr->addr));\r
-     devAddr->port= clientResponse->addr->port;\r
\r
-     provInfo->provDeviceInfo.addr = devAddr;\r
\r
-     provInfo->provStatus = provStatus;\r
\r
-     return provInfo;\r
- }\r
\r
\r
\r
\r
++//******************************************************************
++//
++// 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 "ocpayload.h"
++#include "provisioninghandler.h"
++#include "common.h"
++// External includes
++
++#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;
++
++void ErrorCallback(ProvStatus status)
++{
++    ProvisioningInfo *provInfo = GetCallbackObjectOnError(status);
++    cbData(provInfo);
++}
++
++OCStackResult InitProvisioningHandler()
++{
++    OCStackResult ret = OC_STACK_ERROR;
++    /* Initialize OCStack*/
++    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
++    {
++        OIC_LOG(ERROR, TAG, "OCStack init error");
++        return ret;
++    }
++
++    g_provisioningMutex = ca_mutex_new();
++
++    OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
++
++    if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle))
++    {
++        OIC_LOG(DEBUG, TAG, "thread_pool_init failed");
++        return OC_STACK_ERROR;
++    }
++
++    g_provisioningCond = ca_cond_new();
++    if (NULL == g_provisioningCond)
++    {
++        OIC_LOG(DEBUG, TAG, "Failed to create condition");
++        ca_mutex_free(g_provisioningMutex);
++        ca_thread_pool_free(g_threadPoolHandle);
++        return OC_STACK_ERROR;
++    }
++
++    char *string = "listeningFunc invoked in a thread";
++    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc, (void *) string))
++    {
++        OIC_LOG(DEBUG, TAG, "thread_pool_add_task failed");
++        ca_thread_pool_free(g_threadPoolHandle);
++        ca_mutex_unlock(g_provisioningMutex);
++        ca_mutex_free(g_provisioningMutex);
++        ca_cond_free(g_provisioningCond);
++        return OC_STACK_ERROR;
++    }
++    return OC_STACK_OK;
++}
++
++OCStackResult TerminateProvisioningHandler()
++{
++    OCStackResult ret = OC_STACK_ERROR;
++    if (OCStop() != OC_STACK_OK)
++    {
++        OIC_LOG(ERROR, TAG, "OCStack stop error");
++    }
++
++    ca_mutex_lock(g_provisioningMutex);
++    g_provisioningCondFlag = true;
++    //ca_cond_signal(g_provisioningCond);
++    ca_mutex_unlock(g_provisioningMutex);
++
++    ca_mutex_free(g_provisioningMutex);
++    g_provisioningMutex = NULL;
++
++    ca_thread_pool_free(g_threadPoolHandle);
++    g_threadPoolHandle = NULL;
++
++    ret = OC_STACK_OK;
++    return ret;
++}
++
++void listeningFunc(void *data)
++{
++    while (!g_provisioningCondFlag)
++    {
++        OCStackResult result;
++
++        ca_mutex_lock(g_provisioningMutex);
++        result = OCProcess();
++        ca_mutex_unlock(g_provisioningMutex);
++
++        if (result != OC_STACK_OK)
++        {
++            OIC_LOG(ERROR, TAG, "OCStack stop error");
++        }
++
++        // To minimize CPU utilization we may wish to do this with sleep
++        sleep(1);
++    }
++}
++
++OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
++        OCClientResponse * clientResponse)
++{
++
++    ProvisioningInfo *provInfo;
++
++    if (!ValidateEnrolleResponse(clientResponse))
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    char* tnn;
++    char* cd;
++
++    OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
++
++    while (input)
++    {
++
++        int64_t ps;
++        if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_PS, &ps))
++        {
++
++            if (ps == 1)
++            {
++                OIC_LOG_V(DEBUG, TAG, "PS is proper");
++                input = input->next;
++                continue;
++            }
++            else
++            {
++                OIC_LOG_V(DEBUG, TAG, "PS is NOT proper");
++                goto Error;
++
++            }
++        }
++
++        if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
++        {
++            if (!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))
++            {
++                OIC_LOG_V(DEBUG, TAG, "SSID is proper");
++                input = input->next;
++                continue;
++            }
++            else
++            {
++                OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
++                goto Error;
++            }
++        }
++
++        if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
++        {
++            if (!strcmp(cd, netProvInfo->netAddressInfo.WIFI.pwd))
++            {
++                OIC_LOG_V(DEBUG, TAG, "Password is proper");
++                input = input->next;
++                continue;
++            }
++            else
++            {
++                OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
++                goto Error;
++            }
++        }
++
++        LogProvisioningResponse(input->values);
++
++        input = input->next;
++
++    }
++
++    SuccessCallback(clientResponse);
++
++    return OC_STACK_KEEP_TRANSACTION;
++
++    Error:
++    {
++
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++}
++
++OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,
++        OCDevAddr *destination)
++{
++    OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
++
++    OCRepPayload* payload = OCRepPayloadCreate();
++
++    OCRepPayloadSetUri(payload, resUri);
++    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_TNN, netProvInfo->netAddressInfo.WIFI.ssid);
++    OCRepPayloadSetPropString(payload, OC_RSRVD_ES_CD, netProvInfo->netAddressInfo.WIFI.pwd);
++
++    OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");
++
++    OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, destination, OC_HIGH_QOS,
++            ProvisionEnrolleeResponse, payload, NULL, 0);
++
++    return ret;
++}
++
++OCStackApplicationResult GetProvisioningStatusResponse(void* ctx, OCDoHandle handle,
++        OCClientResponse * clientResponse)
++{
++
++    ProvisioningInfo *provInfo;
++
++    if (!ValidateEnrolleResponse(clientResponse))
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        ClearMemory();
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
++
++    char query[OIC_STRING_MAX_VALUE] =
++    { '\0' };
++    char resURI[MAX_URI_LENGTH] =
++    { '\0' };
++
++    OIC_LOG_V(DEBUG, TAG, "resUri = %s", input->uri);
++
++    strncpy(resURI, input->uri, sizeof(resURI));
++
++    snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY, clientResponse->addr->addr, IP_PORT,
++            resURI);
++
++    //OCPayloadLogRep(DEBUG,TAG,input);
++
++    if (ProvisionEnrollee(OC_HIGH_QOS, query, OC_RSRVD_ES_URI_PROV, clientResponse->addr)
++            != OC_STACK_OK)
++    {
++        OIC_LOG(INFO, TAG,
++                "GetProvisioningStatusResponse received NULL clientResponse.Invoking Provisioing Status Callback");
++
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        ClearMemory();
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    return OC_STACK_KEEP_TRANSACTION;
++
++}
++
++OCStackResult InvokeOCDoResource(const char* query, OCMethod method, const OCDevAddr *dest,
++        OCQualityOfService qos, OCClientResponseHandler cb, OCRepPayload* payload,
++        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, dest, (OCPayload*) payload, 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,
++        const OCDevAddr *destination)
++{
++    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, destination, OC_HIGH_QOS,
++            GetProvisioningStatusResponse, NULL, options, 2);
++    return ret;
++}
++
++OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
++        OCProvisioningStatusCB provisioningStatusCallback)
++{
++
++    OCStackResult result = OC_STACK_ERROR;
++
++    if (!ValidateEasySetupParams(netInfo, provisioningStatusCallback))
++    {
++        goto Error;
++    }
++
++    //Only basis test is done for below API
++    if (!SetProgress(provisioningStatusCallback))
++    {
++        // Device provisioning session is running already.
++        OIC_LOG(INFO, TAG, PCF("Device provisioning session is running already"));
++        goto Error;
++    }
++
++    if (!ConfigEnrolleeObject(netInfo))
++    {
++        goto Error;
++    }
++
++    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
++            (void *) ""))
++    {
++        goto Error;
++    }
++
++    return OC_STACK_OK;
++
++    Error:
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        ClearMemory();
++        return OC_STACK_ERROR;
++    }
++
++}
++
++void StopProvisioningProcess()
++{
++    //Only basis test is done for below API
++    ResetProgress();
++}
++
++// 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"));
++
++    if (!ValidateFinddResourceResponse(clientResponse))
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
++
++    ProvisioningInfo *provInfo;
++    char szQueryUri[64] =
++    { 0 };
++
++    OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*) (clientResponse->payload);
++
++    // Need to conform if below check is required or not. As Null check of clientResponse->payload is already performed above
++    if (!discoveryPayload)
++    {
++        OIC_LOG_V(DEBUG, TAG, "Failed To parse");
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    OIC_LOG_V(DEBUG, TAG, "resUri = %s", discoveryPayload->resources->uri);
++
++    snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
++            clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);
++
++    OIC_LOG_V(DEBUG, TAG, "query before GetProvisioningStatus call = %s", szQueryUri);
++
++    if (GetProvisioningStatus(OC_HIGH_QOS, szQueryUri, &clientResponse->devAddr) != OC_STACK_OK)
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        return OC_STACK_DELETE_TRANSACTION;
++    }
++
++    return OC_STACK_KEEP_TRANSACTION;
++
++}
++
++void FindProvisioningResource(void *data)
++{
++    OCStackResult ret = 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);
++
++    OCCallbackData ocCBData;
++
++    ocCBData.cb = FindProvisioningResourceResponse;
++    ocCBData.context = (void*) DEFAULT_CONTEXT_VALUE;
++    ocCBData.cd = NULL;
++
++    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, NULL, OC_CONNTYPE, OC_LOW_QOS,
++            &ocCBData, NULL, 0);
++
++    if (ret != OC_STACK_OK)
++    {
++        ErrorCallback( DEVICE_NOT_PROVISIONED);
++        ClearMemory();
++    }
++}
++
++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"));
++
++        if (clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++        {
++            OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
++            return response;
++        }
++
++        OCRepPayload* discoveryPayload = (OCRepPayload*) (clientResponse->payload);
++        if (!discoveryPayload)
++        {
++            OIC_LOG_V(DEBUG, TAG, "invalid payload");
++            return response;
++        }
++
++        char sourceIPAddr[OIC_STRING_MAX_VALUE] =
++        { '\0' };
++        snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
++
++        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s", discoveryPayload->uri, sourceIPAddr);
++
++        /* Start a discovery query*/
++        char szQueryUri[64] =
++        { 0 };
++
++        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY, sourceIPAddr, IP_PORT);
++
++        /*if (FindProvisioningResource(qos, szQueryUri) != OC_STACK_OK) {
++         OIC_LOG(ERROR, TAG, "FindProvisioningResource failed");
++         return OC_STACK_KEEP_TRANSACTION;
++         }*/
++    }
++    else
++    {
++        // clientResponse is invalid
++        OIC_LOG(ERROR, TAG, PCF("Client Response is NULL!"));
++    }
++    return OC_STACK_KEEP_TRANSACTION;
++}
++
++OCStackResult SubscribeProvPresence(OCQualityOfService qos, const char* requestURI)
++{
++    OCStackResult ret = OC_STACK_ERROR;
++
++    OCCallbackData cbData;
++
++    cbData.cb = &SubscribeProvPresenceCallback;
++    cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
++    cbData.cd = NULL;
++
++    ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE, OC_LOW_QOS, &cbData,
++            NULL, 0);
++
++    if (ret != OC_STACK_OK)
++    {
++        OIC_LOG(ERROR, TAG, "OCStack resource error");
++    }
++
++    return ret;
++}
++
++OCStackResult FindNetworkResource()
++{
++    OCStackResult ret = OC_STACK_ERROR;
++    if (OCStop() != OC_STACK_OK)
++    {
++        OIC_LOG(ERROR, TAG, "OCStack stop error");
++    }
++
++    return ret;
++}
++
++ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
++        ProvStatus provStatus)
++{
++
++    ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
++
++    if (provInfo == NULL)
++    {
++        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++        return NULL;
++    }
++
++    OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
++
++    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;
++}
++
++bool ValidateEasySetupParams(const EnrolleeNWProvInfo_t *netInfo,
++        OCProvisioningStatusCB provisioningStatusCallback)
++{
++
++    if (netInfo == NULL || netInfo->netAddressInfo.WIFI.ipAddress == NULL)
++    {
++        OIC_LOG(ERROR, TAG, "Request URI is NULL");
++        return false;
++    }
++
++    if (provisioningStatusCallback == NULL)
++    {
++        OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
++        return false;
++    }
++
++    return true;
++
++}
++
++bool InProgress()
++{
++
++    // It means already Easy Setup provisioning session is going on.
++    if (NULL != cbData)
++    {
++        OIC_LOG(ERROR, TAG, "Easy setup session is already in progress");
++        return true;
++    }
++
++    return false;
++}
++
++bool SetProgress(OCProvisioningStatusCB provisioningStatusCallback)
++{
++    ca_mutex_lock(g_provisioningMutex);
++
++    if (InProgress())
++        return false;
++
++    cbData = provisioningStatusCallback;
++
++    ca_mutex_unlock(g_provisioningMutex);
++
++    return true;
++}
++
++bool ResetProgress()
++{
++    ca_mutex_lock(g_provisioningMutex);
++
++    cbData = NULL;
++
++    ca_mutex_unlock(g_provisioningMutex);
++}
++
++ProvisioningInfo* CreateCallBackObject()
++{
++
++    ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
++
++    if (provInfo == NULL)
++    {
++        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++        return NULL;
++    }
++
++    OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
++
++    if (devAddr == NULL)
++    {
++        OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
++        return NULL;
++    }
++
++    provInfo->provDeviceInfo.addr = devAddr;
++
++    return provInfo;
++
++}
++
++ProvisioningInfo* GetCallbackObjectOnError(ProvStatus status)
++{
++
++    ProvisioningInfo *provInfo = CreateCallBackObject();
++    strncpy(provInfo->provDeviceInfo.addr->addr, netProvInfo->netAddressInfo.WIFI.ipAddress,
++            sizeof(provInfo->provDeviceInfo.addr->addr));
++    provInfo->provDeviceInfo.addr->port = IP_PORT;
++    provInfo->provStatus = status;
++    return provInfo;
++}
++
++ProvisioningInfo* GetCallbackObjectOnSuccess(OCClientResponse * clientResponse,
++        ProvStatus provStatus)
++{
++    ProvisioningInfo *provInfo = CreateCallBackObject();
++    strncpy(provInfo->provDeviceInfo.addr->addr, clientResponse->addr->addr,
++            sizeof(provInfo->provDeviceInfo.addr->addr));
++    provInfo->provDeviceInfo.addr->port = clientResponse->addr->port;
++    provInfo->provStatus = provStatus;
++    return provInfo;
++}
++
++bool ValidateFinddResourceResponse(OCClientResponse * clientResponse)
++{
++
++    if (!(clientResponse) || !(clientResponse->payload))
++    {
++
++        OIC_LOG_V(INFO, TAG, "ProvisionEnrolleeResponse received Null clientResponse");
++
++        return false;
++
++    }
++return true;
++}
++
++bool ValidateEnrolleResponse(OCClientResponse * clientResponse)
++{
++
++    if (!(clientResponse) || !(clientResponse->payload))
++    {
++
++        OIC_LOG_V(INFO, TAG, "ProvisionEnrolleeResponse received Null clientResponse");
++
++        return false;
++
++    }
++
++    if (clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
++    {
++
++        OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
++        return false;
++
++    }
++
++    // If flow reachese here means no error condition hit.
++    return true;
++
++}
++
++
++void SuccessCallback(OCClientResponse * clientResponse)
++{
++    ProvisioningInfo *provInfo = GetCallbackObjectOnSuccess(clientResponse, DEVICE_PROVISIONED);
++    cbData(provInfo);
++}
++
++bool ClearMemory()
++{
++
++    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 true;
++
++}
++
++bool ConfigEnrolleeObject(const EnrolleeNWProvInfo_t *netInfo)
++{
++
++    //Copy Network Provisioning  Information
++    netProvInfo = (EnrolleeNWProvInfo_t *) OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
++
++    if (netProvInfo == NULL)
++    {
++        OIC_LOG(ERROR, TAG, "Invalid input..");
++        return false;
++    }
++
++    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);
++
++    return true;
++
++}
++
++void LogProvisioningResponse(OCRepPayloadValue* val)
++{
++
++    switch (val->type)
++    {
++        case OCREP_PROP_NULL:
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s: NULL", val->name);
++            break;
++        case OCREP_PROP_INT:
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s(int):%lld", val->name, val->i);
++            break;
++        case OCREP_PROP_DOUBLE:
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s(double):%f", val->name, val->d);
++            break;
++        case OCREP_PROP_BOOL:
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool):%s", val->name, val->b ? "true" : "false");
++            break;
++        case OCREP_PROP_STRING:
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s(string):%s", val->name, val->str);
++            break;
++        case OCREP_PROP_OBJECT:
++            // Note: Only prints the URI (if available), to print further, you'll
++            // need to dig into the object better!
++            OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep):%s", val->name, val->obj->uri);
++            break;
++        case OCREP_PROP_ARRAY:
++            switch (val->arr.type)
++            {
++                case OCREP_PROP_INT:
++                    OIC_LOG_V(DEBUG, TAG, "\t\t%s(int array):%lld x %lld x %lld", val->name,
++                            val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++                    break;
++                case OCREP_PROP_DOUBLE:
++                    OIC_LOG_V(DEBUG, TAG, "\t\t%s(double array):%lld x %lld x %lld", val->name,
++                            val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++                    break;
++                case OCREP_PROP_BOOL:
++                    OIC_LOG_V(DEBUG, TAG, "\t\t%s(bool array):%lld x %lld x %lld", val->name,
++                            val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++                    break;
++                case OCREP_PROP_STRING:
++                    OIC_LOG_V(DEBUG, TAG, "\t\t%s(string array):%lld x %lld x %lld", val->name,
++                            val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++                    break;
++                case OCREP_PROP_OBJECT:
++                    OIC_LOG_V(DEBUG, TAG, "\t\t%s(OCRep array):%lld x %lld x %lld", val->name,
++                            val->arr.dimensions[0], val->arr.dimensions[1], val->arr.dimensions[2]);
++                    break;
++                default:
++                    //OIC_LOG_V(ERROR, TAG, "\t\t%s <-- Unknown/unsupported array type!",
++                    //  val->name);
++                    break;
++            }
++            break;
++        default:
++            /*OC_LOG_V(ERROR, TAG
++             , "\t\t%s <-- Unknown type!", val->name);*/
++            break;
++    }
++}
++