Pstat payload conversion from JSON to CBOR
authorHabib Virji <habib.virji@samsung.com>
Thu, 18 Feb 2016 15:24:29 +0000 (15:24 +0000)
committerHabib Virji <habib.virji@samsung.com>
Sat, 12 Mar 2016 18:02:56 +0000 (18:02 +0000)
Converts Pstat payload conversion from JSON to CBOR directly using tinycbor library.

- Pstat unit test is updated to match new changes.
- Fixes bug in psinterface to move to the next element.
- ocpayloadparse.c, is updated to include bytestring or cjson depending on the message contents.
- Pstat format: {"isop": <0/1>, "deviceid":<bytestring>, "ch": <int>, "cm": <int>, "om": <int>, "tm": <int>, sm:[<int>, <int>] }.
- Persistant storage format: { "acl": <aclcbor>, "pstat": <pstatcbor> }

Change-Id: I29a92bbf0f24d82612b8795b86119863c4a1905b
Signed-off-by: Habib Virji <habib.virji@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5045
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5775

resource/csdk/security/include/internal/pstatresource.h
resource/csdk/security/include/internal/security_internals.h
resource/csdk/security/provisioning/src/ownershiptransfermanager.c
resource/csdk/security/src/psinterface.c
resource/csdk/security/src/pstatresource.c
resource/csdk/security/unittest/pstatresource.cpp
resource/csdk/stack/src/ocpayloadparse.c

index 3134788..7331484 100644 (file)
@@ -40,24 +40,33 @@ OCStackResult InitPstatResource();
 OCStackResult DeInitPstatResource();
 
 /**
- * This method converts JSON PSTAT into binary PSTAT.
+ * This method converts PSTAT into the cbor payload.
  *
- * @param[in] jsonStr  pstat data in json string.
- * @return pointer to OicSecPstat_t.
+ * @param pstat pointer to the initialized pstat structure.
+ * @param cborPayload pointer to pstat cbor payload.
+ * @param size of the cbor payload converted. It is 0 in case of error,
+ * else a positive value if succcessful.
+ *
+ * @return ::OC_STACK_OK for Success, otherwise some error value.
  */
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
+ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **cborPayload,
+                                  size_t *cborSize);
 
 /**
- * This method converts pstat data into JSON format.
+ * This method converts cbor into PSTAT data.
  *
- * @param[in] pstat  pstat data in binary format.
- * @return pointer to pstat json string.
+ * @param cborPayload is the pstat data in cbor format.
+ * @param size of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
+ * @param pstat pointer to @ref OicSecPstat_t.
+  *
+  * @return ::OC_STACK_OK for Success, otherwise some error value.
  */
-char * BinToPstatJSON(const OicSecPstat_t * pstat);
+ OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t cborSize,
+                                  OicSecPstat_t **pstat);
 
 /** This function deallocates the memory for OicSecPstat_t.
  *
- * @param[in] pstat  Pointer to OicSecPstat_t.
+ * @param pstat is the pointer to @ref OicSecPstat_t.
  */
 void DeletePstatBinData(OicSecPstat_t* pstat);
 
@@ -72,5 +81,3 @@ void RestorePstatToInitState();
 #endif
 
 #endif //IOTVT_SRM_PSTATR_H
-
-
index 4a92ad1..de1e4fc 100644 (file)
@@ -45,6 +45,18 @@ OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size, OicSecSv
  */
 void DeleteSVCList(OicSecSvc_t* svc);
 
+/**
+ * Create PSTAT resource after default PSTAT initialization is done.
+ */
+OCStackResult CreatePstatResource();
+
+/**
+ * This internal method is the entity handler for PSTAT resources and
+ * will handle REST request (GET/PUT/POST/DEL) for them.
+ */
+OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
+                                         OCEntityHandlerRequest * ehRequest);
+
 #ifdef __cplusplus
 }
 #endif
index 958d670..e1ba69b 100644 (file)
@@ -545,12 +545,14 @@ static OCStackApplicationResult ListMethodsHandler(void *ctx, OCDoHandle UNUSED,
             SetResult(otmCtx, OC_STACK_ERROR);
             return OC_STACK_DELETE_TRANSACTION;
         }
-
-        OicSecPstat_t* pstat = JSONToPstatBin(
-                ((OCSecurityPayload*)clientResponse->payload)->securityData);
-        if(NULL == pstat)
+        uint8_t size = 0;
+        OicSecPstat_t* pstat = NULL;
+        OCStackResult result = CBORPayloadToPstat(
+                ((OCSecurityPayload*)clientResponse->payload)->securityData1,
+                size, &pstat);
+        if(NULL == pstat && result != OC_STACK_OK)
         {
-            OIC_LOG(ERROR, TAG, "Error while converting json to pstat bin");
+            OIC_LOG(ERROR, TAG, "Error while converting cbor to pstat.");
             SetResult(otmCtx, OC_STACK_ERROR);
             return OC_STACK_DELETE_TRANSACTION;
         }
@@ -1201,11 +1203,13 @@ static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
         return OC_STACK_NO_MEMORY;
     }
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    secPayload->securityData = BinToPstatJSON(deviceInfo->pstat);
-    if (NULL == secPayload->securityData)
+    size_t size = 0;
+    OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData1,
+                                           &size);
+   if (OC_STACK_OK != res)
     {
-        OICFree(secPayload);
-        OIC_LOG(ERROR, TAG, "Error while converting pstat bin to json");
+        OCPayloadDestroy((OCPayload *)secPayload);
+        OIC_LOG(ERROR, TAG, "Error while converting pstat to cbor.");
         return OC_STACK_INVALID_PARAM;
     }
 
@@ -1213,8 +1217,8 @@ static OCStackResult PutUpdateOperationMode(OTMContext_t* otmCtx)
     cbData.cb = &OperationModeUpdateHandler;
     cbData.context = (void *)otmCtx;
     cbData.cd = NULL;
