From: Habib Virji Date: Thu, 18 Feb 2016 20:18:33 +0000 (+0000) Subject: SVC payload conversion from JSON to CBOR X-Git-Tag: 1.2.0+RC1~355^2^2~216 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2e43eb2a802ba90f4cc3b123cdcf24b6992f031a;p=platform%2Fupstream%2Fiotivity.git SVC payload conversion from JSON to CBOR Converts SVC payload conversion from JSON to CBOR directly using tinycbor library. - SVC unit test is updated to match new changes. - Persistant storage format: { "acl": , "svc": } Change-Id: I1a5b5600260b8965e468844636f6d77274688d29 Signed-off-by: Habib Virji Reviewed-on: https://gerrit.iotivity.org/gerrit/5047 Tested-by: jenkins-iotivity Reviewed-by: Randeep Singh Reviewed-on: https://gerrit.iotivity.org/gerrit/5771 --- diff --git a/resource/csdk/security/include/internal/psinterface.h b/resource/csdk/security/include/internal/psinterface.h index 9e6ffb6..34a7822 100644 --- a/resource/csdk/security/include/internal/psinterface.h +++ b/resource/csdk/security/include/internal/psinterface.h @@ -21,7 +21,7 @@ #ifndef IOTVT_SRM_PSI_H #define IOTVT_SRM_PSI_H -struct cJSON; +#include "cJSON.h" /** * Reads the Secure Virtual Database from PS into dynamically allocated diff --git a/resource/csdk/security/include/internal/security_internals.h b/resource/csdk/security/include/internal/security_internals.h index 6f969e1..4a92ad1 100644 --- a/resource/csdk/security/include/internal/security_internals.h +++ b/resource/csdk/security/include/internal/security_internals.h @@ -26,8 +26,27 @@ OCEntityHandlerResult ACLEntityHandler(OCEntityHandlerFlag flag, OCStackResult SetDefaultACL(OicSecAcl_t *acl); +/** + * Converts CBOR payload to SVC. + * + * @param cborPayload is the svc payload cbor value that neds to be converted. + * @param cborSize of the cborPayload. In case size is not known, it is 0. + * @param svc is the value that is initialized. It is NULL in case of error. + * + * @return ::OC_STACK_OK in case successful. ::OC_STACK_INVALID_PARAM if one of + * the passed parameter is NULL. ::OC_STACK_ERROR in case of error. + */ +OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size, OicSecSvc_t **svc); + +/** + * Deletes the passed initialized reference to @ref OicSecSvc_t. + * + * @param svc is the reference to be deleted. + */ +void DeleteSVCList(OicSecSvc_t* svc); + #ifdef __cplusplus } #endif -#endif //IOTVT_SRM_SECURITY_INTERNALS_H \ No newline at end of file +#endif //IOTVT_SRM_SECURITY_INTERNALS_H diff --git a/resource/csdk/security/include/internal/svcresource.h b/resource/csdk/security/include/internal/svcresource.h index 9db42c5..e77329d 100644 --- a/resource/csdk/security/include/internal/svcresource.h +++ b/resource/csdk/security/include/internal/svcresource.h @@ -40,19 +40,23 @@ OCStackResult InitSVCResource(); void DeInitSVCResource(); /** - * This function converts SVC data into JSON format. - * Caller needs to invoke 'free' when done using - * returned string. - * @param svc instance of OicSecSvc_t structure. + * This function converts SVC data into CBOR format. + * Caller needs to invoke 'free' when done using returned string. * - * @retval pointer to SVC in json format. + * @param svc is the instance of @ref OicSecSvc_t structure. In case of NULL it + * will return ::OC_STACK_INVALID_PARAM. + * @param cborPayload is the converted cbor value of SVC structure. + * @param cborSize is the size of the cbor payload. This value is the size of the + * cborPayload. It should not be NON-NULL value. + * + * @return ::OC_STACK_OK for Success. ::OC_STACK_INVALID in case of invalid parameters. + * ::OC_STACK_ERROR in case of error in converting to cbor. */ -char* BinToSvcJSON(const OicSecSvc_t * svc); + OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload, + size_t *cborSize); #ifdef __cplusplus } #endif #endif //IOTVT_SRM_SVCR_H - - diff --git a/resource/csdk/security/src/psinterface.c b/resource/csdk/security/src/psinterface.c index a27817b..73d4a21 100644 --- a/resource/csdk/security/src/psinterface.c +++ b/resource/csdk/security/src/psinterface.c @@ -250,6 +250,8 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat goto exit; } OICFree(name); + cborFindResult = cbor_value_advance(&cborValue); + VERIFY_SUCCESS(TAG, cborFindResult == CborNoError, ERROR); } } // return everything in case rsrcName is NULL @@ -262,7 +264,7 @@ OCStackResult GetSecureVirtualDatabaseFromPS(const char *rsrcName, uint8_t **dat } else { - OIC_LOG (ERROR, TAG, "Unable to open SVR database to read!! "); + OIC_LOG(ERROR, TAG, "Unable to open SVR database to read!! "); } exit: diff --git a/resource/csdk/security/src/svcresource.c b/resource/csdk/security/src/svcresource.c index bb55450..af92133 100644 --- a/resource/csdk/security/src/svcresource.c +++ b/resource/csdk/security/src/svcresource.c @@ -17,24 +17,35 @@ // limitations under the License. // //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +#include +#include #include "ocstack.h" -#include "logger.h" +#include "ocpayload.h" #include "oic_malloc.h" -#include "cJSON.h" -#include "base64.h" +#include "utlist.h" +#include "payload_logging.h" #include "resourcemanager.h" #include "psinterface.h" #include "svcresource.h" -#include "utlist.h" #include "srmresourcestrings.h" #include "srmutility.h" -#include -#include + +#include "security_internals.h" #define TAG "SRM-SVC" -OicSecSvc_t *gSvc = NULL; +/** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory. + * The value of payload size is increased until reaching belox max cbor size. */ +static const uint8_t CBOR_SIZE = 255; + +/** Max cbor size payload. */ +static const uint16_t CBOR_MAX_SIZE = 4400; + +/** SVC Map size - Number of mandatory items. */ +static const uint8_t SVC_MAP_SIZE = 3; + +static OicSecSvc_t *gSvc = NULL; static OCResourceHandle gSvcHandle = NULL; void DeleteSVCList(OicSecSvc_t* svc) @@ -55,189 +66,260 @@ void DeleteSVCList(OicSecSvc_t* svc) } } -/* - * This internal method converts SVC data into JSON format. - * - * Note: Caller needs to invoke 'free' when finished done using - * return string. - */ -char * BinToSvcJSON(const OicSecSvc_t * svc) +static size_t svcElementsCount(const OicSecSvc_t *secSvc) +{ + size_t size = 0; + for (const OicSecSvc_t *svc = secSvc; svc; svc = svc->next) + { + size++; + } + return size; +} + +OCStackResult SVCToCBORPayload(const OicSecSvc_t *svc, uint8_t **cborPayload, + size_t *cborSize) { - cJSON *jsonRoot = NULL; - char *jsonStr = NULL; + if (NULL == svc || NULL == cborPayload || NULL != *cborPayload || NULL == cborSize) + { + return OC_STACK_INVALID_PARAM; + } - if (svc) + size_t cborLen = *cborSize; + if (0 == cborLen) { - jsonRoot = cJSON_CreateObject(); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + cborLen = CBOR_SIZE; + } + *cborPayload = NULL; + *cborSize = 0; - cJSON *jsonSvcArray = NULL; - cJSON_AddItemToObject (jsonRoot, OIC_JSON_SVC_NAME, jsonSvcArray = cJSON_CreateArray()); - VERIFY_NON_NULL(TAG, jsonSvcArray, ERROR); + CborError cborEncoderResult = CborNoError; + OCStackResult ret = OC_STACK_ERROR; + CborEncoder encoder = { {.ptr = NULL }, .end = 0 }; + CborEncoder svcArray = { {.ptr = NULL }, .end = 0 }; - while(svc) - { - char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; + uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen); + VERIFY_NON_NULL(TAG, outPayload, ERROR); - cJSON *jsonSvc = cJSON_CreateObject(); + cbor_encoder_init(&encoder, outPayload, cborLen, 0); - // Service Device Identity - outLen = 0; - b64Ret = b64Encode(svc->svcdid.id, sizeof(OicUuid_t), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); - cJSON_AddStringToObject(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID, base64Buff ); + // Create SVC Array + cborEncoderResult = cbor_encoder_create_array(&encoder, &svcArray, + svcElementsCount(svc)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Array."); - // Service Type - cJSON_AddNumberToObject (jsonSvc, OIC_JSON_SERVICE_TYPE, svc->svct); + while (svc) + { + CborEncoder svcMap = { {.ptr = NULL }, .end = 0}; + cborEncoderResult = cbor_encoder_create_map(&svcArray, &svcMap, SVC_MAP_SIZE); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Create SVC Map."); + + // Service Device Identity + cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_DEVICE_ID, + strlen(OIC_JSON_SERVICE_DEVICE_ID)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Device Id."); + cborEncoderResult = cbor_encode_byte_string(&svcMap, (uint8_t *)svc->svcdid.id, + sizeof(svc->svcdid.id)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to "); + + // Service Type + cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_SERVICE_TYPE, + strlen(OIC_JSON_SERVICE_TYPE)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Tag."); + cborEncoderResult = cbor_encode_int(&svcMap, svc->svct); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Serv Type Value."); + + // Owners + cborEncoderResult = cbor_encode_text_string(&svcMap, OIC_JSON_OWNERS_NAME, + strlen(OIC_JSON_OWNERS_NAME)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Tag."); + CborEncoder owners = { {.ptr = NULL }, .end = 0 }; + cborEncoderResult = cbor_encoder_create_array(&svcMap, &owners, svc->ownersLen); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Array."); + for (size_t i = 0; i < svc->ownersLen; i++) + { + cborEncoderResult = cbor_encode_byte_string(&owners, (uint8_t *)svc->owners[i].id, + sizeof(svc->owners[i].id)); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Add SVC Owners Value."); + } + cborEncoderResult = cbor_encoder_close_container(&svcMap, &owners); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array."); - // Owners - cJSON *jsonOwnrArray = NULL; - cJSON_AddItemToObject (jsonSvc, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray()); - VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR); - for (unsigned int i = 0; i < svc->ownersLen; i++) - { - outLen = 0; + cborEncoderResult = cbor_encoder_close_container(&svcArray, &svcMap); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Map."); - b64Ret = b64Encode(svc->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); + svc = svc->next; + } - cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff)); - } + cborEncoderResult = cbor_encoder_close_container(&encoder, &svcArray); + VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed to Close SVC Array."); - // Attach current svc node to Svc Array - cJSON_AddItemToArray(jsonSvcArray, jsonSvc); - svc = svc->next; - } + *cborPayload = outPayload; + *cborSize = encoder.ptr - outPayload; + ret = OC_STACK_OK; - jsonStr = cJSON_PrintUnformatted(jsonRoot); +exit: + if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE)) + { + // reallocate and try again! + OICFree(outPayload); + outPayload = NULL; + // Since the allocated initial memory failed, double the memory. + cborLen += encoder.ptr - encoder.end; + cborEncoderResult = CborNoError; + ret = SVCToCBORPayload(svc, cborPayload, &cborLen); } -exit: - if (jsonRoot) + if (CborNoError != cborEncoderResult) { - cJSON_Delete(jsonRoot); + OICFree(outPayload); + outPayload = NULL; + *cborSize = 0; + *cborPayload = NULL; + ret = OC_STACK_ERROR; } - return jsonStr; + + return ret; } -/* - * This internal method converts JSON SVC into binary SVC. - */ -OicSecSvc_t * JSONToSvcBin(const char * jsonStr) +OCStackResult CBORPayloadToSVC(const uint8_t *cborPayload, size_t size, + OicSecSvc_t **secSvc) { + if (NULL == cborPayload || NULL == secSvc || NULL != *secSvc) + { + return OC_STACK_INVALID_PARAM; + } + + *secSvc = NULL; + OCStackResult ret = OC_STACK_ERROR; - OicSecSvc_t * headSvc = NULL; - OicSecSvc_t * prevSvc = NULL; - cJSON *jsonRoot = NULL; - cJSON *jsonSvcArray = NULL; - VERIFY_NON_NULL(TAG, jsonStr, ERROR); + CborValue svcCbor = { .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, &svcCbor); - jsonRoot = cJSON_Parse(jsonStr); - VERIFY_NON_NULL(TAG, jsonRoot, ERROR); + OicSecSvc_t *headSvc = NULL; - jsonSvcArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME); - VERIFY_NON_NULL(TAG, jsonSvcArray, INFO); + CborValue svcArray = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&svcCbor, &svcArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Array."); - if (cJSON_Array == jsonSvcArray->type) + while (cbor_value_is_valid(&svcArray)) { - int numSvc = cJSON_GetArraySize(jsonSvcArray); - int idx = 0; + CborValue svcMap = { .parser = NULL }; + cborFindResult = cbor_value_enter_container(&svcArray, &svcMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter SVC Map."); + + OicSecSvc_t *svc = (OicSecSvc_t *) OICCalloc(1, sizeof(OicSecSvc_t)); + VERIFY_NON_NULL(TAG, svc, ERROR); - VERIFY_SUCCESS(TAG, numSvc > 0, INFO); - do + while (cbor_value_is_valid(&svcMap)) { - cJSON *jsonSvc = cJSON_GetArrayItem(jsonSvcArray, idx); - VERIFY_NON_NULL(TAG, jsonSvc, ERROR); + char* name = NULL; + size_t len = 0; + cborFindResult = cbor_value_dup_text_string(&svcMap, &name, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name."); + cborFindResult = cbor_value_advance(&svcMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance."); - OicSecSvc_t *svc = (OicSecSvc_t*)OICCalloc(1, sizeof(OicSecSvc_t)); - VERIFY_NON_NULL(TAG, svc, ERROR); + CborType type = cbor_value_get_type(&svcMap); - headSvc = (headSvc) ? headSvc : svc; - if (prevSvc) + // Service Device Identity + if (0 == strcmp(OIC_JSON_SERVICE_DEVICE_ID, name)) { - prevSvc->next = svc; + uint8_t *subjectId = NULL; + cborFindResult = cbor_value_dup_byte_string(&svcMap, &subjectId, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SubjectId."); + memcpy(svc->svcdid.id, subjectId, len); + OICFree(subjectId); } - - cJSON *jsonObj = NULL; - - unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {}; - uint32_t outLen = 0; - B64Result b64Ret = B64_OK; - - // Service Device Identity - jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_DEVICE_ID); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR); - outLen = 0; - b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff, - sizeof(base64Buff), &outLen); - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->svcdid.id)), ERROR); - memcpy(svc->svcdid.id, base64Buff, outLen); - // Service Type - jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_SERVICE_TYPE); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR); - svc->svct = (OicSecSvcType_t)jsonObj->valueint; - - // Resource Owners - jsonObj = cJSON_GetObjectItem(jsonSvc, OIC_JSON_OWNERS_NAME); - VERIFY_NON_NULL(TAG, jsonObj, ERROR); - VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR); - - svc->ownersLen = (size_t)cJSON_GetArraySize(jsonObj); - VERIFY_SUCCESS(TAG, svc->ownersLen > 0, ERROR); - svc->owners = (OicUuid_t*)OICCalloc(svc->ownersLen, sizeof(OicUuid_t)); - VERIFY_NON_NULL(TAG, (svc->owners), ERROR); - - size_t idxx = 0; - do + if (0 == strcmp(OIC_JSON_SERVICE_TYPE, name)) { - cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx); - VERIFY_NON_NULL(TAG, jsonOwnr, ERROR); - VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR); - - outLen = 0; - b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff, - sizeof(base64Buff), &outLen); + cborFindResult = cbor_value_get_int(&svcMap, (int *) &svc->svct); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find SVCT."); + } - VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(svc->owners[idxx].id)), - ERROR); - memcpy(svc->owners[idxx].id, base64Buff, outLen); - } while ( ++idxx < svc->ownersLen); + // Owners -- Mandatory + if (0 == strcmp(OIC_JSON_OWNERS_NAME, name)) + { + CborValue owners = { .parser = NULL }; + cborFindResult = cbor_value_get_array_length(&svcMap, &svc->ownersLen); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Len."); + cborFindResult = cbor_value_enter_container(&svcMap, &owners); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Enter Owner Array."); + int i = 0; + svc->owners = (OicUuid_t *)OICCalloc(svc->ownersLen, sizeof(*svc->owners)); + VERIFY_NON_NULL(TAG, svc->owners, ERROR); + while (cbor_value_is_valid(&owners)) + { + uint8_t *owner = NULL; + cborFindResult = cbor_value_dup_byte_string(&owners, &owner, &len, NULL); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Owner Array Value."); + cborFindResult = cbor_value_advance(&owners); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance Owner Array."); + memcpy(svc->owners[i].id, owner, len); + OICFree(owner); + } + } + if (CborMapType != type && cbor_value_is_valid(&svcMap)) + { + cborFindResult = cbor_value_advance(&svcMap); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Advance SVC."); + } + OICFree(name); + } - prevSvc = svc; - } while( ++idx < numSvc); + svc->next = NULL; + if (NULL == headSvc) + { + headSvc = svc; + } + else + { + OicSecSvc_t *temp = headSvc; + while (temp->next) + { + temp = temp->next; + } + temp->next = svc; + } + if (cbor_value_is_valid(&svcArray)) + { + cborFindResult = cbor_value_advance(&svcArray); + VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed to Find Name."); + } } - + *secSvc = headSvc; ret = OC_STACK_OK; exit: - cJSON_Delete(jsonRoot); - if (OC_STACK_OK != ret) + if (CborNoError != cborFindResult) { DeleteSVCList(headSvc); headSvc = NULL; + ret = OC_STACK_ERROR; } - return headSvc; + return ret; } static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * ehRequest) { // Convert SVC data into JSON for transmission - char* jsonStr = BinToSvcJSON(gSvc); - - OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR); + size_t size = 0; + uint8_t *cborSvc = NULL; + OCStackResult res = SVCToCBORPayload(gSvc, &cborSvc, &size); + OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR; // Send response payload to request originator - SendSRMResponse(ehRequest, ehRet, jsonStr); + SendSRMCBORResponse(ehRequest, ehRet, cborSvc); - OICFree(jsonStr); + OICFree(cborSvc); OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); return ehRet; @@ -246,33 +328,32 @@ static OCEntityHandlerResult HandleSVCGetRequest (const OCEntityHandlerRequest * static OCEntityHandlerResult HandleSVCPostRequest (const OCEntityHandlerRequest * ehRequest) { OCEntityHandlerResult ehRet = OC_EH_ERROR; - - // Convert JSON SVC data into binary. This will also validate the SVC data received. - OicSecSvc_t* newSvc = JSONToSvcBin(((OCSecurityPayload*)ehRequest->payload)->securityData); - - if (newSvc) + uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData1;; + if (payload) { - // Append the new SVC to existing SVC - LL_APPEND(gSvc, newSvc); - - // Convert SVC data into JSON for update to persistent storage - char *jsonStr = BinToSvcJSON(gSvc); - if (jsonStr) + // Convert CBOR SVC data into SVC. This will also validate the SVC data received. + OicSecSvc_t *newSvc = NULL; + OCStackResult res = CBORPayloadToSVC(payload, CBOR_SIZE, &newSvc); + if (newSvc && res == OC_STACK_OK) { - cJSON *jsonSvc = cJSON_Parse(jsonStr); - OICFree(jsonStr); - - if ((jsonSvc) && - (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_SVC_NAME, jsonSvc))) + // Append the new SVC to existing SVC + LL_APPEND(gSvc, newSvc); + + // Convert SVC data into JSON for update to persistent storage + size_t size = 0; + uint8_t *cborPayload = NULL; + res = SVCToCBORPayload(gSvc, &cborPayload, &size); + if (cborPayload && OC_STACK_OK == res && + UpdateSecureResourceInPS(OIC_JSON_SVC_NAME, cborPayload, size) == OC_STACK_OK) { ehRet = OC_EH_RESOURCE_CREATED; } - cJSON_Delete(jsonSvc); + OICFree(cborPayload); } } // Send payload to request originator - SendSRMResponse(ehRequest, ehRet, NULL); + SendSRMCBORResponse(ehRequest, ehRet, NULL); OIC_LOG_V (DEBUG, TAG, "%s RetVal %d", __func__ , ehRet); return ehRet; @@ -308,7 +389,7 @@ OCEntityHandlerResult SVCEntityHandler (OCEntityHandlerFlag flag, default: ehRet = OC_EH_ERROR; - SendSRMResponse(ehRequest, ehRet, NULL); + SendSRMCBORResponse(ehRequest, ehRet, NULL); } } @@ -332,7 +413,7 @@ OCStackResult CreateSVCResource() if (OC_STACK_OK != ret) { - OIC_LOG (FATAL, TAG, "Unable to instantiate SVC resource"); + OIC_LOG(FATAL, TAG, "Unable to instantiate SVC resource"); DeInitSVCResource(); } return ret; @@ -341,18 +422,23 @@ OCStackResult CreateSVCResource() OCStackResult InitSVCResource() { - OCStackResult ret = OC_STACK_ERROR; - OIC_LOG_V (DEBUG, TAG, "Begin %s ", __func__ ); + OCStackResult ret = OC_STACK_ERROR; - // Read SVC resource from PS - char* jsonSVRDatabase = GetSVRDatabase(); + uint8_t *data = NULL; + size_t size = 0; + ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_SVC_NAME, &data, &size); + // If database read failed + if (ret != OC_STACK_OK) + { + OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed"); + } - if (jsonSVRDatabase) + if (data) { // Convert JSON SVC into binary format - gSvc = JSONToSvcBin(jsonSVRDatabase); - OICFree(jsonSVRDatabase); + ret = CBORPayloadToSVC(data, size, &gSvc); + OICFree(data); } // Instantiate 'oic.sec.svc' @@ -380,4 +466,3 @@ void DeInitSVCResource() DeleteSVCList(gSvc); gSvc = NULL; } - diff --git a/resource/csdk/security/unittest/SConscript b/resource/csdk/security/unittest/SConscript index 87495ec..55a767a 100644 --- a/resource/csdk/security/unittest/SConscript +++ b/resource/csdk/security/unittest/SConscript @@ -115,4 +115,3 @@ if env.get('TEST') == '1': srmtest_env.AppendENVPath('LD_LIBRARY_PATH', ['./extlibs/gtest/gtest-1.7.0/lib/.libs']) ut = srmtest_env.Command ('ut', None, out_dir + '/resource/csdk/security/unittest/unittest') AlwaysBuild ('ut') - diff --git a/resource/csdk/security/unittest/svcresourcetest.cpp b/resource/csdk/security/unittest/svcresourcetest.cpp index 5c3f75e..8d4553f 100644 --- a/resource/csdk/security/unittest/svcresourcetest.cpp +++ b/resource/csdk/security/unittest/svcresourcetest.cpp @@ -19,63 +19,72 @@ //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #include "gtest/gtest.h" -#include -#include -#include -#include #include "ocstack.h" #include "oic_malloc.h" -#include "cJSON.h" #include "cainterface.h" #include "secureresourcemanager.h" #include "securevirtualresourcetypes.h" #include "srmresourcestrings.h" #include "svcresource.h" #include "srmtestcommon.h" +#include "security_internals.h" using namespace std; -#ifdef __cplusplus -extern "C" { -#endif -extern char * BinToSvcJSON(const OicSecSvc_t * svc); -extern OicSecSvc_t * JSONToSvcBin(const char * jsonStr); -extern void DeleteSVCList(OicSecSvc_t* svc); -#ifdef __cplusplus -} -#endif - -static const char* JSON_FILE_NAME = "oic_unittest.json"; - -#define NUM_SVC_IN_JSON_DB (2) +#define NUM_SVC_IN_CBOR_DB (2) - -// JSON Marshalling Tests -TEST(SVCResourceTest, JSONMarshallingTests) +TEST(SVCResourceTest, CBORConversionTests) { - char *jsonStr1 = ReadFile(JSON_FILE_NAME); - if (jsonStr1) - { - OicSecSvc_t * svc = JSONToSvcBin(jsonStr1); - EXPECT_TRUE(NULL != svc); + OicSecSvc_t *svc1 = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1)); + ASSERT_TRUE(NULL != svc1); + uint8_t svcdid[] = {0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35}; + memcpy(svc1->svcdid.id, svcdid, sizeof(svcdid)); + ASSERT_EQ(sizeof(svc1->svcdid.id), sizeof(svcdid)); - int cnt = 0; - OicSecSvc_t * tempSvc = svc; - while(tempSvc) - { + svc1->svct = (OicSecSvcType_t) 1; + uint8_t owners[] = {0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39}; + svc1->ownersLen = 1; + svc1->owners = (OicUuid_t *)OICCalloc(svc1->ownersLen, sizeof(*svc1->owners)); + ASSERT_TRUE(NULL != svc1->owners); + memcpy(svc1->owners[0].id, owners, sizeof(owners)); + ASSERT_EQ(sizeof(svc1->owners[0].id), sizeof(owners)); - EXPECT_EQ(tempSvc->svct, ACCESS_MGMT_SERVICE); - cnt++; - tempSvc = tempSvc->next; - } - EXPECT_EQ(cnt, NUM_SVC_IN_JSON_DB); + svc1->next = (OicSecSvc_t *) OICCalloc(1, sizeof(*svc1->next)); + ASSERT_TRUE(svc1->next != NULL); + memcpy(svc1->next->svcdid.id, svcdid, sizeof(svcdid)); + ASSERT_EQ(sizeof(svc1->next->svcdid.id), sizeof(svcdid)); + svc1->next->svct = (OicSecSvcType_t) 1; + uint8_t owners1[] = {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}; + svc1->next->ownersLen = 1; + svc1->next->owners = (OicUuid_t *)OICCalloc(svc1->next->ownersLen, + sizeof(*svc1->next->owners)); + ASSERT_TRUE(NULL != svc1->next->owners); + memcpy(svc1->next->owners[0].id, owners1, sizeof(owners1)); + svc1->next->next = NULL; - char * jsonStr2 = BinToSvcJSON(svc); - EXPECT_TRUE(NULL != jsonStr2); + size_t size = 0; + uint8_t *psStorage = NULL; + EXPECT_EQ(OC_STACK_OK, SVCToCBORPayload(svc1, &psStorage, &size)); + ASSERT_TRUE(NULL != psStorage); - OICFree(jsonStr1); - OICFree(jsonStr2); - DeleteSVCList(svc); + OicSecSvc_t *svc = NULL; + EXPECT_EQ(OC_STACK_OK, CBORPayloadToSVC(psStorage, size, &svc)); + ASSERT_TRUE(NULL != svc); + + int cnt = 0; + OicSecSvc_t *tempSvc = svc; + while (tempSvc) + { + EXPECT_EQ(ACCESS_MGMT_SERVICE, tempSvc->svct); + cnt++; + tempSvc = tempSvc->next; } -} + EXPECT_EQ(NUM_SVC_IN_CBOR_DB, cnt); + OICFree(psStorage); + DeleteSVCList(svc); + DeleteSVCList(svc1); +}