1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
25 #include "oic_malloc.h"
26 #include "ocpayload.h"
27 #include "payload_logging.h"
28 #include "resourcemanager.h"
29 #include "pstatresource.h"
30 #include "doxmresource.h"
31 #include "psinterface.h"
32 #include "srmresourcestrings.h"
33 #include "srmutility.h"
35 #define TAG "SRM-PSTAT"
37 /** Default cbor payload size. This value is increased in case of CborErrorOutOfMemory.
38 * The value of payload size is increased until reaching below max cbor size. */
39 static const uint16_t CBOR_SIZE = 512;
41 // Max cbor size payload.
42 static const uint16_t CBOR_MAX_SIZE = 4400;
44 // PSTAT Map size - Number of mandatory items
45 static const uint8_t PSTAT_MAP_SIZE = 9;
47 static OicSecDpom_t gSm = SINGLE_SERVICE_CLIENT_DRIVEN;
48 static OicSecPstat_t gDefaultPstat =
51 (OicSecDpm_t)(BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
52 PROVISION_CREDENTIALS | PROVISION_ACLS), // OicSecDpm_t cm
53 (OicSecDpm_t)(TAKE_OWNER | BOOTSTRAP_SERVICE | SECURITY_MANAGEMENT_SERVICES |
54 PROVISION_CREDENTIALS | PROVISION_ACLS), // OicSecDpm_t tm
55 {.id = {0}}, // OicUuid_t deviceID
56 SINGLE_SERVICE_CLIENT_DRIVEN, // OicSecDpom_t om */
57 1, // the number of elts in Sms
58 &gSm, // OicSecDpom_t *sm
59 0, // uint16_t commitHash
60 {.id = {0}}, // OicUuid_t rownerID
63 static OicSecPstat_t *gPstat = NULL;
65 static OCResourceHandle gPstatHandle = NULL;
67 void DeletePstatBinData(OicSecPstat_t* pstat)
71 //Clean 'supported modes' field
79 OCStackResult PstatToCBORPayload(const OicSecPstat_t *pstat, uint8_t **payload, size_t *size)
81 if (NULL == pstat || NULL == payload || NULL != *payload || NULL == size)
83 return OC_STACK_INVALID_PARAM;
86 size_t cborLen = *size;
95 OCStackResult ret = OC_STACK_ERROR;
101 int64_t cborEncoderResult = CborNoError;
103 uint8_t *outPayload = (uint8_t *)OICCalloc(1, cborLen);
104 VERIFY_NON_NULL(TAG, outPayload, ERROR);
105 cbor_encoder_init(&encoder, outPayload, cborLen, 0);
107 cborEncoderResult = cbor_encoder_create_map(&encoder, &pstatMap, PSTAT_MAP_SIZE);
108 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Pstat Map.");
110 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ISOP_NAME,
111 strlen(OIC_JSON_ISOP_NAME));
112 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Tag.");
113 cborEncoderResult = cbor_encode_boolean(&pstatMap, pstat->isOp);
114 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ISOP Name Value.");
116 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_DEVICE_ID_NAME,
117 strlen(OIC_JSON_DEVICE_ID_NAME));
118 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Tag.");
119 ret = ConvertUuidToStr(&pstat->deviceID, &strUuid);
120 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
121 cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid));
122 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Device Id Value.");
126 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_CM_NAME,
127 strlen(OIC_JSON_CM_NAME));
128 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Tag.");
129 cborEncoderResult = cbor_encode_int(&pstatMap, pstat->cm);
130 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding CM Name Value.");
132 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_TM_NAME,
133 strlen(OIC_JSON_TM_NAME));
134 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Tag.");
135 cborEncoderResult = cbor_encode_int(&pstatMap, pstat->tm);
136 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding TM Name Value.");
138 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_OM_NAME,
139 strlen(OIC_JSON_OM_NAME));
140 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Tag.");
141 cborEncoderResult = cbor_encode_int(&pstatMap, pstat->om);
142 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding OM Name Value.");
144 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_SM_NAME,
145 strlen(OIC_JSON_SM_NAME));
146 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Tag.");
147 cborEncoderResult = cbor_encode_int(&pstatMap, pstat->sm[0]);
148 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding SM Name Value.");
150 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_ROWNERID_NAME,
151 strlen(OIC_JSON_ROWNERID_NAME));
152 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Tag.");
153 ret = ConvertUuidToStr(&pstat->rownerID, &strUuid);
154 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret , ERROR);
155 cborEncoderResult = cbor_encode_text_string(&pstatMap, strUuid, strlen(strUuid));
156 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding ROwner Id Value.");
162 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_RT_NAME,
163 strlen(OIC_JSON_RT_NAME));
164 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Name Tag.");
165 cborEncoderResult = cbor_encoder_create_array(&pstatMap, &rtArray, 1);
166 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding RT Value.");
167 for (size_t i = 0; i < 1; i++)
169 cborEncoderResult = cbor_encode_text_string(&rtArray, OIC_RSRC_TYPE_SEC_PSTAT,
170 strlen(OIC_RSRC_TYPE_SEC_PSTAT));
171 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding RT Value.");
173 cborEncoderResult = cbor_encoder_close_container(&pstatMap, &rtArray);
174 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing RT.");
178 cborEncoderResult = cbor_encode_text_string(&pstatMap, OIC_JSON_IF_NAME,
179 strlen(OIC_JSON_IF_NAME));
180 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Name Tag.");
181 cborEncoderResult = cbor_encoder_create_array(&pstatMap, &ifArray, 1);
182 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Addding IF Value.");
183 for (size_t i = 0; i < 1; i++)
185 cborEncoderResult = cbor_encode_text_string(&ifArray, OC_RSRVD_INTERFACE_DEFAULT,
186 strlen(OC_RSRVD_INTERFACE_DEFAULT));
187 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding IF Value.");
189 cborEncoderResult = cbor_encoder_close_container(&pstatMap, &ifArray);
190 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Closing IF.");
192 cborEncoderResult = cbor_encoder_close_container(&encoder, &pstatMap);
193 VERIFY_CBOR_SUCCESS(TAG, cborEncoderResult, "Failed Adding Closing PSTAT Map.");
195 if (CborNoError == cborEncoderResult)
197 *size = encoder.ptr - outPayload;
198 *payload = outPayload;
202 if ((CborErrorOutOfMemory == cborEncoderResult) && (cborLen < CBOR_MAX_SIZE))
204 // reallocate and try again!
206 // Since the allocated initial memory failed, double the memory.
207 cborLen += encoder.ptr - encoder.end;
208 cborEncoderResult = CborNoError;
209 ret = PstatToCBORPayload(pstat, payload, &cborLen);
210 if (OC_STACK_OK == ret)
216 if ((CborNoError != cborEncoderResult) || (OC_STACK_OK != ret))
222 ret = OC_STACK_ERROR;
228 OCStackResult CBORPayloadToPstat(const uint8_t *cborPayload, const size_t size,
229 OicSecPstat_t **secPstat)
231 if (NULL == cborPayload || NULL == secPstat || NULL != *secPstat || 0 == size)
233 return OC_STACK_INVALID_PARAM;
236 OCStackResult ret = OC_STACK_ERROR;
241 CborError cborFindResult = CborNoError;
242 char *strUuid = NULL;
245 cbor_parser_init(cborPayload, size, 0, &parser, &pstatCbor);
246 CborValue pstatMap = { .parser = NULL };
248 OicSecPstat_t *pstat = NULL;
249 cborFindResult = cbor_value_enter_container(&pstatCbor, &pstatMap);
250 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding PSTAT Map.");
252 pstat = (OicSecPstat_t *)OICCalloc(1, sizeof(OicSecPstat_t));
253 VERIFY_NON_NULL(TAG, pstat, ERROR);
255 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ISOP_NAME, &pstatMap);
256 if (CborNoError == cborFindResult && cbor_value_is_boolean(&pstatMap))
258 cborFindResult = cbor_value_get_boolean(&pstatMap, &pstat->isOp);
259 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding isOp Value.");
262 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_DEVICE_ID_NAME, &pstatMap);
263 if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap))
265 cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL);
266 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding Device Id Value.");
267 ret = ConvertStrToUuid(strUuid , &pstat->deviceID);
268 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
273 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_CM_NAME, &pstatMap);
274 if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
276 cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->cm);
277 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding CM.");
280 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_TM_NAME, &pstatMap);
281 if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
283 cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->tm);
284 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding TM.");
287 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_OM_NAME, &pstatMap);
288 if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
290 cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->om);
291 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding OM.");
294 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_SM_NAME, &pstatMap);
295 if (CborNoError == cborFindResult && cbor_value_is_integer(&pstatMap))
298 pstat->sm = (OicSecDpom_t*)OICCalloc(pstat->smLen, sizeof(OicSecDpom_t));
299 cborFindResult = cbor_value_get_int(&pstatMap, (int *) &pstat->sm[0]);
300 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding SM.");
304 cborFindResult = cbor_value_map_find_value(&pstatCbor, OIC_JSON_ROWNERID_NAME, &pstatMap);
305 if (CborNoError == cborFindResult && cbor_value_is_text_string(&pstatMap))
307 cborFindResult = cbor_value_dup_text_string(&pstatMap, &strUuid , &len, NULL);
308 VERIFY_CBOR_SUCCESS(TAG, cborFindResult, "Failed Finding ROwner Id Value.");
309 ret = ConvertStrToUuid(strUuid , &pstat->rownerID);
310 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
319 if (CborNoError != cborFindResult)
321 OIC_LOG(ERROR, TAG, "CBORPayloadToPstat failed");
322 DeletePstatBinData(pstat);
325 ret = OC_STACK_ERROR;
332 * Function to update persistent storage
334 static bool UpdatePersistentStorage(OicSecPstat_t *pstat)
339 uint8_t *cborPayload = NULL;
340 OCStackResult ret = PstatToCBORPayload(pstat, &cborPayload, &size);
341 if (OC_STACK_OK == ret)
343 if (OC_STACK_OK == UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size))
347 OICFree(cborPayload);
353 static bool ValidateQuery(const char * query)
355 OIC_LOG (DEBUG, TAG, "In ValidateQuery");
361 bool bInterfaceQry = false; // does querystring contains 'if' query ?
362 bool bInterfaceMatch = false; // does 'if' query matches with oic.if.baseline ?
364 OicParseQueryIter_t parseIter = {.attrPos = NULL};
366 ParseQueryIterInit((unsigned char*)query, &parseIter);
368 while (GetNextQuery(&parseIter))
370 if (strncasecmp((char *)parseIter.attrPos, OC_RSRVD_INTERFACE, parseIter.attrLen) == 0)
372 bInterfaceQry = true;
373 if ((strncasecmp((char *)parseIter.valPos, OC_RSRVD_INTERFACE_DEFAULT, parseIter.valLen) == 0))
375 bInterfaceMatch = true;
379 return (bInterfaceQry ? bInterfaceMatch: true);
383 * The entity handler determines how to process a GET request.
385 static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest)
387 OCEntityHandlerResult ehRet = OC_EH_OK;
389 OIC_LOG(INFO, TAG, "HandlePstatGetRequest processing GET request");
391 //Checking if Get request is a query.
392 if (ehRequest->query)
394 OIC_LOG_V(DEBUG,TAG,"query:%s",ehRequest->query);
395 OIC_LOG(DEBUG, TAG, "HandlePstatGetRequest processing query");
396 if (!ValidateQuery(ehRequest->query))
403 * For GET or Valid Query request return doxm resource CBOR payload.
404 * For non-valid query return NULL json payload.
405 * A device will 'always' have a default Pstat, so PstatToCBORPayload will
406 * return valid pstat resource json.
409 uint8_t *payload = NULL;
410 if (ehRet == OC_EH_OK)
412 if(OC_STACK_OK != PstatToCBORPayload(gPstat, &payload, &size))
414 OIC_LOG(WARNING, TAG, "PstatToCBORPayload failed in HandlePstatGetRequest");
418 // Send response payload to request originator
419 if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size))
422 OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest");
429 * The entity handler determines how to process a POST request.
430 * Per the REST paradigm, POST can also be used to update representation of existing
431 * resource or create a new resource.
432 * For pstat, it updates only tm and om.
434 static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest *ehRequest)
436 OCEntityHandlerResult ehRet = OC_EH_ERROR;
437 OIC_LOG(INFO, TAG, "HandlePstatPostRequest processing POST request");
438 OicSecPstat_t *pstat = NULL;
439 static uint16_t prevMsgId = 0;
441 if (ehRequest->payload)
443 uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData;
444 size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize;
445 VERIFY_NON_NULL(TAG, payload, ERROR);
447 OCStackResult ret = CBORPayloadToPstat(payload, size, &pstat);
448 VERIFY_NON_NULL(TAG, pstat, ERROR);
449 if (OC_STACK_OK == ret)
451 if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp)
453 gPstat->cm = pstat->cm;
454 OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning");
456 else if (false == (pstat->cm & TAKE_OWNER) && true == pstat->isOp)
458 gPstat->isOp =pstat->isOp;
459 OIC_LOG (INFO, TAG, "State changed to Ready for Normal Operation");
463 OIC_LOG(DEBUG, TAG, "Invalid Device provisionig state");
465 if (pstat->om != MULTIPLE_SERVICE_SERVER_DRIVEN && gPstat)
468 * Check if the operation mode is in the supported provisioning services
469 * operation mode list.
471 for (size_t i=0; i< gPstat->smLen; i++)
473 if(gPstat->sm[i] == pstat->om)
475 gPstat->om = pstat->om;
480 // Convert pstat data into CBOR for update to persistent storage
481 if (UpdatePersistentStorage(gPstat))
488 if(OC_EH_OK != ehRet)
491 * If some error is occured while ownership transfer,
492 * ownership transfer related resource should be revert back to initial status.
494 const OicSecDoxm_t* doxm = GetDoxmResourceData();
497 if(!doxm->owned && prevMsgId != ehRequest->messageID)
499 RestoreDoxmToInitState();
500 RestorePstatToInitState();
505 OIC_LOG(ERROR, TAG, "Invalid DOXM resource.");
510 prevMsgId = ehRequest->messageID;
514 //Send payload to request originator
515 if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL, 0))
518 OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest");
520 DeletePstatBinData(pstat);
525 * This internal method is the entity handler for pstat resources.
527 OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag,
528 OCEntityHandlerRequest * ehRequest,
532 OCEntityHandlerResult ehRet = OC_EH_ERROR;
533 // This method will handle REST request (GET/POST) for /oic/sec/pstat
534 if (flag & OC_REQUEST_FLAG)
536 OIC_LOG(INFO, TAG, "Flag includes OC_REQUEST_FLAG");
537 switch (ehRequest->method)
540 ehRet = HandlePstatGetRequest(ehRequest);
543 ehRet = HandlePstatPostRequest(ehRequest);
547 SendSRMResponse(ehRequest, ehRet, NULL, 0);
555 * This internal method is used to create '/oic/sec/pstat' resource.
557 OCStackResult CreatePstatResource()
559 OCStackResult ret = OCCreateResource(&gPstatHandle,
560 OIC_RSRC_TYPE_SEC_PSTAT,
561 OC_RSRVD_INTERFACE_DEFAULT,
568 if (OC_STACK_OK != ret)
570 OIC_LOG(FATAL, TAG, "Unable to instantiate pstat resource");
571 DeInitPstatResource();
577 * Get the default value.
579 * @return the gDefaultPstat pointer.
581 static OicSecPstat_t* GetPstatDefault()
583 return &gDefaultPstat;
586 OCStackResult InitPstatResource()
588 OCStackResult ret = OC_STACK_ERROR;
590 // Read Pstat resource from PS
591 uint8_t *data = NULL;
593 OicUuid_t emptyUuid = {.id={0}};
594 ret = GetSecureVirtualDatabaseFromPS(OIC_JSON_PSTAT_NAME, &data, &size);
595 // If database read failed
596 if (OC_STACK_OK != ret)
598 OIC_LOG (DEBUG, TAG, "ReadSVDataFromPS failed");
602 // Read ACL resource from PS
603 ret = CBORPayloadToPstat(data, size, &gPstat);
607 * If SVR database in persistent storage got corrupted or
608 * is not available for some reason, a default pstat is created
609 * which allows user to initiate pstat provisioning again.
611 if ((OC_STACK_OK != ret) || !gPstat)
613 gPstat = GetPstatDefault();
615 VERIFY_NON_NULL(TAG, gPstat, FATAL);
617 //In case of Pstat's device id is empty, fill the device id as doxm's device id.
618 if(0 == memcmp(&gPstat->deviceID, &emptyUuid, sizeof(OicUuid_t)))
620 OicUuid_t doxmUuid = {.id={0}};
621 if(OC_STACK_OK == GetDoxmDeviceID(&doxmUuid))
623 memcpy(&gPstat->deviceID, &doxmUuid, sizeof(OicUuid_t));
627 // Instantiate 'oic.sec.pstat'
628 ret = CreatePstatResource();
631 if (OC_STACK_OK != ret)
633 DeInitPstatResource();
638 OCStackResult DeInitPstatResource()
640 if (gPstat != &gDefaultPstat)
642 DeletePstatBinData(gPstat);
645 return OCDeleteResource(gPstatHandle);
649 * Function to restore pstat resurce to initial status.
650 * This function will use in case of error while ownership transfer
652 void RestorePstatToInitState()
656 OIC_LOG(INFO, TAG, "PSTAT resource will revert back to initial status.");
658 gPstat->cm = (OicSecDpm_t)(gPstat->cm | TAKE_OWNER);
659 gPstat->tm = (OicSecDpm_t)(gPstat->tm & (~TAKE_OWNER));
660 gPstat->om = SINGLE_SERVICE_CLIENT_DRIVEN;
661 if(gPstat->sm && 0 < gPstat->smLen)
663 gPstat->sm[0] = SINGLE_SERVICE_CLIENT_DRIVEN;
666 if (!UpdatePersistentStorage(gPstat))
668 OIC_LOG(ERROR, TAG, "Failed to revert PSTAT in persistent storage");
673 OCStackResult SetPstatRownerId(const OicUuid_t* newROwner)
675 OCStackResult ret = OC_STACK_ERROR;
676 uint8_t *cborPayload = NULL;
678 OicUuid_t prevId = {.id={0}};
680 if(NULL == newROwner)
682 ret = OC_STACK_INVALID_PARAM;
686 ret = OC_STACK_NO_RESOURCE;
689 if(newROwner && gPstat)
691 memcpy(prevId.id, gPstat->rownerID.id, sizeof(prevId.id));
692 memcpy(gPstat->rownerID.id, newROwner->id, sizeof(newROwner->id));
694 ret = PstatToCBORPayload(gPstat, &cborPayload, &size);
695 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
697 ret = UpdateSecureResourceInPS(OIC_JSON_PSTAT_NAME, cborPayload, size);
698 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, ERROR);
700 OICFree(cborPayload);
706 OICFree(cborPayload);
707 memcpy(gPstat->rownerID.id, prevId.id, sizeof(prevId.id));
712 * This function returns the "isop" status of the device.
714 * @return true iff pstat.isop == 1, else false
721 OCStackResult GetPstatRownerId(OicUuid_t *rowneruuid)
723 OCStackResult retVal = OC_STACK_ERROR;
726 *rowneruuid = gPstat->rownerID;
727 retVal = OC_STACK_OK;