Commit be01086f authored by Oleksandr Dmytrenko's avatar Oleksandr Dmytrenko Committed by Nathan Heldt-Sheller

[IOT-2815][IOT-2844]

provisioningclient set rowneruuid for all the SVRs

Change-Id: I46df6479aeb313955639df32b7e73c52b14691e0
Signed-off-by: default avatarOleksandr Dmytrenko <o.dmytrenko@samsung.com>
parent 7f9d8c71
......@@ -197,6 +197,11 @@ OCStackResult GetAclRownerId(OicUuid_t *rowneruuid);
OicSecAcl_t* CBORPayloadToCloudAcl(const uint8_t *cborPayload, const size_t size);
#endif //defined(TCP_ADAPTER) && defined(WITH_CLOUD)
/*
* Check acl rowner uuid
*/
bool IsAclRowneruuidTheNilUuid();
#ifdef __cplusplus
}
#endif
......
......@@ -298,4 +298,9 @@ void FreeCred(OicSecCred_t *cred);
}
#endif
/*
* Check cred rowner uuid
*/
bool IsCredRowneruuidTheNilUuid();
#endif //IOTVT_SRM_CREDR_H
......@@ -272,4 +272,24 @@ OCStackResult DoxmUpdateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t*
}
#endif
/*
* Check doxm is owned
*/
bool IsDoxmOwned();
/*
* Check doxm owner id
*/
bool IsDoxmDevowneruuidTheNilUuid();
/*
* Check doxm device id
*/
bool IsDoxmDeviceuuidTheNilUuid();
/*
* Check doxm rowner uuid
*/
bool IsDoxmRowneruuidTheNilUuid();
#endif //IOTVT_SRM_DOXMR_H
......@@ -218,6 +218,11 @@ OCStackResult SetPstatTm(const OicSecDpm_t tm);
*/
OCStackResult SetPstatSelfOwnership(const OicUuid_t* newROwner);
/*
* Check rowner uuid
*/
bool IsPstatRowneruuidTheNilUuid();
#ifdef __cplusplus
}
#endif
......
......@@ -173,6 +173,11 @@ bool IsNilUuid(const OicUuid_t *uuid);
OCStackResult OC_CALL SetDeviceIdSeed(const uint8_t* seed, size_t seedSize);
#endif
/**
* Log OicUuid_t structs.
*/
void LogUuid(const OicUuid_t* uuid);
#ifdef __cplusplus
}
#endif // __cplusplus
......
......@@ -445,6 +445,15 @@ static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
*/
static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
/**
* Function set pstat rowner uuid.
*
* @param[in] ctx context value passed to callback from calling function.
* @param[in] selectedDevice selected device information to performing provisioning.
* @return OC_STACK_OK on success
*/
static OCStackResult PostRownerUuid(OTMContext_t* otmCtx);
/**
* Function to update pstat as Ready for Normal Operation.
* This function would update 'dos.s' to DOS_RFNOP.
......@@ -1365,6 +1374,13 @@ static OCStackApplicationResult OwnershipInformationHandler(void *ctx, OCDoHandl
OIC_LOG(INFO, TAG, "Ownership transfer was successfully completed.");
OIC_LOG(INFO, TAG, "Set Ready for provisioning state .");
res = PostRownerUuid(otmCtx);
if(OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "Failed to set rowneruuid pstat");
SetResult(otmCtx, res);
}
res = PostProvisioningStatus(otmCtx);
if(OC_STACK_OK != res)
{
......@@ -2028,6 +2044,11 @@ static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
bool propertiesToInclude[DOXM_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[DOXM_OWNED] = true;
//include rowner uuid
propertiesToInclude[DOXM_ROWNERUUID] = true;
///doxm.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
GetDoxmDeviceID(&otmCtx->selectedDeviceInfo->doxm->rownerID);
OCStackResult res = DoxmToCBORPayloadPartial(otmCtx->selectedDeviceInfo->doxm,
&secPayload->securityData, &secPayload->payloadSize,
propertiesToInclude);
......@@ -2473,6 +2494,9 @@ OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_DOS] = true;
propertiesToInclude[PSTAT_TM] = true;
propertiesToInclude[PSTAT_ROWNERUUID] = true;
///pstat.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
GetDoxmDeviceID(&otmCtx->selectedDeviceInfo->pstat->rownerID);
if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false))
......@@ -2665,3 +2689,118 @@ exit:
return ret;
}
/**
* Response handler of set rowner uuid.
*
* @param[in] ctx ctx value passed to callback from calling function.
* @param[in] UNUSED handle to an invocation
* @param[in] clientResponse Response from queries to remote servers.
* @return OC_STACK_DELETE_TRANSACTION to delete the transaction
* and OC_STACK_KEEP_TRANSACTION to keep it.
*/
static OCStackApplicationResult RownerUuidHandler(void *ctx, OCDoHandle handle,
OCClientResponse *clientResponse)
{
OIC_LOG_V(INFO, TAG, "%s IN", __func__);
VERIFY_NOT_NULL(TAG, clientResponse, ERROR);
VERIFY_NOT_NULL(TAG, ctx, ERROR);
OTMContext_t* otmCtx = (OTMContext_t*) ctx;
OC_UNUSED(handle);
OIC_LOG_V(INFO, TAG, "%s response got: %d", __func__, clientResponse->result);
if(OC_STACK_RESOURCE_CHANGED < clientResponse->result)
{
//Remove the current OTM Context from OTM queue
RemoveOTMContext(otmCtx->selectedDeviceInfo->endpoint.addr,
getSecurePort(otmCtx->selectedDeviceInfo));
//If there is a request being performed, cancel it to prevent retransmission.
if(otmCtx->ocDoHandle)
{
OIC_LOG_V(DEBUG, TAG, "OCCancel - %s : %d",
otmCtx->selectedDeviceInfo->endpoint.addr,
getSecurePort(otmCtx->selectedDeviceInfo));
if(OC_STACK_OK != OCCancel(otmCtx->ocDoHandle, OC_HIGH_QOS, NULL, 0))
{
OIC_LOG(WARNING, TAG, "Failed to remove registered callback");
}
else
{
otmCtx->ocDoHandle = NULL;
}
}
}
exit:
OIC_LOG_V(INFO, TAG, "%s OUT", __func__);
return OC_STACK_DELETE_TRANSACTION;
}
OCStackResult PostRownerUuid(OTMContext_t* otmCtx)
{
OIC_LOG_V(INFO, TAG, "%s IN", __func__);
if(!otmCtx || !otmCtx->selectedDeviceInfo)
{
OIC_LOG_V(ERROR, TAG, "%s: %s is NULL", __func__, !otmCtx ? "OTMContext" : "selectedDeviceInfo" );
return OC_STACK_INVALID_PARAM;
}
OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
if (!secPayload)
{
OIC_LOG_V(ERROR, TAG, "%s: Failed to memory allocation", __func__);
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_ROWNERUUID] = true;
///pstat.rowneruuid set to the provisioningclient's /doxm.deviceuuid.
GetDoxmDeviceID(&otmCtx->selectedDeviceInfo->pstat->rownerID);
if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, propertiesToInclude, false))
{
OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_INVALID_JSON;
}
OIC_LOG(DEBUG, TAG, "Created payload for set rowner uuid");
OIC_LOG_BUFFER(DEBUG, TAG, secPayload->securityData, secPayload->payloadSize);
char query[MAX_URI_LENGTH + MAX_QUERY_LENGTH] = {0};
assert(otmCtx->selectedDeviceInfo->connType & CT_FLAG_SECURE);
if(!PMGenerateQuery(true,
otmCtx->selectedDeviceInfo->endpoint.addr,
getSecurePort(otmCtx->selectedDeviceInfo),
otmCtx->selectedDeviceInfo->connType,
query, sizeof(query), OIC_RSRC_PSTAT_URI))
{
OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "%s: Query=%s", __func__, query);
OCCallbackData cbData;
memset(&cbData, 0, sizeof(cbData));
cbData.cb = &RownerUuidHandler;
cbData.context = (void*)otmCtx;
cbData.cd = NULL;
OCStackResult ret = OCDoResource(&otmCtx->ocDoHandle, OC_REST_POST, query, 0, (OCPayload*)secPayload,
otmCtx->selectedDeviceInfo->connType, OC_HIGH_QOS, &cbData, NULL, 0);
OIC_LOG_V(INFO, TAG, "%s: OCDoResource returned: %d", __func__, ret);
if (ret != OC_STACK_OK)
{
OIC_LOG(ERROR, TAG, "OCStack resource error");
}
OIC_LOG_V(INFO, TAG, "%s OUT", __func__);
return ret;
}
......@@ -2043,19 +2043,25 @@ static OicSecAcl_t* CBORPayloadToAclVersionOpt(const uint8_t *cborPayload, const
}
//rownerID -- Mandatory
if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0)
{
char *stRowner = NULL;
cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Rownerid Value.");
ret = ConvertStrToUuid(stRowner, &acl->rownerID);
free(stRowner);
VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
}
else if (NULL != gAcl)
if (IsNilUuid(&acl->rownerID))
{
memcpy(&(acl->rownerID), &(gAcl->rownerID), sizeof(OicUuid_t));
if (strcmp(tagName, OIC_JSON_ROWNERID_NAME) == 0)
{
char *stRowner = NULL;
cborFindResult = cbor_value_dup_text_string(&aclMap, &stRowner, &len, NULL);
VERIFY_CBOR_SUCCESS_OR_OUT_OF_MEMORY(TAG, cborFindResult, "Failed Finding Rownerid Value.");
ret = ConvertStrToUuid(stRowner, &acl->rownerID);
OIC_LOG_V(DEBUG, TAG, "%s: rowner uuid: %s", __func__, stRowner);
free(stRowner);
VERIFY_SUCCESS(TAG, ret == OC_STACK_OK, ERROR);
}
else if (NULL != gAcl)
{
memcpy(&(acl->rownerID), &(gAcl->rownerID), sizeof(OicUuid_t));
OIC_LOG_V(DEBUG, TAG, "%s: rowner uuid from gAcl", __func__);
}
}
free(tagName);
tagName = NULL;
}
......@@ -4021,3 +4027,12 @@ OCStackResult GetAclRownerId(OicUuid_t *rowneruuid)
}
return OC_STACK_ERROR;
}
bool IsAclRowneruuidTheNilUuid()
{
if (gAcl)
{
return IsNilUuid(&gAcl->rownerID);
}
return true;
}
......@@ -3113,28 +3113,34 @@ exit:
OCStackResult SetCredRownerId(const OicUuid_t* newROwner)
{
OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
OCStackResult ret = OC_STACK_ERROR;
OicUuid_t prevId = {.id={0}};
if(NULL == newROwner)
{
ret = OC_STACK_INVALID_PARAM;
goto exit;
}
if (newROwner)
if (UuidCmp(&gRownerId, newROwner))
{
memcpy(prevId.id, gRownerId.id, sizeof(prevId.id));
memcpy(gRownerId.id, newROwner->id, sizeof(newROwner->id));
VERIFY_SUCCESS(TAG, UpdatePersistentStorage(gCred), ERROR);
OIC_LOG_V(DEBUG, TAG, "%s: the same uuid, skip update", __func__);
ret = OC_STACK_OK;
goto exit;
}
return ret;
memcpy(gRownerId.id, newROwner->id, sizeof(newROwner->id));
VERIFY_SUCCESS(TAG, UpdatePersistentStorage(gCred), ERROR);
ret = OC_STACK_OK;
exit:
memcpy(gRownerId.id, prevId.id, sizeof(prevId.id));
if (OC_STACK_OK != ret)
{
OIC_LOG_V(WARNING, TAG, "%s: cannot set cred rowner uuid, revert", __func__);
}
OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
return ret;
}
......@@ -3148,6 +3154,11 @@ OCStackResult GetCredRownerId(OicUuid_t *rowneruuid)
return OC_STACK_ERROR;
}
bool IsCredRowneruuidTheNilUuid()
{
return IsNilUuid(&gRownerId);
}
#if defined (__WITH_TLS__) || defined(__WITH_DTLS__)
void GetCaCert(ByteArrayLL_t * chain, const char * usage)
{
......
......@@ -96,21 +96,17 @@ static bool IsReadyToEnterRFNOP()
{
bool ret = false;
bool tempBool = false;
OicUuid_t tempUuid = {.id={0}};
// Note: pstat.dos.p asserted by DoStateChange(), so not checked here.
// Verify doxm.owned == TRUE.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmIsOwned(&tempBool), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, tempBool, WARNING);
VERIFY_TRUE_OR_EXIT(TAG, IsDoxmOwned(), WARNING);
// Verify doxm.devowneruuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDevOwnerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDevowneruuidTheNilUuid(), WARNING);
// Verify doxm.deviceuuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDeviceID(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDeviceuuidTheNilUuid(), WARNING);
// Verify oxmsel was the actual OTM used (no-op: CTT will verify this during
// certification testing, as it requires OBT cooperation to verify).
......@@ -120,17 +116,13 @@ static bool IsReadyToEnterRFNOP()
VERIFY_TRUE_OR_EXIT(TAG, !tempBool, WARNING);
// Verify implemented SVRs with rowneruuid Property have non-Nil rowneruuid
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetAclRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsAclRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCredRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsCredRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetPstatRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsPstatRowneruuidTheNilUuid(), WARNING);
// Verify each rowneruuid, devowneruuid has a corresponding /cred entry
// TODO [IOT-2023]
......@@ -148,25 +140,19 @@ exit:
static bool IsReadyToEnterRFOTM()
{
bool ret = false;
bool tempBool = false;
OicUuid_t tempUuid = {.id={0}};
// Note: pstat.dos.p asserted by DoStateChange(), so not checked here.
// Verify doxm.owned == FALSE.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmIsOwned(&tempBool), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !tempBool, WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmOwned(), WARNING);
// Verify doxm.devowneruuid == nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDevOwnerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, IsDoxmDevowneruuidTheNilUuid(), WARNING);
// Check and log whether doxm.deviceuuid == nil UUID ("may" reqt not "shall")
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDeviceID(&tempUuid), ERROR);
if (!IsNilUuid(&tempUuid))
if(!IsDoxmDeviceuuidTheNilUuid())
{
OIC_LOG_V(INFO, TAG, "%s: doxm.deviceuuid != Nil UUID... allowed but noted.",
__func__);
OIC_LOG_V(INFO, TAG, "%s: doxm.deviceuuid != Nil UUID... allowed but noted.", __func__);
}
ret = true;
......@@ -182,37 +168,28 @@ exit:
static bool IsReadyToEnterRFPRO()
{
bool ret = false;
bool tempBool = false;
OicUuid_t tempUuid = {.id={0}};
// Note: pstat.dos.p asserted by DoStateChange(), so not checked here.
// Verify doxm.owned == TRUE.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmIsOwned(&tempBool), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, tempBool, WARNING);
VERIFY_TRUE_OR_EXIT(TAG, IsDoxmOwned(), WARNING);
// Verify doxm.devowneruuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDevOwnerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDevowneruuidTheNilUuid(), WARNING);
// Verify doxm.deviceuuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDeviceID(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDeviceuuidTheNilUuid(), WARNING);
// doxm.sct and doxm.oxmsel retain previous values (checked by CTT)
// Verify implemented SVRs with rowneruuid Property have non-Nil rowneruuid
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetAclRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsAclRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetCredRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsCredRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmRowneruuidTheNilUuid(), WARNING);
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetPstatRownerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsPstatRowneruuidTheNilUuid(), WARNING);
// Verify each rowneruuid, devowneruuid has a corresponding /cred entry
// TODO [IOT-2023]
......@@ -230,24 +207,19 @@ exit:
static bool IsReadyToEnterSRESET()
{
bool ret = false;
bool tempBool = false;
OicUuid_t tempUuid = {.id={0}};
// Note: pstat.dos.p set by DoStateChange(), so not checked here.
// TODO [IOT-2023]: sanity check SVRs (optional)
// Verify doxm.owned == TRUE.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmIsOwned(&tempBool), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, tempBool, WARNING);
VERIFY_TRUE_OR_EXIT(TAG, IsDoxmOwned(), WARNING);
// Verify doxm.devowneruuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDevOwnerId(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDevowneruuidTheNilUuid(), WARNING);
// Verify doxm.deviceuuid != nil UUID.
VERIFY_SUCCESS(TAG, OC_STACK_OK == GetDoxmDeviceID(&tempUuid), ERROR);
VERIFY_TRUE_OR_EXIT(TAG, !IsNilUuid(&tempUuid), WARNING);
VERIFY_TRUE_OR_EXIT(TAG, !IsDoxmDeviceuuidTheNilUuid(), WARNING);
// doxm.sct and doxm.oxmsel retain previous values (checked by CTT)
......
......@@ -982,6 +982,8 @@ void printDoxm(const OicSecDoxm_t* doxm)
{
OIC_LOG_V(DEBUG, TAG, "%s: doxm.deviceuuid = %s", __func__, uuidString);
}
OIC_LOG_V(WARNING, TAG, "%s: doxm.owned = %s", __func__, doxm->owned ? "true" : "false");
}
OCStackResult DoxmUpdateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t* dst)
......@@ -1076,6 +1078,7 @@ OCStackResult DoxmUpdateWriteableProperty(const OicSecDoxm_t* src, OicSecDoxm_t*
#endif //MULTIPLE_OWNER
#ifndef NDEBUG // if debug build, log the new uuid
printDoxm(src);
printDoxm(dst);
#endif
#ifdef MULTIPLE_OWNER
......@@ -1996,69 +1999,49 @@ OCStackResult GetDoxmDeviceID(OicUuid_t *deviceuuid)
OCStackResult SetDoxmDeviceID(const OicUuid_t *deviceuuid)
{
bool isOwnerUpdated = false;
bool isRownerUpdated = false;
OIC_LOG_V(DEBUG, TAG, "%s IN", __func__);
OCStackResult ret = OC_STACK_ERROR;
if (NULL == deviceuuid)
{
return OC_STACK_INVALID_PARAM;
OIC_LOG_V(ERROR, TAG, "%s: device uuid id null.", __func__);
ret = OC_STACK_INVALID_PARAM;
goto exit;
}
if (NULL == gDoxm)
{
OIC_LOG(ERROR, TAG, "Doxm resource is not initialized.");
return OC_STACK_NO_RESOURCE;
ret = OC_STACK_NO_RESOURCE;
goto exit;
}
#ifdef __WITH_DTLS__
//for normal device.
if (true == gDoxm->owned &&
memcmp(gDoxm->deviceID.id, gDoxm->owner.id, sizeof(gDoxm->owner.id)) != 0)
!UuidCmp(&gDoxm->deviceID, &gDoxm->owner))
{
OIC_LOG(ERROR, TAG, "This device owned by owner's device.");
OIC_LOG(ERROR, TAG, "Device UUID cannot be changed to guarantee the reliability of the connection.");
return OC_STACK_ERROR;
ret = OC_STACK_ERROR;
goto exit;
}
#endif //__WITH_DTLS
//Save the previous UUID
OicUuid_t prevUuid;
memcpy(prevUuid.id, gDoxm->deviceID.id, sizeof(prevUuid.id));
//Change the device UUID
memcpy(gDoxm->deviceID.id, deviceuuid->id, sizeof(gDoxm->deviceID.id));
//Change the owner ID if necessary
if (memcmp(gDoxm->owner.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
{
memcpy(gDoxm->owner.id, deviceuuid->id, sizeof(gDoxm->owner.id));
isOwnerUpdated = true;
}
//Change the resource owner ID if necessary
// TODO [IOT-2023] change this behavior and upate the usage of this function
// so that rowneruuid for each resource is set by OBT
if (memcmp(gDoxm->rownerID.id, prevUuid.id, sizeof(prevUuid.id)) == 0)
{
memcpy(gDoxm->rownerID.id, deviceuuid->id, sizeof(gDoxm->rownerID.id));
isRownerUpdated = true;
}
//Update PS
if (!UpdatePersistentStorage(gDoxm))
VERIFY_SUCCESS(TAG, UpdatePersistentStorage(gDoxm), ERROR);
ret = OC_STACK_OK;
exit:
if (OC_STACK_OK != ret)
{
//revert UUID in case of PSI error
memcpy(gDoxm->deviceID.id, prevUuid.id, sizeof(gDoxm->deviceID.id));
if (isOwnerUpdated)
{
memcpy(gDoxm->owner.id, prevUuid.id, sizeof(gDoxm->owner.id));
}
if (isRownerUpdated)
{
memcpy(gDoxm->rownerID.id, prevUuid.id, sizeof(gDoxm->rownerID.id));
}
OIC_LOG(ERROR, TAG, "Failed to update persistent storage");
return OC_STACK_ERROR;
OIC_LOG_V(WARNING, TAG, "%s: cannot set doxm: owner and rowner uuid, revert", __func__);
}
return OC_STACK_OK;
OIC_LOG_V(DEBUG, TAG, "%s OUT", __func__);
return ret;
}
OCStackResult GetDoxmDevOwnerId(OicUuid_t *devowneruuid)
......@@ -2091,6 +2074,33 @@ OCStackResult GetDoxmIsOwned(bool *isowned)
return OC_STACK_ERROR;
}
bool IsDoxmOwned()
{
if (gDoxm)
{