Browse Source

OTA mesh worker

feature/blockingOTA
Hendrik Schutter 1 year ago
parent
commit
b274d939c4
  1. 199
      components/mesh_ota/Mesh_OTA.c
  2. 4
      components/mesh_ota/Mesh_network.c
  3. 3
      components/mesh_ota/include/Mesh_OTA.h
  4. 2
      components/mesh_ota/include/Mesh_network.h

199
components/mesh_ota/Mesh_OTA.c

@ -160,41 +160,6 @@ void vChangeStateOfServerWorker(bool bState) //allow access via function ptn to
}
}
void vTaskOTAWorker(void *arg)
{
while(true)
{
if((uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE) == 0)
{
//nodes queue is empty
ESP_LOGI(LOG_TAG, "nodes queue is empty");
if(bWantReboot == true)
{
ESP_LOGI(LOG_TAG, "ESP32 Reboot ...");
//vTaskDelay( (1000) / portTICK_PERIOD_MS);
//esp_restart();
}
//read OTAMessages queue
//if OTA_Version_Response
// --> send OTA_Version_Request
// --> this version older --> start OTA_Rx --> vAddAllNeighboursToQueue(); //add all existing neighbours to queues
// --> this version newer --> start OTA_Tx
//if not OTA_Version_Response --> do nothing
}
vTaskDelay( (1000) / portTICK_PERIOD_MS);
}
}
void vTaskServerWorker(void *arg)
{
esp_err_t err;
@ -237,6 +202,61 @@ void vTaskServerWorker(void *arg)
}
}
void vTaskOTAWorker(void *arg)
{
esp_err_t err = ESP_OK;
bool bNewOTAImage; //true if a new ota image was downloaded and validated
mesh_addr_t meshNodeAddr; //node that should be checked for ota update
while(true)
{
err = ESP_OK;
bNewOTAImage = false;
if((uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE) == 0)
{
//nodes queue is empty
ESP_LOGI(LOG_TAG, "nodes queue is empty");
if(bWantReboot == true)
{
ESP_LOGI(LOG_TAG, "ESP32 Reboot ...");
//vTaskDelay( (1000) / portTICK_PERIOD_MS);
//esp_restart();
}
ERROR_CHECK(errOTAMeshSlave(&bNewOTAImage));
}
else
{
//queue not empty
ESP_LOGI(LOG_TAG, "nodes queue not empty: %i", (QUEUE_NODES_SIZE - uxQueueSpacesAvailable(queueNodes)));
if (xQueueReceive(queueNodes, &meshNodeAddr, ((100) / portTICK_PERIOD_MS)) != pdTRUE)
{
ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from Queue");
err = ESP_FAIL;
}
ERROR_CHECK(errOTAMeshMaster(&bNewOTAImage, &meshNodeAddr));
}
if(bNewOTAImage == true)
{
//set want reboot
ESP_LOGI(LOG_TAG, "Updated successfully via Mesh, set pending reboot");
bWantReboot = true;
vAddAllNeighboursToQueue(); //add all existing neighbours to queue
}
vTaskDelay( (1000) / portTICK_PERIOD_MS);
}
}
esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
{
esp_err_t err = ESP_OK;
@ -250,15 +270,17 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
uint32_t u32OTABytesWritten = 0U; //counter unsed for progress log
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 metadate of partition
ERROR_CHECK(errHTTPSClientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version
ERROR_CHECK(errExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers
if(err == ESP_OK) //check if version number is found
{
xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
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, pcRemoteVersionNumber)) //compare local and remote version
{
// server image is newer --> OTA update required
@ -266,8 +288,6 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process
if(err == ESP_OK)
{
@ -306,16 +326,83 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
ERROR_CHECK(esp_ota_abort(otaHandle));
*pbNewOTAImage = false; //ota update failed
}
xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
}
else
{
ESP_LOGI(LOG_TAG, "server image is NOT newer --> OTA update NOT required");
}
xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
} //end version number extracted
return err;
}
esp_err_t errOTAMeshSlave(bool* pbNewOTAImage)
{
esp_err_t err = ESP_OK;
MESH_PACKET_t sOTAMessage;
const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset)
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
*pbNewOTAImage = false; //set default false
//read OTAMessages queue
if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
{
//queue not empty
if (xQueueReceive(queueMessageOTA, &sOTAMessage, ((100) / 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_Request)) //if OTA_Version_Request
{
xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
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
ERROR_CHECK(errSendOTAVersionResponse(&sOTAMessage.meshSenderAddr));
if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version
{
//remote newer as local
ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required");
// --> this version older --> start OTA_Rx --> set pbNewOTAImage true
}
if((bNewerVersion((char*) sOTAMessage.au8Payload, (bootPartitionDesc).version)) && (err == ESP_OK)) //compare remote and local version
{
//local newer as remote
ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required");
// --> this version newer --> start OTA_Tx
}
xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
}
}
return err;
}
esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
{
esp_err_t err = ESP_OK;
MESH_PACKET_t sOTAMessage;
const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset)
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
*pbNewOTAImage = false; //set default false
//get node
//check if node is still connected
// --> send OTA_Version_Request
// --> read OTA_Version_Response (if from this node) (all other OTA message add again)
// --> this version older --> start OTA_Rx --> vAddAllNeighboursToQueue(); //add all existing neighbours to queues
// --> this version newer --> start OTA_Tx
return err;
}
/*
* Return true if remote version is newer (higher) than local version
*/
@ -328,8 +415,8 @@ bool bNewerVersion(const char* pu8Local, const char* pu8Remote)
bool bReturn = false; //flag to stop loop
uint8_t u8Index = 0; //numbers counter in version string
strcpy(u8LocalTmp, pu8Local); //copy in tmp
strcpy(u8RemoteTmp, pu8Remote); //copy in tmp
strncpy(u8LocalTmp, pu8Local, 12); //copy in tmp
strncpy(u8RemoteTmp, pu8Remote, 12); //copy in tmp
char* pu8TokenLocal = strtok_r(u8LocalTmp, ".", &pu8saveptrLocal); //split tokens
char* pu8TokenRemote = strtok_r(u8RemoteTmp, ".", &pu8saveptrRemote); //split tokens
@ -469,23 +556,43 @@ void vAddAllNeighboursToQueue(void)
mesh_addr_t addrParent; //addr of parent node
mesh_addr_t childrenAddr[CONFIG_MESH_ROUTE_TABLE_SIZE]; //array of children attached to this node
uint16_t u16ChildrenSize; //number of children attached to this node
uint16_t u16ChildrenSize = 0U; //number of children attached to this node
err = errGetParentNode(&addrParent);
if(err == ESP_OK)
{
vAddNodeToPossibleUpdatableQueue(addrParent.addr);
ESP_LOGI(LOG_TAG, "added parent");
}
err = ESP_OK; //reset error code
ERROR_CHECK(errGetChildren(childrenAddr, &u16ChildrenSize)); //get all children
for (uint16_t u16Index = 0; u16Index < u16ChildrenSize; u16Index++)
for (uint16_t u16Index = 0; ((u16Index < u16ChildrenSize) && (err == ESP_OK)); u16Index++)
{
vAddNodeToPossibleUpdatableQueue(childrenAddr[u16Index].addr);
ESP_LOGI(LOG_TAG, "added child");
}
}
esp_err_t errSendOTAVersionResponse(mesh_addr_t* pMeshReceiverAddr)
{
esp_err_t err = ESP_OK;
MESH_PACKET_t packet;
packet.type = OTA_Version_Response;
const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset)
esp_app_desc_t bootPartitionDesc; //Metadata from boot partition
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 metadate of partition
memcpy(&packet.au8Payload, &bootPartitionDesc.version, 12); //copy local version to OTA_Version_Response packet
err = errSendMeshPacket(pMeshReceiverAddr, &packet);
return err;
}
/*
esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
{
@ -591,4 +698,4 @@ esp_err_t esp_mesh_ota_receive(mesh_addr_t* dest, struct ota_mesh_packet* packet
return err;
}
*/
*/

