/* * Function to device revocation * This function will remove credential of target device from all devices in subnet. * * @param[in] ctx Application context would be returned in result callback * @param[in] waitTimeForOwnedDeviceDiscovery Maximum wait time for owned device discovery.(seconds) * @param[in] pTargetDev Device information to be revoked. * @param[in] resultCallback callback provided by API user, callback will be called when * credential revocation is finished. * @return OC_STACK_OK in case of success and other value otherwise. */ OCStackResult OCRemoveDeviceWithUuid(void* ctx, unsigned short waitTimeForOwnedDeviceDiscovery, const OicUuid_t* pTargetUuid, OCProvisionResultCB resultCallback) { OIC_LOG(INFO, TAG, "IN OCRemoveDeviceWithUuid"); OCStackResult res = OC_STACK_ERROR; if (!pTargetUuid || 0 == waitTimeForOwnedDeviceDiscovery) { OIC_LOG(INFO, TAG, "OCRemoveDeviceWithUuid : Invalied parameters"); return OC_STACK_INVALID_PARAM; } if (!resultCallback) { OIC_LOG(INFO, TAG, "OCRemoveDeviceWithUuid : NULL Callback"); return OC_STACK_INVALID_CALLBACK; } OCProvisionDev_t* pOwnedDevList = NULL; //2. Find owned device from the network res = PMDeviceDiscovery(waitTimeForOwnedDeviceDiscovery, true, &pOwnedDevList); if (OC_STACK_OK != res) { OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid : Failed to PMDeviceDiscovery"); goto error; } OCProvisionDev_t* pTargetDev = NULL; LL_FOREACH(pOwnedDevList, pTargetDev) { if(memcmp(&pTargetDev->doxm->deviceID.id, pTargetUuid->id, sizeof(pTargetUuid->id)) == 0) { break; } } char* strUuid = NULL; if(OC_STACK_OK != ConvertUuidToStr(pTargetUuid, &strUuid)) { OIC_LOG(WARNING, TAG, "Failed to covert UUID to String."); goto error; } if(pTargetDev) { OIC_LOG_V(INFO, TAG, "[%s] is dectected on the network.", strUuid); OIC_LOG_V(INFO, TAG, "Trying [%s] revocation.", strUuid); // Send DELETE requests to linked devices OCStackResult resReq = OC_STACK_ERROR; // Check that we have to wait callback or not. resReq = SRPRemoveDeviceWithoutDiscovery(ctx, pOwnedDevList, pTargetDev, resultCallback); if (OC_STACK_OK != resReq) { if (OC_STACK_CONTINUE == resReq) { OIC_LOG(DEBUG, TAG, "OCRemoveDeviceWithUuid : Revoked device has no linked device except PT."); } else { OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid : Failed to invoke SRPRemoveDevice"); res = resReq; OICFree(strUuid); goto error; } } res = RemoveDeviceInfoFromLocal(pTargetDev); if(OC_STACK_OK != res) { OIC_LOG(ERROR, TAG, "OCRemoveDeviceWithUuid : Filed to remove the device information from local."); OICFree(strUuid); goto error; } if(OC_STACK_CONTINUE == resReq) { /** * If there is no linked device, PM does not send any request. * So we should directly invoke the result callback to inform the result of OCRemoveDevice. */ if(resultCallback) { resultCallback(ctx, 0, NULL, false); } res = OC_STACK_OK; } } else { OIC_LOG_V(WARNING, TAG, "OCRemoveDeviceWithUuid : Failed to find the [%s] on the network.", strUuid); res = OC_STACK_ERROR; } error: OICFree(strUuid); PMDeleteDeviceList(pOwnedDevList); OIC_LOG(INFO, TAG, "OUT OCRemoveDeviceWithUuid"); return res; }
OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload, size_t *size) { if (NULL == pstat || NULL == payload || NULL != *payload || NULL == size) { return OC_STACK_INVALID_PARAM; } size_t cborLen = *size; if (0 == cborLen) { cborLen = CBOR_SIZE; } *payload = NULL; *size = 0; OCStackResult ret = OC_STACK_ERROR; CborEncoder encoder; CborEncoder pstatMap; char* strUuid = NULL; int64_t 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."); ret = ConvertUuidToStr(&pstat->deviceID, &strUuid); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR); cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value."); OICFree(strUuid); strUuid = NULL; 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."); cborEncoderResult = cbor_encode_int(&pstatMap, pstat->sm[0]); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Value."); cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ROWNERID_NAME, strlen(OIC_JSON_ROWNERID_NAME)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag."); ret = ConvertUuidToStr(&pstat->rownerID, &strUuid); VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR); cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid)); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value."); OICFree(strUuid); strUuid = NULL; cborEncoderResult = cbor_encoder_close_container(&encoder, &pstatMap); VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Closing PSTAT Map."); if (CborNoError == cborEncoderResult) { *size = encoder.ptr - outPayload; *payload = outPayload; ret = OC_STACK_OK; } exit: if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE)) { // 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); if (OC_STACK_OK == ret) { *size = cborLen; } } if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret)) { OICFree(outPayload); outPayload = NULL; *payload = NULL; *size = 0; ret = OC_STACK_ERROR; } return ret; }