-    OCStackResult res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
-                                     deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
+    res = OCDoResource(NULL, OC_REST_PUT, query, 0, (OCPayload*)secPayload,
+                       deviceInfo->connType, OC_LOW_QOS, &cbData, NULL, 0);
     if (res != OC_STACK_OK)
     {
         OIC_LOG(ERROR, TAG, "OCStack resource error");
@@ -1369,7 +1373,6 @@ error:
     OICFree(otmCtx->ctxResultArray);
     OICFree(otmCtx);
     return res;
-
 }
 
 OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
@@ -1398,14 +1401,15 @@ OCStackResult PutProvisioningStatus(OTMContext_t* otmCtx)
         return OC_STACK_NO_MEMORY;
     }
     secPayload->base.type = PAYLOAD_TYPE_SECURITY;
-    secPayload->securityData = BinToPstatJSON(otmCtx->selectedDeviceInfo->pstat);
-    if (NULL == secPayload->securityData)
+    size_t size = 0;
+    if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
+            &secPayload->securityData1, &size))
     {
-        OICFree(secPayload);
+        OCPayloadDestroy((OCPayload *)secPayload);
         SetResult(otmCtx, OC_STACK_INVALID_JSON);
         return OC_STACK_INVALID_JSON;
     }
-    OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData);
+    OIC_LOG_V(INFO, TAG, "Created payload for commit hash: %s",secPayload->securityData1);
 
     char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
     if(!PMGenerateQuery(true,
index 73d4a21..269591b 100644 (file)
@@ -226,10 +226,10 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat
             VERIFY_NON_NULL(TAG, fsData, ERROR);
             if (rsrcName != NULL)
             {
-                CborParser parser = { .end = NULL, .flags = 0 };
-                CborValue cbor =  { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+                CborParser parser = { .end = NULL };
+                CborValue cbor =  { .parser = NULL };
                 cbor_parser_init(fsData, fileSize, 0, &parser, &cbor);
-                CborValue cborValue =  { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+                CborValue cborValue =  { .parser = NULL };
                 CborError cborFindResult = cbor_value_enter_container(&cbor, &cborValue);
 
                 while (cbor_value_is_valid(&cborValue))
@@ -299,19 +299,19 @@ OCStackResult UpdateSecureResourceInPS(const char* rsrcName, const uint8_t* psPa
         outPayload = (uint8_t *)OICCalloc(1, size);
         VERIFY_NON_NULL(TAG, outPayload, ERROR);
 
-        CborEncoder encoder = { { .ptr = NULL }, .end = NULL, .added = 0, .flags = 0};
+        CborEncoder encoder = { { .ptr = NULL }, .end = };
         cbor_encoder_init(&encoder, outPayload, size, 0);
         {
-            CborEncoder map = { {.ptr = NULL }, .end = 0, .added = 0, .flags = 0};
+            CborEncoder map = { {.ptr = NULL }, .end = 0 };
             CborError cborEncoderResult = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength);
             VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating PS Interface Map.");
             {
                 bool found = false;
-                CborValue cbor = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
-                CborParser parser = { .end = NULL, .flags = 0 };
+                CborValue cbor = { .parser = NULL };
+                CborParser parser = { .end = NULL };
                 cbor_parser_init(dbData, size, 0, &parser, &cbor);
 
-                CborValue cborValue = { .parser = NULL, .ptr = NULL, .remaining = 0, .extra = 0, .type = 0, .flags = 0 };
+                CborValue cborValue = { .parser = NULL };
                 CborError cborFindResult = CborNoError;
 
                 if (cbor_value_is_container(&cbor))
index d3ecc27..84750e0 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#include <stdlib.h>
+#include <string.h>
+
 #include "ocstack.h"
-#include "logger.h"
 #include "oic_malloc.h"
-#include "cJSON.h"
+#include "ocpayload.h"
+#include "payload_logging.h"
 #include "resourcemanager.h"
 #include "pstatresource.h"
 #include "doxmresource.h"
 #include "psinterface.h"
-#include "utlist.h"
-#include "base64.h"
 #include "srmresourcestrings.h"
 #include "srmutility.h"
-#include <stdlib.h>
-#include <string.h>
 
 #define TAG  "SRM-PSTAT"
 
+/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
+ * The value of payload size is increased until reaching below max cbor size. */
+static const uint8_t CBOR_SIZE = 255;
+
+// Max cbor size payload.
+static const uint16_t CBOR_MAX_SIZE = 4400;
+
+// PSTAT Map size - Number of mandatory items
+static const uint8_t PSTAT_MAP_SIZE = 7;
+
 static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
 static OicSecPstat_t gDefaultPstat =
 {
@@ -66,156 +75,258 @@ void DeletePstatBinData(OicSecPstat_t* pstat)
     }
 }
 
-char * BinToPstatJSON(const OicSecPstat_t * pstat)
+OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload, size_t *size)
 {
-    if(NULL == pstat)
+    if (NULL == pstat || NULL == payload || NULL != *payload || NULL == size)
     {
-        return NULL;
+        return OC_STACK_INVALID_PARAM;
     }
 
-    cJSON *jsonPstat = NULL;
-    char *jsonStr = NULL;
-    cJSON *jsonSmArray = NULL;
-    char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*) 0)->id)) + 1] = {};
-    uint32_t outLen = 0;
-    B64Result b64Ret = B64_OK;
+    size_t cborLen = *size;
+    if (0 == cborLen)
+    {
+        cborLen = CBOR_SIZE;
+    }
 
-    cJSON *jsonRoot = cJSON_CreateObject();
-    VERIFY_NON_NULL(TAG, jsonRoot, INFO);
+    *payload = NULL;
+    *size = 0;
 
-    cJSON_AddItemToObject(jsonRoot, OIC_JSON_PSTAT_NAME, jsonPstat=cJSON_CreateObject());
-    cJSON_AddBoolToObject(jsonPstat, OIC_JSON_ISOP_NAME, pstat->isOp);
+    OCStackResult ret = OC_STACK_ERROR;
 
-    b64Ret = b64Encode(pstat->deviceID.id,
-            sizeof(pstat->deviceID.id), base64Buff, sizeof(base64Buff), &outLen);
-    VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
+    CborEncoder encoder = { {.ptr = NULL }, .end = 0 };
+    CborEncoder pstatMap = { {.ptr = NULL }, .end = 0 };
+
+    CborError cborEncoderResult = CborNoError;
+
+    uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
+    VERIFY_NON_NULL(TAG, outPayload, ERROR);
+    cbor_encoder_init(&encoder, outPayload, cborLen, 0);
+
+    cborEncoderResult = cbor_encoder_create_map(&encoder, &pstatMap, PSTAT_MAP_SIZE);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pstat Map.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ISOP_NAME,
+        strlen(OIC_JSON_ISOP_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Tag.");
+    cborEncoderResult = cbor_encode_boolean(&pstatMap, pstat->isOp);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_DEVICE_ID_NAME,
+        strlen(OIC_JSON_DEVICE_ID_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
+    cborEncoderResult = cbor_encode_byte_string(&pstatMap, (uint8_t *)pstat->deviceID.id,
+                                                sizeof(pstat->deviceID.id));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_COMMIT_HASH_NAME,
+        strlen(OIC_JSON_COMMIT_HASH_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Commit Hash Tag.");
+    cborEncoderResult = cbor_encode_int(&pstatMap, pstat->commitHash);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Commit Hash Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_CM_NAME,
+        strlen(OIC_JSON_CM_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Tag.");
+    cborEncoderResult = cbor_encode_int(&pstatMap, pstat->cm);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_TM_NAME,
+        strlen(OIC_JSON_TM_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Tag.");
+    cborEncoderResult = cbor_encode_int(&pstatMap, pstat->tm);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_OM_NAME,
+        strlen(OIC_JSON_OM_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Tag.");
+    cborEncoderResult = cbor_encode_int(&pstatMap, pstat->om);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Value.");
+
+    cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_SM_NAME,
+        strlen(OIC_JSON_SM_NAME));
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Tag.");
+    {
+        CborEncoder sm = { {.ptr = NULL }, .end = 0 };
+        cborEncoderResult = cbor_encoder_create_array(&pstatMap, &sm, pstat->smLen);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Array.");
 
-    cJSON_AddStringToObject(jsonPstat, OIC_JSON_DEVICE_ID_NAME, base64Buff);
-    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_COMMIT_HASH_NAME, pstat->commitHash);
-    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_CM_NAME, (int)pstat->cm);
-    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_TM_NAME, (int)pstat->tm);
-    cJSON_AddNumberToObject(jsonPstat, OIC_JSON_OM_NAME, (int)pstat->om);
+        for (size_t i = 0; i < pstat->smLen; i++)
+        {
+            cborEncoderResult = cbor_encode_int(&sm, pstat->sm[i]);
+            VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Value in Array.");
+        }
+        cborEncoderResult = cbor_encoder_close_container(&pstatMap, &sm);
+        VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing SM Array.");
+    }
+    cborEncoderResult = cbor_encoder_close_container(&encoder, &pstatMap);
+    VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Closing PSTAT Map.");
+
+    *size = encoder.ptr - outPayload;
+    *payload = outPayload;
+    ret = OC_STACK_OK;
 
-    cJSON_AddItemToObject(jsonPstat, OIC_JSON_SM_NAME, jsonSmArray = cJSON_CreateArray());
-    VERIFY_NON_NULL(TAG, jsonSmArray, INFO);
-    for (size_t i = 0; i < pstat->smLen; i++)
+exit:
+    if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
     {
-        cJSON_AddItemToArray(jsonSmArray, cJSON_CreateNumber((int )pstat->sm[i]));
+        // reallocate and try again!
+        OICFree(outPayload);
+        // Since the allocated initial memory failed, double the memory.
+        cborLen += encoder.ptr - encoder.end;
+        cborEncoderResult = CborNoError;
+        ret = PstatToCBORPayload(pstat, payload, &cborLen);
     }
-    jsonStr = cJSON_Print(jsonRoot);
 
-exit:
-    if (jsonRoot)
+    if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
     {
-        cJSON_Delete(jsonRoot);
+        OICFree(outPayload);
+        outPayload = NULL;
+        *payload = NULL;
+        *size = 0;
+        ret = OC_STACK_ERROR;
     }
-    return jsonStr;
+
+    return ret;
 }
 
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr)
+OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t size,
+                                 OicSecPstat_t **secPstat)
 {
-    if(NULL == jsonStr)
+    if (NULL == cborPayload || NULL == secPstat || NULL != *secPstat)
     {
-        return NULL;
+        return OC_STACK_INVALID_PARAM;
     }
 
     OCStackResult ret = OC_STACK_ERROR;
+    *secPstat = NULL;
+
+    CborValue pstatCbor = { .parser = NULL };
+    CborParser parser = { .end = NULL };
+    CborError cborFindResult = CborNoError;
+    int cborLen = size;
+    if (0 == size)
+    {
+        cborLen = CBOR_SIZE;
+    }
+    cbor_parser_init(cborPayload, cborLen, 0, &parser, &pstatCbor);
+    CborValue pstatMap = { .parser = NULL } ;
     OicSecPstat_t *pstat = NULL;
-    cJSON *jsonPstat = NULL;
-    cJSON *jsonObj = NULL;
-
-    unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
-    uint32_t outLen = 0;
-    B64Result b64Ret = B64_OK;
-
-    cJSON *jsonRoot = cJSON_Parse(jsonStr);
-    VERIFY_NON_NULL(TAG, jsonRoot, INFO);
-
-    jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME);
-    VERIFY_NON_NULL(TAG, jsonPstat, INFO);
-
-    pstat = (OicSecPstat_t*)OICCalloc(1, sizeof(OicSecPstat_t));
-    VERIFY_NON_NULL(TAG, pstat, INFO);
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_ISOP_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    VERIFY_SUCCESS(TAG, (cJSON_True == jsonObj->type || cJSON_False == jsonObj->type) , ERROR);
-    pstat->isOp = jsonObj->valueint;
-
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_DEVICE_ID_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
-    b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
-                sizeof(base64Buff), &outLen);
-    VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(pstat->deviceID.id)), ERROR);
-    memcpy(pstat->deviceID.id, base64Buff, outLen);
-
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
-    pstat->commitHash  = jsonObj->valueint;
-
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_CM_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
-    pstat->cm  = (OicSecDpm_t)jsonObj->valueint;
-
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
-    pstat->om  = (OicSecDpom_t)jsonObj->valueint;
-
-    jsonObj = cJSON_GetObjectItem(jsonPstat, OIC_JSON_SM_NAME);
-    VERIFY_NON_NULL(TAG, jsonObj, ERROR);
-    if (cJSON_Array == jsonObj->type)
+    char *name = NULL;
+    cborFindResult = cbor_value_enter_container(&pstatCbor, &pstatMap);
+    VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Map.");
+
+    pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
+    VERIFY_NON_NULL(TAG, pstat, ERROR);
+
+    while (cbor_value_is_valid(&pstatMap))
     {
-        pstat->smLen = (size_t)cJSON_GetArraySize(jsonObj);
-        size_t idxx = 0;
-        VERIFY_SUCCESS(TAG, pstat->smLen != 0, ERROR);
-        pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
-        VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
-        do
+        size_t len = 0;
+        cborFindResult = cbor_value_dup_text_string(&pstatMap, &name, &len, NULL);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Name Value.");
+        cborFindResult = cbor_value_advance(&pstatMap);
+        VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Advancing PSTAT MAP.");
+
+        CborType type = cbor_value_get_type(&pstatMap);
+
+        if (0 == strcmp(OIC_JSON_ISOP_NAME, name))
+        {
+            cborFindResult = cbor_value_get_boolean(&pstatMap, &pstat->isOp);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ISOP Name.");
+        }
+
+        if (0 == strcmp(OIC_JSON_DEVICE_ID_NAME, name))
+        {
+            uint8_t *subjectId = NULL;
+            cborFindResult = cbor_value_dup_byte_string(&pstatMap, &subjectId, &len, NULL);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SubjectId.");
+            memcpy(pstat->deviceID.id, subjectId, len);
+            OICFree(subjectId);
+        }
+
+        if (0 == strcmp(OIC_JSON_COMMIT_HASH_NAME, name))
+        {
+            cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->commitHash);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CommitHash.");
+        }
+
+        if (0 == strcmp(OIC_JSON_CM_NAME, name))
+        {
+            cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->cm);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CM Name.");
+        }
+
+        if (0 == strcmp(OIC_JSON_OM_NAME, name))
+        {
+            cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->om);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OM Name.");
+        }
+
+        if (0 == strcmp(OIC_JSON_SM_NAME, name))
+        {
+            CborValue sm = { .parser = NULL };
+
+            cborFindResult = cbor_value_get_array_length(&pstatMap, &pstat->smLen);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM Len Array.");
+            VERIFY_SUCCESS(TAG, pstat->smLen != 0, ERROR);
+
+            pstat->sm = (OicSecDpom_t *)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
+            VERIFY_NON_NULL(TAG, pstat->sm, ERROR);
+
+            cborFindResult = cbor_value_enter_container(&pstatMap, &sm);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM Container.");
+
+            int i = 0;
+            while (cbor_value_is_valid(&sm))
+            {
+                cborFindResult = cbor_value_get_int(&sm, (int *)&pstat->sm[i++]);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM Value.");
+                cborFindResult = cbor_value_advance(&sm);
+                VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM Array.");
+            }
+        }
+        if (CborMapType != type && cbor_value_is_valid(&pstatMap))
         {
-            cJSON *jsonSm = cJSON_GetArrayItem(jsonObj, idxx);
-            VERIFY_NON_NULL(TAG, jsonSm, ERROR);
-            pstat->sm[idxx] = (OicSecDpom_t)jsonSm->valueint;
-        }while ( ++idxx < pstat->smLen);
+            cborFindResult = cbor_value_advance(&pstatMap);
+            VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT MAP.");
+        }
+        OICFree(name);
+        name = NULL;
     }
