/** * Function to save the result of provisioning. * * @param[in,out] otmCtx Context value of ownership transfer. * @param[in] res result of provisioning */ static void SetResult(OTMContext_t* otmCtx, const OCStackResult res) { OC_LOG_V(DEBUG, TAG, "IN SetResult : %d ", res); if(!otmCtx) { OC_LOG(WARNING, TAG, "OTMContext is NULL"); return; } if(otmCtx->selectedDeviceInfo) { for(size_t i = 0; i < otmCtx->ctxResultArraySize; i++) { if(memcmp(otmCtx->selectedDeviceInfo->doxm->deviceID.id, otmCtx->ctxResultArray[i].deviceId.id, UUID_LENGTH) == 0) { otmCtx->ctxResultArray[i].res = res; if(OC_STACK_OK != res) { otmCtx->ctxHasError = true; } } } g_otmCtx = NULL; //If all request is completed, invoke the user callback. if(IsComplete(otmCtx)) { otmCtx->ctxResultCallback(otmCtx->userCtx, otmCtx->ctxResultArraySize, otmCtx->ctxResultArray, otmCtx->ctxHasError); OICFree(otmCtx->ctxResultArray); OICFree(otmCtx); } else { if(OC_STACK_OK != StartOwnershipTransfer(otmCtx, otmCtx->selectedDeviceInfo->next)) { OC_LOG(ERROR, TAG, "Failed to StartOwnershipTransfer"); } } } OC_LOG(DEBUG, TAG, "OUT SetResult"); }
/** * NOTE : Unowned discovery should be done before performing OTMDoOwnershipTransfer */ OCStackResult OTMDoOwnershipTransfer(void* ctx, OCProvisionDev_t *selectedDevicelist, OCProvisionResultCB resultCallback) { OC_LOG(DEBUG, TAG, "IN OTMDoOwnershipTransfer"); if (NULL == selectedDevicelist || NULL == resultCallback ) { return OC_STACK_INVALID_PARAM; } OTMContext_t* otmCtx = (OTMContext_t*)OICCalloc(1,sizeof(OTMContext_t)); if(!otmCtx) { OC_LOG(ERROR, TAG, "Failed to create OTM Context"); return OC_STACK_NO_MEMORY; } otmCtx->ctxResultCallback = resultCallback; otmCtx->ctxHasError = false; otmCtx->userCtx = ctx; OCProvisionDev_t* pCurDev = selectedDevicelist; //Counting number of selected devices. otmCtx->ctxResultArraySize = 0; while(NULL != pCurDev) { otmCtx->ctxResultArraySize++; pCurDev = pCurDev->next; } otmCtx->ctxResultArray = (OCProvisionResult_t*)OICCalloc(otmCtx->ctxResultArraySize, sizeof(OCProvisionResult_t)); if(NULL == otmCtx->ctxResultArray) { OC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Failed to memory allocation"); OICFree(otmCtx); return OC_STACK_NO_MEMORY; } pCurDev = selectedDevicelist; //Fill the device UUID for result array. for(size_t devIdx = 0; devIdx < otmCtx->ctxResultArraySize; devIdx++) { //Checking duplication of Device ID. bool isDuplicate = true; OCStackResult res = PDMIsDuplicateDevice(&pCurDev->doxm->deviceID, &isDuplicate); if (OC_STACK_OK != res) { OICFree(otmCtx->ctxResultArray); OICFree(otmCtx); return res; } if (isDuplicate) { OC_LOG(ERROR, TAG, "OTMDoOwnershipTransfer : Device ID is duplicated"); OICFree(otmCtx->ctxResultArray); OICFree(otmCtx); return OC_STACK_INVALID_PARAM; } memcpy(otmCtx->ctxResultArray[devIdx].deviceId.id, pCurDev->doxm->deviceID.id, UUID_LENGTH); otmCtx->ctxResultArray[devIdx].res = OC_STACK_CONTINUE; pCurDev = pCurDev->next; } StartOwnershipTransfer(otmCtx, selectedDevicelist); OC_LOG(DEBUG, TAG, "OUT OTMDoOwnershipTransfer"); return OC_STACK_OK; }
/** * Function to handle the handshake result in OTM. * This function will be invoked after DTLS handshake * @param endPoint [IN] The remote endpoint. * @param errorInfo [IN] Error information from the endpoint. * @return NONE */ void DTLSHandshakeCB(const CAEndpoint_t *endpoint, const CAErrorInfo_t *info) { if(g_otmCtx && endpoint && info) { OC_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) { OCStackResult res; CARegisterDTLSHandshakeCallback(NULL); //In case of success, send next coaps request. if(CA_STATUS_OK == info->result) { //Send request : PUT /oic/sec/doxm [{"Owned":"True", .. , "Owner":"PT's UUID"}] res = PutOwnershipInformation(g_otmCtx); if(OC_STACK_OK != res) { OC_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++; if(g_otmCtx->selectedDeviceInfo->doxm->oxmSel == OIC_RANDOM_DEVICE_PIN) { res = RemoveCredential(&g_otmCtx->subIdForPinOxm); if(OC_STACK_RESOURCE_DELETED != res) { OC_LOG_V(ERROR, TAG, "Failed to remove temporal PSK : %d", res); SetResult(g_otmCtx, res); return; } if(WRONG_PIN_MAX_ATTEMP > g_otmCtx->attemptCnt) { res = StartOwnershipTransfer(g_otmCtx, g_otmCtx->selectedDeviceInfo); if(OC_STACK_OK != res) { SetResult(g_otmCtx, res); OC_LOG(ERROR, TAG, "Failed to Re-StartOwnershipTransfer"); } } else { SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); } } else { SetResult(g_otmCtx, OC_STACK_AUTHENTICATION_FAILURE); } } } } }