diff --git a/.gitignore b/.gitignore
index 19e3a2a..e73ccd5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,3 +60,4 @@ test/build/
*.orig
+Doxygen/html/
diff --git a/README.md b/README.md
index 1b9f76c..8d93590 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,4 @@
# ESP32-Mesh-OTA
-## Work in progress
-
-
-## Todo for first release
-
-### Refactoring
-- architecture
-- full error handling through all functions
-- export as a component library
-
-### Features
-- root node: Download new Firmware from HTTPS server instead using newest ota partition
-- add example main app
-
-
diff --git a/components/mesh_ota/Mesh_OTA.c b/components/mesh_ota/Mesh_OTA.c
index bf1388b..699f5d9 100644
--- a/components/mesh_ota/Mesh_OTA.c
+++ b/components/mesh_ota/Mesh_OTA.c
@@ -114,7 +114,6 @@ esp_err_t errMeshOTAInitialize(void)
err = ESP_FAIL;
}
}
-
return err;
}
@@ -162,7 +161,6 @@ void vMeshOtaTaskServerWorker(void *arg)
//set want reboot
ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, set pending reboot");
bWantReboot = true;
- vMeshOtaUtilAddAllNeighboursToQueue(); //add all existing neighbours to queue (aparent will not be added because this node is the root)
}
vTaskDelay( (SERVER_CHECK_INTERVAL*1000) / portTICK_PERIOD_MS); //sleep till next server checks
}
@@ -182,6 +180,7 @@ void vMeshOtaTaskOTAWorker(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
+ BaseType_t xReturned;
while(true)
{
@@ -190,25 +189,30 @@ void vMeshOtaTaskOTAWorker(void *arg)
if((uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE) == 0)
{
- //nodes queue is empty
- if((bWantReboot == true) && (OTA_ALLOW_REBOOT == 1))
+ ESP_LOGI(LOG_TAG, "//nodes queue is empty");
+
+ xReturned = xSemaphoreTake(bsOTAProcess, portMAX_DELAY); //wait for binary semaphore that allows to start the OTA process
+ if((xReturned == pdTRUE) && (bWantReboot == true) && (OTA_ALLOW_REBOOT == 1))
{
ESP_LOGE(LOG_TAG, "ESP32 Reboot ...");
vTaskDelay( (1000) / portTICK_PERIOD_MS);
esp_restart();
}
+ xSemaphoreGive(bsOTAProcess); //free binary semaphore, this allows other tasks to start the OTA process
ERROR_CHECK(errMeshOtaSlaveEndpoint(&bNewOTAImage));
}
else
{
- //queue not empty
+ ESP_LOGI(LOG_TAG, "//queue not empty %i", (uxQueueSpacesAvailable(queueNodes) - QUEUE_NODES_SIZE));
if (xQueueReceive(queueNodes, &meshNodeAddr, ((100) / portTICK_PERIOD_MS)) != pdTRUE)
{
ESP_LOGE(LOG_TAG, "Unable to receive OTA Messages from Queue");
err = ESP_FAIL;
}
+ ESP_LOGI(LOG_TAG, "//handle node %x", meshNodeAddr.addr[5]);
+
ERROR_CHECK(errMeshOtaMasterEndpoint(&bNewOTAImage, &meshNodeAddr));
if (err != ESP_OK)
@@ -275,7 +279,7 @@ esp_err_t errMeshOtaSlaveEndpoint(bool* const cpbNewOTAImage)
if((bMeshOtaUtilNewerVersion((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");
+ ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required from node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version older --> start OTA_Rx --> set cpbNewOTAImage true
ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(cpbNewOTAImage, &sOTAMessage.meshSenderAddr));
}
@@ -283,7 +287,7 @@ esp_err_t errMeshOtaSlaveEndpoint(bool* const cpbNewOTAImage)
if((bMeshOtaUtilNewerVersion((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");
+ ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required to node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version newer --> start OTA_Tx
ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr));
}
@@ -343,7 +347,7 @@ esp_err_t errMeshOtaMasterEndpoint(bool* const cpbNewOTAImage, const mesh_addr_t
if((bMeshOtaUtilNewerVersion((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");
+ ESP_LOGI(LOG_TAG, "remote image on node is newer --> OTA update required from node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version older --> start OTA_Rx --> set cpbNewOTAImage true
ERROR_CHECK(errMeshOtaPartitionAccessMeshReceive(cpbNewOTAImage, &sOTAMessage.meshSenderAddr));
}
@@ -351,7 +355,7 @@ esp_err_t errMeshOtaMasterEndpoint(bool* const cpbNewOTAImage, const mesh_addr_t
if((bMeshOtaUtilNewerVersion((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");
+ ESP_LOGI(LOG_TAG, "remote image on node is older --> OTA send required to node \"%x:%x:%x:%x:%x:%x\"", sOTAMessage.meshSenderAddr.addr[0], sOTAMessage.meshSenderAddr.addr[1], sOTAMessage.meshSenderAddr.addr[2], sOTAMessage.meshSenderAddr.addr[3], sOTAMessage.meshSenderAddr.addr[4], sOTAMessage.meshSenderAddr.addr[5]);
// --> this version newer --> start OTA_Tx
ERROR_CHECK(errMeshOtaPartitionAccessMeshTransmit(&sOTAMessage.meshSenderAddr));
}
diff --git a/components/mesh_ota/Mesh_OTA_Partition_Access.c b/components/mesh_ota/Mesh_OTA_Partition_Access.c
index a545b11..8a6e63f 100644
--- a/components/mesh_ota/Mesh_OTA_Partition_Access.c
+++ b/components/mesh_ota/Mesh_OTA_Partition_Access.c
@@ -89,6 +89,7 @@ esp_err_t errMeshOtaPartitionAccessHttps(bool* const cpbNewOTAImage)
if(err == ESP_OK)
{
*cpbNewOTAImage = true; //image validated
+ vMeshOtaUtilAddAllNeighboursToQueue(); //add all existing neighbours to queue (aparent will not be added because this node is the root)
}
}
else
diff --git a/components/mesh_ota/Mesh_OTA_Util.c b/components/mesh_ota/Mesh_OTA_Util.c
index c6ec2db..712329f 100644
--- a/components/mesh_ota/Mesh_OTA_Util.c
+++ b/components/mesh_ota/Mesh_OTA_Util.c
@@ -328,17 +328,24 @@ void vMeshOtaUtilClearOtaMessageQueue(const mesh_addr_t* const cpcMeshNodeAddr)
void vMeshOtaUtilClearNeighboursQueue(const mesh_addr_t* const cpcMeshNodeAddr)
{
mesh_addr_t sNode; //packet for sending and receiving
- for (uint32_t u32Index = 0; (u32Index < QUEUE_MESSAGE_OTA_SIZE); u32Index++) //loop through all OTA messages
+ for (uint32_t u32Index = 0; (u32Index < QUEUE_NODES_SIZE); u32Index++) //loop through all node queue
{
if (xQueueReceive(queueNodes, &sNode, 0) == pdTRUE)
{
- if(!(bMeshNetworkCheckMacEquality(sNode.addr, cpcMeshNodeAddr->addr)))
+ if((bMeshNetworkCheckMacEquality(sNode.addr, cpcMeshNodeAddr->addr)))
{
- //node is NOT cpcMeshNodeAddr --> keep it in queue
- vMeshOtaUtilAddNodeToPossibleUpdatableQueue(cpcMeshNodeAddr->addr);
+ ESP_LOGI(LOG_TAG, "REMOVE_NODE: remove node %x", sNode.addr[5]);
}
+ else
+ {
+ ESP_LOGI(LOG_TAG, "//node is NOT cpcMeshNodeAddr: %i --> keep it in queue", sNode.addr[5]);
+ vMeshOtaUtilAddNodeToPossibleUpdatableQueue(sNode.addr);
+ }
+
+ }else{
+ ESP_LOGI(LOG_TAG, "REMOVE_NODE: queue leer");
}
- }//end OTA message loop
+ }//end nodes
}
/**
@@ -361,7 +368,7 @@ void vMeshOtaUtilAddNodeToPossibleUpdatableQueue(const uint8_t* const cpcu8MAC)
}
else
{
- ESP_LOGD(LOG_TAG, "added node \"%x:%x:%x:%x:%x:%x\" to possible updatable queue", addrNode.addr[0], addrNode.addr[1], addrNode.addr[2], addrNode.addr[3], addrNode.addr[4], addrNode.addr[5]);
+ ESP_LOGI(LOG_TAG, "added node \"%x:%x:%x:%x:%x:%x\" to possible updatable queue", addrNode.addr[0], addrNode.addr[1], addrNode.addr[2], addrNode.addr[3], addrNode.addr[4], addrNode.addr[5]);
}
}
diff --git a/components/mesh_ota/include/Mesh_OTA.h b/components/mesh_ota/include/Mesh_OTA.h
index c6d7c4d..d28421f 100644
--- a/components/mesh_ota/include/Mesh_OTA.h
+++ b/components/mesh_ota/include/Mesh_OTA.h
@@ -18,14 +18,14 @@
#include "HTTPS_Client.h"
#define ERASE_NVS //erase non volatile storage if full
-#define QUEUE_NODES_SIZE 10
-#define QUEUE_MESSAGE_OTA_SIZE 10
+#define QUEUE_NODES_SIZE 20
+#define QUEUE_MESSAGE_OTA_SIZE 20
#define SERVER_CHECK_INTERVAL 30 //in seconds
#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 20000U //in ms
-#define OTA_ALLOW_REBOOT 0
+#define OTA_ALLOW_REBOOT 1
#define ERROR_CHECK(x) if (err == ESP_OK) \
{ \
diff --git a/components/mesh_ota/test/test_mesh_ota.c b/components/mesh_ota/test/test_mesh_ota.c
index ff8a866..d14d66f 100644
--- a/components/mesh_ota/test/test_mesh_ota.c
+++ b/components/mesh_ota/test/test_mesh_ota.c
@@ -1,7 +1,7 @@
#include
#include "unity.h"
-#include "Mesh_OTA.h"
+#include "Mesh_OTA_Util.h"
#include "test_image_hex.h"
// ### ### ### distinguish newer image version ### ### ###
diff --git a/main/Blinky_LED.c b/main/Blinky_LED.c
index 56160c3..d3e5102 100644
--- a/main/Blinky_LED.c
+++ b/main/Blinky_LED.c
@@ -61,6 +61,11 @@ esp_err_t errBlinkyLEDInitialize(void)
err = ESP_FAIL;
}
}
+
+#ifdef NEW_VERSION
+ gpio_set_level(GPIO_LED_GREEN, 1); //switch on
+#endif
+
return err;
}
@@ -79,8 +84,13 @@ void vGPIOInitialize(void)
gpio_config_t gpioConf;
//LED as Output
- gpio_reset_pin(GPIO_LED);
- gpio_set_direction(GPIO_LED, GPIO_MODE_OUTPUT);
+ gpio_reset_pin(GPIO_LED_BLUE);
+ gpio_set_direction(GPIO_LED_BLUE, GPIO_MODE_OUTPUT);
+
+#ifdef NEW_VERSION
+ gpio_reset_pin(GPIO_LED_GREEN);
+ gpio_set_direction(GPIO_LED_GREEN, GPIO_MODE_OUTPUT);
+#endif
//BTN as Input
gpioConf.intr_type = GPIO_INTR_DISABLE;
@@ -212,19 +222,19 @@ void vTaskReceiveData(void *arg)
{
case LED_ON:
bLEDisOn = true;
- gpio_set_level(GPIO_LED, 1); //switch on
+ gpio_set_level(GPIO_LED_BLUE, 1); //switch on
ESP_LOGI(LOG_TAG,"switch LED ON");
break;
case LED_OFF:
bLEDisOn = false;
- gpio_set_level(GPIO_LED, 0); //switch off
+ gpio_set_level(GPIO_LED_BLUE, 0); //switch off
ESP_LOGI(LOG_TAG,"switch LED OFF");
break;
default:
bLEDisOn = false;
- gpio_set_level(GPIO_LED, 0); //switch off
+ gpio_set_level(GPIO_LED_BLUE, 0); //switch off
ESP_LOGI(LOG_TAG,"switch LED OFF");
break;
}
diff --git a/main/Blinky_LED.h b/main/Blinky_LED.h
index c25cf04..909d5d4 100644
--- a/main/Blinky_LED.h
+++ b/main/Blinky_LED.h
@@ -20,9 +20,13 @@
#include "Mesh_OTA.h"
+//#define NEW_VERSION
#define GPIO_BOOT_BTN 0 //GPIO0 (Boot BTN)
-#define GPIO_LED 2 //GPIO2 (internal blue LED in DevKit V1.0)
+#define GPIO_LED_BLUE 2 //GPIO2 (internal blue LED in DevKit V1.0)
+#ifdef NEW_VERSION
+#define GPIO_LED_GREEN 13 //GPIO13
+#endif
#define GPIO_INPUT_PIN_SEL (1ULL<