+
+    *secPstat = pstat;
     ret = OC_STACK_OK;
 
 exit:
-    cJSON_Delete(jsonRoot);
-    if (OC_STACK_OK != ret)
+    if (CborNoError != cborFindResult)
     {
-        OIC_LOG (ERROR, TAG, "JSONToPstatBin failed");
+        OIC_LOG(ERROR, TAG, "CBORPayloadToPstat failed");
         DeletePstatBinData(pstat);
         pstat = NULL;
+        ret = OC_STACK_ERROR;
     }
-    return pstat;
+    if (name)
+    {
+        OICFree(name);
+    }
+    return ret;
 }
 
 /**
  * Function to update persistent storage
  */
-static bool UpdatePersistentStorage(OicSecPstat_t * pstat)
+static bool UpdatePersistentStorage(OicSecPstat_t *pstat)
 {
     bool bRet = false;
 
-    if (pstat)
+    size_t size = 0;
+    uint8_t *cborPayload = NULL;
+    OCStackResult ret = PstatToCBORPayload(pstat, &cborPayload, &size);
+    if (OC_STACK_OK == ret)
     {
-        // Convert pstat data into JSON for update to persistent storage
-        char *jsonStr = BinToPstatJSON(pstat);
-        if (jsonStr)
+        if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size))
         {
-            cJSON *jsonPstat = cJSON_Parse(jsonStr);
-            OICFree(jsonStr);
-
-            if (jsonPstat &&
-                (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat)))
-            {
-                bRet = true;
-            }
-            cJSON_Delete(jsonPstat);
+            bRet = true;
         }
