Commit 7315a6b4 authored by leechul's avatar leechul Committed by Randeep

Modify OTM & SRM according to spec CR document.

NOTE : This patch is modified based on ownership transfer CR document.
Please refer to https://workspace.openinterconnect.org/apps/org/workgroup/security_tg/download.php/4703/STG008_OIC%20CR%20Ownership%20Transfer%20sequence%20diagram%20v2.docx
This CR document seems to be applied to next spec.
I'd like to apply CR to save time for prepare 1.1.0 release.

This patch includes the following modifications :
   1. Modify not to include private data when OBT sends owner credential.
        - Please see the step 19 of CR document.

   2. Modify to re-establish secure session using owner credential
      when owner credential was successfully exchanged.
        - We can verify owner credential through re-establish secure session.
        - Please see the step 38,39 of CR docuemnt.

   3. Add logic to handle errors that occurred during ownership transfer.

[Patch #1] Initial upload.
[Patch #2] Add logic to handle errors
[Patch #3] Remove the compile errors and warnings.
[Patch #4] Retrigger
[Patch #5] Retrigger
[Patch #6] Rebase
[Patch #7] Rebase
[Patch #8] Update based on self-review.
[Patch #9] Rebase
[Patch #10] Retrigger
[Patch #11] Modify according to Mr.JongSung Lee's comment.

Change-Id: If3d8f21ef686db86dbfcc1b15382eeebaa232a9d
Signed-off-by: default avatarleechul <chuls.lee@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/5341Reviewed-by: Randeep's avatarRandeep Singh <randeep.s@samsung.com>
Tested-by: Randeep's avatarRandeep Singh <randeep.s@samsung.com>
parent 862f950c
......@@ -94,6 +94,11 @@ OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner);
*/
void DeleteDoxmBinData(OicSecDoxm_t* doxm);
/**
* Function to restore doxm resurce to initial status.
* This function will use in case of error while ownership transfer
*/
void RestoreDoxmToInitState();
#ifdef __cplusplus
}
......
......@@ -61,6 +61,11 @@ char * BinToPstatJSON(const OicSecPstat_t * pstat);
*/
void DeletePstatBinData(OicSecPstat_t* pstat);
/**
* Function to restore pstat resurce to initial status.
* This function will use in case of error while ownership transfer
*/
void RestorePstatToInitState();
#ifdef __cplusplus
}
......
......@@ -323,65 +323,84 @@ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res)
*/
void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info)
{
if(g_otmCtx && endpoint && info)
if(NULL != g_otmCtx && NULL != g_otmCtx->selectedDeviceInfo &&
NULL != endpoint && NULL != info)
{
OIC_LOG_V(INFO, TAG, "Received status from remote device(%s:%d) : %d",
endpoint->addr, endpoint->port, info->result);
//Make sure the address matches.
if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
endpoint->addr,
sizeof(endpoint->addr)) == 0 &&
g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
OicSecDoxm_t* newDevDoxm = g_otmCtx->selectedDeviceInfo->doxm;
if(NULL != newDevDoxm)
{
OCStackResult res = OC_STACK_ERROR;
OicUuid_t emptyUuid = {.id={0}};
//In case of success, send next coaps request.
if(CA_STATUS_OK == info->result)
//Make sure the address matches.
if(strncmp(g_otmCtx->selectedDeviceInfo->endpoint.addr,
endpoint->addr,
sizeof(endpoint->addr)) == 0 &&
g_otmCtx->selectedDeviceInfo->securePort == endpoint->port)
{
//Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
res = PutOwnerUuid(g_otmCtx);
if(OC_STACK_OK != res)
{
OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
SetResult(g_otmCtx, res);
}
}
//In case of failure, re-start the ownership transfer in case of PIN OxM
else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
{
g_otmCtx->selectedDeviceInfo->doxm->owned = false;
g_otmCtx->attemptCnt++;
OCStackResult res = OC_STACK_ERROR;
if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN)
//If temporal secure sesstion established successfully
if(CA_STATUS_OK == info->result &&
false == newDevDoxm->owned &&
memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) == 0)
{
/*
res = RemoveCredential(&g_otmCtx->subIdForPinOxm);
if(OC_STACK_RESOURCE_DELETED != res)
//Send request : PUT /oic/sec/doxm [{... , "devowner":"PT's UUID"}]
res = PutOwnerUuid(g_otmCtx);
if(OC_STACK_OK != res)
{
OIC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res);
OIC_LOG(ERROR, TAG, "OperationModeUpdate : Failed to send owner information");
SetResult(g_otmCtx, res);
return;
}*/
}
}
//In case of authentication failure
else if(CA_DTLS_AUTHENTICATION_FAILURE == info->result)
{
//in case of error from owner credential
if(memcmp(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t)) != 0 &&
true == newDevDoxm->owned)
{
OIC_LOG(ERROR, TAG, "The owner credential may incorrect.");
if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
if(OC_STACK_OK != RemoveCredential(&(newDevDoxm->deviceID)))
{
OIC_LOG(WARNING, TAG, "Failed to remove the invaild owner credential");
}
SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
}
//in case of error from wrong PIN, re-start the ownership transfer
else if(OIC_RANDOM_DEVICE_PIN == newDevDoxm->oxmSel)
{
res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
if(OC_STACK_OK != res)
OIC_LOG(ERROR, TAG, "The PIN number may incorrect.");
memcpy(&(newDevDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
newDevDoxm->owned = false;
g_otmCtx->attemptCnt++;
if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt)
{
res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo);
if(OC_STACK_OK != res)
{
SetResult(g_otmCtx, res);
OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
}
}
else
{
SetResult(g_otmCtx, res);
OIC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer");
OIC_LOG(ERROR, TAG, "User has exceeded the number of authentication attempts.");
SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
}
}
else
{
OIC_LOG(ERROR, TAG, "Failed to establish secure session.");
SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
}
}
else
{
SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE);
}
}
}
}
......@@ -711,6 +730,46 @@ static OCStackApplicationResult OwnerCredentialHandler(void *ctx, OCDoHandle UNU
{
if(otmCtx && otmCtx->selectedDeviceInfo)
{
//Close the temporal secure session to verify the owner credential
CAEndpoint_t* endpoint = (CAEndpoint_t *)&otmCtx->selectedDeviceInfo->endpoint;
endpoint->port = otmCtx->selectedDeviceInfo->securePort;
CAResult_t caResult = CACloseDtlsSession(endpoint);
if(CA_STATUS_OK != caResult)
{
OIC_LOG(ERROR, TAG, "Failed to close DTLS session");
SetResult(otmCtx, caResult);
return OC_STACK_DELETE_TRANSACTION;
}
/**
* If we select NULL cipher,
* client will select appropriate cipher suite according to server's cipher-suite list.
*/
caResult = CASelectCipherSuite(TLS_NULL_WITH_NULL_NULL);
if(CA_STATUS_OK != caResult)
{
OIC_LOG(ERROR, TAG, "Failed to select TLS_NULL_WITH_NULL_NULL");
SetResult(otmCtx, caResult);
return OC_STACK_DELETE_TRANSACTION;
}
/**
* in case of random PIN based OxM,
* revert get_psk_info callback of tinyDTLS to use owner credential.
*/
if(OIC_RANDOM_DEVICE_PIN == otmCtx->selectedDeviceInfo->doxm->oxmSel)
{
OicUuid_t emptyUuid = { .id={0}};
SetUuidForRandomPinOxm(&emptyUuid);
if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
{
OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
SetResult(otmCtx, OC_STACK_INVALID_CALLBACK);
return OC_STACK_DELETE_TRANSACTION;
}
}
//PUT /oic/sec/doxm [{ ..., "owned":"TRUE" }]
res = PutOwnershipInformation(otmCtx);
if(OC_STACK_OK != res)
......@@ -907,8 +966,13 @@ static OCStackResult PutOwnerCredential(OTMContext_t* otmCtx)
OicSecCred_t newCredential;
memcpy(&newCredential, ownerCredential, sizeof(OicSecCred_t));
newCredential.next = NULL;
//Set subject ID as PT's ID
memcpy(&(newCredential.subject), &credSubjectId, sizeof(OicUuid_t));
//Fill private data as empty string
newCredential.privateData.data = NULL;
//Send owner credential to new device : PUT /oic/sec/cred [ owner credential ]
secPayload->securityData = BinToCredJSON(&newCredential);
if (NULL == secPayload->securityData)
......
......@@ -38,6 +38,10 @@
#include "iotvticalendar.h"
#include "ocserverrequest.h"
#ifdef __WITH_DTLS__
#include "global.h"
#endif //__WITH_DTLS__
#ifdef WITH_ARDUINO
#include <string.h>
#else
......@@ -306,8 +310,10 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
(cred->credType & SYMMETRIC_GROUP_KEY) ||
(cred->credType & PIN_PASSWORD))
{
VERIFY_NON_NULL(TAG, jsonObj, ERROR);
VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
if(jsonObj)
{
VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
}
}
#ifdef __WITH_X509__
else if (cred->credType & SIGNED_ASYMMETRIC_KEY)
......@@ -333,6 +339,10 @@ OicSecCred_t * JSONToCredBin(const char * jsonStr)
}
#endif // __WITH_X509__
}
else
{
cred->privateData.data = NULL;
}
//PublicData is mandatory only for SIGNED_ASYMMETRIC_KEY credentials type.
jsonObj = cJSON_GetObjectItem(jsonCred, OIC_JSON_PUBLICDATA_NAME);
......@@ -662,29 +672,19 @@ OCStackResult RemoveAllCredentials(void)
#ifdef __WITH_DTLS__
/**
* Internal function to verify recevied owner PSK.
* Internal function to fill private data of owner PSK.
*
* @param receviedCred recevied Owner Credential from OBT(PT)
* @param receviedCred recevied owner credential from OBT(PT)
* @param ownerAdd address of OBT(PT)
* @param doxm current device's doxm resource
*
* @retval
* true valid ower psk
* false Invalid owner psk or failed to owner psk verification
* true successfully done and valid ower psk information
* false Invalid owner psk information or failed to owner psk generation
*/
static bool isValidOwnerPSK(const OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
static bool FillPrivateDataOfOwnerPSK(OicSecCred_t* receviedCred, const CAEndpoint_t* ownerAddr,
const OicSecDoxm_t* doxm)
{
//Decode received PSK to verify OwnerPSKs match
uint32_t privLen = strlen(receviedCred->privateData.data);
size_t b64BufSize = B64DECODE_OUT_SAFESIZE((privLen + 1) * sizeof(char));
uint8_t* decodeBuff = OICMalloc(b64BufSize);
VERIFY_NON_NULL(TAG, decodeBuff, ERROR);
uint32_t decodedSize = 0;
B64Result b64Ret = b64Decode(receviedCred->privateData.data, privLen,
decodeBuff, b64BufSize, &decodedSize);
VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
//Derive OwnerPSK locally
const char* oxmLabel = GetOxmString(doxm->oxmSel);
VERIFY_NON_NULL(TAG, oxmLabel, ERROR);
......@@ -697,20 +697,38 @@ static bool isValidOwnerPSK(const OicSecCred_t* receviedCred, const CAEndpoint_t
ownerPSK, OWNER_PSK_LENGTH_128);
VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR);
OIC_LOG_V(DEBUG, TAG, "Oxm Label = %s", oxmLabel);
OIC_LOG_V(DEBUG, TAG, "PSK size compare : %s",
OWNER_PSK_LENGTH_128 == decodedSize ? "TRUE" : "FALSE");
OIC_LOG_V(DEBUG, TAG, "SubjectID compare = %s",
memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 ?
"TRUE" : "FALSE");
OIC_LOG_V(DEBUG, TAG, "Owner PSK compare = %s",
memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 ? "TRUE" : "FALSE");
//Verify OwnerPSKs match
return (OWNER_PSK_LENGTH_128 == decodedSize &&
memcmp(ownerPSK, decodeBuff, OWNER_PSK_LENGTH_128) == 0 &&
memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0);
OIC_LOG(DEBUG, TAG, "OwnerPSK dump :");
OIC_LOG_BUFFER(DEBUG, TAG, ownerPSK, OWNER_PSK_LENGTH_128);
//Generate owner credential based on recevied credential information
size_t b64BufSize = B64ENCODE_OUT_SAFESIZE(OWNER_PSK_LENGTH_128 * sizeof(char));
uint8_t* encodeBuff = OICMalloc((b64BufSize + 1) * sizeof(char));
VERIFY_NON_NULL(TAG, encodeBuff, ERROR);
uint32_t encodedSize = 0;
B64Result b64Ret = b64Encode(ownerPSK, OWNER_PSK_LENGTH_128,
(char*)encodeBuff, b64BufSize + 1, &encodedSize);
VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
encodeBuff[encodedSize] = '\0';
//memory re-allocation for private data
OICFree(receviedCred->privateData.data);
receviedCred->privateData.data = (char*)OICMalloc((encodedSize + 1) * sizeof(char));
VERIFY_NON_NULL(TAG, receviedCred->privateData.data, ERROR);
//fill the base64 encoded private data
strncpy(receviedCred->privateData.data, (char*)encodeBuff, b64BufSize + 1);
OIC_LOG(INFO, TAG, "PrivateData of OwnerPSK was calculated successfully");
//deallocate local memory
OICFree(encodeBuff);
//Verify OwnerPSK information
return (memcmp(&(receviedCred->subject), &(doxm->owner), sizeof(OicUuid_t)) == 0 &&
receviedCred->credType == SYMMETRIC_PAIR_WISE_KEY);
exit:
//receviedCred->privateData.data will be deallocated when deleting credential.
OICFree(encodeBuff);
return false;
}
......@@ -736,9 +754,14 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR
case SYMMETRIC_PAIR_WISE_KEY:
{
OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle;
if(isValidOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
if(FillPrivateDataOfOwnerPSK(cred, (CAEndpoint_t *)&request->devAddr, doxm))
{
OIC_LOG(ERROR, TAG, "OwnerPKS is matched");
if(OC_STACK_RESOURCE_DELETED == RemoveCredential(&cred->subject))
{
OIC_LOG(WARNING, TAG, "The credential with the same subject ID was detected!");
}
OIC_LOG(ERROR, TAG, "OwnerPSK was generated successfully.");
if(OC_STACK_OK == AddCredential(cred))
{
ret = OC_EH_RESOURCE_CREATED;
......@@ -755,6 +778,44 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR
ret = OC_EH_ERROR;
}
if(OC_EH_RESOURCE_CREATED == ret)
{
/**
* in case of random PIN based OxM,
* revert get_psk_info callback of tinyDTLS to use owner credential.
*/
if(OIC_RANDOM_DEVICE_PIN == doxm->oxmSel)
{
OicUuid_t emptyUuid = { .id={0}};
SetUuidForRandomPinOxm(&emptyUuid);
if(CA_STATUS_OK != CARegisterDTLSCredentialsHandler(GetDtlsPskCredentials))
{
OIC_LOG(ERROR, TAG, "Failed to revert DTLS credential handler.");
ret = OC_EH_ERROR;
break;
}
}
//Select cipher suite to use owner PSK
if(CA_STATUS_OK != CAEnableAnonECDHCipherSuite(false))
{
OIC_LOG(ERROR, TAG, "Failed to disable anonymous cipher suite");
ret = OC_EH_ERROR;
}
else
{
OIC_LOG(INFO, TAG, "Anonymous cipher suite is DISABLED");
}
if(CA_STATUS_OK !=
CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256))
{
OIC_LOG(ERROR, TAG, "Failed to select cipher suite");
ret = OC_EH_ERROR;
}
}
break;
}
case SYMMETRIC_GROUP_KEY:
......@@ -774,6 +835,16 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR
break;
}
}
if(OC_EH_RESOURCE_CREATED != ret)
{
/*
* If some error is occured while ownership transfer,
* ownership transfer related resource should be revert back to initial status.
*/
RestoreDoxmToInitState();
RestorePstatToInitState();
}
}
else
{
......@@ -796,6 +867,15 @@ static OCEntityHandlerResult HandlePutRequest(const OCEntityHandlerRequest * ehR
#endif//__WITH_DTLS__
}
if(OC_EH_RESOURCE_CREATED != ret)
{
if(OC_STACK_OK != RemoveCredential(&cred->subject))
{
OIC_LOG(WARNING, TAG, "Failed to remove the invalid credential");
}
FreeCred(cred);
}
return ret;
}
......@@ -812,7 +892,7 @@ static OCEntityHandlerResult HandlePostRequest(const OCEntityHandlerRequest * eh
//discarded and the next available credId will be assigned
//to it before getting appended to the existing credential
//list and updating svr database.
ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
ret = (OC_STACK_OK == AddCredential(cred))? OC_EH_RESOURCE_CREATED : OC_EH_ERROR;
}
return ret;
......
......@@ -24,6 +24,7 @@
#include "cJSON.h"
#include "resourcemanager.h"
#include "doxmresource.h"
#include "pstatresource.h"
#include "psinterface.h"
#include "utlist.h"
#include "srmresourcestrings.h"
......@@ -576,7 +577,6 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
*/
caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm);
VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR);
ehRet = OC_EH_OK;
}
else
......@@ -592,12 +592,6 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
//Save the owner's UUID to derive owner credential
memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t));
// OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle;
// //Generate new credential for provisioning tool
// ehRet = AddOwnerPSK((CAEndpoint_t*)(&request->devAddr), newDoxm,
// (uint8_t*)OXM_RANDOM_DEVICE_PIN, strlen(OXM_RANDOM_DEVICE_PIN));
// VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR);
//Update new state in persistent storage
if((UpdatePersistentStorage(gDoxm) == true))
{
......@@ -623,7 +617,7 @@ static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest
{
gDoxm->owned = true;
// Update new state in persistent storage
if (true == UpdatePersistentStorage(gDoxm))
if (UpdatePersistentStorage(gDoxm))
{
ehRet = OC_EH_OK;
}
......@@ -642,17 +636,11 @@ exit:
"DOXM will be reverted.");
/*
* If persistent storage update failed, revert back the state
* for global variable.
* If some error is occured while ownership transfer,
* ownership transfer related resource should be revert back to initial status.
*/
gDoxm->owned = false;
gDoxm->oxmSel = OIC_JUST_WORKS;
memset(&(gDoxm->owner), 0, sizeof(OicUuid_t));
if(!UpdatePersistentStorage(gDoxm))
{
OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage");
}
RestoreDoxmToInitState();
RestorePstatToInitState();
}
//Send payload to request originator
......@@ -813,6 +801,14 @@ OCStackResult InitDoxmResource()
{
gDoxm = GetDoxmDefault();
}
//In case of the server is shut down unintentionally, we should initialize the owner
if(false == gDoxm->owned)
{
OicUuid_t emptyUuid = {.id={0}};
memcpy(&gDoxm->owner, &emptyUuid, sizeof(OicUuid_t));
}
ret = CheckDeviceID();
if (ret == OC_STACK_OK)
{
......@@ -887,3 +883,25 @@ OCStackResult GetDoxmDevOwnerId(OicUuid_t *devOwner)
}
return retVal;
}
/**
* Function to restore doxm resurce to initial status.
* This function will use in case of error while ownership transfer
*/
void RestoreDoxmToInitState()
{
if(gDoxm)
{
OIC_LOG(INFO, TAG, "DOXM resource will revert back to initial status.");
OicUuid_t emptyUuid = {.id={0}};
memcpy(&(gDoxm->owner), &emptyUuid, sizeof(OicUuid_t));
gDoxm->owned = false;
gDoxm->oxmSel = OIC_JUST_WORKS;
if(!UpdatePersistentStorage(gDoxm))
{
OIC_LOG(ERROR, TAG, "Failed to revert DOXM in persistent storage");
}
}
}
......@@ -24,6 +24,7 @@
#include "cJSON.h"
#include "resourcemanager.h"
#include "pstatresource.h"
#include "doxmresource.h"
#include "psinterface.h"
#include "utlist.h"
#include "base64.h"
......@@ -48,7 +49,9 @@ static OicSecPstat_t gDefaultPstat =
&gSm, // OicSecDpom_t *sm
0, // uint16_t commitHash
};
static OicSecPstat_t *gPstat = NULL;
static OCResourceHandle gPstatHandle = NULL;
void DeletePstatBinData(OicSecPstat_t* pstat)
......@@ -190,6 +193,35 @@ exit:
return pstat;
}
/**
* Function to update persistent storage
*/
static bool UpdatePersistentStorage(OicSecPstat_t * pstat)
{
bool bRet = false;
if (pstat)
{
// Convert pstat data into JSON for update to persistent storage
char *jsonStr = BinToPstatJSON(pstat);
if (jsonStr)
{
cJSON *jsonPstat = cJSON_Parse(jsonStr);
OICFree(jsonStr);
if (jsonPstat &&
(OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat)))
{
bRet = true;
}
cJSON_Delete(jsonPstat);
}
}
return bRet;
}
/**
* The entity handler determines how to process a GET request.
*/
......@@ -264,18 +296,22 @@ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest
}
}
// Convert pstat data into JSON for update to persistent storage
char *jsonStr = BinToPstatJSON(gPstat);
if (jsonStr)
if(UpdatePersistentStorage(gPstat))
{
cJSON *jsonPstat = cJSON_Parse(jsonStr);
OICFree(jsonStr);
if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat))
{
ehRet = OC_EH_OK;
}
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))
{
......@@ -380,6 +416,7 @@ OCStackResult InitPstatResource()
{
gPstat = GetPstatDefault();
}
// Instantiate 'oic.sec.pstat'
ret = CreatePstatResource();
......@@ -402,3 +439,28 @@ OCStackResult DeInitPstatResource()
return OCDeleteResource(gPstatHandle);
}