/*
* 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;
}
예제 #2
0
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;
}