Modify permissions for files in Things Manager
[platform/upstream/iotivity.git] / service / easy-setup / sdk / mediator / src / provisioninghandler.cpp
old mode 100644 (file)
new mode 100755 (executable)
index 5d5f31a..52fc9e3
 #include <string.h>
 #include <signal.h>
 #include <unistd.h>
-
+#include "ocpayload.h"
 #include "provisioninghandler.h"
-
+#include "common.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.
@@ -51,10 +50,19 @@ static EnrolleeNWProvInfo_t* netProvInfo;
 static OCProvisioningStatusCB cbData = NULL;
 static ca_thread_pool_t g_threadPoolHandle = NULL;
 
-OCStackResult InitProvisioningHandler() {
+void ErrorCallback(ProvStatus status)
+{
+    ProvisioningInfo *provInfo = GetCallbackObjectOnError(status);
+    cbData(provInfo);
+    ResetProgress();
+}
+
+OCStackResult InitProvisioningHandler()
+{
     OCStackResult ret = OC_STACK_ERROR;
     /* Initialize OCStack*/
-    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK) {
+    if (OCInit(NULL, 0, OC_CLIENT) != OC_STACK_OK)
+    {
         OIC_LOG(ERROR, TAG, "OCStack init error");
         return ret;
     }
@@ -63,13 +71,15 @@ OCStackResult InitProvisioningHandler() {
 
     OIC_LOG(DEBUG, TAG, "ca_thread_pool_init initializing");
 
-    if (CA_STATUS_OK != ca_thread_pool_init(2, &g_threadPoolHandle)) {
+    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) {
+    if (NULL == g_provisioningCond)
+    {
         OIC_LOG(DEBUG, TAG, "Failed to create condition");
         ca_mutex_free(g_provisioningMutex);
         ca_thread_pool_free(g_threadPoolHandle);
@@ -77,9 +87,8 @@ OCStackResult InitProvisioningHandler() {
     }
 
     char *string = "listeningFunc invoked in a thread";
-    if (CA_STATUS_OK
-            != ca_thread_pool_add_task(g_threadPoolHandle, listeningFunc,
-                    (void *) string)) {
+    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);
@@ -87,12 +96,17 @@ OCStackResult InitProvisioningHandler() {
         ca_cond_free(g_provisioningCond);
         return OC_STACK_ERROR;
     }
+
+    ResetProgress();
+
     return OC_STACK_OK;
 }
 
-OCStackResult TerminateProvisioningHandler() {
+OCStackResult TerminateProvisioningHandler()
+{
     OCStackResult ret = OC_STACK_ERROR;
-    if (OCStop() != OC_STACK_OK) {
+    if (OCStop() != OC_STACK_OK)
+    {
         OIC_LOG(ERROR, TAG, "OCStack stop error");
     }
 
@@ -111,15 +125,18 @@ OCStackResult TerminateProvisioningHandler() {
     return ret;
 }
 
-void listeningFunc(void *data) {
-    while (!g_provisioningCondFlag) {
+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) {
+        if (result != OC_STACK_OK)
+        {
             OIC_LOG(ERROR, TAG, "OCStack stop error");
         }
 
@@ -129,277 +146,160 @@ void listeningFunc(void *data) {
 }
 
 OCStackApplicationResult ProvisionEnrolleeResponse(void* ctx, OCDoHandle handle,
-        OCClientResponse * clientResponse) {
+        OCClientResponse * clientResponse)
+{
+
     ProvisioningInfo *provInfo;
 
-    if (clientResponse) {
-        OIC_LOG_V(INFO, TAG, "Put Response JSON = %s",
-                clientResponse->resJSONPayload);
-    } else {
-        OIC_LOG_V(INFO, TAG,
-                "ProvisionEnrolleeResponse received Null clientResponse");
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_NOT_PROVISIONED);
-        cbData(provInfo);
+    if (!ValidateEnrolleResponse(clientResponse))
+    {
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
         return OC_STACK_DELETE_TRANSACTION;
     }
 
-    OIC_LOG_V(DEBUG, TAG, "ProvisionEnrolleeResponse %s ",
-            clientResponse->resJSONPayload);
+    char* tnn;
+    char* cd;
 
-    if (clientResponse->resJSONPayload) {
-        cJSON *observeJson = cJSON_CreateObject();
-        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
+    OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
 
-        cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-
-        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
-        char *ocArray_str = cJSON_PrintUnformatted(representationArray);
+    while (input)
+    {
 
-        if (strstr(ocArray_str, "[{}") == ocArray_str) {
-            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
-            cJSON_Delete(observeJson);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+        int64_t ps;
+        if (OCRepPayloadGetPropInt(input, OC_RSRVD_ES_PS, &ps))
+        {
 
-        int countofrep = cJSON_GetArraySize(representationArray);
+            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;
 
-        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 (OCRepPayloadGetPropString(input, OC_RSRVD_ES_TNN, &tnn))
+        {
+            if (!strcmp(tnn, netProvInfo->netAddressInfo.WIFI.ssid))
             {
-                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);
-                }
+                OIC_LOG_V(DEBUG, TAG, "SSID is proper");
+                input = input->next;
+                continue;
             }
-
-            if (!strcmp(arrayJSON->string, OC_RSRVD_ES_TNN))
+            else
             {
-                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);
-                }
+                OIC_LOG_V(DEBUG, TAG, "SSID is NOT proper");
+                goto Error;
             }
+        }
 
-            if (!strcmp(arrayJSON->string, OC_RSRVD_ES_CD))
+        if (OCRepPayloadGetPropString(input, OC_RSRVD_ES_CD, &cd))
+        {
+            if (!strcmp(cd, netProvInfo->netAddressInfo.WIFI.pwd))
             {
-                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);
-                }
+                OIC_LOG_V(DEBUG, TAG, "Password is proper");
+                input = input->next;
+                continue;
             }
-
-            switch (arrayJSON->type) {
-            case cJSON_False:
-            case cJSON_True:
-                OIC_LOG_V(DEBUG, TAG, "rep#%d's int value : %d", i,
-                        arrayJSON->valueint);
-                break;
-            case cJSON_Number:
-                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;
+            else
+            {
+                OIC_LOG_V(DEBUG, TAG, "Password is NOT proper");
+                goto Error;
             }
         }
 
-        cJSON_Delete(observeJson);
+        LogProvisioningResponse(input->values);
 
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_PROVISIONED);
-        cbData(provInfo);
+        input = input->next;
 
-        return OC_STACK_KEEP_TRANSACTION;
-    } else {
-        OIC_LOG(INFO, TAG,
-                "ProvisionEnrolleeResponse received NULL clientResponse. \
-                                Invoking Provisioing Status Callback");
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_NOT_PROVISIONED);
-        cbData(provInfo);
-        return OC_STACK_DELETE_TRANSACTION;
     }
-}
 
-OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri) {
-    OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
+    SuccessCallback(clientResponse);
 
-    cJSON *jsonFinal = cJSON_CreateObject();
-    cJSON *json = cJSON_CreateObject();
-    cJSON *jsonArray;
-    cJSON *format;
-    char* payload = NULL;
-
-    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);
+    return OC_STACK_KEEP_TRANSACTION;
 
-    cJSON_Delete(json);
-    return ret;
-}
+    Error:
+    {
 
-OCStackApplicationResult GetProvisioningStatusResponse(void* ctx,
-        OCDoHandle handle, OCClientResponse * clientResponse) {
-    ProvisioningInfo *provInfo;
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
 
-    if (clientResponse == NULL) {
-        OIC_LOG(INFO, TAG,
-                "getReqCB received NULL clientResponse. \
-            Invoking Provisioing Status Callback");
-        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);
-            }
-        }
-    }
+}
+
+OCStackResult ProvisionEnrollee(OCQualityOfService qos, const char* query, const char* resUri,
+        OCDevAddr *destination)
+{
+    OIC_LOG_V(INFO, TAG, "\n\nExecuting ProvisionEnrollee%s", __func__);
 
-    char query[OIC_STRING_MAX_VALUE] = { '\0' };
+    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);
 
-    if (clientResponse->resJSONPayload) {
-        cJSON *observeJson = cJSON_CreateObject();
-        observeJson = cJSON_Parse(clientResponse->resJSONPayload);
+    OIC_LOG_V(DEBUG, TAG, "OCPayload ready for ProvisionEnrollee");
 
-        cJSON *ocArray = cJSON_GetObjectItem(observeJson, OC_RSRVD_OC);
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
+    OCStackResult ret = InvokeOCDoResource(query, OC_REST_PUT, destination, OC_HIGH_QOS,
+            ProvisionEnrolleeResponse, payload, NULL, 0);
 
-        cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
+    return ret;
+}
 
-        OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
-            resUriObj->string, resUriObj->valuestring);
+OCStackApplicationResult GetProvisioningStatusResponse(void* ctx, OCDoHandle handle,
+        OCClientResponse * clientResponse)
+{
 
-        char resURI[MAX_URI_LENGTH]={'\0'};
+    ProvisioningInfo *provInfo;
 
-        strncpy(resURI, resUriObj->valuestring, sizeof(resURI));
+    if (!ValidateEnrolleResponse(clientResponse))
+    {
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
+        ClearMemory();
+        return OC_STACK_DELETE_TRANSACTION;
+    }
 
-        snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY,
-                clientResponse->addr->addr,
-                IP_PORT, resURI);
+    OCRepPayload* input = (OCRepPayload*) (clientResponse->payload);
 