+        OICFree(cborPayload);
     }
 
     return bRet;
@@ -227,16 +338,19 @@ static bool UpdatePersistentStorage(OicSecPstat_t * pstat)
  */
 static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest)
 {
-    OIC_LOG (INFO, TAG, "HandlePstatGetRequest  processing GET request");
-   // Convert ACL data into JSON for transmission
-    char* jsonStr = BinToPstatJSON(gPstat);
+    OIC_LOG(INFO, TAG, "HandlePstatGetRequest  processing GET request");
+
+    // Convert ACL data into CBOR for transmission
+    size_t size = 0;
+    uint8_t *payload = NULL;
+    OCStackResult res = PstatToCBORPayload(gPstat, &payload, &size);
 
-    // A device should always have a default pstat. Therefore, jsonStr should never be NULL.
-    OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
+    // A device should always have a default pstat. Therefore, payload should never be NULL.
+    OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR;
 
     // Send response payload to request originator
-    SendSRMResponse(ehRequest, ehRet, jsonStr);
-    OICFree(jsonStr);
+    SendSRMCBORResponse(ehRequest, ehRet, payload);
+    OICFree(payload);
     return ehRet;
 }
 
@@ -249,57 +363,56 @@ static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest
 static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest *ehRequest)
 {
     OCEntityHandlerResult ehRet = OC_EH_ERROR;
-    cJSON *postJson = NULL;
-    OIC_LOG (INFO, TAG, "HandlePstatPutRequest  processing PUT request");
+    OIC_LOG(INFO, TAG, "HandlePstatPutRequest  processing PUT request");
+    OicSecPstat_t *pstat = NULL;
 
     if (ehRequest->resource)
     {
-        postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData);
-        VERIFY_NON_NULL(TAG, postJson, INFO);
-        cJSON *jsonPstat = cJSON_GetObjectItem(postJson, OIC_JSON_PSTAT_NAME);
-        VERIFY_NON_NULL(TAG, jsonPstat, INFO);
-        cJSON *commitHashJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME);
-        uint16_t commitHash = 0;
-        if (commitHashJson)
-        {
-            commitHash = commitHashJson->valueint;
-        }
-        cJSON *tmJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME);
-        if (tmJson && gPstat)
+        uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData1;
+        VERIFY_NON_NULL(TAG, payload, ERROR);
+
+        OCStackResult ret = CBORPayloadToPstat(payload, CBOR_SIZE, &pstat);
+        OICFree(payload);
+        VERIFY_NON_NULL(TAG, pstat, ERROR);
+        if (OC_STACK_OK == ret)
         {
-            gPstat->tm = (OicSecDpm_t)tmJson->valueint;
-            if(0 == tmJson->valueint && gPstat->commitHash == commitHash)
+            if (pstat->tm)
             {
-                gPstat->isOp = true;
-                gPstat->cm = NORMAL;
-                OIC_LOG (INFO, TAG, "CommitHash is valid and isOp is TRUE");
-            }
-            else
-            {
-                OIC_LOG (INFO, TAG, "CommitHash is not valid");
+                gPstat->tm = pstat->tm;
+                if(0 == pstat->tm && gPstat->commitHash == pstat->commitHash)
+                {
+                    gPstat->isOp = true;
+                    gPstat->cm = NORMAL;
+                    OIC_LOG (INFO, TAG, "CommitHash is valid and isOp is TRUE");
+                }
+                else
+                {
+                    OIC_LOG(DEBUG, TAG, "CommitHash is not valid");
+                }
             }
-        }
-        cJSON *omJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME);
-        if (omJson && gPstat)
-        {
-            /*
-             * Check if the operation mode is in the supported provisioning services
-             * operation mode list.
-             */
-            for(size_t i=0; i< gPstat->smLen; i++)
+            if (pstat->om && gPstat)
             {
-                if(gPstat->sm[i] == (unsigned int)omJson->valueint)
+                /*
+                 * Check if the operation mode is in the supported provisioning services
+                 * operation mode list.
+                 */
+                for(size_t i=0; i< gPstat->smLen; i++)
                 {
-                    gPstat->om = (OicSecDpom_t)omJson->valueint;
-                    break;
+                    if(gPstat->sm[i] == pstat->om)
+                    {
+                        gPstat->om = pstat->om;
+                        break;
+                    }
                 }
             }
+            // Convert pstat data into CBOR for update to persistent storage
+            if(UpdatePersistentStorage(gPstat))
+            {
+                ehRet = OC_EH_OK;
+            }
         }
