/** * This internal method is the entity handler for pstat resources. */ OCEntityHandlerResult PstatEntityHandler(OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest, void *callbackParam) { (void)callbackParam; OCEntityHandlerResult ehRet = OC_EH_ERROR; // This method will handle REST request (GET/POST) for /oic/sec/pstat if (flag & OC_REQUEST_FLAG) { OC_LOG (INFO, TAG, "Flag includes OC_REQUEST_FLAG"); switch (ehRequest->method) { case OC_REST_GET: ehRet = HandlePstatGetRequest(ehRequest); break; case OC_REST_PUT: ehRet = HandlePstatPutRequest(ehRequest); break; default: ehRet = OC_EH_ERROR; SendSRMResponse(ehRequest, ehRet, NULL); break; } } return ehRet; }
/* * This internal method is the entity handler for DOXM resources. */ OCEntityHandlerResult DoxmEntityHandler (OCEntityHandlerFlag flag, OCEntityHandlerRequest * ehRequest, void* callbackParam) { (void)callbackParam; OCEntityHandlerResult ehRet = OC_EH_ERROR; if(NULL == ehRequest) { return ehRet; } if (flag & OC_REQUEST_FLAG) { OIC_LOG (DEBUG, TAG, "Flag includes OC_REQUEST_FLAG"); switch (ehRequest->method) { case OC_REST_GET: ehRet = HandleDoxmGetRequest(ehRequest); break; case OC_REST_PUT: ehRet = HandleDoxmPutRequest(ehRequest); break; default: ehRet = OC_EH_ERROR; SendSRMResponse(ehRequest, ehRet, NULL); break; } } return ehRet; }
/** * The entity handler determines how to process a GET request. */ static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest) { // Convert ACL data into JSON for transmission char* jsonStr = BinToPstatJSON(gPstat); // A device should always have a default pstat. Therefore, jsonStr should never be NULL. OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR); // Send response payload to request originator SendSRMResponse(ehRequest, ehRet, jsonStr); OICFree(jsonStr); return ehRet; }
/** * The entity handler determines how to process a GET request. */ static OCEntityHandlerResult HandlePstatGetRequest (const OCEntityHandlerRequest * ehRequest) { OIC_LOG(INFO, TAG, "HandlePstatGetRequest processing GET request"); // Convert ACL data into CBOR for transmission size_t size = 0; uint8_t *payload = NULL; OCStackResult res = PstatToCBORPayload(gPstat, &payload, &size); // A device should always have a default pstat. Therefore, payload should never be NULL. OCEntityHandlerResult ehRet = (res == OC_STACK_OK) ? OC_EH_OK : OC_EH_ERROR; // Send response payload to request originator if (OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, payload, size)) { ehRet = OC_EH_ERROR; OIC_LOG(ERROR, TAG, "SendSRMResponse failed in HandlePstatGetRequest"); } OICFree(payload); return ehRet; }
static OCEntityHandlerResult HandleDoxmGetRequest (const OCEntityHandlerRequest * ehRequest) { char* jsonStr = NULL; OCEntityHandlerResult ehRet = OC_EH_OK; OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing GET request"); //Checking if Get request is a query. if(ehRequest->query) { OIC_LOG (DEBUG, TAG, "HandleDoxmGetRequest processing query"); if(!ValidateQuery(ehRequest->query)) { ehRet = OC_EH_ERROR; } } /* * For GET or Valid Query request return doxm resource json payload. * For non-valid query return NULL json payload. * A device will 'always' have a default Doxm, so BinToDoxmJSON will * return valid doxm resource json. */ jsonStr = (ehRet == OC_EH_OK) ? BinToDoxmJSON(gDoxm) : NULL; // Send response payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, jsonStr)) { OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandleDoxmGetRequest"); } OICFree(jsonStr); return ehRet; }
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest) { OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing PUT request"); OCEntityHandlerResult ehRet = OC_EH_ERROR; OicUuid_t emptyOwner = {.id = {0}}; /* * Convert JSON Doxm data into binary. This will also validate * the Doxm data received. */ OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData); if (newDoxm) { // Iotivity SRM ONLY supports OIC_JUST_WORKS now if (OIC_JUST_WORKS == newDoxm->oxmSel) { if ((false == gDoxm->owned) && (false == newDoxm->owned)) { /* * If current state of the device is un-owned, enable * anonymous ECDH cipher in tinyDTLS so that Provisioning * tool can initiate JUST_WORKS ownership transfer process. */ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0) { OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite"); #ifdef __WITH_DTLS__ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR; #endif //__WITH_DTLS__ goto exit; } else { #ifdef __WITH_DTLS__ //Save the owner's UUID to derive owner credential memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)); // OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; // //Generating OwnerPSK // OIC_LOG (INFO, TAG, "Doxm EntityHandle generating OwnerPSK"); // //Generate new credential for provisioning tool // ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm, // (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS)); // VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR); // Update new state in persistent storage if (true == UpdatePersistentStorage(gDoxm)) { ehRet = OC_EH_OK; } else { OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage"); ehRet = OC_EH_ERROR; } /* * Disable anonymous ECDH cipher in tinyDTLS since device is now * in owned state. */ CAResult_t caRes = CA_STATUS_OK; caRes = CAEnableAnonECDHCipherSuite(false); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); #ifdef __WITH_X509__ #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); #endif //__WITH_X509__ #endif //__WITH_DTLS__ } } } else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel) { if ((false == gDoxm->owned) && (false == newDoxm->owned)) { /* * If current state of the device is un-owned, enable * anonymous ECDH cipher in tinyDTLS so that Provisioning * tool can initiate JUST_WORKS ownership transfer process. */ if(memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) == 0) { gDoxm->oxmSel = newDoxm->oxmSel; //Update new state in persistent storage if((UpdatePersistentStorage(gDoxm) == true)) { ehRet = OC_EH_OK; } else { OIC_LOG(WARNING, TAG, "Failed to update DOXM in persistent storage"); ehRet = OC_EH_ERROR; } #ifdef __WITH_DTLS__ CAResult_t caRes = CA_STATUS_OK; caRes = CAEnableAnonECDHCipherSuite(false); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); caRes = CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,}; if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1)) { //Set the device id to derive temporal PSK SetUuidForRandomPinOxm(&gDoxm->deviceID); /** * Since PSK will be used directly by DTLS layer while PIN based ownership transfer, * Credential should not be saved into SVR. * For this reason, use a temporary get_psk_info callback to random PIN OxM. */ caRes = CARegisterDTLSCredentialsHandler(GetDtlsPskForRandomPinOxm); VERIFY_SUCCESS(TAG, caRes == CA_STATUS_OK, ERROR); ehRet = OC_EH_OK; } else { OIC_LOG(ERROR, TAG, "Failed to generate random PIN"); ehRet = OC_EH_ERROR; } #endif //__WITH_DTLS__ } else { #ifdef __WITH_DTLS__ //Save the owner's UUID to derive owner credential memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)); //Update new state in persistent storage if((UpdatePersistentStorage(gDoxm) == true)) { ehRet = OC_EH_OK; } else { OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage"); ehRet = OC_EH_ERROR; } #endif } } } /* * When current state of the device is un-owned and Provisioning * Tool is attempting to change the state to 'Owned' with a * qualified value for the field 'Owner' */ if ((false == gDoxm->owned) && (true == newDoxm->owned) && (memcmp(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)) == 0)) { gDoxm->owned = true; // Update new state in persistent storage if (UpdatePersistentStorage(gDoxm)) { //Update default ACL of security resource to prevent anonymous user access. if(OC_STACK_OK == UpdateDefaultSecProvACL()) { ehRet = OC_EH_OK; } else { OIC_LOG(ERROR, TAG, "Failed to remove default ACL for security provisioning"); ehRet = OC_EH_ERROR; } } else { OIC_LOG(ERROR, TAG, "Failed to update DOXM in persistent storage"); ehRet = OC_EH_ERROR; } } } exit: if(OC_EH_OK != ehRet) { OIC_LOG(WARNING, TAG, "The operation failed during handle DOXM request,"\ "DOXM will be reverted."); /* * 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)) { OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } DeleteDoxmBinData(newDoxm); return ehRet; }
/** * The entity handler determines how to process a POST request. * Per the REST paradigm, POST can also be used to update representation of existing * resource or create a new resource. * For pstat, it updates only tm and om. */ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest *ehRequest) { OCEntityHandlerResult ehRet = OC_EH_ERROR; cJSON *postJson = NULL; OC_LOG (INFO, TAG, "HandlePstatPutRequest processing PUT request"); if (ehRequest->resource) { postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData); VERIFY_NON_NULL(TAG, postJson, INFO); cJSON *commitHashJson = cJSON_GetObjectItem(postJson, OIC_JSON_COMMIT_HASH_NAME); uint16_t commitHash = 0; if (commitHashJson) { commitHash = commitHashJson->valueint; } cJSON *tmJson = cJSON_GetObjectItem(postJson, OIC_JSON_TM_NAME); if (tmJson && gPstat) { gPstat->tm = (OicSecDpm_t)tmJson->valueint; if(0 == tmJson->valueint && gPstat->commitHash == commitHash) { gPstat->isOp = true; gPstat->cm = NORMAL; OC_LOG (INFO, TAG, "CommitHash is valid and isOp is TRUE"); } else { OC_LOG (INFO, TAG, "CommitHash is not valid"); } } cJSON *omJson = cJSON_GetObjectItem(postJson, OIC_JSON_OM_NAME); if (omJson && gPstat) { /* * Check if the operation mode is in the supported provisioning services * operation mode list. */ for(size_t i=0; i< gPstat->smLen; i++) { if(gPstat->sm[i] == (unsigned int)omJson->valueint) { gPstat->om = (OicSecDpom_t)omJson->valueint; break; } } } // Convert pstat data into JSON for update to persistent storage char *jsonStr = BinToPstatJSON(gPstat, true); if (jsonStr) { cJSON *jsonPstat = cJSON_Parse(jsonStr); OICFree(jsonStr); if (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_PSTAT_NAME, jsonPstat)) { ehRet = OC_EH_OK; } } } exit: //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) { OC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } cJSON_Delete(postJson); return ehRet; }
/** * The entity handler determines how to process a POST request. * Per the REST paradigm, POST can also be used to update representation of existing * resource or create a new resource. * For pstat, it updates only tm and om. */ static OCEntityHandlerResult HandlePstatPutRequest(const OCEntityHandlerRequest *ehRequest) { OCEntityHandlerResult ehRet = OC_EH_ERROR; cJSON *postJson = NULL; OIC_LOG (INFO, TAG, "HandlePstatPutRequest processing PUT request"); if (ehRequest->resource) { postJson = cJSON_Parse(((OCSecurityPayload*)ehRequest->payload)->securityData); VERIFY_NON_NULL(TAG, postJson, INFO); cJSON *jsonPstat = cJSON_GetObjectItem(postJson, OIC_JSON_PSTAT_NAME); VERIFY_NON_NULL(TAG, jsonPstat, INFO); cJSON *commitHashJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_COMMIT_HASH_NAME); uint16_t commitHash = 0; if (commitHashJson) { commitHash = commitHashJson->valueint; } cJSON *tmJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_TM_NAME); if (tmJson && gPstat) { gPstat->tm = (OicSecDpm_t)tmJson->valueint; if(0 == tmJson->valueint && gPstat->commitHash == commitHash) { gPstat->isOp = true; gPstat->cm = NORMAL; OIC_LOG (INFO, TAG, "CommitHash is valid and isOp is TRUE"); } else { OIC_LOG (INFO, TAG, "CommitHash is not valid"); } } cJSON *omJson = cJSON_GetObjectItem(jsonPstat, OIC_JSON_OM_NAME); if (omJson && gPstat) { /* * Check if the operation mode is in the supported provisioning services * operation mode list. */ for(size_t i=0; i< gPstat->smLen; i++) { if(gPstat->sm[i] == (unsigned int)omJson->valueint) { gPstat->om = (OicSecDpom_t)omJson->valueint; break; } } } // Convert pstat data into JSON for update to persistent storage if(UpdatePersistentStorage(gPstat)) { 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)) { OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } cJSON_Delete(postJson); return ehRet; }
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest) { OC_LOG (INFO, TAG, PCF("Doxm EntityHandle processing PUT request")); OCEntityHandlerResult ehRet = OC_EH_ERROR; OicUuid_t emptyOwner = {.id = {0}}; /* * Convert JSON Doxm data into binary. This will also validate * the Doxm data received. */ OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData); if (newDoxm) { // Iotivity SRM ONLY supports OIC_JUST_WORKS now if (OIC_JUST_WORKS == newDoxm->oxmSel) { /* * If current state of the device is un-owned, enable * anonymous ECDH cipher in tinyDTLS so that Provisioning * tool can initiate JUST_WORKS ownership transfer process. */ if ((false == gDoxm->owned) && (false == newDoxm->owned)) { OC_LOG (INFO, TAG, PCF("Doxm EntityHandle enabling AnonECDHCipherSuite")); #ifdef __WITH_DTLS__ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR; #endif //__WITH_DTLS__ goto exit; } /* * When current state of the device is un-owned and Provisioning * Tool is attempting to change the state to 'Owned' with a * qualified value for the field 'Owner' */ if ((false == gDoxm->owned) && (true == newDoxm->owned) && (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)) { /* * Generate OwnerPSK and create credential for Provisioning * tool with the generated OwnerPSK. * Update persistent storage and disable anonymous ECDH cipher * */ #ifdef __WITH_DTLS__ CAResult_t pskRet; OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; uint8_t ownerPSK[OWNER_PSK_LENGTH_128] = {}; //Generating OwnerPSK OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating OwnerPSK")); pskRet = CAGenerateOwnerPSK((CAEndpoint_t *)&request->devAddr, (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS), newDoxm->owner.id, sizeof(newDoxm->owner.id), gDoxm->deviceID.id, sizeof(gDoxm->deviceID.id), ownerPSK, OWNER_PSK_LENGTH_128); VERIFY_SUCCESS(TAG, pskRet == CA_STATUS_OK, ERROR); //Generating new credential for provisioning tool size_t ownLen = 1; uint32_t outLen = 0; char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(ownerPSK)) + 1] = {}; B64Result b64Ret = b64Encode(ownerPSK, sizeof(ownerPSK), base64Buff, sizeof(base64Buff), &outLen); VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR); OC_LOG (INFO, TAG, PCF("Doxm EntityHandle generating Credential")); OicSecCred_t *cred = GenerateCredential(&newDoxm->owner, SYMMETRIC_PAIR_WISE_KEY, NULL, base64Buff, ownLen, &newDoxm->owner); VERIFY_NON_NULL(TAG, cred, ERROR); //Adding provisioning tool credential to cred Resource. VERIFY_SUCCESS(TAG, OC_STACK_OK == AddCredential(cred), ERROR); gDoxm->owned = true; memcpy(&(gDoxm->owner), &(newDoxm->owner), sizeof(OicUuid_t)); // Update new state in persistent storage if (true == UpdatePersistentStorage(gDoxm)) { ehRet = OC_EH_OK; } else { ehRet = OC_EH_ERROR; /* * If persistent storage update failed, revert back the state * for global variable. */ gDoxm->owned = false; memset(&(gDoxm->owner), 0, sizeof(OicUuid_t)); } /* * Disable anonymous ECDH cipher in tinyDTLS since device is now * in owned state. */ CAEnableAnonECDHCipherSuite(false); #endif //__WITH_DTLS__ } } } exit: //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) { OC_LOG (ERROR, TAG, PCF("SendSRMResponse failed in HandlePstatPostRequest")); } DeleteDoxmBinData(newDoxm); return ehRet; }
static OCEntityHandlerResult HandleDoxmPutRequest (const OCEntityHandlerRequest * ehRequest) { OIC_LOG (DEBUG, TAG, "Doxm EntityHandle processing PUT request"); OCEntityHandlerResult ehRet = OC_EH_ERROR; OicUuid_t emptyOwner = {.id = {0}}; /* * Convert JSON Doxm data into binary. This will also validate * the Doxm data received. */ OicSecDoxm_t* newDoxm = JSONToDoxmBin(((OCSecurityPayload*)ehRequest->payload)->securityData); if (newDoxm) { // Iotivity SRM ONLY supports OIC_JUST_WORKS now if (OIC_JUST_WORKS == newDoxm->oxmSel) { /* * If current state of the device is un-owned, enable * anonymous ECDH cipher in tinyDTLS so that Provisioning * tool can initiate JUST_WORKS ownership transfer process. */ if ((false == gDoxm->owned) && (false == newDoxm->owned)) { OIC_LOG (INFO, TAG, "Doxm EntityHandle enabling AnonECDHCipherSuite"); #ifdef __WITH_DTLS__ ehRet = (CAEnableAnonECDHCipherSuite(true) == CA_STATUS_OK) ? OC_EH_OK : OC_EH_ERROR; #endif //__WITH_DTLS__ goto exit; } /* * When current state of the device is un-owned and Provisioning * Tool is attempting to change the state to 'Owned' with a * qualified value for the field 'Owner' */ if ((false == gDoxm->owned) && (true == newDoxm->owned) && (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)) { /* * Generate OwnerPSK and create credential for Provisioning * tool with the generated OwnerPSK. * Update persistent storage and disable anonymous ECDH cipher * */ #ifdef __WITH_DTLS__ OCServerRequest *request = (OCServerRequest *)ehRequest->requestHandle; //Generating OwnerPSK OIC_LOG (INFO, TAG, "Doxm EntityHandle generating OwnerPSK"); //Generate new credential for provisioning tool ehRet = AddOwnerPSK((CAEndpoint_t *)&request->devAddr, newDoxm, (uint8_t*) OXM_JUST_WORKS, strlen(OXM_JUST_WORKS)); VERIFY_SUCCESS(TAG, OC_EH_OK == ehRet, ERROR); // Update new state in persistent storage if (true == UpdatePersistentStorage(gDoxm)) { ehRet = OC_EH_OK; } else { ehRet = OC_EH_ERROR; /* * If persistent storage update failed, revert back the state * for global variable. */ gDoxm->owned = false; gDoxm->oxmSel = 0; memset(&(gDoxm->owner), 0, sizeof(OicUuid_t)); } /* * Disable anonymous ECDH cipher in tinyDTLS since device is now * in owned state. */ CAEnableAnonECDHCipherSuite(false); #ifdef __WITH_X509__ #define TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 0xC0AE CASelectCipherSuite(TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8); #endif //__WITH_X509__ #endif //__WITH_DTLS__ } } else if(OIC_RANDOM_DEVICE_PIN == newDoxm->oxmSel) { #ifdef __WITH_DTLS__ //this temp Credential ID is used to track temporal Cred Id static OicUuid_t tmpCredId = {.id={0}}; static bool tmpCredGenFlag = false; #endif //__WITH_DTLS__ if ((false == gDoxm->owned) && (false == newDoxm->owned)) { #ifdef __WITH_DTLS__ CAEnableAnonECDHCipherSuite(false); OIC_LOG(INFO, TAG, "ECDH_ANON CipherSuite is DISABLED"); CASelectCipherSuite(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA_256); char ranPin[OXM_RANDOM_PIN_SIZE + 1] = {0,}; if(OC_STACK_OK == GeneratePin(ranPin, OXM_RANDOM_PIN_SIZE + 1)) { if(tmpCredGenFlag) { OIC_LOG(INFO, TAG, "Corrupted PSK is detected!!!"); VERIFY_SUCCESS(TAG, OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId), ERROR); } OCStackResult res = AddTmpPskWithPIN( &(newDoxm->owner), SYMMETRIC_PAIR_WISE_KEY, ranPin, OXM_RANDOM_PIN_SIZE, 1, &(newDoxm->owner), &tmpCredId); VERIFY_SUCCESS(TAG, res == OC_STACK_OK, ERROR); tmpCredGenFlag = true; ehRet = OC_EH_OK; } else { OIC_LOG(ERROR, TAG, "Failed to generate random PIN"); ehRet = OC_EH_ERROR; } #endif //__WITH_DTLS__ } /* * When current state of the device is un-owned and Provisioning * Tool is attempting to change the state to 'Owned' with a * qualified value for the field 'Owner' */ if ((false == gDoxm->owned) && (true == newDoxm->owned) && (memcmp(&(newDoxm->owner), &emptyOwner, sizeof(OicUuid_t)) != 0)) { #ifdef __WITH_DTLS__ OCServerRequest * request = (OCServerRequest *)ehRequest->requestHandle; //Remove Temporal Credential resource if(tmpCredGenFlag) { VERIFY_SUCCESS(TAG, OC_STACK_RESOURCE_DELETED == RemoveCredential(&tmpCredId), ERROR); tmpCredGenFlag = false; } //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)) { ehRet = OC_EH_OK; } else { /* * If persistent storage update failed, revert back the state * for global variable. */ gDoxm->owned = false; gDoxm->oxmSel = 0; memset(&(gDoxm->owner), 0, sizeof(OicUuid_t)); ehRet = OC_EH_ERROR; } #endif } } } exit: //Send payload to request originator if(OC_STACK_OK != SendSRMResponse(ehRequest, ehRet, NULL)) { OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } DeleteDoxmBinData(newDoxm); return ehRet; }
/** * The entity handler determines how to process a POST request. * Per the REST paradigm, POST can also be used to update representation of existing * resource or create a new resource. * For pstat, it updates only tm and om. */ static OCEntityHandlerResult HandlePstatPostRequest(const OCEntityHandlerRequest *ehRequest) { OCEntityHandlerResult ehRet = OC_EH_ERROR; OIC_LOG(INFO, TAG, "HandlePstatPostRequest processing POST request"); OicSecPstat_t *pstat = NULL; if (ehRequest->payload) { uint8_t *payload = ((OCSecurityPayload *) ehRequest->payload)->securityData; size_t size = ((OCSecurityPayload *) ehRequest->payload)->payloadSize; VERIFY_NON_NULL(TAG, payload, ERROR); OCStackResult ret = CBORPayloadToPstat(payload, size, &pstat); VERIFY_NON_NULL(TAG, pstat, ERROR); if (OC_STACK_OK == ret) { if (false == (pstat->cm & TAKE_OWNER) && false == pstat->isOp) { gPstat->cm = pstat->cm; OIC_LOG (INFO, TAG, "State changed to Ready for Provisioning"); } else if (false == (pstat->cm & TAKE_OWNER) && true == pstat->isOp) { gPstat->isOp =pstat->isOp; OIC_LOG (INFO, TAG, "State changed to Ready for Normal Operation"); } else { OIC_LOG(DEBUG, TAG, "Invalid Device provisionig state"); } if (pstat->om != MULTIPLE_SERVICE_SERVER_DRIVEN && gPstat) { /* * Check if the operation mode is in the supported provisioning services * operation mode list. */ for (size_t i=0; i< gPstat->smLen; i++) { if(gPstat->sm[i] == pstat->om) { gPstat->om = pstat->om; break; } } } // Convert pstat data into CBOR for update to persistent storage if (UpdatePersistentStorage(gPstat)) { 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, 0)) { ehRet = OC_EH_ERROR; OIC_LOG (ERROR, TAG, "SendSRMResponse failed in HandlePstatPostRequest"); } DeletePstatBinData(pstat); return ehRet; }