/** * Perform cleanup for pstat resources. * * @retval OC_STACK_OK for Success, otherwise some error value */ OCStackResult DeInitPstatResource() { if(gPstat != &gDefaultPstat) { DeletePstatBinData(gPstat); gPstat = NULL; } return OCDeleteResource(gPstatHandle); }
static void ConvertJsonToCBOR(const char *jsonFileName, const char *cborFileName) { char *jsonStr = NULL; FILE *fp = NULL; FILE *fp1 = NULL; uint8_t *aclCbor = NULL; uint8_t *pstatCbor = NULL; uint8_t *doxmCbor = NULL; uint8_t *amaclCbor = NULL; uint8_t *svcCbor = NULL; uint8_t *credCbor = NULL; cJSON *jsonRoot = NULL; OCStackResult ret = OC_STACK_ERROR; size_t size = GetJSONFileSize(jsonFileName); if (0 == size) { OIC_LOG (ERROR, TAG, "Failed converting to JSON"); return; } jsonStr = (char *)OICMalloc(size + 1); VERIFY_NON_NULL(TAG, jsonStr, FATAL); fp = fopen(jsonFileName, "r"); if (fp) { size_t bytesRead = fread(jsonStr, 1, size, fp); jsonStr[bytesRead] = '\0'; OIC_LOG_V(DEBUG, TAG, "Read %zu bytes", bytesRead); fclose(fp); fp = NULL; } else { OIC_LOG (ERROR, TAG, "Unable to open JSON file!!"); goto exit; } jsonRoot = cJSON_Parse(jsonStr); cJSON *value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME); //printf("ACL json : \n%s\n", cJSON_PrintUnformatted(value)); size_t aclCborSize = 0; if (NULL != value) { OicSecAcl_t *acl = JSONToAclBin(jsonStr); VERIFY_NON_NULL(TAG, acl, FATAL); ret = AclToCBORPayload(acl, &aclCbor, &aclCborSize); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Acl to Cbor Payload"); DeleteACLList(acl); goto exit; } printf("ACL Cbor Size: %zd\n", aclCborSize); DeleteACLList(acl); } value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME); size_t pstatCborSize = 0; if (NULL != value) { OicSecPstat_t *pstat = JSONToPstatBin(jsonStr); VERIFY_NON_NULL(TAG, pstat, FATAL); ret = PstatToCBORPayload(pstat, &pstatCbor, &pstatCborSize); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Pstat to Cbor Payload"); DeletePstatBinData(pstat); goto exit; } printf("PSTAT Cbor Size: %zd\n", pstatCborSize); DeletePstatBinData(pstat); } value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_DOXM_NAME); size_t doxmCborSize = 0; if (NULL != value) { OicSecDoxm_t *doxm = JSONToDoxmBin(jsonStr); VERIFY_NON_NULL(TAG, doxm, FATAL); ret = DoxmToCBORPayload(doxm, &doxmCbor, &doxmCborSize); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Doxm to Cbor Payload"); DeleteDoxmBinData(doxm); goto exit; } printf("DOXM Cbor Size: %zd\n", doxmCborSize); DeleteDoxmBinData(doxm); } value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_AMACL_NAME); size_t amaclCborSize = 0; if (NULL != value) { OicSecAmacl_t *amacl = JSONToAmaclBin(jsonStr); VERIFY_NON_NULL(TAG, amacl, FATAL); ret = AmaclToCBORPayload(amacl, &amaclCbor, &amaclCborSize); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Amacl to Cbor Payload"); DeleteAmaclList(amacl); goto exit; } printf("AMACL Cbor Size: %zd\n", amaclCborSize); DeleteAmaclList(amacl); } value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_SVC_NAME); size_t svcCborSize = 0; if (NULL != value) { OicSecSvc_t *svc = JSONToSvcBin(jsonStr); VERIFY_NON_NULL(TAG, svc, FATAL); ret = SVCToCBORPayload(svc, &svcCbor, &svcCborSize); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Svc to Cbor Payload"); DeleteSVCList(svc); goto exit; } printf("SVC Cbor Size: %zd\n", svcCborSize); DeleteSVCList(svc); } value = cJSON_GetObjectItem(jsonRoot, OIC_JSON_CRED_NAME); //printf("CRED json : \n%s\n", cJSON_PrintUnformatted(value)); size_t credCborSize = 0; int secureFlag = 0; if (NULL != value) { OicSecCred_t *cred = JSONToCredBin(jsonStr); VERIFY_NON_NULL(TAG, cred, FATAL); ret = CredToCBORPayload(cred, &credCbor, &credCborSize, secureFlag); if(OC_STACK_OK != ret) { OIC_LOG (ERROR, TAG, "Failed converting Cred to Cbor Payload"); DeleteCredList(cred); goto exit; } printf("CRED Cbor Size: %zd\n", credCborSize); DeleteCredList(cred); } CborEncoder encoder; size_t cborSize = aclCborSize + pstatCborSize + doxmCborSize + svcCborSize + credCborSize + amaclCborSize; printf("Total Cbor Size : %zd\n", cborSize); cborSize += 255; // buffer margin for adding map and byte string uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborSize); VERIFY_NON_NULL(TAG, outPayload, ERROR); cbor_encoder_init(&encoder, outPayload, cborSize, 0); CborEncoder map; CborError cborEncoderResult = cbor_encoder_create_map(&encoder, &map, CborIndefiniteLength); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Creating Main Map."); if (aclCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_ACL_NAME, strlen(OIC_JSON_ACL_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Name."); cborEncoderResult = cbor_encode_byte_string(&map, aclCbor, aclCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ACL Value."); } if (pstatCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_PSTAT_NAME, strlen(OIC_JSON_PSTAT_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Name."); cborEncoderResult = cbor_encode_byte_string(&map, pstatCbor, pstatCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding PSTAT Value."); } if (doxmCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_DOXM_NAME, strlen(OIC_JSON_DOXM_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Name."); cborEncoderResult = cbor_encode_byte_string(&map, doxmCbor, doxmCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding DOXM Value."); } if (amaclCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_AMACL_NAME, strlen(OIC_JSON_AMACL_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding AMACL Name."); cborEncoderResult = cbor_encode_byte_string(&map, amaclCbor, amaclCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding AMACL Value."); } if (svcCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_SVC_NAME, strlen(OIC_JSON_SVC_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Name."); cborEncoderResult = cbor_encode_byte_string(&map, svcCbor, svcCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SVC Value."); } if (credCborSize > 0) { cborEncoderResult = cbor_encode_text_string(&map, OIC_JSON_CRED_NAME, strlen(OIC_JSON_CRED_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Name."); cborEncoderResult = cbor_encode_byte_string(&map, credCbor, credCborSize); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CRED Value."); } cborEncoderResult = cbor_encoder_close_container(&encoder, &map); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing Container."); size_t s = encoder.ptr - outPayload; OIC_LOG_V(DEBUG, TAG, "Payload size %zu", s); fp1 = fopen(cborFileName, "w"); if (fp1) { size_t bytesWritten = fwrite(outPayload, 1, s, fp1); if (bytesWritten == s) { OIC_LOG_V(DEBUG, TAG, "Written %zu bytes", bytesWritten); } else { OIC_LOG_V(ERROR, TAG, "Failed writing %zu bytes", s); } fclose(fp1); fp1 = NULL; } exit: cJSON_Delete(jsonRoot); OICFree(aclCbor); OICFree(doxmCbor); OICFree(pstatCbor); OICFree(amaclCbor); OICFree(svcCbor); OICFree(credCbor); OICFree(jsonStr); return ; }
/** * The entity handler determines how to process a POST request. * Per the REST paradigm, POST can also be used to update representation of existing * resource or create a new resource. * For pstat, it updates only tm and om. */ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest *ehRequest) { OCEntityHandlerResult ehRet = OC_EH_ERROR; OIC_LOG(INFO, TAG, "HandlePstatPostRequest processing POST request"); OicSecPstat_t *pstat = NULL; if (ehRequest->payload) { uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData; size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize; VERIFY_NON_NULL(TAG, payload, ERROR); OCStackResult ret = CBORPayloadToPstat(payload, size, &pstat); VERIFY_NON_NULL(TAG, pstat, ERROR); if (OC_STACK_OK == ret) { if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp) { gPstat->cm = pstat->cm; OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning"); } else if (false == (pstat->cm & TAKE_OWNER) && true == pstat->isOp) { gPstat->isOp =pstat->isOp; OIC_LOG (INFO, TAG, "State changed to Ready for Normal Operation"); } else { OIC_LOG(DEBUG, TAG, "Invalid Device provisionig state"); } if (pstat->om != MULTIPLE_SERVICE_SERVER_DRIVEN && 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(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; } } } exit: if(OC_EH_OK != ehRet) { /* * If some error is occured while ownership transfer, * ownership transfer related resource should be revert back to initial status. */ RestoreDoxmToInitState(); RestorePstatToInitState(); } //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0)) { ehRet = OC_EH_ERROR; OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } DeletePstatBinData(pstat); return ehRet; }
OicSecPstat_t * JSONToPstatBin(const char * jsonStr, const bool isIncResName) { if(NULL == jsonStr) { return NULL; } OCStackResult ret = OC_STACK_ERROR; 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); if(isIncResName) { jsonPstat = cJSON_GetObjectItem(jsonRoot, OIC_JSON_PSTAT_NAME); } else { jsonPstat = jsonRoot; } 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) { pstat->smLen = 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 { cJSON *jsonSm = cJSON_GetArrayItem(jsonObj, idxx); VERIFY_NON_NULL(TAG, jsonSm, ERROR); pstat->sm[idxx] = (OicSecDpom_t)jsonSm->valueint; }while ( ++idxx < pstat->smLen); } ret = OC_STACK_OK; exit: cJSON_Delete(jsonRoot); if (OC_STACK_OK != ret) { OC_LOG (ERROR, TAG, "JSONToPstatBin failed"); DeletePstatBinData(pstat); pstat = NULL; } return pstat; }
OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t size, OicSecPstat_t **secPstat) { if (NULL == cborPayload || NULL == secPstat || NULL != *secPstat || 0 == size) { return OC_STACK_INVALID_PARAM; } OCStackResult ret = OC_STACK_ERROR; *secPstat = NULL; CborValue pstatCbor; CborParser parser; CborError cborFindResult = CborNoError; char *strUuid = NULL; size_t len = 0; cbor_parser_init(cborPayload, size, 0, &parser, &pstatCbor); CborValue pstatMap = { .parser = NULL }; OicSecPstat_t *pstat = 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); cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ISOP_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_boolean(&pstatMap)) { cborFindResult = cbor_value_get_boolean(&pstatMap, &pstat->isOp); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding isOp Value."); } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_DEVICE_ID_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap)) { cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value."); ret = ConvertStrToUuid(strUuid , &pstat->deviceID); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); OICFree(strUuid ); strUuid = NULL; } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_CM_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap)) { cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->cm); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CM."); } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_TM_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap)) { cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->tm); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding TM."); } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_OM_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap)) { cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->om); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OM."); } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_SM_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap)) { pstat->smLen = 1; pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t)); cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->sm[0]); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM."); } cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ROWNERID_NAME, &pstatMap); if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap)) { cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL); VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Id Value."); ret = ConvertStrToUuid(strUuid , &pstat->rownerID); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR); OICFree(strUuid ); strUuid = NULL; } *secPstat = pstat; ret = OC_STACK_OK; exit: if (CborNoError != cborFindResult) { OIC_LOG(ERROR, TAG, "CBORPayloadToPstat failed"); DeletePstatBinData(pstat); pstat = NULL; *secPstat = NULL; ret = OC_STACK_ERROR; } return ret; }