-        // Convert pstat data into JSON for update to persistent storage
-        if(UpdatePersistentStorage(gPstat))
-        {
-            ehRet = OC_EH_OK;
-        }
+
+        OICFree(payload);
     }
  exit:
     if(OC_EH_OK != ehRet)
@@ -313,11 +426,11 @@ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest
     }
 
     //Send payload to request originator
-    if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL))
+    if(OC_STACK_OK != SendSRMCBORResponse(ehRequest, ehRet, NULL))
     {
         OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
     }
-    cJSON_Delete(postJson);
+    DeletePstatBinData(pstat);
     return ehRet;
 }
 
@@ -333,7 +446,7 @@ OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
     // This method will handle REST request (GET/POST) for /oic/sec/pstat
     if (flag & OC_REQUEST_FLAG)
     {
-        OIC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG");
+        OIC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
         switch (ehRequest->method)
         {
             case OC_REST_GET:
@@ -344,7 +457,7 @@ OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
                 break;
             default:
                 ehRet = OC_EH_ERROR;
-                SendSRMResponse(ehRequest, ehRet, NULL);
+                SendSRMCBORResponse(ehRequest, ehRet, NULL);
                 break;
         }
     }
@@ -356,71 +469,70 @@ OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
  */
 OCStackResult CreatePstatResource()
 {
-    OCStackResult ret;
+    OCStackResult ret = OCCreateResource(&gPstatHandle,
+                                         OIC_RSRC_TYPE_SEC_PSTAT,
+                                         OIC_MI_DEF,
+                                         OIC_RSRC_PSTAT_URI,
+                                         PstatEntityHandler,
+                                         NULL,
+                                         OC_RES_PROP_NONE);
 
-    ret = OCCreateResource(&gPstatHandle,
-                           OIC_RSRC_TYPE_SEC_PSTAT,
-                           OIC_MI_DEF,
-                           OIC_RSRC_PSTAT_URI,
-                           PstatEntityHandler,
-                           NULL,
-                           OC_RES_PROP_NONE);
-
-    if (ret != OC_STACK_OK)
+    if (OC_STACK_OK != ret)
     {
-        OIC_LOG (FATAL, TAG, "Unable to instantiate pstat resource");
+        OIC_LOG(FATAL, TAG, "Unable to instantiate pstat resource");
         DeInitPstatResource();
     }
     return ret;
 }
 
 /**
- * Post ACL hander update the commitHash during ACL provisioning.
- */
-void SetCommitHash(uint16_t commitHash)
-{
-    gPstat->commitHash = commitHash;
-}
-
-/**
- * Get the default value
- * @retval  the gDefaultPstat pointer
+ * Get the default value.
+ *
+ * @return the gDefaultPstat pointer.
  */
 static OicSecPstat_t* GetPstatDefault()
 {
     return &gDefaultPstat;
 }
 