4
components/mesh_ota/Mesh_network.c

@ -147,7 +147,7 @@ esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize)
if(! (bCheckMACEquality(u8ownMAC, route_table[index].addr)) )
{
//child node
//ESP_LOGI(MESH_TAG, "adding Node: \"0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\" ", route_table[index].addr[0], route_table[index].addr[1], route_table[index].addr[2], route_table[index].addr[3], route_table[index].addr[4], route_table[index].addr[5]);
//ESP_LOGI(LOG_TAG, "adding Node: \"0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\" ", route_table[index].addr[0], route_table[index].addr[1], route_table[index].addr[2], route_table[index].addr[3], route_table[index].addr[4], route_table[index].addr[5]);
pChildren[*pu16ChildrenSize] = route_table[index];
*pu16ChildrenSize = (*pu16ChildrenSize)+1;
}
@ -266,7 +266,7 @@ void vTaskReceiveMeshData(void *arg)
pAppRxHandle(packet.au8Payload, from.addr); //hand over payload and sender of this mesh packet
break;
case OTA_Version_Request:
case OTA_Version_Respone:
case OTA_Version_Response:
case OTA_Data:
case OTA_ACK:
case OTA_Complete:

3
components/mesh_ota/include/Mesh_OTA.h

@ -35,6 +35,8 @@
esp_err_t errMeshOTAInitialize();
esp_err_t errOTAHTTPS(bool* pbNewOTAImage);
esp_err_t errOTAMeshSlave(bool* pbNewOTAImage);
esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr);
//helper functions
bool bNewerVersion(const char* pu8Local, const char* pu8Remote);
@ -42,6 +44,7 @@ esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght
esp_err_t errFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32StartOffset);
void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten);
void vAddAllNeighboursToQueue(void);
esp_err_t errSendOTAVersionResponse(mesh_addr_t* meshReceiverAddr);
//Handler
void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC);

2
components/mesh_ota/include/Mesh_network.h

@ -53,7 +53,7 @@ struct meshPacket
{
APP_Data, //data for application
OTA_Version_Request, //send own version in payload
OTA_Version_Respone, //send own version in payload
OTA_Version_Response, //send own version in payload
OTA_Data, //send image segment
OTA_ACK, //ack image segment
OTA_Complete //signal end of image

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close