-        cJSON *representationArray = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_REPRESENTATION);
-        char *ocArray_str = cJSON_PrintUnformatted(representationArray);
+    char query[OIC_STRING_MAX_VALUE] =
+    { '\0' };
+    char resURI[MAX_URI_LENGTH] =
+    { '\0' };
 
-        if (strstr(ocArray_str, "[{}") == ocArray_str) {
-            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
-            cJSON_Delete(observeJson);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
+    OIC_LOG_V(DEBUG, TAG, "resUri = %s", input->uri);
 
-        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);
+    strncpy(resURI, input->uri, sizeof(resURI));
 
-        if (ProvisionEnrollee(OC_HIGH_QOS, query, resURI) != OC_STACK_OK) {
-            OIC_LOG(INFO, TAG,
-                    "GetProvisioningStatusResponse received NULL clientResponse. \
-                Invoking Provisioing Status Callback");
-            provInfo = PrepareProvisioingStatusCB(clientResponse,
-                    DEVICE_NOT_PROVISIONED);
-            cbData(provInfo);
+    snprintf(query, sizeof(query), UNICAST_PROV_STATUS_QUERY, clientResponse->addr->addr, IP_PORT,
+            resURI);
 
-            return OC_STACK_DELETE_TRANSACTION;
-        }
-    } else {
+    //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");
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_NOT_PROVISIONED);
-        cbData(provInfo);
+                "GetProvisioningStatusResponse received NULL clientResponse.Invoking Provisioing Status Callback");
+
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
+        ClearMemory();
         return OC_STACK_DELETE_TRANSACTION;
     }