-/**
- * Initialize pstat resource by loading data from persistent storage.
- *
- * @retval  OC_STACK_OK for Success, otherwise some error value
- */
 OCStackResult InitPstatResource()
 {
     OCStackResult ret = OC_STACK_ERROR;
 
     // Read Pstat resource from PS
-    char* jsonSVRDatabase = GetSVRDatabase();
-    if (jsonSVRDatabase)
+    uint8_t *data = NULL;
+    size_t size = 0;
+    ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &data, &size);
+    // If database read failed
+    if (OC_STACK_OK != ret)
+    {
+        OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
+    }
+    if (data)
     {
-        // Convert JSON Pstat into binary format
-        gPstat = JSONToPstatBin(jsonSVRDatabase);
+        // Read ACL resource from PS
+        ret = CBORPayloadToPstat(data, size, &gPstat);
     }
     /*
      * If SVR database in persistent storage got corrupted or
      * is not available for some reason, a default pstat is created
      * which allows user to initiate pstat provisioning again.
      */
-    if(!jsonSVRDatabase || !gPstat)
+    if ((OC_STACK_OK != ret) || !data || !gPstat)
     {
         gPstat = GetPstatDefault();
     }
+    VERIFY_NON_NULL(TAG, gPstat, FATAL);
 
     // Instantiate 'oic.sec.pstat'
     ret = CreatePstatResource();
 
-    OICFree(jsonSVRDatabase);
+exit:
+    OICFree(data);
+    if (OC_STACK_OK != ret)
+    {
+        DeInitPstatResource();
+    }
     return ret;
 }
 
@@ -439,7 +551,6 @@ OCStackResult DeInitPstatResource()
     return OCDeleteResource(gPstatHandle);
 }
 
