From 730130513569aba98ffd97f176e8e492bf7e5e44 Mon Sep 17 00:00:00 2001 From: localhorst Date: Wed, 20 Jan 2021 10:23:41 +0100 Subject: [PATCH] blocking OTA Tx and Rx --- components/mesh_ota/Mesh_OTA.c | 558 ++++++++++++--------- components/mesh_ota/Mesh_network.c | 61 ++- components/mesh_ota/include/Mesh_OTA.h | 6 + components/mesh_ota/include/Mesh_network.h | 7 +- 4 files changed, 397 insertions(+), 235 deletions(-) diff --git a/components/mesh_ota/Mesh_OTA.c b/components/mesh_ota/Mesh_OTA.c index 4bc55d3..2e52623 100644 --- a/components/mesh_ota/Mesh_OTA.c +++ b/components/mesh_ota/Mesh_OTA.c @@ -11,6 +11,12 @@ SemaphoreHandle_t bsOTAProcess; //binary semaphore const esp_partition_t* pOTAPartition; //pointer to ota partition bool bWantReboot; //flag to signal pending reboot +bool bOtaAbortTx = false; +esp_partition_t* pBootPartitionTx; //pointer to boot partition (that will booted after reset) +uint32_t u32OTABytesWrittenTx = 0U; +uint32_t u32SegmentCounterTx = 0U; +bool bNodeIsRespondingTx = false; //remote node is still active + esp_err_t errMeshOTAInitialize() { esp_err_t err = ESP_OK; @@ -67,8 +73,12 @@ esp_err_t errMeshOTAInitialize() } ERROR_CHECK(errMeshNetworkSetChildConnectedHandle(vAddNodeToPossibleUpdatableQueue)); - ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vAddOTAControllMessageToQueue)); + ERROR_CHECK(errMeshNetworkSetOTAMessageHandle(vAddOTAControllMessageToQueue)); ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vChangeStateOfServerWorker)); + ERROR_CHECK(errMeshNetworkSetOtaDataHandle(vRecOtaDataHandler)); + ERROR_CHECK(errMeshNetworkSetOtaAckHandle(vRecOtaAckHandler)); + //ERROR_CHECK(errMeshNetworkSetOtaCompleteHandle(vRecOtaCompleteHandler)); + // ERROR_CHECK(errMeshNetworkSetOtaAbortHandle(vRecOtaAbortHandler)); if(err == ESP_OK) { @@ -254,7 +264,7 @@ void vTaskOTAWorker(void *arg) bWantReboot = true; vAddAllNeighboursToQueue(); //add all existing neighbours to queue } - vTaskDelay( (1000) / portTICK_PERIOD_MS); + vTaskDelay( (1000) / portTICK_PERIOD_MS); //TODO this is debug } } @@ -362,7 +372,7 @@ esp_err_t errOTAMeshSlave(bool* pbNewOTAImage) pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadata of partition - //send OTA_Version_Response to sender of OTA_Version_Request packet wirh version in payload + ESP_LOGI(LOG_TAG, "//send OTA_Version_Response to sender of OTA_Version_Request packet with version in payload"); ERROR_CHECK(errSendOTAVersionResponse(&sOTAMessage.meshSenderAddr)); if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version @@ -406,55 +416,57 @@ esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) for (uint32_t u32Index = 0; u32Index < QUEUE_MESSAGE_OTA_SIZE; u32Index++) //loop through all OTA messages { - if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) + //if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) + // { + //queue not empty + if (xQueueReceive(queueMessageOTA, &sOTAMessage, ((OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS)) != pdTRUE) { - //queue not empty - if (xQueueReceive(queueMessageOTA, &sOTAMessage, ((3000) / portTICK_PERIOD_MS)) != pdTRUE) + ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); + err = ESP_FAIL; + } + + if((err == ESP_OK) && (sOTAMessage.type == OTA_Version_Response) && (bCheckMACEquality(sOTAMessage.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request + { + bNodeIsResponding = true; + u32Index = QUEUE_MESSAGE_OTA_SIZE; //this will exit the loop through all OTA messages + pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition + ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadata of partition + + if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version { - ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); - err = ESP_FAIL; + //remote newer as local + ESP_LOGI(LOG_TAG, "Mesh: remote image on node is newer --> OTA update required"); + // --> this version older --> start OTA_Rx --> set pbNewOTAImage true + ERROR_CHECK(errOTAMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); } - if((err == ESP_OK) && (sOTAMessage.type == OTA_Version_Response) && (bCheckMACEquality(sOTAMessage.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request + if((bNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version { - bNodeIsResponding = true; - pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition - ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadata of partition - - if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version - { - //remote newer as local - ESP_LOGI(LOG_TAG, "Mesh: remote image on node is newer --> OTA update required"); - // --> this version older --> start OTA_Rx --> set pbNewOTAImage true - ERROR_CHECK(errOTAMeshReceive(pbNewOTAImage, &sOTAMessage.meshSenderAddr)); - } - - if((bNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version - { - //local newer as remote - ESP_LOGI(LOG_TAG, "Mesh: remote image on node is older --> OTA send required"); - // --> this version newer --> start OTA_Tx - ERROR_CHECK(errOTAMeshTransmit(&sOTAMessage.meshSenderAddr)); - } - } - else if (err == ESP_OK) - { - //received from wrong node or type --> back to queue - vAddOTAControllMessageToQueue(&sOTAMessage); + //local newer as remote + ESP_LOGI(LOG_TAG, "Mesh: remote image on node is older --> OTA send required"); + // --> this version newer --> start OTA_Tx + ERROR_CHECK(errOTAMeshTransmit(&sOTAMessage.meshSenderAddr)); } } + else if (err == ESP_OK) + { + ESP_LOGI(LOG_TAG, "//received from wrong node or type --> back to queue"); + vAddOTAControllMessageToQueue(&sOTAMessage); + } + /* } else - { - // OTA Message queue is empty --> wait some time - vTaskDelay( (1000/QUEUE_MESSAGE_OTA_SIZE) / portTICK_PERIOD_MS); - } + { + ESP_LOGI(LOG_TAG, "// OTA Message queue is empty --> wait some time"); + vTaskDelay(OTA_MESH_TIMEOUT*u32Index / portTICK_PERIOD_MS); + } + */ }//end loop xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process } if((bNodeIsResponding == false) && (bNodeIsConnected == true)) { - //add node back to queue if connected and NOT responding + ESP_LOGI(LOG_TAG, "//add node back to queue if connected and NOT responding"); vAddNodeToPossibleUpdatableQueue(pMeshNodeAddr->addr); } return err; @@ -604,12 +616,12 @@ void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* { if(eRole == Transmitter) { - ESP_LOGI(LOG_TAG, "Transmitting OTA update: %i %%", u32Percentage); + ESP_LOGE(LOG_TAG, "Transmitting OTA update: %i %%", u32Percentage); } if(eRole == Receiver) { - ESP_LOGI(LOG_TAG, "Receiving OTA update: %i %%", u32Percentage); + ESP_LOGE(LOG_TAG, "Receiving OTA update: %i %%", u32Percentage); } @@ -680,213 +692,301 @@ esp_err_t errSendOTAVersionRequest(mesh_addr_t* pMeshReceiverAddr) esp_err_t errOTAMeshTransmit(mesh_addr_t* pMeshNodeAddr) { esp_err_t err = ESP_OK; - const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset) + //const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset) MESH_PACKET_t sMeshPacket; //packet for sending and receiving - uint32_t u32Index = 0U; //index for partition read offset - bool bAbort = false; //abort the OTA process - bool bNodeIsResponding = false; //remote node is still active - uint32_t u32OTABytesWritten = 0U; + //uint32_t u32Index = 0U; //index for partition read offset + //bool bAbort = false; //abort the OTA process + //bool bNodeIsResponding = false; //remote node is still active + //uint32_t u32OTABytesWritten = 0U; + //uint32_t u32SegmentCounter = 0U; - pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition + pBootPartitionTx = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition + + u32OTABytesWrittenTx = 0U; + u32SegmentCounterTx = 0U; + bNodeIsRespondingTx = false; //remote node is still active //loop through partition to read in segmensts until end or error or abort called - while( ((OTA_MESH_SEGMENT_SIZE * u32Index) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false)) - { - bNodeIsResponding = false; //reset to default + // while( ((OTA_MESH_SEGMENT_SIZE * u32SegmentCounter) < pBootPartition->size) && (err == ESP_OK) && (bAbort == false)) + { + //bNodeIsResponding = false; //reset to default + /* + ESP_LOGI(LOG_TAG, "// read partition with offset based in index"); + ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32Index), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); + u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); + vPrintOTAProgress(&(pBootPartition->size), &u32OTABytesWritten, Transmitter); - // read partition with offset based in index - ERROR_CHECK(esp_partition_read(pBootPartition, (OTA_MESH_SEGMENT_SIZE * u32Index), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); - u32OTABytesWritten = ((u32Index+1) * OTA_MESH_SEGMENT_SIZE); - vPrintOTAProgress(&(pBootPartition->size), &u32OTABytesWritten, Transmitter); + if(err == ESP_OK) + { + //ESP_LOGI(LOG_TAG, "//no error while read --> send OTA_DATA packet"); + sMeshPacket.type = OTA_Data; - if(err == ESP_OK) - { - //no error while read --> send OTA_DATA packet - sMeshPacket.type = OTA_Data; + if((OTA_MESH_SEGMENT_SIZE * (u32SegmentCounter+1)) >= pBootPartition->size) //check if last segment + { + ESP_LOGI(LOG_TAG, "//last partition image segment --> send OTA_Complete"); + sMeshPacket.type = OTA_Complete; + ESP_LOGE(LOG_TAG, "u32SegmentCounter: %i", u32SegmentCounter); + } - if((OTA_MESH_SEGMENT_SIZE * (u32Index+1)) >= pBootPartition->size) //check if last segment - { - //last partition image segment --> send OTA_Complete - sMeshPacket.type = OTA_Complete; - } + err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); + } + else + { + ESP_LOGI(LOG_TAG, "// error while read --> send OTA_ABORT and abort this OTA process"); + sMeshPacket.type = OTA_Abort; + bAbort = true; + errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); + } + */ + // loop through all OTA messages or until abort is called or error + for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bOtaAbortTx == false)); u32Index++) //loop through all OTA messages + { + // if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) + // { + //queue not empty + if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS)) != pdTRUE) + { + ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); + err = ESP_FAIL; + } - err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); - } - else - { - // error while read --> send OTA_ABORT and abort this OTA process - sMeshPacket.type = OTA_Abort; - bAbort = true; - errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); - } + if((err == ESP_OK) && (bCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request + { + ESP_LOGI(LOG_TAG, "//packet from node received"); + switch (sMeshPacket.type) + { + case OTA_Abort: //abort this OTA process + bOtaAbortTx = true; + bNodeIsRespondingTx = true; + break; + default: + ESP_LOGI(LOG_TAG, "//receives wrong OTA message type from node --> back to queue"); + vAddOTAControllMessageToQueue(&sMeshPacket); + break; + } + } + else if (err == ESP_OK) + { + ESP_LOGI(LOG_TAG, "//received from wrong node --> back to queue"); + vAddOTAControllMessageToQueue(&sMeshPacket); - // loop through all OTA messages or until abort is called or error - for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bAbort == false) && (err == ESP_OK)); u32Index++) //loop through all OTA messages - { - if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) - { - //queue not empty - if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((3000) / portTICK_PERIOD_MS)) != pdTRUE) - { - ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); - err = ESP_FAIL; - } + if(bNodeIsRespondingTx == false) + { + ESP_LOGI(LOG_TAG, "//no abort was called but node didn’t responded"); + bOtaAbortTx = true; + err = ESP_FAIL; //this OTA process failed with error + } + else + { + bNodeIsRespondingTx = false; + } - if((err == ESP_OK) && (bCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request - { - //packet from node received - switch (sMeshPacket.type) - { - case OTA_ACK: //increase index for next round - u32Index++; - bNodeIsResponding = true; - break; - case OTA_Abort: //abort this OTA process - bAbort = true; - bNodeIsResponding = true; - break; - default: - //receives wrong OTA message type from node --> back to queue - vAddOTAControllMessageToQueue(&sMeshPacket); - break; - } - } - else if (err == ESP_OK) - { - //received from wrong node --> back to queue - vAddOTAControllMessageToQueue(&sMeshPacket); - } - } - else - { - // OTA Message queue is empty --> wait some time - vTaskDelay( (1000/QUEUE_MESSAGE_OTA_SIZE) / portTICK_PERIOD_MS); - } - }//end OTA message loop + } + // } + // else + //{ + // ESP_LOGI(LOG_TAG, "// OTA Message queue is empty --> wait some time"); + //vTaskDelay(OTA_MESH_TIMEOUT*u32Index/ portTICK_PERIOD_MS); + // } - if(bNodeIsResponding == false) - { - //no abort was called but node didn’t responded - bAbort = true; - err = ESP_FAIL; //this OTA process failed with error - } - }//end of partition segment loop - return err; -} + }//end OTA message loop -esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) -{ - esp_err_t err = ESP_OK; - MESH_PACKET_t sMeshPacket; //packet for sending and receiving - bool bComplete = false; //complete the OTA process - bool bAbort = false; //abort the OTA process - bool bNodeIsResponding = false; //remote node is still active - uint32_t u32OTABytesWritten = 0U; //counter unsed for progress log - static esp_ota_handle_t otaHandle; //OTA process handle - *pbNewOTAImage = false; + } + // u32SegmentCounter++; + //}//end of partition segment loop + return err; + } - ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process + esp_err_t errOTAMeshReceive(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr) + { + esp_err_t err = ESP_OK; + MESH_PACKET_t sMeshPacket; //packet for sending and receiving + bool bComplete = false; //complete the OTA process + bool bAbort = false; //abort the OTA process + bool bNodeIsResponding = false; //remote node is still active + uint32_t u32OTABytesWritten = 0U; //counter unsed for progress log + static esp_ota_handle_t otaHandle; //OTA process handle + *pbNewOTAImage = false; + uint32_t u32SegmentCounter = 0U; - //partition segement loop through partition to read in segmensts until end or error or abort called - while((bComplete == false) && (err == ESP_OK) && (bAbort == false) && (u32OTABytesWritten <= pOTAPartition->size)) - { - bNodeIsResponding = false; //reset to default + ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process - // loop through all OTA messages or until abort is called - for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bAbort == false)); u32Index++) //loop through all OTA messages - { - if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) - { - //queue not empty - if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((3000) / portTICK_PERIOD_MS)) != pdTRUE) - { - ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); - err = ESP_FAIL; - } + //partition segement loop through partition to read in segmensts until end or error or abort called + while((bComplete == false) && (err == ESP_OK) && (bAbort == false) && (u32OTABytesWritten <= pOTAPartition->size)) + { + bNodeIsResponding = false; //reset to default - if((err == ESP_OK) && (bCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request - { - //packet from node received - switch (sMeshPacket.type) - { - case OTA_Complete: //signal end of this OTA process, fall through because same behavior as OTA_Data - bComplete = true; - //fall through - case OTA_Data: //data segement received - bNodeIsResponding = true; - ERROR_CHECK(esp_ota_write(otaHandle, sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); - u32OTABytesWritten = ((u32Index+1) * OTA_MESH_SEGMENT_SIZE); - vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); - break; - case OTA_Abort: //abort this OTA process - bAbort = true; - bNodeIsResponding = true; - break; - default: - //receives wrong OTA message type from node --> back to queue - vAddOTAControllMessageToQueue(&sMeshPacket); - break; - } - } - else if (err == ESP_OK) - { - //received from wrong node --> back to queue - vAddOTAControllMessageToQueue(&sMeshPacket); - } - } - else - { - // OTA Message queue is empty --> wait some time - vTaskDelay( (1000/QUEUE_MESSAGE_OTA_SIZE) / portTICK_PERIOD_MS); - } + // loop through all OTA messages or until abort is called + for (uint32_t u32Index = 0; ((u32Index < QUEUE_MESSAGE_OTA_SIZE) && (bAbort == false)); u32Index++) //loop through all OTA messages + { + //if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE) + // { + //queue not empty + if (xQueueReceive(queueMessageOTA, &sMeshPacket, ((OTA_MESH_TIMEOUT) / portTICK_PERIOD_MS)) != pdTRUE) + { + ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from queue"); + err = ESP_FAIL; + } - }//end of OTA message loop + if((err == ESP_OK) && (bCheckMACEquality(sMeshPacket.meshSenderAddr.addr, pMeshNodeAddr->addr))) //if OTA_Version_Request + { + ESP_LOGI(LOG_TAG, "//packet from node received"); + switch (sMeshPacket.type) + { + case OTA_Complete: + ESP_LOGI(LOG_TAG, "//signal end of this OTA process, fall through because same behavior as OTA_Data"); + bComplete = true; + ESP_LOGE(LOG_TAG, "after rec:Complete u32SegmentCounter: %i", u32SegmentCounter); + //fall through + case OTA_Data: + ESP_LOGI(LOG_TAG, "//data segement received"); + bNodeIsResponding = true; + u32Index = QUEUE_MESSAGE_OTA_SIZE; //this will exit the loop through all OTA messages + ERROR_CHECK(esp_ota_write(otaHandle, sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); - if(bNodeIsResponding == false) - { - //no abort was called but node didn’t responded --> error - bAbort = true; //this will stop the partition segement loop - err = ESP_FAIL; //this OTA process failed with error - } - else - { - //node has responded with OTA_DATA or OTA_Complete or OTA_ABORT - if(err == ESP_OK) - { + if(err != ESP_OK) + { + ESP_LOGE(LOG_TAG, "write error - Segement: %i", u32SegmentCounter); + } - if(bAbort == false) - { - //no error while ota write --> send OTA_ACK packet - sMeshPacket.type = OTA_ACK; - err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); - } - } - else - { - // error while read --> send OTA_ABORT and abort this OTA process - sMeshPacket.type = OTA_Abort; - bAbort = true; - errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); - } - } - }//end of partition segement loop + u32OTABytesWritten = ((u32SegmentCounter+1) * OTA_MESH_SEGMENT_SIZE); + vPrintOTAProgress(&(pOTAPartition->size), &u32OTABytesWritten, Receiver); + break; + case OTA_Abort: //abort this OTA process + bAbort = true; + bNodeIsResponding = true; + break; + default: + ESP_LOGI(LOG_TAG, "//receives wrong OTA message type from node --> back to queue"); + vAddOTAControllMessageToQueue(&sMeshPacket); + break; + } + } + else if (err == ESP_OK) + { + ESP_LOGI(LOG_TAG, "//received from wrong node --> back to queue"); + vAddOTAControllMessageToQueue(&sMeshPacket); + } + // } + // else + // { + // ESP_LOGI(LOG_TAG, "// OTA Message queue is empty --> wait some time"); + // vTaskDelay((OTA_MESH_TIMEOUT*u32Index) / portTICK_PERIOD_MS); + // } - if(bComplete == true) - { - //all OTA segments received --> validate - ERROR_CHECK(esp_ota_end(otaHandle)); - ERROR_CHECK(esp_ota_set_boot_partition(pOTAPartition)); - if(err == ESP_OK) - { - //successfully updated OTA partition - *pbNewOTAImage = true; - } - } - else - { - //not all OTA segments received --> abort this OTA process - ERROR_CHECK(esp_ota_abort(otaHandle)); - } - return err; -} + }//end of OTA message loop + + if(bNodeIsResponding == false) + { + ESP_LOGI(LOG_TAG, "//no abort was called but node didn’t responded --> error"); + bAbort = true; //this will stop the partition segement loop + err = ESP_FAIL; //this OTA process failed with error + } + else + { + ESP_LOGI(LOG_TAG, "//node has responded with OTA_DATA or OTA_Complete or OTA_ABORT"); + if(err == ESP_OK) + { + + if((bAbort == false) && (bComplete == false)) + { + ESP_LOGI(LOG_TAG, "//no error while ota write --> send OTA_ACK packet"); + sMeshPacket.type = OTA_ACK; + err = errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); + } + } + else if (bComplete == false) + { + ESP_LOGI(LOG_TAG, "// error while read --> send OTA_ABORT and abort this OTA process"); + sMeshPacket.type = OTA_Abort; + bAbort = true; + errSendMeshPacket(pMeshNodeAddr, &sMeshPacket); + } + } + u32SegmentCounter++; + }//end of partition segement loop + + if(bComplete == true) + { + ESP_LOGI(LOG_TAG, "//all OTA segments received --> validate"); + ERROR_CHECK(esp_ota_end(otaHandle)); + ERROR_CHECK(esp_ota_set_boot_partition(pOTAPartition)); + if(err == ESP_OK) + { + ESP_LOGI(LOG_TAG, "//successfully updated OTA partition"); + *pbNewOTAImage = true; + } + } + else + { + ESP_LOGI(LOG_TAG, "//not all OTA segments received --> abort this OTA process"); + ERROR_CHECK(esp_ota_abort(otaHandle)); + } + return err; + } + + void vRecOtaDataHandler(MESH_PACKET_t* puMeshPacket) + { + if(bOtaAbortTx == false) + { + + } + + } + + void vRecOtaAckHandler(MESH_PACKET_t* puMeshPacket) + { + esp_err_t err = ESP_OK; + + MESH_PACKET_t sMeshPacket; //packet for sending and receiving + + + + if(bOtaAbortTx == false) + { + + //sender node == ota node ? + bNodeIsRespondingTx = true; + ESP_LOGI(LOG_TAG, "// read partition with offset based in index"); + ERROR_CHECK(esp_partition_read(pBootPartitionTx, (OTA_MESH_SEGMENT_SIZE * u32SegmentCounterTx), sMeshPacket.au8Payload, OTA_MESH_SEGMENT_SIZE)); + + u32OTABytesWrittenTx = ((u32SegmentCounterTx+1) * OTA_MESH_SEGMENT_SIZE); + + vPrintOTAProgress(&(pBootPartitionTx->size), &u32OTABytesWrittenTx, Transmitter); + + + sMeshPacket.type = OTA_Data; + + if(err != ESP_OK) + { + bOtaAbortTx = true; + sMeshPacket.type = OTA_Abort; + } + + if((OTA_MESH_SEGMENT_SIZE * (u32SegmentCounterTx+1)) >= pBootPartitionTx->size) //check if last segment + { + ESP_LOGI(LOG_TAG, "//last partition image segment --> send OTA_Complete"); + sMeshPacket.type = OTA_Complete; + ESP_LOGE(LOG_TAG, "u32SegmentCounterTx: %i", u32SegmentCounterTx); + } + + err = errSendMeshPacket(&puMeshPacket->meshSenderAddr, &sMeshPacket); + + u32SegmentCounterTx++; + } + + + + } +/* + void vRecOtaCompleteHandler(MESH_PACKET_t* puMeshPacket) + { +return; + } + + void vRecOtaAbortHandler(MESH_PACKET_t* puMeshPacket) + { +return; + } + */ \ No newline at end of file diff --git a/components/mesh_ota/Mesh_network.c b/components/mesh_ota/Mesh_network.c index e28c1c8..c1beff6 100644 --- a/components/mesh_ota/Mesh_network.c +++ b/components/mesh_ota/Mesh_network.c @@ -14,6 +14,12 @@ void (*pOTAChildConnectHandle)(uint8_t* ); void (*pOTAMessageHandle)(MESH_PACKET_t* ); void (*pChangeStateOfServerWorkerHandle)(bool ); +void (*pOtaDataHandle)(MESH_PACKET_t* ); +void (*pOtaAckHandle)(MESH_PACKET_t* ); +void (*pOtaCompleteHandle)(MESH_PACKET_t* ); +void (*pOtaAbortHandle)(MESH_PACKET_t* ); + + esp_err_t errMeshNetworkInitialize() { //init module variables @@ -230,12 +236,36 @@ esp_err_t errMeshNetworkSetChildConnectedHandle(void (*pChildConnectHandleTmp)(u return ESP_OK; } -esp_err_t errMeshNetworkSetOTAMessageHandleHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)) +esp_err_t errMeshNetworkSetOTAMessageHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)) { pOTAMessageHandle = pOTAMessageHandleTmp; return ESP_OK; } +esp_err_t errMeshNetworkSetOtaDataHandle(void (*pOtaDataHandleTmp)(MESH_PACKET_t* puMeshPacket)) +{ + pOtaDataHandle = pOtaDataHandleTmp; + return ESP_OK; +} + +esp_err_t errMeshNetworkSetOtaAckHandle(void (*pOtaAckHandleTmp)(MESH_PACKET_t* puMeshPacket)) +{ + pOtaAckHandle = pOtaAckHandleTmp; + return ESP_OK; +} + +esp_err_t errMeshNetworkSetOtaCompleteHandle(void (*pOtaCompleteHandleTmp)(MESH_PACKET_t* puMeshPacket)) +{ + pOtaCompleteHandle = pOtaCompleteHandleTmp; + return ESP_OK; +} + +esp_err_t errMeshNetworkSetOtaAbortHandle(void (*pOtaAbortHandleTmp)(MESH_PACKET_t* puMeshPacket)) +{ + pOtaAbortHandle = pOtaAbortHandleTmp; + return ESP_OK; +} + esp_err_t errMeshNetworkSetChangeStateOfServerWorkerHandle(void (*pChangeStateOfServerWorkerHandleTmp)(bool bState)) { pChangeStateOfServerWorkerHandle = pChangeStateOfServerWorkerHandleTmp; @@ -302,8 +332,6 @@ void vTaskReceiveMeshData(void *arg) break; case OTA_Version_Request: case OTA_Version_Response: - case OTA_Data: - case OTA_ACK: case OTA_Complete: case OTA_Abort: //call the rx handle from OTA @@ -312,6 +340,31 @@ void vTaskReceiveMeshData(void *arg) pOTAMessageHandle(&packet); } break; + case OTA_Data: + if(pOtaDataHandle) + { + pOtaDataHandle(&packet); + } + break; + case OTA_ACK: + if(pOtaAckHandle) + { + pOtaAckHandle(&packet); + } + break; + /* case OTA_Complete: + if(pOtaCompleteHandle) + { + pOtaCompleteHandle(&packet); + } + break; + case OTA_Abort: + if(pOtaAbortHandle) + { + pOtaAbortHandle(&packet); + } + break; + */ default: ESP_LOGE(LOG_TAG, "recv: something"); break; @@ -321,5 +374,3 @@ void vTaskReceiveMeshData(void *arg) - - diff --git a/components/mesh_ota/include/Mesh_OTA.h b/components/mesh_ota/include/Mesh_OTA.h index d83710d..aeb7c50 100644 --- a/components/mesh_ota/include/Mesh_OTA.h +++ b/components/mesh_ota/include/Mesh_OTA.h @@ -23,6 +23,7 @@ #define OTA_HTTPS_SEGMENT_SIZE 2048U #define OTA_PROGRESS_LOG_INTERVAL 7U #define OTA_MESH_SEGMENT_SIZE MESH_NETWORK_PAYLOAD_SIZE +#define OTA_MESH_TIMEOUT 100U //in ms #define ERROR_CHECK(x) if (err == ESP_OK) \ { \ @@ -64,6 +65,11 @@ void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC); void vAddOTAControllMessageToQueue(MESH_PACKET_t* puMeshPacket); void vChangeStateOfServerWorker(bool state); +void vRecOtaDataHandler(MESH_PACKET_t* puMeshPacket); +void vRecOtaAckHandler(MESH_PACKET_t* puMeshPacket); +//void vRecOtaCompleteHandler(MESH_PACKET_t* puMeshPacket); +//void vRecOtaAbortHandler(MESH_PACKET_t* puMeshPacket); + //Tasks void vTaskServerWorker(void *arg); void vTaskOTAWorker(void *arg); diff --git a/components/mesh_ota/include/Mesh_network.h b/components/mesh_ota/include/Mesh_network.h index b4c2d13..edd1c3c 100644 --- a/components/mesh_ota/include/Mesh_network.h +++ b/components/mesh_ota/include/Mesh_network.h @@ -80,7 +80,12 @@ esp_err_t errMeshNetworkInitializeRouter(mesh_cfg_t* cfg); esp_err_t errMeshNetworkSetAppReceiveHandle(void (*pAppRxHandleTmp)(uint8_t * pu8Data, uint8_t* pu8Sender)); esp_err_t errMeshNetworkSetChildConnectedHandle(void (*pChildConnectHandleTmp)(uint8_t * pu8Data)); -esp_err_t errMeshNetworkSetOTAMessageHandleHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)); +esp_err_t errMeshNetworkSetOTAMessageHandle(void (*pOTAMessageHandleTmp)(MESH_PACKET_t* puMeshPacket)); + +esp_err_t errMeshNetworkSetOtaDataHandle(void (*pOtaDataHandleTmp)(MESH_PACKET_t* puMeshPacket)); +esp_err_t errMeshNetworkSetOtaAckHandle(void (*pOtaAckHandleTmp)(MESH_PACKET_t* puMeshPacket)); +esp_err_t errMeshNetworkSetOtaCompleteHandle(void (*pOtaCompleteHandleTmp)(MESH_PACKET_t* puMeshPacket)); +esp_err_t errMeshNetworkSetOtaAbortHandle(void (*pOtaAbortHandleTmp)(MESH_PACKET_t* puMeshPacket)); esp_err_t errMeshNetworkSetChangeStateOfServerWorkerHandle(void (*pChangeStateOfServerWorkerHandleTmp)(bool bState));