-    return OC_STACK_DELETE_TRANSACTION;
+
+    return OC_STACK_KEEP_TRANSACTION;
+
 }
 
-OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
-        OCQualityOfService qos, OCClientResponseHandler cb, const char* request,
-        OCHeaderOption * options, uint8_t numOptions) {
+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;
 
@@ -407,25 +307,29 @@ OCStackResult InvokeOCDoResource(const char* query, OCMethod method,
     cbData.context = (void*) DEFAULT_CONTEXT_VALUE;
     cbData.cd = NULL;
 
-    ret = OCDoResource(NULL, method, query, 0, request, OC_CONNTYPE, qos,
-            &cbData, options, numOptions);
+    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);
+    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 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 };
+    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;
@@ -436,132 +340,102 @@ OCStackResult GetProvisioningStatus(OCQualityOfService qos, const char* query) {
     memcpy(options[1].optionData, option1, sizeof(option1));
     options[1].optionLength = 10;
 
-    ret = InvokeOCDoResource(query, OC_REST_GET, OC_HIGH_QOS,
+    ret = InvokeOCDoResource(query, OC_REST_GET, destination, OC_HIGH_QOS,
             GetProvisioningStatusResponse, NULL, options, 2);
     return ret;
 }
 
 OCStackResult StartProvisioningProcess(const EnrolleeNWProvInfo_t *netInfo,
-        OCProvisioningStatusCB provisioningStatusCallback) {
+        OCProvisioningStatusCB provisioningStatusCallback)
+{
+
     OCStackResult result = OC_STACK_ERROR;
 
-    if (netInfo->netAddressInfo.WIFI.ipAddress == NULL) {
-        OIC_LOG(ERROR, TAG, "Request URI is NULL");
-        return result;
+    if (!ValidateEasySetupParams(netInfo, provisioningStatusCallback))
+    {
+        goto Error;
     }
 
-    if (provisioningStatusCallback == NULL) {
-        OIC_LOG(ERROR, TAG, "ProvisioningStatusCallback is NULL");
-        return result;
+    //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;
     }
 
-    cbData = provisioningStatusCallback;
-
-    //Copy Network Provisioning  Information
-    netProvInfo = (EnrolleeNWProvInfo_t *)OICCalloc(1, sizeof(EnrolleeNWProvInfo_t));
-
-    if (NULL == netProvInfo)
+    if (!ConfigEnrolleeObject(netInfo))
     {
-        OIC_LOG(ERROR, TAG, "Invalid input..");
-        return OC_STACK_ERROR;
+        goto 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);
+    if (CA_STATUS_OK != ca_thread_pool_add_task(g_threadPoolHandle, FindProvisioningResource,
+            (void *) ""))
+    {
+        goto Error;
+    }
 
+    return OC_STACK_OK;
 
-    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);
+    Error:
+    {
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
+        ClearMemory();
         return OC_STACK_ERROR;
     }
-    return OC_STACK_OK;
+
 }
 
-void StopProvisioningProcess() {
-    cbData = NULL;
+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) {
+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 };
 
-    if (clientResponse->result != OC_STACK_OK) {
-        OIC_LOG(ERROR, TAG,
-                "OCStack stop error. Calling Provisioing Status Callback");
+    OCDiscoveryPayload* discoveryPayload = (OCDiscoveryPayload*) (clientResponse->payload);
 
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_NOT_PROVISIONED);
-
-        cbData(provInfo);
-        return response;
+    // 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;
     }
 
