Commit 3f184aa8 authored by Nathan Heldt-Sheller's avatar Nathan Heldt-Sheller

[IOT-1958] CR 22 State Specific Property Access for /pstat Resource

Implementation of CR 22 feature to deny UPDATE to /pstat if any
Property in the POST representation is read-only in the current
/pstat.dos.s state.

Includes necessary update to the CBOR marshalling code to support
partial Resource representations for /pstat.

Includes updates to provisioning tools to correctly include only the
/pstat Properties being updated in the POST payload.

This same change must be implemented for each SVR.

- patch set 2&3: rebased
- patch set 4: fixed a few comments and trigger jenkins
- patch set 5&6: rebased
- patch set 7: addressed Greg's review comments

Change-Id: Ie86fcc1edf4b2370ffcb755c78f1289252dcb516
Signed-off-by: Nathan Heldt-Sheller's avatarNathan Heldt-Sheller <nathan.heldt-sheller@intel.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/18989Tested-by: default avatarjenkins-iotivity <jenkins@iotivity.org>
Reviewed-by: default avatarKevin Kane <kkane@microsoft.com>
parent 72e1ab0d
......@@ -25,6 +25,17 @@
extern "C" {
#endif
typedef enum {
PSTAT_DOS = 0,
PSTAT_ISOP,
PSTAT_CM,
PSTAT_TM,
PSTAT_OM,
PSTAT_SM,
PSTAT_ROWNERUUID,
PSTAT_PROPERTY_COUNT
} PstatProperty_t;
/**
* Initialize Pstat resource by loading data from persistent storage.
*
......@@ -40,18 +51,36 @@ OCStackResult InitPstatResource();
OCStackResult DeInitPstatResource();
/**
* This method converts PSTAT into the cbor payload.
* Converts PSTAT into the cbor payload, including only the
* Properties marked "true" in the propertiesToInclude array.
*
* @param pstat pointer to the initialized pstat structure.
* @param cborPayload pointer to pstat cbor payload.
* @param cborSize of the cbor payload converted. It is 0 in case of error,
* @param payload pointer to pstat cbor payload.
* @param size of the cbor payload converted. It is 0 in case of error,
* else a positive value if succcessful.
* @param writableOnly indicates whether it is writable only or not.
* @param propertiesToInclude Array of bools, size "PSTAT_PROPERTY_COUNT",
* where "true" indicates the corresponding property should be
* included in the CBOR representation that is created.
*
* @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **cborPayload,
size_t *cborSize, bool writableOnly);
OCStackResult PstatToCBORPayloadPartial(const OicSecPstat_t *pstat,
uint8_t **payload, size_t *size, const bool *propertiesToInclude);
/**
* Converts PSTAT into the cbor payload, including all Properties for a
* full representation.
*
* @param pstat pointer to the initialized pstat structure.
* @param payload pointer to pstat cbor payload.
* @param size of the cbor payload converted. It is 0 in case of error,
* else a positive value if succcessful.
*
* @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat,
uint8_t **payload, size_t *size);
/**
* This method converts cbor into PSTAT data.
......@@ -59,11 +88,11 @@ OCStackResult DeInitPstatResource();
* @param cborPayload is the pstat data in cbor format.
* @param cborSize of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
* @param pstat pointer to @ref OicSecPstat_t.
*
* @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t cborSize,
OicSecPstat_t **pstat);
*
* @return ::OC_STACK_OK for Success, otherwise some error value.
*/
OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t cborSize,
OicSecPstat_t **pstat);
/** This function deallocates the memory for OicSecPstat_t.
*
......
......@@ -224,7 +224,8 @@ typedef enum OicSecDeviceOnboardingState
DOS_RFOTM,
DOS_RFPRO,
DOS_RFNOP,
DOS_SRESET
DOS_SRESET,
DOS_STATE_COUNT
} OicSecDeviceOnboardingState_t;
typedef struct OicSecDostype
......
......@@ -414,7 +414,7 @@ static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx);
/**
* Function to update pstat as Ready for provisioning.
* This function would update 'cm' from bx0000,0010 to bx0000,0000.
* This function would update 'dos.s' to DOS_RFPRO.
*
* @param[in] ctx context value passed to callback from calling function.
* @param[in] selectedDevice selected device information to performing provisioning.
......@@ -424,7 +424,7 @@ static OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx);
/**
* Function to update pstat as Ready for Normal Operation.
* This function would update 'isop' from false to true.
* This function would update 'dos.s' to DOS_RFNOP.
*
* @param[in] ctx context value passed to callback from calling function.
* @param[in] selectedDevice selected device information to performing provisioning.
......@@ -1995,7 +1995,7 @@ static OCStackResult PostOwnerUuid(OTMContext_t* otmCtx)
static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
{
OIC_LOG(DEBUG, TAG, "IN PostOwnershipInformation");
OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
if(!otmCtx || !otmCtx->selectedDeviceInfo)
{
......@@ -2012,7 +2012,7 @@ static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
deviceInfo->connType,
query, sizeof(query), OIC_RSRC_DOXM_URI))
{
OIC_LOG(ERROR, TAG, "PostOwnershipInformation : Failed to generate query");
OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
......@@ -2049,14 +2049,14 @@ static OCStackResult PostOwnershipInformation(OTMContext_t* otmCtx)
OIC_LOG(ERROR, TAG, "OCStack resource error");
}
OIC_LOG(DEBUG, TAG, "OUT PostOwnershipInformation");
OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
return res;
}
static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
{
OIC_LOG(DEBUG, TAG, "IN PostUpdateOperationMode");
OIC_LOG_V(DEBUG, TAG, "IN %s", __func__);
if(!otmCtx || !otmCtx->selectedDeviceInfo)
{
......@@ -2072,7 +2072,7 @@ static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
deviceInfo->connType,
query, sizeof(query), OIC_RSRC_PSTAT_URI))
{
OIC_LOG(ERROR, TAG, "PostUpdateOperationMode : Failed to generate query");
OIC_LOG_V(ERROR, TAG, "%s Failed to generate query", __func__);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
......@@ -2084,8 +2084,13 @@ static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
OCStackResult res = PstatToCBORPayload(deviceInfo->pstat, &secPayload->securityData,
&secPayload->payloadSize, true);
bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_OM] = true;
OCStackResult res = PstatToCBORPayloadPartial(deviceInfo->pstat, &secPayload->securityData,
&secPayload->payloadSize, propertiesToInclude);
if (OC_STACK_OK != res)
{
OCPayloadDestroy((OCPayload *)secPayload);
......@@ -2104,7 +2109,7 @@ static OCStackResult PostUpdateOperationMode(OTMContext_t* otmCtx)
OIC_LOG(ERROR, TAG, "OCStack resource error");
}
OIC_LOG(DEBUG, TAG, "OUT PostUpdateOperationMode");
OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__);
return res;
}
......@@ -2432,7 +2437,7 @@ OCStackResult OTMSetOxmAllowStatus(const OicSecOxm_t oxm, const bool allowStatus
OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
{
OIC_LOG(INFO, TAG, "IN PostProvisioningStatus");
OIC_LOG_V(INFO, TAG, "IN %s", __func__);
if(!otmCtx || !otmCtx->selectedDeviceInfo)
{
......@@ -2440,9 +2445,15 @@ OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
return OC_STACK_INVALID_PARAM;
}
//Change the TAKE_OWNER bit of TM to 0.
// Change the TAKE_OWNER bit of TM to 0 (optional in Client Directed)
otmCtx->selectedDeviceInfo->pstat->tm &= (~TAKE_OWNER);
// Change the dos.s value to RFPRO
otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFPRO;
// TODO [IOT-2052] set the rowneruuid for /pstat directly, so the hack
// in pstatresource.c which sets all rowneruuids can be removed.
OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
if (!secPayload)
{
......@@ -2450,8 +2461,18 @@ OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, true))
// Note [IOT-2052] all the POST payloads in the provisioningclient app
// should be updated to use the Partial payload APIs for the SVRs, so they
// do not include read-only Properties for the Server device current
// state.
bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_DOS] = true;
propertiesToInclude[PSTAT_TM] = true;
if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, propertiesToInclude))
{
OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_INVALID_JSON;
......@@ -2468,7 +2489,7 @@ OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
otmCtx->selectedDeviceInfo->connType,
query, sizeof(query), OIC_RSRC_PSTAT_URI))
{
OIC_LOG(ERROR, TAG, "PostProvisioningStatus : Failed to generate query");
OIC_LOG_V(ERROR, TAG, "%s : Failed to generate query", __func__);
return OC_STACK_ERROR;
}
OIC_LOG_V(DEBUG, TAG, "Query=%s", query);
......@@ -2485,7 +2506,7 @@ OCStackResult PostProvisioningStatus(OTMContext_t* otmCtx)
OIC_LOG(ERROR, TAG, "OCStack resource error");
}
OIC_LOG(INFO, TAG, "OUT PostProvisioningStatus");
OIC_LOG_V(INFO, TAG, "OUT %s", __func__);
return ret;
}
......@@ -2500,7 +2521,6 @@ OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
return OC_STACK_INVALID_PARAM;
}
// TODO [IOT-1763] put RFPRO and other pstat.dos.s updates in the right places.
otmCtx->selectedDeviceInfo->pstat->dos.state = DOS_RFNOP;
OCSecurityPayload *secPayload = (OCSecurityPayload *)OICCalloc(1, sizeof(OCSecurityPayload));
......@@ -2510,8 +2530,13 @@ OCStackResult PostNormalOperationStatus(OTMContext_t* otmCtx)
return OC_STACK_NO_MEMORY;
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
if (OC_STACK_OK != PstatToCBORPayload(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, true))
bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_DOS] = true;
if (OC_STACK_OK != PstatToCBORPayloadPartial(otmCtx->selectedDeviceInfo->pstat,
&secPayload->securityData, &secPayload->payloadSize, propertiesToInclude))
{
OCPayloadDestroy((OCPayload *)secPayload);
return OC_STACK_INVALID_JSON;
......
......@@ -791,7 +791,7 @@ OCStackResult SRPProvisionCredentials(void *ctx, OicSecCredType_t type, size_t k
OIC_LOG(INFO, TAG, "SRPProvisionCredentials: NULL Callback");
return OC_STACK_INVALID_CALLBACK;
}
if ((SYMMETRIC_PAIR_WISE_KEY == type) &&
if ((SYMMETRIC_PAIR_WISE_KEY == type) &&
(NULL != pDev2) &&
(0 == memcmp(&pDev1->doxm->deviceID, &pDev2->doxm->deviceID, sizeof(OicUuid_t))))
{
......@@ -2534,6 +2534,8 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
return OC_STACK_NO_MEMORY;
}
pstat->dos.state = DOS_RESET; // Note [IOT-2052] in OCF 1.0 this is the only
// value that needs to be set to cause RESET
pstat->cm = RESET;
pstat->isOp = false;
pstat->tm = TAKE_OWNER;
......@@ -2557,8 +2559,16 @@ OCStackResult SRPResetDevice(const OCProvisionDev_t* pTargetDev,
}
secPayload->base.type = PAYLOAD_TYPE_SECURITY;
if (OC_STACK_OK != PstatToCBORPayload(pstat, &(secPayload->securityData),
&(secPayload->payloadSize), true))
// Note [IOT-2052] all the POST payloads in the provisioningclient app
// should be updated to use the Partial payload APIs for the SVRs, so they
// do not include read-only Properties for the Server device current
// state.
bool propertiesToInclude[PSTAT_PROPERTY_COUNT];
memset(propertiesToInclude, 0, sizeof(propertiesToInclude));
propertiesToInclude[PSTAT_DOS] = true;
if (OC_STACK_OK != PstatToCBORPayloadPartial(pstat, &(secPayload->securityData),
&(secPayload->payloadSize), propertiesToInclude))
{
OCPayloadDestroy((OCPayload *) secPayload);
OIC_LOG(ERROR, TAG, "Failed to PstatToCBORPayload");
......
......@@ -43,19 +43,14 @@ static const uint16_t CBOR_SIZE = 512;
// Max cbor size payload.
static const uint16_t CBOR_MAX_SIZE = 4400;
// PSTAT Map size - Number of read-write items +2 for rt and if.
// TODO [IOT-2023] isOp becomes read-only; -1 here
static const uint8_t PSTAT_MIN_MAP_SIZE = 7; // dos, isOp, tm, om, rowneruuid, rt, if
// starting pstat map size before adding any Properties, +2 for rt and if.
static const uint8_t PSTAT_EMPTY_MAP_SIZE = 2; // rt, if are included, in addition to props
// .dos Property map size
static const uint8_t PSTAT_DOS_MAP_SIZE = 2; // s, p
// Number of read-only Properties, added to map if not creating a writable-only
// representation.
// TODO [IOT-2023] isOp becomes read-only; +1 here
static const uint8_t READ_ONLY_PROPERTY_SIZE = 2; // cm, sm
static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
static OicSecPstat_t gDefaultPstat =
{
{DOS_RFOTM, false}, // OicSecDostype_t dos
......@@ -73,6 +68,40 @@ static OicSecPstat_t *gPstat = NULL;
static OCResourceHandle gPstatHandle = NULL;
#define R PERMISSION_READ
#define W PERMISSION_WRITE
#define RW PERMISSION_READ | PERMISSION_WRITE
static const uint8_t gPstatPropertyAccessModes[PSTAT_PROPERTY_COUNT][DOS_STATE_COUNT] =
{ // RESET RFOTM RFPRO RFNOP SRESET
{ R, RW, RW, RW, RW }, // .dos
{ R, R, R, R, R }, // .isop
{ R, R, R, R, R }, // .cm
{ R, RW, RW, RW, RW }, // .tm
{ R, RW, RW, RW, RW }, // .om
{ R, R, R, R, R }, // .sm
{ R, RW, R, R, RW } // .rowneruuid
};
#undef R
#undef W
#undef RW
static bool IsPropertyReadOnly(PstatProperty_t p,
OicSecDeviceOnboardingState_t s)
{
bool ret = false;
if (PERMISSION_READ == gPstatPropertyAccessModes[p][s])
{
OIC_LOG_V(DEBUG, TAG, "%s: property %d is read-only in state %d.",
__func__, p, s);
ret = true;
}
return ret;
}
/**
* Get the default value.
*
......@@ -84,12 +113,24 @@ static OicSecPstat_t* GetPstatDefault()
}
/**
* This method is internal method.
* the param roParsed is optionally used to know whether cborPayload has
* at least read only property value or not.
*/
static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload, const size_t size,
OicSecPstat_t **secPstat, bool *roParsed);
* Internal method converts CBOR into PSTAT data, and determines if a read-only
* Property was parsed in the CBOR payload.
*
* @param cborPayload The pstat data in cbor format.
* @param cborSize Size of the cborPayload. In case 0 is provided it assigns CBOR_SIZE (255) value.
* @param pstat Pointer to @ref OicSecPstat_t.
* @param roParsed Ptr to bool marked "true" iff a read-only Property is parsed
* @param stateForReadOnlyCheck The state to use when determining if a Property is
* read-only.
*
* @return ::OC_STACK_OK for Success, otherwise some error value.
*/
static OCStackResult CBORPayloadToPstatBin(const uint8_t *cborPayload,
const size_t size,
OicSecPstat_t **secPstat,
bool *roParsed,
OicSecDeviceOnboardingState_t stateForReadOnlyCheck);
void DeletePstatBinData(OicSecPstat_t* pstat)
{
......@@ -112,7 +153,7 @@ static bool UpdatePersistentStorage(OicSecPstat_t *pstat)
size_t size = 0;
uint8_t *cborPayload = NULL;
OCStackResult ret = PstatToCBORPayload(pstat, &cborPayload, &size, false);
OCStackResult ret = PstatToCBORPayload(pstat, &cborPayload, &size);
if (OC_STACK_OK == ret)
{
if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size))
......@@ -125,8 +166,10 @@ static bool UpdatePersistentStorage(OicSecPstat_t *pstat)
return bRet;
}
OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload, size_t *size,
bool writableOnly)
OCStackResult PstatToCBORPayloadPartial(const OicSecPstat_t *pstat,
uint8_t **payload,
size_t *size,
const bool *propertiesToInclude)
{
if (NULL == pstat || NULL == payload || NULL != *payload || NULL == size)
{
......@@ -143,7 +186,7 @@ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload,
*size = 0;
OCStackResult ret = OC_STACK_ERROR;
size_t pstatMapSize = PSTAT_MIN_MAP_SIZE;
size_t pstatMapSize = PSTAT_EMPTY_MAP_SIZE;
CborEncoder encoder;
CborEncoder pstatMap;
char* strUuid = NULL;
......@@ -155,56 +198,68 @@ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload,
cbor_encoder_init(&encoder, outPayload, cborLen, 0);
// If not creating a writable-Properties-only pstat, grow map to include
// read-only Properties as well.
if (false == writableOnly)
// Calculate map size
for (int i = 0; i < PSTAT_PROPERTY_COUNT; i++)
{
pstatMapSize += READ_ONLY_PROPERTY_SIZE;
if (propertiesToInclude[i])
{
pstatMapSize++;
}
}
OIC_LOG_V(INFO, TAG, "%s: creating pstat CBOR payload with %d Properties.",
__func__, pstatMapSize - PSTAT_EMPTY_MAP_SIZE);
// Top Level Pstat Map
cborEncoderResult = cbor_encoder_create_map(&encoder, &pstatMap, pstatMapSize);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pstat Map.");
// Device Onboarding State Property tag
cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_DOS_NAME,
strlen(OIC_JSON_DOS_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding dos Name Tag.");
// dos Property
if (propertiesToInclude[PSTAT_DOS])
{
OIC_LOG_V(DEBUG, TAG, "%s: including dos Property.", __func__);
// Device Onboarding State Property tag
cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_DOS_NAME,
strlen(OIC_JSON_DOS_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding dos Name Tag.");
// Device Onboarding State Property map
CborEncoder dosMap;
cborEncoderResult = cbor_encoder_create_map(&pstatMap, &dosMap, PSTAT_DOS_MAP_SIZE);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed creating pstat.dos map");
// Device Onboarding State Property map
CborEncoder dosMap;
cborEncoderResult = cbor_encoder_create_map(&pstatMap, &dosMap, PSTAT_DOS_MAP_SIZE);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed creating pstat.dos map");
cborEncoderResult = cbor_encode_text_string(&dosMap, OIC_JSON_S_NAME,
strlen(OIC_JSON_S_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.s tag.");
cborEncoderResult = cbor_encode_text_string(&dosMap, OIC_JSON_S_NAME,
strlen(OIC_JSON_S_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.s tag.");
cborEncoderResult = cbor_encode_int(&dosMap, pstat->dos.state);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.s value.");
cborEncoderResult = cbor_encode_int(&dosMap, pstat->dos.state);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.s value.");
cborEncoderResult = cbor_encode_text_string(&dosMap, OIC_JSON_P_NAME,
strlen(OIC_JSON_P_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.p tag.");
cborEncoderResult = cbor_encode_text_string(&dosMap, OIC_JSON_P_NAME,
strlen(OIC_JSON_P_NAME));
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.p tag.");
cborEncoderResult = cbor_encode_boolean(&dosMap, pstat->dos.pending);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.p value.");
cborEncoderResult = cbor_encode_boolean(&dosMap, pstat->dos.pending);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed adding pstat.dos.p value.");
cborEncoderResult = cbor_encoder_close_container(&pstatMap, &dosMap);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing pstat.dos map");
cborEncoderResult = cbor_encoder_close_container(&pstatMap, &dosMap);
VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed closing pstat.dos map");
}
// isop Property
// TODO [IOT-2023] move isOp inside !writableOnly check
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.");
if (propertiesToInclude[PSTAT_ISOP])
{
OIC_LOG_V(DEBUG, TAG, "%s: including isop Property.", __func__);
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.");
}
// If not creating a writable-Properties-only pstat, add read-only cm.
if (false == writableOnly)
// cm Property
if (propertiesToInclude[PSTAT_CM])
{
// cm Property
OIC_LOG_V(DEBUG, TAG, "%s: including cm Property.", __func__);
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.");
......@@ -213,23 +268,31 @@ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload,
}
// tm Property
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.");
if (propertiesToInclude[PSTAT_TM])
{
OIC_LOG_V(DEBUG, TAG, "%s: including tm Property.", __func__);
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.");
}
// om Property
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.");
if (propertiesToInclude[PSTAT_OM])
{
OIC_LOG_V(DEBUG, TAG, "%s: including om Property.", __func__);
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.");
}
// If not creating a writable-Properties-only pstat, add read-only sm.
if (false == writableOnly)
// sm Property
if (propertiesToInclude[PSTAT_SM])
{
// sm Property
OIC_LOG_V(DEBUG, TAG, "%s: including sm Property.", __func__);
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.");
......@@ -238,15 +301,19 @@ OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload,
}
// rowneruuid property
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;
if (propertiesToInclude[PSTAT_ROWNERUUID])
{
OIC_LOG_V(DEBUG, TAG, "%s: including rowneruuid Property.", __func__);
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;
}
//RT -- Mandatory
CborEncoder rtArray;
......@@ -298,7 +365,7 @@ exit:
// Since the allocated initial memory failed, double the memory.
cborLen += cbor_encoder_get_buffer_size(&encoder, encoder.end);
cborEncoderResult = CborNoError;
ret = PstatToCBORPayload(pstat, payload, &cborLen, writableOnly);
ret = PstatToCBORPayloadPartial(pstat, payload, &cborLen, propertiesToInclude);
if (OC_STACK_OK == ret)
{
*size = cborLen;
......@@ -317,14 +384,30 @@ exit:
return ret;
}
OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat,
uint8_t **payload, size_t *size)
{
bool allProps[PSTAT_PROPERTY_COUNT];
for (int i = 0; i < PSTAT_PROPERTY_COUNT; i++)
{
allProps[i] = true;
}
return PstatToCBORPayloadPartial(pstat, payload, size, allProps);
}