-
 /**
  * Function to restore pstat resurce to initial status.
  * This function will use in case of error while ownership transfer
@@ -458,7 +569,7 @@ void RestorePstatToInitState()
             gPstat->sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
         }
 
-        if(!UpdatePersistentStorage(gPstat))
+        if (!UpdatePersistentStorage(gPstat))
         {
             OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage");
         }
index 03c8a68..16999bc 100644 (file)
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
 
+#include <unistd.h>
 #include "gtest/gtest.h"
+
+#include "ocpayload.h"
 #include "ocstack.h"
-#include "resourcemanager.h"
-#include "pstatresource.h"
 #include "oic_malloc.h"
-#include "cJSON.h"
-#include "base64.h"
 #include "cainterface.h"
+#include "resourcemanager.h"
 #include "secureresourcemanager.h"
-#include "srmtestcommon.h"
-#include "ocpayload.h"
-#include <unistd.h>
-#ifdef __cplusplus
-extern "C" {
-#endif
-//Declare Provision status resource methods for testing
-OCStackResult CreatePstatResource();
-OCEntityHandlerResult PstatEntityHandler (OCEntityHandlerFlag flag,
-                                        OCEntityHandlerRequest * ehRequest);
-char * BinToPstatJSON(const OicSecPstat_t * pstat);
-OicSecPstat_t * JSONToPstatBin(const char * jsonStr);
-const char* UNIT_TEST_JSON_FILE_NAME = "oic_unittest.json";
-#ifdef __cplusplus
-}
-#endif
+#include "pstatresource.h"
+#include "security_internals.h"
 
-//InitPstatResource Tests
-TEST(InitPstatResourceTest, InitPstatResource)
+// InitPstatResource Tests
+TEST(PstatResourceTest, InitPstatResource)
 {
-    EXPECT_EQ(OC_STACK_INVALID_PARAM,  InitPstatResource());
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, InitPstatResource());
 }
 
-
-//DeInitPstatResource Tests
-TEST(DeInitPstatResourceTest, DeInitPstatResource)
+// DeInitPstatResource Tests
+TEST(PstatResourceTest, DeInitPstatResource)
 {
     EXPECT_EQ(OC_STACK_INVALID_PARAM, DeInitPstatResource());
 }
 
 //CreatePstatResource Tests
-TEST(CreatePstatResourceTest, CreatePstatResource)
+TEST(PstatResourceTest, CreatePstatResource)
 {
-    EXPECT_EQ(OC_STACK_INVALID_PARAM,  CreatePstatResource());
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, CreatePstatResource());
 }
 
 //PstatEntityHandler Tests
-TEST(PstatEntityHandlerTest, PstatEntityHandlerWithDummyRequest)
+TEST(PstatResourceTest, PstatEntityHandlerWithDummyRequest)
 {
     OCEntityHandlerRequest req;
     EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
 }
 
-TEST(PstatEntityHandlerTest, PstatEntityHandlerWithPostRequest)
+TEST(PstatResourceTest, PstatEntityHandlerWithPostRequest)
 {
+    OicSecPstat_t *defaultPstat = (OicSecPstat_t *) OICCalloc(1, sizeof(*defaultPstat));
+    ASSERT_TRUE(defaultPstat != NULL);
+    defaultPstat->isOp = false;
+    uint8_t deviceId[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x69, 0x64, 0x00,
+                          0x00, 0x00, 0x00, 0x00, 0x18, 0x5a, 0x9f};
+    memcpy(defaultPstat->deviceID.id, deviceId, sizeof(deviceId));
+    EXPECT_EQ(sizeof(defaultPstat->deviceID.id), sizeof(deviceId));
+    defaultPstat->commitHash = 1234;
+    defaultPstat->cm = (OicSecDpm_t) 63;
+    defaultPstat->tm = (OicSecDpm_t) 48;
+    defaultPstat->om = (OicSecDpom_t) 0;
+    defaultPstat->smLen = 2;
+    defaultPstat->sm = (OicSecDpom_t *)OICCalloc(defaultPstat->smLen, sizeof(*defaultPstat->sm));
+    ASSERT_TRUE(defaultPstat->sm != NULL);
+    defaultPstat->sm[0] = (OicSecDpom_t) 3;
+    defaultPstat->sm[1] = (OicSecDpom_t) 1;
+    size_t size = 0;
+    uint8_t *cbor = NULL;
+    EXPECT_EQ(OC_STACK_OK, PstatToCBORPayload(defaultPstat, &cbor, &size));
+    DeletePstatBinData(defaultPstat);
+    ASSERT_TRUE(cbor != NULL);
+
     OCEntityHandlerRequest req;
     req.method = OC_REST_POST;
-    req.payload = reinterpret_cast<OCPayload*>(
-            OCSecurityPayloadCreate("{ \"pstat\": { \"tm\": 0, \"om\": 3 }}"));
+    req.payload = (OCPayload *) OCSecurityPayloadCBORCreate(cbor);
     EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_REQUEST_FLAG, &req));
     OCPayloadDestroy(req.payload);
 }
 
-TEST(PstatEntityHandlerTest, PstatEntityHandlerInvalidRequest)
+TEST(PstatResourceTest, PstatEntityHandlerInvalidRequest)
 {
     EXPECT_EQ(OC_EH_ERROR, PstatEntityHandler(OCEntityHandlerFlag::OC_OBSERVE_FLAG, NULL));
 }
 
-//BinToJSON Tests
-TEST(BinToJSONTest, BinToNullJSON)
+TEST(PstatResourceTest, PstatToCBORPayloadNULL)
 {
-    char* value = BinToPstatJSON(NULL);
-    EXPECT_TRUE(value == NULL);
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(NULL, NULL, 0));
+    // Case when cbor payload is NULL
+    OicSecPstat_t pstat;
+    size_t size = 10;
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, NULL, &size));
+    uint8_t *cborPayload = (uint8_t *) OICCalloc(1, size);
+    ASSERT_TRUE(NULL != cborPayload);
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, &cborPayload, &size));
+    OICFree(cborPayload);
+    cborPayload = NULL;
+    // Case when pstat is zero.
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(NULL, &cborPayload, &size));
+    // Case when size is 0.
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, PstatToCBORPayload(&pstat, &cborPayload, 0));
+    OICFree(cborPayload);
 }
 
-TEST(JSONToBinTest, NullJSONToBin)
+TEST(PstatResourceTest, CBORPayloadToPstat)
 {
-    OicSecPstat_t *pstat1 = JSONToPstatBin(NULL);
-    EXPECT_TRUE(pstat1 == NULL);
+    EXPECT_EQ(OC_STACK_INVALID_PARAM, CBORPayloadToPstat(NULL, 0, NULL));
 }
 
-TEST(MarshalingAndUnMarshalingTest, BinToPstatJSONAndJSONToPstatBin)
+TEST(PstatResourceTest, PstatToCBORPayloadAndCBORPayloadToPstat)
 {
-    const char* id = "ZGV2aWNlaWQAAAAAABhanw==";
     OicSecPstat_t pstat;
     pstat.cm = NORMAL;
     pstat.commitHash = 0;
-    uint32_t outLen = 0;
-    unsigned char base64Buff[sizeof(((OicUuid_t*) 0)->id)] = {};
-    EXPECT_EQ(B64_OK, b64Decode(id, strlen(id), base64Buff, sizeof(base64Buff), &outLen));
-    memcpy(pstat.deviceID.id, base64Buff, outLen);
+    uint8_t deviceId[] = {0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x69, 0x64, 0x00,
+                          0x00, 0x00, 0x00, 0x00, 0x18, 0x5a, 0x9f};
+    memcpy(pstat.deviceID.id, deviceId, sizeof(deviceId));
     pstat.isOp = true;
     pstat.tm = NORMAL;
     pstat.om = SINGLE_SERVICE_CLIENT_DRIVEN;
     pstat.smLen = 2;
-    pstat.sm = (OicSecDpom_t*)OICCalloc(pstat.smLen, sizeof(OicSecDpom_t));
-    if(!pstat.sm)
-    {
-        FAIL() << "Failed to allocate the pstat.sm";
-    }
+    pstat.sm = (OicSecDpom_t*)OICCalloc(pstat.smLen, sizeof(pstat.sm));
+    ASSERT_TRUE(NULL != pstat.sm);
     pstat.sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
     pstat.sm[1] = SINGLE_SERVICE_SERVER_DRIVEN;
-    char* jsonPstat = BinToPstatJSON(&pstat);
-    if(!jsonPstat)
+
+    size_t size = 0;
+    uint8_t *cbor = NULL;
+    EXPECT_EQ(OC_STACK_OK, PstatToCBORPayload(&pstat, &cbor, &size));
+    if (!cbor)
     {
         OICFree(pstat.sm);
-        FAIL() << "Failed to convert BinToPstatJSON";
+        FAIL() << "Failed to convert PstatToCBORPayload";
         return;
     }
-    printf("BinToJSON Dump:\n%s\n\n", jsonPstat);
-    EXPECT_TRUE(jsonPstat != NULL);
-    OicSecPstat_t *pstat1 = JSONToPstatBin(jsonPstat);
-    EXPECT_TRUE(pstat1 != NULL);
-    if(pstat1)
-    {
-        OICFree(pstat1->sm);
-    }
-    OICFree(pstat1);
-    OICFree(jsonPstat);
-    OICFree(pstat.sm);
-}
-
-TEST(PstatTests, JSONMarshalliingTests)
-{
-    char *jsonStr1 = ReadFile(UNIT_TEST_JSON_FILE_NAME);
-    if (NULL != jsonStr1)
-    {
-        cJSON_Minify(jsonStr1);
-        /* Workaround : cJSON_Minify does not remove all the unwanted characters
-         from the end. Here is an attempt to remove those characters */
-        int len = strlen(jsonStr1);
-        while (len > 0)
-        {
-            if (jsonStr1[--len] == '}')
-            {
-                break;
-            }
-        }
-        jsonStr1[len + 1] = 0;
-
-        OicSecPstat_t* pstat = JSONToPstatBin(jsonStr1);
-        EXPECT_TRUE(NULL != pstat);
-
-        char* jsonStr2 = BinToPstatJSON(pstat);
-        EXPECT_STRNE(jsonStr1, jsonStr2);
+    ASSERT_TRUE(NULL != cbor);
+    OicSecPstat_t *pstat1 = NULL;
+    EXPECT_EQ(OC_STACK_OK, CBORPayloadToPstat(cbor, size, &pstat1));
+    ASSERT_TRUE(NULL != pstat1);
+    EXPECT_EQ(pstat.commitHash, pstat1->commitHash);
+    EXPECT_EQ(pstat.isOp, pstat1->isOp);
+    EXPECT_EQ(pstat.tm, pstat1->tm);
+    EXPECT_EQ(pstat.om, pstat1->om);
+    EXPECT_EQ(pstat.smLen, pstat1->smLen);
+    EXPECT_EQ(pstat.sm[0], pstat1->sm[0]);
+    EXPECT_EQ(pstat.sm[1], pstat1->sm[1]);
 