-    if (clientResponse) {
-        cJSON *discoveryJson = cJSON_CreateObject();
-        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
-        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);
-
-            provInfo = PrepareProvisioingStatusCB(clientResponse,
-                    DEVICE_NOT_PROVISIONED);
-            cbData(provInfo);
-            return response;
-        }
-
-        cJSON *ocArray_sub = cJSON_GetArrayItem(ocArray, 0);
-        cJSON *resUriObj = cJSON_GetObjectItem(ocArray_sub, OC_RSRVD_HREF);
-
-        OIC_LOG_V(DEBUG, TAG, "resUriObj = %s, valueString = %s",
-            resUriObj->string, resUriObj->valuestring);
-
+    OIC_LOG_V(DEBUG, TAG, "resUri = %s", discoveryPayload->resources->uri);
 
-        char szQueryUri[64] = { 0 };
+    snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROV_STATUS_QUERY,
+            clientResponse->devAddr.addr, IP_PORT, discoveryPayload->resources->uri);
 
-        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);
+    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");
-            provInfo = PrepareProvisioingStatusCB(clientResponse,
-                    DEVICE_NOT_PROVISIONED);
-
-            cbData(provInfo);
-            return OC_STACK_DELETE_TRANSACTION;
-        }
-    } else {
-        // clientResponse is invalid
-        OIC_LOG(ERROR, TAG,
-                "Invalid response for Provisioning Discovery request. \
-        Invoking Provisioing Status Callback");
-        provInfo = PrepareProvisioingStatusCB(clientResponse,
-                DEVICE_NOT_PROVISIONED);
-        cbData(provInfo);
-        return response;
+    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)
@@ -569,7 +443,8 @@ void FindProvisioningResource(void *data)
     OCStackResult ret = OC_STACK_ERROR;
 
     /* Start a discovery query*/
-    char szQueryUri[64] = { 0 };
+    char szQueryUri[64] =
+    { 0 };
 
     snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
             netProvInfo->netAddressInfo.WIFI.ipAddress, IP_PORT);
@@ -582,94 +457,73 @@ void FindProvisioningResource(void *data)
     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");
-
-        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;
+    ret = OCDoResource(NULL, OC_REST_DISCOVER, szQueryUri, NULL, NULL, OC_CONNTYPE, OC_LOW_QOS,
+            &ocCBData, NULL, 0);
 
