Compare commits
	
		
			1 Commits
		
	
	
		
			master
			...
			feature/bl
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7301305135 | 
| @ -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; | ||||
|     } | ||||
|     */ | ||||
| @ -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) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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)); | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user