Mesh OTA Master & Slave
This commit is contained in:
parent
b274d939c4
commit
94aa8751cb
@ -248,15 +248,10 @@ void vTaskOTAWorker(void *arg)
|
|||||||
bWantReboot = true;
|
bWantReboot = true;
|
||||||
vAddAllNeighboursToQueue(); //add all existing neighbours to queue
|
vAddAllNeighboursToQueue(); //add all existing neighbours to queue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
vTaskDelay( (1000) / portTICK_PERIOD_MS);
|
vTaskDelay( (1000) / portTICK_PERIOD_MS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
|
esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
@ -284,7 +279,7 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
|
|||||||
if(bNewerVersion((bootPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version
|
if(bNewerVersion((bootPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version
|
||||||
{
|
{
|
||||||
// server image is newer --> OTA update required
|
// server image is newer --> OTA update required
|
||||||
ESP_LOGI(LOG_TAG, "server image is newer --> OTA update required");
|
ESP_LOGI(LOG_TAG, "Server: image is newer --> OTA update required");
|
||||||
|
|
||||||
ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
|
ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
|
||||||
|
|
||||||
@ -306,7 +301,7 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
|
|||||||
u32OTABytesWritten = u32OTABytesWritten + u32BytesRead; //update counter
|
u32OTABytesWritten = u32OTABytesWritten + u32BytesRead; //update counter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ((u32BytesRead > 0) && (err == ESP_OK)); //loop until error or complete image downloaded
|
while ((u32BytesRead > 0) && (err == ESP_OK) && (u32OTABytesWritten <= pOTAPartition->size)); //loop until error or complete image downloaded
|
||||||
}
|
}
|
||||||
|
|
||||||
if(err == ESP_OK)
|
if(err == ESP_OK)
|
||||||
@ -361,7 +356,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
|
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
|
ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadata of partition
|
||||||
|
|
||||||
//send OTA_Version_Response to sender of OTA_Version_Request packet
|
//send OTA_Version_Response to sender of OTA_Version_Request packet wirh version in payload
|
||||||
ERROR_CHECK(errSendOTAVersionResponse(&sOTAMessage.meshSenderAddr));
|
ERROR_CHECK(errSendOTAVersionResponse(&sOTAMessage.meshSenderAddr));
|
||||||
|
|
||||||
if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version
|
if((bNewerVersion((bootPartitionDesc).version, (char*) sOTAMessage.au8Payload)) && (err == ESP_OK)) //compare local and remote version
|
||||||
@ -388,26 +383,77 @@ esp_err_t errOTAMeshMaster(bool* pbNewOTAImage, mesh_addr_t* pMeshNodeAddr)
|
|||||||
esp_err_t err = ESP_OK;
|
esp_err_t err = ESP_OK;
|
||||||
MESH_PACKET_t sOTAMessage;
|
MESH_PACKET_t sOTAMessage;
|
||||||
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)
|
||||||
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
|
esp_app_desc_t bootPartitionDesc; //Metadata from boot partition
|
||||||
|
bool bNodeIsConnected = false;
|
||||||
|
bool bNodeIsResponding = false;
|
||||||
|
|
||||||
*pbNewOTAImage = false; //set default false
|
*pbNewOTAImage = false; //set default false
|
||||||
|
|
||||||
//get node
|
if(bIsNodeNeighbour(pMeshNodeAddr) == true) //check if node is still connected
|
||||||
//check if node is still connected
|
{
|
||||||
// --> send OTA_Version_Request
|
bNodeIsConnected = true; //node is one of the neighbours
|
||||||
// --> read OTA_Version_Response (if from this node) (all other OTA message add again)
|
xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
|
||||||
// --> this version older --> start OTA_Rx --> vAddAllNeighboursToQueue(); //add all existing neighbours to queues
|
|
||||||
|
ERROR_CHECK(errSendOTAVersionRequest(pMeshNodeAddr)); //send OTA_VERSION_REQUEST with local version in payload
|
||||||
|
|
||||||
|
//read OTA_Version_Response (if from this node) (all other OTA message add again)
|
||||||
|
// if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
|
||||||
|
//{
|
||||||
|
|
||||||
|
for (uint32_t u32Index = 0; u32Index < QUEUE_MESSAGE_OTA_SIZE; u32Index++) //loop through all OTA messages
|
||||||
|
{
|
||||||
|
if(uxQueueSpacesAvailable(queueMessageOTA) < QUEUE_MESSAGE_OTA_SIZE)
|
||||||
|
{
|
||||||
|
//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;
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// --> this version newer --> start OTA_Tx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//send wrong OTA message back to queue
|
||||||
|
vAddOTAControllMessageToQueue(&sOTAMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//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
|
||||||
|
vAddNodeToPossibleUpdatableQueue(pMeshNodeAddr->addr);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return true if remote version is newer (higher) than local version
|
|
||||||
*/
|
|
||||||
bool bNewerVersion(const char* pu8Local, const char* pu8Remote)
|
bool bNewerVersion(const char* pu8Local, const char* pu8Remote)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Return true if remote version is newer (higher) than local version
|
||||||
|
*/
|
||||||
char u8LocalTmp[12]; //local version
|
char u8LocalTmp[12]; //local version
|
||||||
char u8RemoteTmp[12]; //remote version
|
char u8RemoteTmp[12]; //remote version
|
||||||
char* pu8saveptrLocal; //context for strok_r
|
char* pu8saveptrLocal; //context for strok_r
|
||||||
@ -593,6 +639,22 @@ esp_err_t errSendOTAVersionResponse(mesh_addr_t* pMeshReceiverAddr)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t errSendOTAVersionRequest(mesh_addr_t* pMeshReceiverAddr)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
MESH_PACKET_t packet;
|
||||||
|
packet.type = OTA_Version_Request;
|
||||||
|
|
||||||
|
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_Request packet
|
||||||
|
err = errSendMeshPacket(pMeshReceiverAddr, &packet);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
|
esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +183,41 @@ bool bIsRootNode()
|
|||||||
return esp_mesh_is_root();
|
return esp_mesh_is_root();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bIsNodeNeighbour(mesh_addr_t* pNode)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
bool bReturn = false;
|
||||||
|
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 = 0U; //number of children attached to this node
|
||||||
|
|
||||||
|
err = errGetParentNode(&addrParent);
|
||||||
|
|
||||||
|
if(err == ESP_OK)
|
||||||
|
{
|
||||||
|
if(bCheckMACEquality(pNode->addr, addrParent.addr) == true)
|
||||||
|
{
|
||||||
|
bReturn = true; //node was found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bReturn == false)
|
||||||
|
{
|
||||||
|
err = ESP_OK; //reset error code
|
||||||
|
|
||||||
|
ERROR_CHECK(errGetChildren(childrenAddr, &u16ChildrenSize)); //get all children
|
||||||
|
|
||||||
|
for (uint16_t u16Index = 0; ((u16Index < u16ChildrenSize) && (err == ESP_OK) && (bReturn == false)); u16Index++)
|
||||||
|
{
|
||||||
|
if(bCheckMACEquality(pNode->addr, childrenAddr[u16Index].addr) == true)
|
||||||
|
{
|
||||||
|
bReturn = true; //node was found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bReturn;
|
||||||
|
}
|
||||||
|
|
||||||
esp_err_t errMeshNetworkSetAppReceiveHandle(void (*pAppRxHandleTmp)(uint8_t * pu8Data, uint8_t* pu8Sender))
|
esp_err_t errMeshNetworkSetAppReceiveHandle(void (*pAppRxHandleTmp)(uint8_t * pu8Data, uint8_t* pu8Sender))
|
||||||
{
|
{
|
||||||
pAppRxHandle = pAppRxHandleTmp; //set handle from app as receive handle if an app packet is received
|
pAppRxHandle = pAppRxHandleTmp; //set handle from app as receive handle if an app packet is received
|
||||||
|
@ -45,6 +45,7 @@ esp_err_t errFindImageStart(const char* pu8Data, uint32_t* pu32DataLenght, uint
|
|||||||
void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten);
|
void vPrintOTAProgress(const uint32_t* const pu32TotalImageSize, const uint32_t* const pu32BytesWritten);
|
||||||
void vAddAllNeighboursToQueue(void);
|
void vAddAllNeighboursToQueue(void);
|
||||||
esp_err_t errSendOTAVersionResponse(mesh_addr_t* meshReceiverAddr);
|
esp_err_t errSendOTAVersionResponse(mesh_addr_t* meshReceiverAddr);
|
||||||
|
esp_err_t errSendOTAVersionRequest(mesh_addr_t* meshReceiverAddr);
|
||||||
|
|
||||||
//Handler
|
//Handler
|
||||||
void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC);
|
void vAddNodeToPossibleUpdatableQueue(uint8_t* pu8MAC);
|
||||||
|
@ -87,6 +87,7 @@ void vGetOwnAddr(mesh_addr_t* pMeshOwnAddr);
|
|||||||
esp_err_t errGetParentNode(mesh_addr_t* pMeshParentAddr);
|
esp_err_t errGetParentNode(mesh_addr_t* pMeshParentAddr);
|
||||||
esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize);
|
esp_err_t errGetChildren(mesh_addr_t* pChildren, uint16_t* pu16ChildrenSize);
|
||||||
bool bIsRootNode();
|
bool bIsRootNode();
|
||||||
|
bool bIsNodeNeighbour(mesh_addr_t* pNode);
|
||||||
|
|
||||||
esp_err_t errStartReceiveTask();
|
esp_err_t errStartReceiveTask();
|
||||||
void vTaskReceiveMeshData(void *arg);
|
void vTaskReceiveMeshData(void *arg);
|
||||||
|
Loading…
Reference in New Issue
Block a user