-
-        cbData(provInfo);
+    if (ret != OC_STACK_OK)
+    {
+        ErrorCallback( DEVICE_NOT_PROVISIONED);
+        ClearMemory();
     }
 }
 
 OCStackApplicationResult SubscribeProvPresenceCallback(void* ctx, OCDoHandle handle,
-        OCClientResponse* clientResponse) {
+        OCClientResponse* clientResponse)
+{
     OIC_LOG(INFO, TAG, PCF("Entering SubscribeProvPresenceCallback"));
 
     OCStackApplicationResult response = OC_STACK_DELETE_TRANSACTION;
 
-    if (clientResponse->result != OC_STACK_OK) {
+    if (clientResponse->result != OC_STACK_OK)
+    {
         OIC_LOG(ERROR, TAG, "OCStack stop error");
         return response;
     }
 
-    if (clientResponse) {
+    if (clientResponse)
+    {
         OIC_LOG(INFO, TAG, PCF("Client Response exists"));
 
-        cJSON *discoveryJson = cJSON_CreateObject();
-        discoveryJson = cJSON_Parse((char *) clientResponse->resJSONPayload);
-
-        cJSON *ocArray = cJSON_GetObjectItem(discoveryJson, OC_RSRVD_OC);
-        char *ocArray_str = cJSON_PrintUnformatted(ocArray);
+        if (clientResponse->payload && clientResponse->payload->type != PAYLOAD_TYPE_REPRESENTATION)
+        {
+            OIC_LOG_V(DEBUG, TAG, "Incoming payload not a representation");
+            return response;
+        }
 
-        if (strstr(ocArray_str, "[{}") == ocArray_str) {
-            OIC_LOG_V(DEBUG, TAG, "invalid payload : %s", ocArray_str);
-            cJSON_Delete(discoveryJson);
+        OCRepPayload* discoveryPayload = (OCRepPayload*) (clientResponse->payload);
+        if (!discoveryPayload)
+        {
+            OIC_LOG_V(DEBUG, TAG, "invalid payload");
             return response;
         }
 
-        char sourceIPAddr[OIC_STRING_MAX_VALUE] = { '\0' };
+        char sourceIPAddr[OIC_STRING_MAX_VALUE] =
+        { '\0' };
         snprintf(sourceIPAddr, sizeof(sourceIPAddr), "%s", clientResponse->addr->addr);
 
-        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s",
-                clientResponse->resJSONPayload, sourceIPAddr);
+        OIC_LOG_V(DEBUG, TAG, "Discovered %s @ %s", discoveryPayload->uri, sourceIPAddr);
 
         /* Start a discovery query*/
-        char szQueryUri[64] = { 0 };
+        char szQueryUri[64] =
+        { 0 };
 
-        snprintf(szQueryUri, sizeof(szQueryUri), UNICAST_PROVISIONING_QUERY,
-                sourceIPAddr, IP_PORT);
+        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 {
+         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 SubscribeProvPresence(OCQualityOfService qos, const char* requestURI)
+{
     OCStackResult ret = OC_STACK_ERROR;
 
     OCCallbackData cbData;
@@ -678,30 +532,35 @@ OCStackResult SubscribeProvPresence(OCQualityOfService qos,
     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);
+    ret = OCDoResource(NULL, OC_REST_PRESENCE, requestURI, 0, 0, OC_CONNTYPE, OC_LOW_QOS, &cbData,
+            NULL, 0);
 
-    if (ret != OC_STACK_OK) {
+    if (ret != OC_STACK_OK)
+    {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
     }
 
     return ret;
 }
 
-OCStackResult FindNetworkResource() {
+OCStackResult FindNetworkResource()
+{
     OCStackResult ret = OC_STACK_ERROR;
-    if (OCStop() != OC_STACK_OK) {
+    if (OCStop() != OC_STACK_OK)
+    {
         OIC_LOG(ERROR, TAG, "OCStack stop error");
     }
 
     return ret;
 }
 
-ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse, ProvStatus provStatus) {
+ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
+        ProvStatus provStatus)
+{
 
     ProvisioningInfo *provInfo = (ProvisioningInfo *) OICCalloc(1, sizeof(ProvisioningInfo));
 
-    if(provInfo == NULL)
+    if (provInfo == NULL)
     {
         OIC_LOG_V(ERROR, TAG, "Failed to allocate memory");
         return NULL;
@@ -709,14 +568,14 @@ ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
 
     OCDevAddr *devAddr = (OCDevAddr *) OICCalloc(1, sizeof(OCDevAddr));
 
-    if(devAddr == NULL)
+    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;
+    devAddr->port = clientResponse->addr->port;
 
     provInfo->provDeviceInfo.addr = devAddr;
 
@@ -725,3 +584,251 @@ ProvisioningInfo* PrepareProvisioingStatusCB(OCClientResponse * clientResponse,
     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);
+    ResetProgress();
+}
+
+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;
+    }
+}
+