-        OICFree(jsonStr1);
-        OICFree(jsonStr2);
-        OICFree(pstat);
-   }
-    else
-    {
-        printf("Please copy %s into unittest folder\n", UNIT_TEST_JSON_FILE_NAME);
-    }
+    DeletePstatBinData(pstat1);
+    OICFree(cbor);
+    OICFree(pstat.sm);
 }
index 82a4674..ad076d0 100755 (executable)
@@ -102,14 +102,15 @@ void OCFreeOCStringLL(OCStringLL* ll);
 
 static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* rootValue)
 {
-    OCStackResult ret = OC_STACK_ERROR;
-    CborError err;
+    OCStackResult ret = OC_STACK_INVALID_PARAM;
+    *outPayload = NULL;
     char *securityData = NULL;
-    CborValue strVal;
-
+    uint8_t *securityData1 = NULL;
+    CborError err;
     VERIFY_PARAM_NON_NULL(TAG, outPayload, "Invalid parameter outPayload");
     VERIFY_PARAM_NON_NULL(TAG, rootValue, "Invalid parameter rootValue");
-    *outPayload = NULL;
+
+    CborValue strVal;
 
     err = cbor_value_enter_container(rootValue, &strVal);
     VERIFY_CBOR_SUCCESS(TAG, err, "Failed entering container");
@@ -123,6 +124,14 @@ static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* r
         VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Invalid cbor");
         ret = OC_STACK_OK;
     }
+    else if (cbor_value_is_byte_string(&strVal))
+    {
+        size_t len = 0;
+        err = cbor_value_dup_byte_string(&strVal, &securityData1, &len, NULL);
+        VERIFY_CBOR_SUCCESS(TAG, err, "Failed reading security data");
+        *outPayload = (OCPayload *)OCSecurityPayloadCBORCreate(securityData1);
+        VERIFY_PARAM_NON_NULL(TAG, *outPayload, "Failed Creating Security Cbor.");
+    }
     else if(cbor_value_is_valid(&strVal))
     {
         ret = OC_STACK_OK;
@@ -134,8 +143,8 @@ static OCStackResult OCParseSecurityPayload(OCPayload** outPayload, CborValue* r
 
 exit:
     OICFree(securityData);
+    OICFree(securityData1);
     return ret;
-
 }
 
 static char* InPlaceStringTrim(char* str)