Merge pull request 'master' (#3) from master into develop
Reviewed-on: #3
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -60,3 +60,4 @@ test/build/ | ||||
|  | ||||
| *.orig | ||||
|  | ||||
| Doxygen/html/ | ||||
|  | ||||
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
									
									
									
									
								
							| @ -1,19 +1,4 @@ | ||||
| # ESP32-Mesh-OTA | ||||
|  | ||||
| ## Work in progress   | ||||
| <img src="https://patenschaft.bienenweide.org/img/loading.gif" alt="code_example_output" width="50"/> | ||||
|  | ||||
| ## 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 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -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)); | ||||
|                                         } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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]); | ||||
|         } | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -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)                                                               \ | ||||
|     {                                                                                                   \ | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| #include <limits.h> | ||||
| #include "unity.h" | ||||
|  | ||||
| #include "Mesh_OTA.h" | ||||
| #include "Mesh_OTA_Util.h" | ||||
| #include "test_image_hex.h" | ||||
|  | ||||
| // ### ### ###  distinguish newer image version ### ### ### | ||||
|  | ||||
| @ -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; | ||||
|                         } | ||||
|  | ||||
| @ -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<<GPIO_BOOT_BTN) | ||||
|  | ||||
|  | ||||
| @ -13,7 +13,6 @@ static const char *LOG_TAG = "esp_main"; | ||||
| void app_main(void) | ||||
| { | ||||
|     esp_err_t err = ESP_OK; | ||||
|     ESP_LOGI(LOG_TAG, "hardcoded version: 0.0.1"); | ||||
|  | ||||
|     ESP_LOGI(LOG_TAG, "start mesh network"); | ||||
|     err = errMeshNetworkInitialize(); | ||||
|  | ||||
| @ -32,7 +32,7 @@ CONFIG_APP_COMPILE_TIME_DATE=y | ||||
| # CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set | ||||
| # CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set | ||||
| CONFIG_APP_PROJECT_VER_FROM_CONFIG=y | ||||
| CONFIG_APP_PROJECT_VER="0.0.1" | ||||
| CONFIG_APP_PROJECT_VER="0.0.26" | ||||
| CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 | ||||
| # end of Application manager | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user